patch-2.4.0-test3 linux/drivers/pcmcia/cs.c
Next file: linux/drivers/pcmcia/cs_internal.h
Previous file: linux/drivers/pci/pci.ids
Back to the patch index
Back to the overall index
- Lines: 271
- Date:
Wed Jul 5 13:14:49 2000
- Orig file:
v2.4.0-test2/linux/drivers/pcmcia/cs.c
- Orig date:
Thu May 11 15:30:07 2000
diff -u --recursive --new-file v2.4.0-test2/linux/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
@@ -309,50 +309,63 @@
static void unreset_socket(u_long i);
static void parse_events(void *info, u_int events);
-int register_ss_entry(int nsock, struct pccard_operations * ss_entry)
+socket_info_t *pcmcia_register_socket (int slot,
+ struct pccard_operations * ss_entry,
+ int use_bus_pm)
{
- int i, ns;
socket_info_t *s;
+ int i;
- DEBUG(0, "cs: register_ss_entry(%d, 0x%p)\n", nsock, ss_entry);
+ DEBUG(0, "cs: pcmcia_register_socket(0x%p)\n", ss_entry);
- for (ns = 0; ns < nsock; ns++) {
- s = kmalloc(sizeof(struct socket_info_t), GFP_KERNEL);
- memset(s, 0, sizeof(socket_info_t));
-
- s->ss_entry = ss_entry;
- s->sock = ns;
- s->setup.data = sockets;
- s->setup.function = &setup_socket;
- s->shutdown.data = sockets;
- s->shutdown.function = &shutdown_socket;
- /* base address = 0, map = 0 */
- s->cis_mem.flags = 0;
- s->cis_mem.speed = cis_speed;
- s->erase_busy.next = s->erase_busy.prev = &s->erase_busy;
- spin_lock_init(&s->lock);
-
- for (i = 0; i < sockets; i++)
- if (socket_table[i] == NULL) break;
- socket_table[i] = s;
- if (i == sockets) sockets++;
+ s = kmalloc(sizeof(struct socket_info_t), GFP_KERNEL);
+ memset(s, 0, sizeof(socket_info_t));
+
+ s->ss_entry = ss_entry;
+ s->sock = slot;
+ s->setup.data = sockets;
+ s->setup.function = &setup_socket;
+ s->shutdown.data = sockets;
+ s->shutdown.function = &shutdown_socket;
+ /* base address = 0, map = 0 */
+ s->cis_mem.flags = 0;
+ s->cis_mem.speed = cis_speed;
+ s->use_bus_pm = use_bus_pm;
+ s->erase_busy.next = s->erase_busy.prev = &s->erase_busy;
+ spin_lock_init(&s->lock);
+
+ for (i = 0; i < sockets; i++)
+ if (socket_table[i] == NULL) break;
+ socket_table[i] = s;
+ if (i == sockets) sockets++;
- init_socket(s);
- ss_entry->inquire_socket(ns, &s->cap);
+ init_socket(s);
+ ss_entry->inquire_socket(slot, &s->cap);
#ifdef CONFIG_PROC_FS
- if (proc_pccard) {
- char name[3];
- sprintf(name, "%02d", i);
- s->proc = proc_mkdir(name, proc_pccard);
- if (s->proc)
- ss_entry->proc_setup(ns, s->proc);
+ if (proc_pccard) {
+ char name[3];
+ sprintf(name, "%02d", i);
+ s->proc = proc_mkdir(name, proc_pccard);
+ if (s->proc)
+ ss_entry->proc_setup(slot, s->proc);
#ifdef PCMCIA_DEBUG
- if (s->proc)
- create_proc_read_entry("clients", 0, s->proc,
- proc_read_clients, s);
+ if (s->proc)
+ create_proc_read_entry("clients", 0, s->proc,
+ proc_read_clients, s);
#endif
- }
+ }
#endif
+ return s;
+} /* pcmcia_register_socket */
+
+int register_ss_entry(int nsock, struct pccard_operations * ss_entry)
+{
+ int ns;
+
+ DEBUG(0, "cs: register_ss_entry(%d, 0x%p)\n", nsock, ss_entry);
+
+ for (ns = 0; ns < nsock; ns++) {
+ pcmcia_register_socket (ns, ss_entry, 0);
}
return 0;
@@ -360,49 +373,57 @@
/*====================================================================*/
-void unregister_ss_entry(struct pccard_operations * ss_entry)
+void pcmcia_unregister_socket(socket_info_t *s)
{
- int i, j;
- socket_info_t *s = NULL;
+ int j, socket = -1;
client_t *client;
+ for (j = 0; j < MAX_SOCK; j++)
+ if (socket_table [j] == s) {
+ socket = j;
+ break;
+ }
+ if (socket < 0)
+ return;
+
#ifdef CONFIG_PROC_FS
- for (i = 0; i < sockets; i++) {
- s = socket_table[i];
- if (s->ss_entry != ss_entry) continue;
- if (proc_pccard) {
- char name[3];
- sprintf(name, "%02d", i);
+ if (proc_pccard) {
+ char name[3];
+ sprintf(name, "%02d", socket);
#ifdef PCMCIA_DEBUG
- remove_proc_entry("clients", s->proc);
+ remove_proc_entry("clients", s->proc);
#endif
- remove_proc_entry(name, proc_pccard);
- }
+ remove_proc_entry(name, proc_pccard);
}
#endif
- for (;;) {
- for (i = 0; i < sockets; i++) {
- s = socket_table[i];
- if (s->ss_entry == ss_entry) break;
- }
- if (i == sockets)
- break;
- shutdown_socket(i);
- release_cis_mem(s);
- while (s->clients) {
- client = s->clients;
- s->clients = s->clients->next;
- kfree(client);
- }
- s->ss_entry = NULL;
- kfree(s);
- socket_table[i] = NULL;
- for (j = i; j < sockets-1; j++)
- socket_table[j] = socket_table[j+1];
- sockets--;
+ shutdown_socket(socket);
+ release_cis_mem(s);
+ while (s->clients) {
+ client = s->clients;
+ s->clients = s->clients->next;
+ kfree(client);
+ }
+ s->ss_entry = NULL;
+ kfree(s);
+
+ socket_table[socket] = NULL;
+ for (j = socket; j < sockets-1; j++)
+ socket_table[j] = socket_table[j+1];
+ sockets--;
+} /* pcmcia_unregister_socket */
+
+void unregister_ss_entry(struct pccard_operations * ss_entry)
+{
+ int i;
+
+ for (i = 0; i < sockets; i++) {
+ socket_info_t *socket = socket_table[i];
+ if (socket->ss_entry == ss_entry)
+ pcmcia_unregister_socket (socket);
+ else
+ i++;
}
-
} /* unregister_ss_entry */
/*======================================================================
@@ -675,35 +696,51 @@
======================================================================*/
+void pcmcia_suspend_socket (socket_info_t *s)
+{
+ if ((s->state & SOCKET_PRESENT) && !(s->state & SOCKET_SUSPEND)) {
+ send_event(s, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
+ suspend_socket(s);
+ s->state |= SOCKET_SUSPEND;
+ }
+}
+
+void pcmcia_resume_socket (socket_info_t *s)
+{
+ int stat;
+
+ /* Do this just to reinitialize the socket */
+ init_socket(s);
+ get_socket_status(s, &stat);
+
+ /* If there was or is a card here, we need to do something
+ about it... but parse_events will sort it all out. */
+ if ((s->state & SOCKET_PRESENT) || (stat & SS_DETECT))
+ parse_events(s, SS_DETECT);
+}
+
static int handle_pm_event(struct pm_dev *dev, pm_request_t rqst, void *data)
{
- int i, stat;
+ int i;
socket_info_t *s;
-
+
+ /* only for busses that don't suspend/resume slots directly */
+
switch (rqst) {
case PM_SUSPEND:
DEBUG(1, "cs: received suspend notification\n");
for (i = 0; i < sockets; i++) {
- s = socket_table[i];
- if ((s->state & SOCKET_PRESENT) &&
- !(s->state & SOCKET_SUSPEND)){
- send_event(s, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
- suspend_socket(s);
- s->state |= SOCKET_SUSPEND;
- }
+ s = socket_table [i];
+ if (!s->use_bus_pm)
+ pcmcia_suspend_socket (socket_table [i]);
}
break;
case PM_RESUME:
DEBUG(1, "cs: received resume notification\n");
for (i = 0; i < sockets; i++) {
- s = socket_table[i];
- /* Do this just to reinitialize the socket */
- init_socket(s);
- get_socket_status(s, &stat);
- /* If there was or is a card here, we need to do something
- about it... but parse_events will sort it all out. */
- if ((s->state & SOCKET_PRESENT) || (stat & SS_DETECT))
- parse_events(s, SS_DETECT);
+ s = socket_table [i];
+ if (!s->use_bus_pm)
+ pcmcia_resume_socket (socket_table [i]);
}
break;
}
@@ -2330,6 +2367,11 @@
#ifdef CONFIG_PROC_FS
EXPORT_SYMBOL(proc_pccard);
#endif
+
+EXPORT_SYMBOL(pcmcia_register_socket);
+EXPORT_SYMBOL(pcmcia_unregister_socket);
+EXPORT_SYMBOL(pcmcia_suspend_socket);
+EXPORT_SYMBOL(pcmcia_resume_socket);
static int __init init_pcmcia_cs(void)
{
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)