diff options
| author | Dominik Brodowski <linux@brodo.de> | 2003-02-22 18:57:23 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-02-22 18:57:23 -0800 |
| commit | fd0dacffdd8b2d84af68aef59fd2fff662323928 (patch) | |
| tree | 214d76f95c485958300f452270d4834b1e3aae23 | |
| parent | ade30b83754e3731dd7a005524e6af9b4ba356ba (diff) | |
[PATCH] pcmcia: add socket_offset for multiple pci_sockets, correct suspend&resume
- suspend & remove for pci_socket was broken -- thanks to Paul
Mackerras for noting this
- to correctly initialize multiple pci_socket devices, a sock_offset is
needed.
- s_info doesn't need to be an array.
| -rw-r--r-- | drivers/pcmcia/cs.c | 7 | ||||
| -rw-r--r-- | drivers/pcmcia/pci_socket.c | 28 | ||||
| -rw-r--r-- | drivers/pcmcia/pci_socket.h | 1 | ||||
| -rw-r--r-- | include/pcmcia/ss.h | 6 |
4 files changed, 21 insertions, 21 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 88fe64a0ac9d..7ea8dfbc91b4 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -337,13 +337,14 @@ int pcmcia_register_socket(struct device *dev) return -ENOMEM; memset(s_info, 0, cls_d->nsock * sizeof(socket_info_t)); + cls_d->s_info = s_info; + /* socket initialization */ for (i = 0; i < cls_d->nsock; i++) { socket_info_t *s = &s_info[i]; - cls_d->s_info[i] = s; s->ss_entry = cls_d->ops; - s->sock = i; + s->sock = i + cls_d->sock_offset; /* base address = 0, map = 0 */ s->cis_mem.flags = 0; @@ -359,7 +360,7 @@ int pcmcia_register_socket(struct device *dev) if (j == sockets) sockets++; init_socket(s); - s->ss_entry->inquire_socket(i, &s->cap); + s->ss_entry->inquire_socket(s->sock, &s->cap); #ifdef CONFIG_PROC_FS if (proc_pccard) { char name[3]; diff --git a/drivers/pcmcia/pci_socket.c b/drivers/pcmcia/pci_socket.c index 9989b3b45281..da0e6ae74b4c 100644 --- a/drivers/pcmcia/pci_socket.c +++ b/drivers/pcmcia/pci_socket.c @@ -171,6 +171,16 @@ static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_sock int err; memset(socket, 0, sizeof(*socket)); + + /* prepare class_data */ + socket->cls_d.sock_offset = nr; + socket->cls_d.nsock = 1; /* yenta is 1, no other low-level driver uses + this yet */ + socket->cls_d.ops = &pci_socket_operations; + socket->cls_d.use_bus_pm = 1; + dev->dev.class_data = &socket->cls_d; + + /* prepare pci_socket_t */ socket->dev = dev; socket->op = ops; pci_set_drvdata(dev, socket); @@ -186,18 +196,6 @@ static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_sock int cardbus_register(struct pci_dev *p_dev) { - pci_socket_t *socket = pci_get_drvdata(p_dev); - struct pcmcia_socket_class_data *cls_d; - - if (!socket) - return -EINVAL; - - cls_d = &socket->cls_d; - cls_d->nsock = 1; /* yenta is 1, no other low-level driver uses - this yet */ - cls_d->ops = &pci_socket_operations; - cls_d->use_bus_pm = 1; - p_dev->dev.class_data = cls_d; return 0; } @@ -227,14 +225,16 @@ static void __devexit cardbus_remove (struct pci_dev *dev) static int cardbus_suspend (struct pci_dev *dev, u32 state) { pci_socket_t *socket = pci_get_drvdata(dev); - pcmcia_suspend_socket (socket->pcmcia_socket); + if (socket && socket->cls_d.s_info) + pcmcia_suspend_socket (socket->cls_d.s_info); return 0; } static int cardbus_resume (struct pci_dev *dev) { pci_socket_t *socket = pci_get_drvdata(dev); - pcmcia_resume_socket (socket->pcmcia_socket); + if (socket && socket->cls_d.s_info) + pcmcia_resume_socket (socket->cls_d.s_info); return 0; } diff --git a/drivers/pcmcia/pci_socket.h b/drivers/pcmcia/pci_socket.h index 8ec55e3875ab..c5daacaec7c9 100644 --- a/drivers/pcmcia/pci_socket.h +++ b/drivers/pcmcia/pci_socket.h @@ -20,7 +20,6 @@ typedef struct pci_socket { socket_cap_t cap; spinlock_t event_lock; unsigned int events; - struct socket_info_t *pcmcia_socket; struct work_struct tq_task; struct timer_list poll_timer; diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 8e3545132980..2d8fee9e7733 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -145,12 +145,12 @@ struct pccard_operations { * Calls to set up low-level "Socket Services" drivers */ -#define MAX_SOCKETS_PER_DEV 8 - struct pcmcia_socket_class_data { unsigned int nsock; /* number of sockets */ + unsigned int sock_offset; /* socket # (which is + * returned to driver) = sock_offset + (0, 1, .. , (nsock-1) */ struct pccard_operations *ops; /* see above */ - void *s_info[MAX_SOCKETS_PER_DEV]; /* socket_info_t */ + void *s_info; /* socket_info_t */ unsigned int use_bus_pm; }; |
