Commit 782ed19e authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.5-pcmcia

into home.transmeta.com:/home/torvalds/v2.5/linux
parents ad80d2d1 ea814ca7
...@@ -29,8 +29,8 @@ config PCMCIA ...@@ -29,8 +29,8 @@ config PCMCIA
and ds. If you want to compile it as a module, say M here and and ds. If you want to compile it as a module, say M here and
read <file:Documentation/modules.txt>. read <file:Documentation/modules.txt>.
config CARDBUS config YENTA
bool "CardBus support" tristate "CardBus yenta-compatible bridge support"
depends on PCMCIA && PCI depends on PCMCIA && PCI
---help--- ---help---
CardBus is a bus mastering architecture for PC-cards, which allows CardBus is a bus mastering architecture for PC-cards, which allows
...@@ -48,6 +48,11 @@ config CARDBUS ...@@ -48,6 +48,11 @@ config CARDBUS
If unsure, say Y. If unsure, say Y.
config CARDBUS
bool
depends on YENTA
default y if YENTA
config I82092 config I82092
tristate "i82092 compatible bridge support" tristate "i82092 compatible bridge support"
depends on PCMCIA && PCI depends on PCMCIA && PCI
...@@ -58,7 +63,7 @@ config I82092 ...@@ -58,7 +63,7 @@ config I82092
config I82365 config I82365
tristate "i82365 compatible bridge support" tristate "i82365 compatible bridge support"
depends on PCMCIA depends on PCMCIA && ISA
help help
Say Y here to include support for ISA-bus PCMCIA host bridges that Say Y here to include support for ISA-bus PCMCIA host bridges that
are register compatible with the Intel i82365. These are found on are register compatible with the Intel i82365. These are found on
......
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
# #
obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o
ifeq ($(CONFIG_CARDBUS),y) obj-$(CONFIG_YENTA) += yenta.o
obj-$(CONFIG_PCMCIA) += yenta_socket.o
endif
obj-$(CONFIG_I82365) += i82365.o obj-$(CONFIG_I82365) += i82365.o
obj-$(CONFIG_I82092) += i82092.o obj-$(CONFIG_I82092) += i82092.o
...@@ -14,8 +12,6 @@ obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o ...@@ -14,8 +12,6 @@ obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
yenta_socket-y += pci_socket.o yenta.o
pcmcia_core-y += cistpl.o rsrc_mgr.o bulkmem.o cs.o pcmcia_core-y += cistpl.o rsrc_mgr.o bulkmem.o cs.o
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
......
...@@ -63,7 +63,7 @@ static int do_mtd_request(memory_handle_t handle, mtd_request_t *req, ...@@ -63,7 +63,7 @@ static int do_mtd_request(memory_handle_t handle, mtd_request_t *req,
{ {
int ret, tries; int ret, tries;
client_t *mtd; client_t *mtd;
socket_info_t *s; struct pcmcia_socket *s;
mtd = handle->mtd; mtd = handle->mtd;
if (mtd == NULL) if (mtd == NULL)
...@@ -130,7 +130,7 @@ static void retry_erase(erase_busy_t *busy, u_int cause) ...@@ -130,7 +130,7 @@ static void retry_erase(erase_busy_t *busy, u_int cause)
eraseq_entry_t *erase = busy->erase; eraseq_entry_t *erase = busy->erase;
mtd_request_t req; mtd_request_t req;
client_t *mtd; client_t *mtd;
socket_info_t *s; struct pcmcia_socket *s;
int ret; int ret;
DEBUG(2, "cs: trying erase request 0x%p...\n", busy); DEBUG(2, "cs: trying erase request 0x%p...\n", busy);
...@@ -259,27 +259,27 @@ static int mtd_modify_window(window_handle_t win, mtd_mod_win_t *req) ...@@ -259,27 +259,27 @@ static int mtd_modify_window(window_handle_t win, mtd_mod_win_t *req)
win->ctl.flags |= MAP_ATTRIB; win->ctl.flags |= MAP_ATTRIB;
win->ctl.speed = req->AccessSpeed; win->ctl.speed = req->AccessSpeed;
win->ctl.card_start = req->CardOffset; win->ctl.card_start = req->CardOffset;
win->sock->ss_entry->set_mem_map(win->sock->sock, &win->ctl); win->sock->ss_entry->set_mem_map(win->sock, &win->ctl);
return CS_SUCCESS; return CS_SUCCESS;
} }
static int mtd_set_vpp(client_handle_t handle, mtd_vpp_req_t *req) static int mtd_set_vpp(client_handle_t handle, mtd_vpp_req_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
if (req->Vpp1 != req->Vpp2) if (req->Vpp1 != req->Vpp2)
return CS_BAD_VPP; return CS_BAD_VPP;
s = SOCKET(handle); s = SOCKET(handle);
s->socket.Vpp = req->Vpp1; s->socket.Vpp = req->Vpp1;
if (s->ss_entry->set_socket(s->sock, &s->socket)) if (s->ss_entry->set_socket(s, &s->socket))
return CS_BAD_VPP; return CS_BAD_VPP;
return CS_SUCCESS; return CS_SUCCESS;
} }
static int mtd_rdy_mask(client_handle_t handle, mtd_rdy_req_t *req) static int mtd_rdy_mask(client_handle_t handle, mtd_rdy_req_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
s = SOCKET(handle); s = SOCKET(handle);
...@@ -287,7 +287,7 @@ static int mtd_rdy_mask(client_handle_t handle, mtd_rdy_req_t *req) ...@@ -287,7 +287,7 @@ static int mtd_rdy_mask(client_handle_t handle, mtd_rdy_req_t *req)
s->socket.csc_mask |= SS_READY; s->socket.csc_mask |= SS_READY;
else else
s->socket.csc_mask &= ~SS_READY; s->socket.csc_mask &= ~SS_READY;
if (s->ss_entry->set_socket(s->sock, &s->socket)) if (s->ss_entry->set_socket(s, &s->socket))
return CS_GENERAL_FAILURE; return CS_GENERAL_FAILURE;
return CS_SUCCESS; return CS_SUCCESS;
} }
...@@ -417,7 +417,7 @@ static int match_region(client_handle_t handle, memory_handle_t list, ...@@ -417,7 +417,7 @@ static int match_region(client_handle_t handle, memory_handle_t list,
int pcmcia_get_first_region(client_handle_t handle, region_info_t *rgn) int pcmcia_get_first_region(client_handle_t handle, region_info_t *rgn)
{ {
socket_info_t *s = SOCKET(handle); struct pcmcia_socket *s = SOCKET(handle);
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
...@@ -450,7 +450,7 @@ int pcmcia_get_next_region(client_handle_t handle, region_info_t *rgn) ...@@ -450,7 +450,7 @@ int pcmcia_get_next_region(client_handle_t handle, region_info_t *rgn)
int pcmcia_register_mtd(client_handle_t handle, mtd_reg_t *reg) int pcmcia_register_mtd(client_handle_t handle, mtd_reg_t *reg)
{ {
memory_handle_t list; memory_handle_t list;
socket_info_t *s; struct pcmcia_socket *s;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
...@@ -533,12 +533,12 @@ int pcmcia_check_erase_queue(eraseq_handle_t eraseq) ...@@ -533,12 +533,12 @@ int pcmcia_check_erase_queue(eraseq_handle_t eraseq)
int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open, memory_handle_t *mh) int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open, memory_handle_t *mh)
{ {
socket_info_t *s; struct pcmcia_socket *s;
memory_handle_t region; memory_handle_t region;
if ((handle == NULL) || CHECK_HANDLE(*handle)) if ((handle == NULL) || CHECK_HANDLE(*handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
s = SOCKET(*handle); s = (*handle)->Socket;
if (open->Attributes & MEMORY_TYPE_AM) if (open->Attributes & MEMORY_TYPE_AM)
region = s->a_region; region = s->a_region;
else else
......
...@@ -119,11 +119,11 @@ static u_int xlate_rom_addr(u_char * b, u_int addr) ...@@ -119,11 +119,11 @@ static u_int xlate_rom_addr(u_char * b, u_int addr)
These are similar to setup_cis_mem and release_cis_mem for 16-bit These are similar to setup_cis_mem and release_cis_mem for 16-bit
cards. The "result" that is used externally is the cb_cis_virt cards. The "result" that is used externally is the cb_cis_virt
pointer in the socket_info_t structure. pointer in the struct pcmcia_socket structure.
=====================================================================*/ =====================================================================*/
static void cb_release_cis_mem(socket_info_t * s) static void cb_release_cis_mem(struct pcmcia_socket * s)
{ {
if (s->cb_cis_virt) { if (s->cb_cis_virt) {
DEBUG(1, "cs: cb_release_cis_mem()\n"); DEBUG(1, "cs: cb_release_cis_mem()\n");
...@@ -133,7 +133,7 @@ static void cb_release_cis_mem(socket_info_t * s) ...@@ -133,7 +133,7 @@ static void cb_release_cis_mem(socket_info_t * s)
} }
} }
static int cb_setup_cis_mem(socket_info_t * s, struct resource *res) static int cb_setup_cis_mem(struct pcmcia_socket * s, struct resource *res)
{ {
unsigned int start, size; unsigned int start, size;
...@@ -162,7 +162,7 @@ static int cb_setup_cis_mem(socket_info_t * s, struct resource *res) ...@@ -162,7 +162,7 @@ static int cb_setup_cis_mem(socket_info_t * s, struct resource *res)
=====================================================================*/ =====================================================================*/
int read_cb_mem(socket_info_t * s, int space, u_int addr, u_int len, void *ptr) int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void *ptr)
{ {
struct pci_dev *dev; struct pci_dev *dev;
struct resource *res; struct resource *res;
...@@ -237,7 +237,7 @@ static void cardbus_assign_irqs(struct pci_bus *bus, int irq) ...@@ -237,7 +237,7 @@ static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
} }
} }
int cb_alloc(socket_info_t * s) int cb_alloc(struct pcmcia_socket * s)
{ {
struct pci_bus *bus = s->cap.cb_dev->subordinate; struct pci_bus *bus = s->cap.cb_dev->subordinate;
struct pci_dev *dev; struct pci_dev *dev;
...@@ -266,7 +266,7 @@ int cb_alloc(socket_info_t * s) ...@@ -266,7 +266,7 @@ int cb_alloc(socket_info_t * s)
return CS_SUCCESS; return CS_SUCCESS;
} }
void cb_free(socket_info_t * s) void cb_free(struct pcmcia_socket * s)
{ {
struct pci_dev *bridge = s->cap.cb_dev; struct pci_dev *bridge = s->cap.cb_dev;
......
...@@ -82,11 +82,11 @@ static const u_int exponent[] = { ...@@ -82,11 +82,11 @@ static const u_int exponent[] = {
INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */
void release_cis_mem(socket_info_t *s) void release_cis_mem(struct pcmcia_socket *s)
{ {
if (s->cis_mem.sys_start != 0) { if (s->cis_mem.sys_start != 0) {
s->cis_mem.flags &= ~MAP_ACTIVE; s->cis_mem.flags &= ~MAP_ACTIVE;
s->ss_entry->set_mem_map(s->sock, &s->cis_mem); s->ss_entry->set_mem_map(s, &s->cis_mem);
if (!(s->cap.features & SS_CAP_STATIC_MAP)) if (!(s->cap.features & SS_CAP_STATIC_MAP))
release_mem_region(s->cis_mem.sys_start, s->cap.map_size); release_mem_region(s->cis_mem.sys_start, s->cap.map_size);
iounmap(s->cis_virt); iounmap(s->cis_virt);
...@@ -101,7 +101,7 @@ void release_cis_mem(socket_info_t *s) ...@@ -101,7 +101,7 @@ void release_cis_mem(socket_info_t *s)
* map the memory space. * map the memory space.
*/ */
static unsigned char * static unsigned char *
set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags) set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)
{ {
pccard_mem_map *mem = &s->cis_mem; pccard_mem_map *mem = &s->cis_mem;
if (!(s->cap.features & SS_CAP_STATIC_MAP) && if (!(s->cap.features & SS_CAP_STATIC_MAP) &&
...@@ -119,7 +119,7 @@ set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags) ...@@ -119,7 +119,7 @@ set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags)
} }
mem->card_start = card_offset; mem->card_start = card_offset;
mem->flags = flags; mem->flags = flags;
s->ss_entry->set_mem_map(s->sock, mem); s->ss_entry->set_mem_map(s, mem);
if (s->cap.features & SS_CAP_STATIC_MAP) { if (s->cap.features & SS_CAP_STATIC_MAP) {
if (s->cis_virt) if (s->cis_virt)
iounmap(s->cis_virt); iounmap(s->cis_virt);
...@@ -139,7 +139,7 @@ set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags) ...@@ -139,7 +139,7 @@ set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags)
#define IS_ATTR 1 #define IS_ATTR 1
#define IS_INDIRECT 8 #define IS_INDIRECT 8
int read_cis_mem(socket_info_t *s, int attr, u_int addr, int read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr) u_int len, void *ptr)
{ {
u_char *sys, *end, *buf = ptr; u_char *sys, *end, *buf = ptr;
...@@ -202,7 +202,7 @@ int read_cis_mem(socket_info_t *s, int attr, u_int addr, ...@@ -202,7 +202,7 @@ int read_cis_mem(socket_info_t *s, int attr, u_int addr,
return 0; return 0;
} }
void write_cis_mem(socket_info_t *s, int attr, u_int addr, void write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr) u_int len, void *ptr)
{ {
u_char *sys, *end, *buf = ptr; u_char *sys, *end, *buf = ptr;
...@@ -266,7 +266,7 @@ void write_cis_mem(socket_info_t *s, int attr, u_int addr, ...@@ -266,7 +266,7 @@ void write_cis_mem(socket_info_t *s, int attr, u_int addr,
======================================================================*/ ======================================================================*/
static void read_cis_cache(socket_info_t *s, int attr, u_int addr, static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr) u_int len, void *ptr)
{ {
struct cis_cache_entry *cis; struct cis_cache_entry *cis;
...@@ -306,7 +306,7 @@ static void read_cis_cache(socket_info_t *s, int attr, u_int addr, ...@@ -306,7 +306,7 @@ static void read_cis_cache(socket_info_t *s, int attr, u_int addr,
} }
static void static void
remove_cis_cache(socket_info_t *s, int attr, u_int addr, u_int len) remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len)
{ {
struct cis_cache_entry *cis; struct cis_cache_entry *cis;
...@@ -318,7 +318,7 @@ remove_cis_cache(socket_info_t *s, int attr, u_int addr, u_int len) ...@@ -318,7 +318,7 @@ remove_cis_cache(socket_info_t *s, int attr, u_int addr, u_int len)
} }
} }
void destroy_cis_cache(socket_info_t *s) void destroy_cis_cache(struct pcmcia_socket *s)
{ {
struct list_head *l, *n; struct list_head *l, *n;
...@@ -337,7 +337,7 @@ void destroy_cis_cache(socket_info_t *s) ...@@ -337,7 +337,7 @@ void destroy_cis_cache(socket_info_t *s)
======================================================================*/ ======================================================================*/
int verify_cis_cache(socket_info_t *s) int verify_cis_cache(struct pcmcia_socket *s)
{ {
struct cis_cache_entry *cis; struct cis_cache_entry *cis;
char buf[256]; char buf[256];
...@@ -369,7 +369,7 @@ int verify_cis_cache(socket_info_t *s) ...@@ -369,7 +369,7 @@ int verify_cis_cache(socket_info_t *s)
int pcmcia_replace_cis(client_handle_t handle, cisdump_t *cis) int pcmcia_replace_cis(client_handle_t handle, cisdump_t *cis)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
s = SOCKET(handle); s = SOCKET(handle);
...@@ -409,7 +409,7 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple); ...@@ -409,7 +409,7 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple);
int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple) int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
s = SOCKET(handle); s = SOCKET(handle);
...@@ -445,7 +445,7 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple) ...@@ -445,7 +445,7 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
return pcmcia_get_next_tuple(handle, tuple); return pcmcia_get_next_tuple(handle, tuple);
} }
static int follow_link(socket_info_t *s, tuple_t *tuple) static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
{ {
u_char link[5]; u_char link[5];
u_int ofs; u_int ofs;
...@@ -487,7 +487,7 @@ static int follow_link(socket_info_t *s, tuple_t *tuple) ...@@ -487,7 +487,7 @@ static int follow_link(socket_info_t *s, tuple_t *tuple)
int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple) int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
{ {
socket_info_t *s; struct pcmcia_socket *s;
u_char link[2], tmp; u_char link[2], tmp;
int ofs, i, attr; int ofs, i, attr;
...@@ -588,7 +588,7 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple) ...@@ -588,7 +588,7 @@ int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple) int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
{ {
socket_info_t *s; struct pcmcia_socket *s;
u_int len; u_int len;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
......
...@@ -124,9 +124,11 @@ socket_state_t dead_socket = { ...@@ -124,9 +124,11 @@ socket_state_t dead_socket = {
0, SS_DETECT, 0, 0, 0 0, SS_DETECT, 0, 0, 0
}; };
/* Table of sockets */
socket_t sockets = 0; /* List of all sockets, protected by a rwsem */
socket_info_t *socket_table[MAX_SOCK]; LIST_HEAD(pcmcia_socket_list);
DECLARE_RWSEM(pcmcia_socket_list_rwsem);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_pccard = NULL; struct proc_dir_entry *proc_pccard = NULL;
...@@ -235,48 +237,48 @@ static const lookup_t service_table[] = { ...@@ -235,48 +237,48 @@ static const lookup_t service_table[] = {
======================================================================*/ ======================================================================*/
static int register_callback(socket_info_t *s, void (*handler)(void *, unsigned int), void * info) static int register_callback(struct pcmcia_socket *s, void (*handler)(void *, unsigned int), void * info)
{ {
int error; int error;
if (handler && !try_module_get(s->ss_entry->owner)) if (handler && !try_module_get(s->ss_entry->owner))
return -ENODEV; return -ENODEV;
error = s->ss_entry->register_callback(s->sock, handler, info); error = s->ss_entry->register_callback(s, handler, info);
if (!handler) if (!handler)
module_put(s->ss_entry->owner); module_put(s->ss_entry->owner);
return error; return error;
} }
static int get_socket_status(socket_info_t *s, int *val) static int get_socket_status(struct pcmcia_socket *s, int *val)
{ {
return s->ss_entry->get_status(s->sock, val); return s->ss_entry->get_status(s, val);
} }
static int set_socket(socket_info_t *s, socket_state_t *state) static int set_socket(struct pcmcia_socket *s, socket_state_t *state)
{ {
return s->ss_entry->set_socket(s->sock, state); return s->ss_entry->set_socket(s, state);
} }
static int set_io_map(socket_info_t *s, struct pccard_io_map *io) static int set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
{ {
return s->ss_entry->set_io_map(s->sock, io); return s->ss_entry->set_io_map(s, io);
} }
static int set_mem_map(socket_info_t *s, struct pccard_mem_map *mem) static int set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
{ {
return s->ss_entry->set_mem_map(s->sock, mem); return s->ss_entry->set_mem_map(s, mem);
} }
static int suspend_socket(socket_info_t *s) static int suspend_socket(struct pcmcia_socket *s)
{ {
s->socket = dead_socket; s->socket = dead_socket;
return s->ss_entry->suspend(s->sock); return s->ss_entry->suspend(s);
} }
static int init_socket(socket_info_t *s) static int init_socket(struct pcmcia_socket *s)
{ {
s->socket = dead_socket; s->socket = dead_socket;
return s->ss_entry->init(s->sock); return s->ss_entry->init(s);
} }
/*====================================================================*/ /*====================================================================*/
...@@ -285,7 +287,7 @@ static int init_socket(socket_info_t *s) ...@@ -285,7 +287,7 @@ static int init_socket(socket_info_t *s)
static int proc_read_clients(char *buf, char **start, off_t pos, static int proc_read_clients(char *buf, char **start, off_t pos,
int count, int *eof, void *data) int count, int *eof, void *data)
{ {
socket_info_t *s = data; struct pcmcia_socket *s = data;
client_handle_t c; client_handle_t c;
char *p = buf; char *p = buf;
...@@ -303,145 +305,226 @@ static int proc_read_clients(char *buf, char **start, off_t pos, ...@@ -303,145 +305,226 @@ static int proc_read_clients(char *buf, char **start, off_t pos,
======================================================================*/ ======================================================================*/
static int pccardd(void *__skt); /**
void pcmcia_unregister_socket(struct class_device *dev); * socket drivers are expected to use the following callbacks in their
* .drv struct:
* - pcmcia_socket_dev_suspend
* - pcmcia_socket_dev_resume
* These functions check for the appropriate struct pcmcia_soket arrays,
* and pass them to the low-level functions pcmcia_{suspend,resume}_socket
*/
static int socket_resume(struct pcmcia_socket *skt);
static int socket_suspend(struct pcmcia_socket *skt);
int pcmcia_socket_dev_suspend(struct device *dev, u32 state, u32 level)
{
struct pcmcia_socket *socket;
if (level != SUSPEND_SAVE_STATE)
return 0;
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
if (socket->dev.dev != dev)
continue;
down(&socket->skt_sem);
socket_suspend(socket);
up(&socket->skt_sem);
}
up_read(&pcmcia_socket_list_rwsem);
return 0;
}
EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
int pcmcia_socket_dev_resume(struct device *dev, u32 level)
{
struct pcmcia_socket *socket;
if (level != RESUME_RESTORE_STATE)
return 0;
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
if (socket->dev.dev != dev)
continue;
down(&socket->skt_sem);
socket_resume(socket);
up(&socket->skt_sem);
}
up_read(&pcmcia_socket_list_rwsem);
return 0;
}
EXPORT_SYMBOL(pcmcia_socket_dev_resume);
static int pccardd(void *__skt);
#define to_class_data(dev) dev->class_data #define to_class_data(dev) dev->class_data
/** static int pcmcia_add_socket(struct class_device *class_dev)
* pcmcia_register_socket - add a new pcmcia socket device
*/
int pcmcia_register_socket(struct class_device *class_dev)
{ {
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev); struct pcmcia_socket *socket = class_get_devdata(class_dev);
socket_info_t *s_info; int ret = 0;
unsigned int i, j, ret;
if (!cls_d) /* base address = 0, map = 0 */
return -EINVAL; socket->cis_mem.flags = 0;
socket->cis_mem.speed = cis_speed;
socket->erase_busy.next = socket->erase_busy.prev = &socket->erase_busy;
INIT_LIST_HEAD(&socket->cis_cache);
spin_lock_init(&socket->lock);
DEBUG(0, "cs: pcmcia_register_socket(0x%p)\n", cls_d->ops); init_socket(socket);
socket->ss_entry->inquire_socket(socket, &socket->cap);
s_info = kmalloc(cls_d->nsock * sizeof(struct socket_info_t), GFP_KERNEL);
if (!s_info) init_completion(&socket->thread_done);
return -ENOMEM; init_waitqueue_head(&socket->thread_wait);
memset(s_info, 0, cls_d->nsock * sizeof(socket_info_t)); init_MUTEX(&socket->skt_sem);
spin_lock_init(&socket->thread_lock);
cls_d->s_info = s_info; ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
ret = 0; if (ret < 0)
return ret;
/* socket initialization */
for (i = 0; i < cls_d->nsock; i++) {
socket_info_t *s = &s_info[i];
s->ss_entry = cls_d->ops;
s->sock = i + cls_d->sock_offset;
/* 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;
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++;
init_socket(s);
s->ss_entry->inquire_socket(s->sock, &s->cap);
init_completion(&s->thread_done);
init_waitqueue_head(&s->thread_wait);
init_MUTEX(&s->skt_sem);
spin_lock_init(&s->thread_lock);
ret = kernel_thread(pccardd, s, CLONE_KERNEL);
if (ret < 0) {
pcmcia_unregister_socket(class_dev);
break;
}
wait_for_completion(&s->thread_done); wait_for_completion(&socket->thread_done);
BUG_ON(!s->thread); BUG_ON(!socket->thread);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
if (proc_pccard) { if (proc_pccard) {
char name[3]; char name[3];
sprintf(name, "%02d", j); sprintf(name, "%02d", socket->sock);
s->proc = proc_mkdir(name, proc_pccard); socket->proc = proc_mkdir(name, proc_pccard);
if (s->proc) if (socket->proc)
s->ss_entry->proc_setup(i, s->proc); socket->ss_entry->proc_setup(socket, socket->proc);
#ifdef PCMCIA_DEBUG #ifdef PCMCIA_DEBUG
if (s->proc) if (socket->proc)
create_proc_read_entry("clients", 0, s->proc, create_proc_read_entry("clients", 0, socket->proc,
proc_read_clients, s); proc_read_clients, socket);
#endif #endif
} }
#endif
return 0;
}
static void pcmcia_remove_socket(struct class_device *class_dev)
{
struct pcmcia_socket *socket = class_get_devdata(class_dev);
client_t *client;
#ifdef CONFIG_PROC_FS
if (proc_pccard) {
char name[3];
sprintf(name, "%02d", socket->sock);
#ifdef PCMCIA_DEBUG
remove_proc_entry("clients", socket->proc);
#endif #endif
remove_proc_entry(name, proc_pccard);
} }
return ret; #endif
if (socket->thread) {
init_completion(&socket->thread_done);
socket->thread = NULL;
wake_up(&socket->thread_wait);
wait_for_completion(&socket->thread_done);
}
release_cis_mem(socket);
while (socket->clients) {
client = socket->clients;
socket->clients = socket->clients->next;
kfree(client);
}
socket->ss_entry = NULL;
}
/**
* pcmcia_register_socket - add a new pcmcia socket device
*/
int pcmcia_register_socket(struct pcmcia_socket *socket)
{
if (!socket || !socket->ss_entry || !socket->dev.dev)
return -EINVAL;
DEBUG(0, "cs: pcmcia_register_socket(0x%p)\n", socket->ss_entry);
/* try to obtain a socket number [yes, it gets ugly if we
* register more than 2^sizeof(unsigned int) pcmcia
* sockets... but the socket number is deprecated
* anyways, so I don't care] */
down_write(&pcmcia_socket_list_rwsem);
if (list_empty(&pcmcia_socket_list))
socket->sock = 0;
else {
unsigned int found, i = 1;
struct pcmcia_socket *tmp;
do {
found = 1;
list_for_each_entry(tmp, &pcmcia_socket_list, socket_list) {
if (tmp->sock == i)
found = 0;
}
i++;
} while (!found);
socket->sock = i - 1;
}
list_add_tail(&socket->socket_list, &pcmcia_socket_list);
up_write(&pcmcia_socket_list_rwsem);
/* set proper values in socket->dev */
socket->dev.class_data = socket;
socket->dev.class = &pcmcia_socket_class;
snprintf(socket->dev.class_id, BUS_ID_SIZE, "pcmcia_socket%u\n", socket->sock);
/* register with the device core */
if (class_device_register(&socket->dev)) {
down_write(&pcmcia_socket_list_rwsem);
list_del(&socket->socket_list);
up_write(&pcmcia_socket_list_rwsem);
return -EINVAL;
}
return 0;
} /* pcmcia_register_socket */ } /* pcmcia_register_socket */
EXPORT_SYMBOL(pcmcia_register_socket);
/** /**
* pcmcia_unregister_socket - remove a pcmcia socket device * pcmcia_unregister_socket - remove a pcmcia socket device
*/ */
void pcmcia_unregister_socket(struct class_device *class_dev) void pcmcia_unregister_socket(struct pcmcia_socket *socket)
{ {
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev); if (!socket)
unsigned int i;
int j, socket = -1;
client_t *client;
socket_info_t *s;
if (!cls_d)
return; return;
s = (socket_info_t *) cls_d->s_info; DEBUG(0, "cs: pcmcia_unregister_socket(0x%p)\n", socket->ss_entry);
for (i = 0; i < cls_d->nsock; i++) { /* remove from the device core */
for (j = 0; j < MAX_SOCK; j++) class_device_unregister(&socket->dev);
if (socket_table [j] == s) {
socket = j;
break;
}
if (socket < 0)
continue;
#ifdef CONFIG_PROC_FS
if (proc_pccard) {
char name[3];
sprintf(name, "%02d", socket);
#ifdef PCMCIA_DEBUG
remove_proc_entry("clients", s->proc);
#endif
remove_proc_entry(name, proc_pccard);
}
#endif
if (s->thread) {
init_completion(&s->thread_done);
s->thread = NULL;
wake_up(&s->thread_wait);
wait_for_completion(&s->thread_done);
}
release_cis_mem(s);
while (s->clients) {
client = s->clients;
s->clients = s->clients->next;
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--;
s++; /* remove from our own list */
} down_write(&pcmcia_socket_list_rwsem);
kfree(cls_d->s_info); list_del(&socket->socket_list);
up_write(&pcmcia_socket_list_rwsem);
} /* pcmcia_unregister_socket */ } /* pcmcia_unregister_socket */
EXPORT_SYMBOL(pcmcia_unregister_socket);
struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)
{
struct pcmcia_socket *s;
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(s, &pcmcia_socket_list, socket_list)
if (s->sock == nr) {
up_read(&pcmcia_socket_list_rwsem);
return s;
}
up_read(&pcmcia_socket_list_rwsem);
return NULL;
}
EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
/*====================================================================== /*======================================================================
...@@ -465,9 +548,9 @@ static void free_regions(memory_handle_t *list) ...@@ -465,9 +548,9 @@ static void free_regions(memory_handle_t *list)
} }
} }
static int send_event(socket_info_t *s, event_t event, int priority); static int send_event(struct pcmcia_socket *s, event_t event, int priority);
static void shutdown_socket(socket_info_t *s) static void shutdown_socket(struct pcmcia_socket *s)
{ {
client_t **c; client_t **c;
...@@ -522,7 +605,7 @@ static void shutdown_socket(socket_info_t *s) ...@@ -522,7 +605,7 @@ static void shutdown_socket(socket_info_t *s)
======================================================================*/ ======================================================================*/
static int send_event(socket_info_t *s, event_t event, int priority) static int send_event(struct pcmcia_socket *s, event_t event, int priority)
{ {
client_t *client = s->clients; client_t *client = s->clients;
int ret; int ret;
...@@ -543,7 +626,7 @@ static int send_event(socket_info_t *s, event_t event, int priority) ...@@ -543,7 +626,7 @@ static int send_event(socket_info_t *s, event_t event, int priority)
return ret; return ret;
} /* send_event */ } /* send_event */
static void pcmcia_error(socket_info_t *skt, const char *fmt, ...) static void pcmcia_error(struct pcmcia_socket *skt, const char *fmt, ...)
{ {
static char buf[128]; static char buf[128];
va_list ap; va_list ap;
...@@ -559,7 +642,7 @@ static void pcmcia_error(socket_info_t *skt, const char *fmt, ...) ...@@ -559,7 +642,7 @@ static void pcmcia_error(socket_info_t *skt, const char *fmt, ...)
#define cs_to_timeout(cs) (((cs) * HZ + 99) / 100) #define cs_to_timeout(cs) (((cs) * HZ + 99) / 100)
static void socket_remove_drivers(socket_info_t *skt) static void socket_remove_drivers(struct pcmcia_socket *skt)
{ {
client_t *client; client_t *client;
...@@ -570,7 +653,7 @@ static void socket_remove_drivers(socket_info_t *skt) ...@@ -570,7 +653,7 @@ static void socket_remove_drivers(socket_info_t *skt)
client->state |= CLIENT_STALE; client->state |= CLIENT_STALE;
} }
static void socket_shutdown(socket_info_t *skt) static void socket_shutdown(struct pcmcia_socket *skt)
{ {
socket_remove_drivers(skt); socket_remove_drivers(skt);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
...@@ -579,7 +662,7 @@ static void socket_shutdown(socket_info_t *skt) ...@@ -579,7 +662,7 @@ static void socket_shutdown(socket_info_t *skt)
shutdown_socket(skt); shutdown_socket(skt);
} }
static int socket_reset(socket_info_t *skt) static int socket_reset(struct pcmcia_socket *skt)
{ {
int status, i; int status, i;
...@@ -609,7 +692,7 @@ static int socket_reset(socket_info_t *skt) ...@@ -609,7 +692,7 @@ static int socket_reset(socket_info_t *skt)
return CS_GENERAL_FAILURE; return CS_GENERAL_FAILURE;
} }
static int socket_setup(socket_info_t *skt, int initial_delay) static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
{ {
int status, i; int status, i;
...@@ -673,7 +756,7 @@ static int socket_setup(socket_info_t *skt, int initial_delay) ...@@ -673,7 +756,7 @@ static int socket_setup(socket_info_t *skt, int initial_delay)
* Handle card insertion. Setup the socket, reset the card, * Handle card insertion. Setup the socket, reset the card,
* and then tell the rest of PCMCIA that a card is present. * and then tell the rest of PCMCIA that a card is present.
*/ */
static int socket_insert(socket_info_t *skt) static int socket_insert(struct pcmcia_socket *skt)
{ {
int ret; int ret;
...@@ -693,7 +776,7 @@ static int socket_insert(socket_info_t *skt) ...@@ -693,7 +776,7 @@ static int socket_insert(socket_info_t *skt)
return ret; return ret;
} }
static int socket_suspend(socket_info_t *skt) static int socket_suspend(struct pcmcia_socket *skt)
{ {
if (skt->state & SOCKET_SUSPEND) if (skt->state & SOCKET_SUSPEND)
return CS_IN_USE; return CS_IN_USE;
...@@ -710,7 +793,7 @@ static int socket_suspend(socket_info_t *skt) ...@@ -710,7 +793,7 @@ static int socket_suspend(socket_info_t *skt)
* our cached copy. If they are different, the card has been * our cached copy. If they are different, the card has been
* replaced, and we need to tell the drivers. * replaced, and we need to tell the drivers.
*/ */
static int socket_resume(socket_info_t *skt) static int socket_resume(struct pcmcia_socket *skt)
{ {
int ret; int ret;
...@@ -742,7 +825,7 @@ static int socket_resume(socket_info_t *skt) ...@@ -742,7 +825,7 @@ static int socket_resume(socket_info_t *skt)
static int pccardd(void *__skt) static int pccardd(void *__skt)
{ {
socket_info_t *skt = __skt; struct pcmcia_socket *skt = __skt;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
daemonize("pccardd"); daemonize("pccardd");
...@@ -799,7 +882,7 @@ static int pccardd(void *__skt) ...@@ -799,7 +882,7 @@ static int pccardd(void *__skt)
static void parse_events(void *info, u_int events) static void parse_events(void *info, u_int events)
{ {
socket_info_t *s = info; struct pcmcia_socket *s = info;
spin_lock(&s->thread_lock); spin_lock(&s->thread_lock);
s->thread_events |= events; s->thread_events |= events;
...@@ -808,68 +891,6 @@ static void parse_events(void *info, u_int events) ...@@ -808,68 +891,6 @@ static void parse_events(void *info, u_int events)
wake_up(&s->thread_wait); wake_up(&s->thread_wait);
} /* parse_events */ } /* parse_events */
/*======================================================================
Another event handler, for power management events.
This does not comply with the latest PC Card spec for handling
power management events.
======================================================================*/
void pcmcia_suspend_socket (socket_info_t *skt)
{
down(&skt->skt_sem);
socket_suspend(skt);
up(&skt->skt_sem);
}
void pcmcia_resume_socket (socket_info_t *skt)
{
down(&skt->skt_sem);
socket_resume(skt);
up(&skt->skt_sem);
}
int pcmcia_socket_dev_suspend(struct pcmcia_socket_class_data *cls_d, u32 state, u32 level)
{
socket_info_t *s;
int i;
if ((!cls_d) || (level != SUSPEND_SAVE_STATE))
return 0;
s = (socket_info_t *) cls_d->s_info;
for (i = 0; i < cls_d->nsock; i++) {
pcmcia_suspend_socket(s);
s++;
}
return 0;
}
EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
int pcmcia_socket_dev_resume(struct pcmcia_socket_class_data *cls_d, u32 level)
{
socket_info_t *s;
int i;
if ((!cls_d) || (level != RESUME_RESTORE_STATE))
return 0;
s = (socket_info_t *) cls_d->s_info;
for (i = 0; i < cls_d->nsock; i++) {
pcmcia_resume_socket(s);
s++;
}
return 0;
}
EXPORT_SYMBOL(pcmcia_socket_dev_resume);
/*====================================================================== /*======================================================================
...@@ -877,7 +898,7 @@ EXPORT_SYMBOL(pcmcia_socket_dev_resume); ...@@ -877,7 +898,7 @@ EXPORT_SYMBOL(pcmcia_socket_dev_resume);
======================================================================*/ ======================================================================*/
static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base, static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
ioaddr_t num, u_int lines, char *name) ioaddr_t num, u_int lines, char *name)
{ {
int i; int i;
...@@ -941,7 +962,7 @@ static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base, ...@@ -941,7 +962,7 @@ static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base,
return (i == MAX_IO_WIN); return (i == MAX_IO_WIN);
} /* alloc_io_space */ } /* alloc_io_space */
static void release_io_space(socket_info_t *s, ioaddr_t base, static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
ioaddr_t num) ioaddr_t num)
{ {
int i; int i;
...@@ -969,7 +990,7 @@ static void release_io_space(socket_info_t *s, ioaddr_t base, ...@@ -969,7 +990,7 @@ static void release_io_space(socket_info_t *s, ioaddr_t base,
int pcmcia_access_configuration_register(client_handle_t handle, int pcmcia_access_configuration_register(client_handle_t handle,
conf_reg_t *reg) conf_reg_t *reg)
{ {
socket_info_t *s; struct pcmcia_socket *s;
config_t *c; config_t *c;
int addr; int addr;
u_char val; u_char val;
...@@ -1020,18 +1041,18 @@ int pcmcia_access_configuration_register(client_handle_t handle, ...@@ -1020,18 +1041,18 @@ int pcmcia_access_configuration_register(client_handle_t handle,
int pcmcia_bind_device(bind_req_t *req) int pcmcia_bind_device(bind_req_t *req)
{ {
client_t *client; client_t *client;
socket_info_t *s; struct pcmcia_socket *s;
if (CHECK_SOCKET(req->Socket)) s = req->Socket;
return CS_BAD_SOCKET; if (!s)
s = SOCKET(req); return CS_BAD_SOCKET;
client = (client_t *)kmalloc(sizeof(client_t), GFP_KERNEL); client = (client_t *)kmalloc(sizeof(client_t), GFP_KERNEL);
if (!client) return CS_OUT_OF_RESOURCE; if (!client) return CS_OUT_OF_RESOURCE;
memset(client, '\0', sizeof(client_t)); memset(client, '\0', sizeof(client_t));
client->client_magic = CLIENT_MAGIC; client->client_magic = CLIENT_MAGIC;
strlcpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN); strlcpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
client->Socket = req->Socket; client->Socket = s;
client->Function = req->Function; client->Function = req->Function;
client->state = CLIENT_UNBOUND; client->state = CLIENT_UNBOUND;
client->erase_busy.next = &client->erase_busy; client->erase_busy.next = &client->erase_busy;
...@@ -1055,12 +1076,12 @@ int pcmcia_bind_device(bind_req_t *req) ...@@ -1055,12 +1076,12 @@ int pcmcia_bind_device(bind_req_t *req)
int pcmcia_bind_mtd(mtd_bind_t *req) int pcmcia_bind_mtd(mtd_bind_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
memory_handle_t region; memory_handle_t region;
if (CHECK_SOCKET(req->Socket)) s = req->Socket;
return CS_BAD_SOCKET; if (!s)
s = SOCKET(req); return CS_BAD_SOCKET;
if (req->Attributes & REGION_TYPE_AM) if (req->Attributes & REGION_TYPE_AM)
region = s->a_region; region = s->a_region;
...@@ -1085,10 +1106,10 @@ int pcmcia_bind_mtd(mtd_bind_t *req) ...@@ -1085,10 +1106,10 @@ int pcmcia_bind_mtd(mtd_bind_t *req)
int pcmcia_deregister_client(client_handle_t handle) int pcmcia_deregister_client(client_handle_t handle)
{ {
client_t **client; client_t **client;
socket_info_t *s; struct pcmcia_socket *s;
memory_handle_t region; memory_handle_t region;
u_long flags; u_long flags;
int i, sn; int i;
DEBUG(1, "cs: deregister_client(%p)\n", handle); DEBUG(1, "cs: deregister_client(%p)\n", handle);
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
...@@ -1109,8 +1130,6 @@ int pcmcia_deregister_client(client_handle_t handle) ...@@ -1109,8 +1130,6 @@ int pcmcia_deregister_client(client_handle_t handle)
if (region->mtd == handle) region->mtd = NULL; if (region->mtd == handle) region->mtd = NULL;
} }
sn = handle->Socket; s = socket_table[sn];
if ((handle->state & CLIENT_STALE) || if ((handle->state & CLIENT_STALE) ||
(handle->Attributes & INFO_MASTER_CLIENT)) { (handle->Attributes & INFO_MASTER_CLIENT)) {
spin_lock_irqsave(&s->lock, flags); spin_lock_irqsave(&s->lock, flags);
...@@ -1142,7 +1161,7 @@ int pcmcia_deregister_client(client_handle_t handle) ...@@ -1142,7 +1161,7 @@ int pcmcia_deregister_client(client_handle_t handle)
int pcmcia_get_configuration_info(client_handle_t handle, int pcmcia_get_configuration_info(client_handle_t handle,
config_info_t *config) config_info_t *config)
{ {
socket_info_t *s; struct pcmcia_socket *s;
config_t *c; config_t *c;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
...@@ -1212,9 +1231,15 @@ int pcmcia_get_configuration_info(client_handle_t handle, ...@@ -1212,9 +1231,15 @@ int pcmcia_get_configuration_info(client_handle_t handle,
int pcmcia_get_card_services_info(servinfo_t *info) int pcmcia_get_card_services_info(servinfo_t *info)
{ {
unsigned int socket_count = 0;
struct list_head *tmp;
info->Signature[0] = 'C'; info->Signature[0] = 'C';
info->Signature[1] = 'S'; info->Signature[1] = 'S';
info->Count = sockets; down_read(&pcmcia_socket_list_rwsem);
list_for_each(tmp, &pcmcia_socket_list)
socket_count++;
up_read(&pcmcia_socket_list_rwsem);
info->Count = socket_count;
info->Revision = CS_RELEASE_CODE; info->Revision = CS_RELEASE_CODE;
info->CSLevel = 0x0210; info->CSLevel = 0x0210;
info->VendorString = (char *)release; info->VendorString = (char *)release;
...@@ -1231,15 +1256,17 @@ int pcmcia_get_card_services_info(servinfo_t *info) ...@@ -1231,15 +1256,17 @@ int pcmcia_get_card_services_info(servinfo_t *info)
int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req) int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
{ {
socket_t s; socket_t s;
struct pcmcia_socket *socket;
if (req->Attributes & CLIENT_THIS_SOCKET) if (req->Attributes & CLIENT_THIS_SOCKET)
s = req->Socket; s = req->Socket;
else else
s = 0; s = 0;
if (CHECK_SOCKET(req->Socket)) socket = pcmcia_get_socket_by_nr(s);
if (!socket)
return CS_BAD_SOCKET; return CS_BAD_SOCKET;
if (socket_table[s]->clients == NULL) if (socket->clients == NULL)
return CS_NO_MORE_ITEMS; return CS_NO_MORE_ITEMS;
*handle = socket_table[s]->clients; *handle = socket->clients;
return CS_SUCCESS; return CS_SUCCESS;
} /* get_first_client */ } /* get_first_client */
...@@ -1247,13 +1274,13 @@ int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req) ...@@ -1247,13 +1274,13 @@ int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req) int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if ((handle == NULL) || CHECK_HANDLE(*handle)) if ((handle == NULL) || CHECK_HANDLE(*handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
if ((*handle)->next == NULL) { if ((*handle)->next == NULL) {
if (req->Attributes & CLIENT_THIS_SOCKET) if (req->Attributes & CLIENT_THIS_SOCKET)
return CS_NO_MORE_ITEMS; return CS_NO_MORE_ITEMS;
s = SOCKET(*handle); s = (*handle)->Socket;
if (s->clients == NULL) if (s->clients == NULL)
return CS_NO_MORE_ITEMS; return CS_NO_MORE_ITEMS;
*handle = s->clients; *handle = s->clients;
...@@ -1266,12 +1293,12 @@ int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req) ...@@ -1266,12 +1293,12 @@ int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req)
int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req) int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
window_t *win; window_t *win;
int w; int w;
if (idx == 0) if (idx == 0)
s = SOCKET((client_handle_t)*handle); s = ((client_handle_t)*handle)->Socket;
else else
s = (*handle)->sock; s = (*handle)->sock;
if (!(s->state & SOCKET_PRESENT)) if (!(s->state & SOCKET_PRESENT))
...@@ -1321,7 +1348,7 @@ int pcmcia_get_next_window(window_handle_t *win, win_req_t *req) ...@@ -1321,7 +1348,7 @@ int pcmcia_get_next_window(window_handle_t *win, win_req_t *req)
struct pci_bus *pcmcia_lookup_bus(client_handle_t handle) struct pci_bus *pcmcia_lookup_bus(client_handle_t handle)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
return NULL; return NULL;
...@@ -1345,7 +1372,7 @@ EXPORT_SYMBOL(pcmcia_lookup_bus); ...@@ -1345,7 +1372,7 @@ EXPORT_SYMBOL(pcmcia_lookup_bus);
int pcmcia_get_status(client_handle_t handle, cs_status_t *status) int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
{ {
socket_info_t *s; struct pcmcia_socket *s;
config_t *c; config_t *c;
int val; int val;
...@@ -1424,7 +1451,7 @@ int pcmcia_get_mem_page(window_handle_t win, memreq_t *req) ...@@ -1424,7 +1451,7 @@ int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
int pcmcia_map_mem_page(window_handle_t win, memreq_t *req) int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if ((win == NULL) || (win->magic != WINDOW_MAGIC)) if ((win == NULL) || (win->magic != WINDOW_MAGIC))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
if (req->Page != 0) if (req->Page != 0)
...@@ -1445,7 +1472,7 @@ int pcmcia_map_mem_page(window_handle_t win, memreq_t *req) ...@@ -1445,7 +1472,7 @@ int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
int pcmcia_modify_configuration(client_handle_t handle, int pcmcia_modify_configuration(client_handle_t handle,
modconf_t *mod) modconf_t *mod)
{ {
socket_info_t *s; struct pcmcia_socket *s;
config_t *c; config_t *c;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
...@@ -1522,14 +1549,13 @@ int pcmcia_modify_window(window_handle_t win, modwin_t *req) ...@@ -1522,14 +1549,13 @@ int pcmcia_modify_window(window_handle_t win, modwin_t *req)
int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
{ {
client_t *client; client_t *client = NULL;
socket_info_t *s; struct pcmcia_socket *s;
socket_t ns;
/* Look for unbound client with matching dev_info */ /* Look for unbound client with matching dev_info */
client = NULL; down_read(&pcmcia_socket_list_rwsem);
for (ns = 0; ns < sockets; ns++) { list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
client = socket_table[ns]->clients; client = s->clients;
while (client != NULL) { while (client != NULL) {
if ((strcmp(client->dev_info, (char *)req->dev_info) == 0) if ((strcmp(client->dev_info, (char *)req->dev_info) == 0)
&& (client->state & CLIENT_UNBOUND)) break; && (client->state & CLIENT_UNBOUND)) break;
...@@ -1537,10 +1563,10 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) ...@@ -1537,10 +1563,10 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
} }
if (client != NULL) break; if (client != NULL) break;
} }
up_read(&pcmcia_socket_list_rwsem);
if (client == NULL) if (client == NULL)
return CS_OUT_OF_RESOURCE; return CS_OUT_OF_RESOURCE;
s = socket_table[ns];
if (++s->real_clients == 1) { if (++s->real_clients == 1) {
register_callback(s, &parse_events, s); register_callback(s, &parse_events, s);
parse_events(s, SS_DETECT); parse_events(s, SS_DETECT);
...@@ -1548,7 +1574,7 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) ...@@ -1548,7 +1574,7 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
*handle = client; *handle = client;
client->state &= ~CLIENT_UNBOUND; client->state &= ~CLIENT_UNBOUND;
client->Socket = ns; client->Socket = s;
client->Attributes = req->Attributes; client->Attributes = req->Attributes;
client->EventMask = req->EventMask; client->EventMask = req->EventMask;
client->event_handler = req->event_handler; client->event_handler = req->event_handler;
...@@ -1577,8 +1603,8 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) ...@@ -1577,8 +1603,8 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
client, client->Socket, client->dev_info); client, client->Socket, client->dev_info);
if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE) if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW); EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
if ((socket_table[ns]->state & SOCKET_PRESENT) && if ((s->state & SOCKET_PRESENT) &&
!(socket_table[ns]->state & SOCKET_SETUP_PENDING)) { !(s->state & SOCKET_SETUP_PENDING)) {
if (client->EventMask & CS_EVENT_CARD_INSERTION) if (client->EventMask & CS_EVENT_CARD_INSERTION)
EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
else else
...@@ -1592,7 +1618,7 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) ...@@ -1592,7 +1618,7 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
int pcmcia_release_configuration(client_handle_t handle) int pcmcia_release_configuration(client_handle_t handle)
{ {
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
socket_info_t *s; struct pcmcia_socket *s;
int i; int i;
if (CHECK_HANDLE(handle) || if (CHECK_HANDLE(handle) ||
...@@ -1642,7 +1668,7 @@ int pcmcia_release_configuration(client_handle_t handle) ...@@ -1642,7 +1668,7 @@ int pcmcia_release_configuration(client_handle_t handle)
int pcmcia_release_io(client_handle_t handle, io_req_t *req) int pcmcia_release_io(client_handle_t handle, io_req_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ)) if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
...@@ -1677,7 +1703,7 @@ int pcmcia_release_io(client_handle_t handle, io_req_t *req) ...@@ -1677,7 +1703,7 @@ int pcmcia_release_io(client_handle_t handle, io_req_t *req)
int pcmcia_release_irq(client_handle_t handle, irq_req_t *req) int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ)) if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
handle->state &= ~CLIENT_IRQ_REQ; handle->state &= ~CLIENT_IRQ_REQ;
...@@ -1713,7 +1739,7 @@ int pcmcia_release_irq(client_handle_t handle, irq_req_t *req) ...@@ -1713,7 +1739,7 @@ int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
int pcmcia_release_window(window_handle_t win) int pcmcia_release_window(window_handle_t win)
{ {
socket_info_t *s; struct pcmcia_socket *s;
if ((win == NULL) || (win->magic != WINDOW_MAGIC)) if ((win == NULL) || (win->magic != WINDOW_MAGIC))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
...@@ -1743,13 +1769,13 @@ int pcmcia_request_configuration(client_handle_t handle, ...@@ -1743,13 +1769,13 @@ int pcmcia_request_configuration(client_handle_t handle,
{ {
int i; int i;
u_int base; u_int base;
socket_info_t *s; struct pcmcia_socket *s;
config_t *c; config_t *c;
pccard_io_map iomap; pccard_io_map iomap;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
i = handle->Socket; s = socket_table[i]; s = SOCKET(handle);
if (!(s->state & SOCKET_PRESENT)) if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD; return CS_NO_CARD;
...@@ -1872,7 +1898,7 @@ int pcmcia_request_configuration(client_handle_t handle, ...@@ -1872,7 +1898,7 @@ int pcmcia_request_configuration(client_handle_t handle,
int pcmcia_request_io(client_handle_t handle, io_req_t *req) int pcmcia_request_io(client_handle_t handle, io_req_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
config_t *c; config_t *c;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
...@@ -1936,7 +1962,7 @@ int pcmcia_request_io(client_handle_t handle, io_req_t *req) ...@@ -1936,7 +1962,7 @@ int pcmcia_request_io(client_handle_t handle, io_req_t *req)
int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
{ {
socket_info_t *s; struct pcmcia_socket *s;
config_t *c; config_t *c;
int ret = 0, irq = 0; int ret = 0, irq = 0;
...@@ -2011,14 +2037,14 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) ...@@ -2011,14 +2037,14 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh) int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)
{ {
socket_info_t *s; struct pcmcia_socket *s;
window_t *win; window_t *win;
u_long align; u_long align;
int w; int w;
if (CHECK_HANDLE(*handle)) if (CHECK_HANDLE(*handle))
return CS_BAD_HANDLE; return CS_BAD_HANDLE;
s = SOCKET(*handle); s = (*handle)->Socket;
if (!(s->state & SOCKET_PRESENT)) if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD; return CS_NO_CARD;
if (req->Attributes & (WIN_PAGED | WIN_SHARED)) if (req->Attributes & (WIN_PAGED | WIN_SHARED))
...@@ -2096,7 +2122,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle ...@@ -2096,7 +2122,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
int pcmcia_reset_card(client_handle_t handle, client_req_t *req) int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
{ {
socket_info_t *skt; struct pcmcia_socket *skt;
int ret; int ret;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
...@@ -2145,7 +2171,7 @@ int pcmcia_reset_card(client_handle_t handle, client_req_t *req) ...@@ -2145,7 +2171,7 @@ int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
int pcmcia_suspend_card(client_handle_t handle, client_req_t *req) int pcmcia_suspend_card(client_handle_t handle, client_req_t *req)
{ {
socket_info_t *skt; struct pcmcia_socket *skt;
int ret; int ret;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
...@@ -2172,7 +2198,7 @@ int pcmcia_suspend_card(client_handle_t handle, client_req_t *req) ...@@ -2172,7 +2198,7 @@ int pcmcia_suspend_card(client_handle_t handle, client_req_t *req)
int pcmcia_resume_card(client_handle_t handle, client_req_t *req) int pcmcia_resume_card(client_handle_t handle, client_req_t *req)
{ {
socket_info_t *skt; struct pcmcia_socket *skt;
int ret; int ret;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
...@@ -2205,7 +2231,7 @@ int pcmcia_resume_card(client_handle_t handle, client_req_t *req) ...@@ -2205,7 +2231,7 @@ int pcmcia_resume_card(client_handle_t handle, client_req_t *req)
int pcmcia_eject_card(client_handle_t handle, client_req_t *req) int pcmcia_eject_card(client_handle_t handle, client_req_t *req)
{ {
socket_info_t *skt; struct pcmcia_socket *skt;
int ret; int ret;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
...@@ -2234,7 +2260,7 @@ int pcmcia_eject_card(client_handle_t handle, client_req_t *req) ...@@ -2234,7 +2260,7 @@ int pcmcia_eject_card(client_handle_t handle, client_req_t *req)
int pcmcia_insert_card(client_handle_t handle, client_req_t *req) int pcmcia_insert_card(client_handle_t handle, client_req_t *req)
{ {
socket_info_t *skt; struct pcmcia_socket *skt;
int ret; int ret;
if (CHECK_HANDLE(handle)) if (CHECK_HANDLE(handle))
...@@ -2519,11 +2545,6 @@ EXPORT_SYMBOL(MTDHelperEntry); ...@@ -2519,11 +2545,6 @@ EXPORT_SYMBOL(MTDHelperEntry);
EXPORT_SYMBOL(proc_pccard); EXPORT_SYMBOL(proc_pccard);
#endif #endif
EXPORT_SYMBOL(pcmcia_register_socket);
EXPORT_SYMBOL(pcmcia_unregister_socket);
EXPORT_SYMBOL(pcmcia_suspend_socket);
EXPORT_SYMBOL(pcmcia_resume_socket);
struct class pcmcia_socket_class = { struct class pcmcia_socket_class = {
.name = "pcmcia_socket", .name = "pcmcia_socket",
}; };
...@@ -2531,8 +2552,8 @@ EXPORT_SYMBOL(pcmcia_socket_class); ...@@ -2531,8 +2552,8 @@ EXPORT_SYMBOL(pcmcia_socket_class);
static struct class_interface pcmcia_socket = { static struct class_interface pcmcia_socket = {
.class = &pcmcia_socket_class, .class = &pcmcia_socket_class,
.add = &pcmcia_register_socket, .add = &pcmcia_add_socket,
.remove = &pcmcia_unregister_socket, .remove = &pcmcia_remove_socket,
}; };
......
...@@ -21,13 +21,6 @@ ...@@ -21,13 +21,6 @@
#include <linux/config.h> #include <linux/config.h>
typedef struct erase_busy_t {
eraseq_entry_t *erase;
client_handle_t client;
struct timer_list timeout;
struct erase_busy_t *prev, *next;
} erase_busy_t;
#define ERASEQ_MAGIC 0xFA67 #define ERASEQ_MAGIC 0xFA67
typedef struct eraseq_t { typedef struct eraseq_t {
u_short eraseq_magic; u_short eraseq_magic;
...@@ -39,7 +32,7 @@ typedef struct eraseq_t { ...@@ -39,7 +32,7 @@ typedef struct eraseq_t {
#define CLIENT_MAGIC 0x51E6 #define CLIENT_MAGIC 0x51E6
typedef struct client_t { typedef struct client_t {
u_short client_magic; u_short client_magic;
socket_t Socket; struct pcmcia_socket *Socket;
u_char Function; u_char Function;
dev_info_t dev_info; dev_info_t dev_info;
u_int Attributes; u_int Attributes;
...@@ -63,23 +56,6 @@ typedef struct client_t { ...@@ -63,23 +56,6 @@ typedef struct client_t {
#define CLIENT_WIN_REQ(i) (0x20<<(i)) #define CLIENT_WIN_REQ(i) (0x20<<(i))
#define CLIENT_CARDBUS 0x8000 #define CLIENT_CARDBUS 0x8000
typedef struct io_window_t {
u_int Attributes;
ioaddr_t BasePort, NumPorts;
ioaddr_t InUse, Config;
} io_window_t;
#define WINDOW_MAGIC 0xB35C
typedef struct window_t {
u_short magic;
u_short index;
client_handle_t handle;
struct socket_info_t *sock;
u_long base;
u_long size;
pccard_mem_map ctl;
} window_t;
#define REGION_MAGIC 0xE3C9 #define REGION_MAGIC 0xE3C9
typedef struct region_t { typedef struct region_t {
u_short region_magic; u_short region_magic;
...@@ -108,12 +84,6 @@ typedef struct config_t { ...@@ -108,12 +84,6 @@ typedef struct config_t {
} irq; } irq;
} config_t; } config_t;
/* Maximum number of IO windows per socket */
#define MAX_IO_WIN 2
/* Maximum number of memory windows per socket */
#define MAX_WIN 4
struct cis_cache_entry { struct cis_cache_entry {
struct list_head node; struct list_head node;
unsigned int addr; unsigned int addr;
...@@ -122,48 +92,6 @@ struct cis_cache_entry { ...@@ -122,48 +92,6 @@ struct cis_cache_entry {
unsigned char cache[0]; unsigned char cache[0];
}; };
typedef struct socket_info_t {
spinlock_t lock;
struct pccard_operations * ss_entry;
u_int sock;
socket_state_t socket;
socket_cap_t cap;
u_int state;
u_short functions;
u_short lock_count;
client_handle_t clients;
u_int real_clients;
pccard_mem_map cis_mem;
u_char *cis_virt;
config_t *config;
#ifdef CONFIG_CARDBUS
struct resource * cb_cis_res;
u_char *cb_cis_virt;
#endif
struct {
u_int AssignedIRQ;
u_int Config;
} irq;
io_window_t io[MAX_IO_WIN];
window_t win[MAX_WIN];
region_t *c_region, *a_region;
erase_busy_t erase_busy;
struct list_head cis_cache;
u_int fake_cis_len;
char *fake_cis;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc;
#endif
struct semaphore skt_sem; /* protects socket h/w state */
struct task_struct *thread;
struct completion thread_done;
wait_queue_head_t thread_wait;
spinlock_t thread_lock; /* protects thread_events */
unsigned int thread_events;
} socket_info_t;
/* Flags in config state */ /* Flags in config state */
#define CONFIG_LOCKED 0x01 #define CONFIG_LOCKED 0x01
#define CONFIG_IRQ_REQ 0x02 #define CONFIG_IRQ_REQ 0x02
...@@ -187,7 +115,7 @@ typedef struct socket_info_t { ...@@ -187,7 +115,7 @@ typedef struct socket_info_t {
#define CHECK_SOCKET(s) \ #define CHECK_SOCKET(s) \
(((s) >= sockets) || (socket_table[s]->ss_entry == NULL)) (((s) >= sockets) || (socket_table[s]->ss_entry == NULL))
#define SOCKET(h) (socket_table[(h)->Socket]) #define SOCKET(h) (h->Socket)
#define CONFIG(h) (&SOCKET(h)->config[(h)->Function]) #define CONFIG(h) (&SOCKET(h)->config[(h)->Function])
#define CHECK_REGION(r) \ #define CHECK_REGION(r) \
...@@ -200,19 +128,19 @@ typedef struct socket_info_t { ...@@ -200,19 +128,19 @@ typedef struct socket_info_t {
((h)->event_handler((e), (p), &(h)->event_callback_args)) ((h)->event_handler((e), (p), &(h)->event_callback_args))
/* In cardbus.c */ /* In cardbus.c */
int cb_alloc(socket_info_t *s); int cb_alloc(struct pcmcia_socket *s);
void cb_free(socket_info_t *s); void cb_free(struct pcmcia_socket *s);
int read_cb_mem(socket_info_t *s, int space, u_int addr, u_int len, void *ptr); int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr);
/* In cistpl.c */ /* In cistpl.c */
int read_cis_mem(socket_info_t *s, int attr, int read_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr); u_int addr, u_int len, void *ptr);
void write_cis_mem(socket_info_t *s, int attr, void write_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr); u_int addr, u_int len, void *ptr);
void release_cis_mem(socket_info_t *s); void release_cis_mem(struct pcmcia_socket *s);
void destroy_cis_cache(socket_info_t *s); void destroy_cis_cache(struct pcmcia_socket *s);
int verify_cis_cache(socket_info_t *s); int verify_cis_cache(struct pcmcia_socket *s);
void preload_cis_cache(socket_info_t *s); void preload_cis_cache(struct pcmcia_socket *s);
int get_first_tuple(client_handle_t handle, tuple_t *tuple); int get_first_tuple(client_handle_t handle, tuple_t *tuple);
int get_next_tuple(client_handle_t handle, tuple_t *tuple); int get_next_tuple(client_handle_t handle, tuple_t *tuple);
int get_tuple_data(client_handle_t handle, tuple_t *tuple); int get_tuple_data(client_handle_t handle, tuple_t *tuple);
...@@ -236,11 +164,11 @@ int write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf); ...@@ -236,11 +164,11 @@ int write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf);
int copy_memory(memory_handle_t handle, copy_op_t *req); int copy_memory(memory_handle_t handle, copy_op_t *req);
/* In rsrc_mgr */ /* In rsrc_mgr */
void validate_mem(socket_info_t *s); void validate_mem(struct pcmcia_socket *s);
int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
char *name, socket_info_t *s); char *name, struct pcmcia_socket *s);
int find_mem_region(u_long *base, u_long num, u_long align, int find_mem_region(u_long *base, u_long num, u_long align,
int force_low, char *name, socket_info_t *s); int force_low, char *name, struct pcmcia_socket *s);
int try_irq(u_int Attributes, int irq, int specific); int try_irq(u_int Attributes, int irq, int specific);
void undo_irq(u_int Attributes, int irq); void undo_irq(u_int Attributes, int irq);
int adjust_resource_info(client_handle_t handle, adjust_t *adj); int adjust_resource_info(client_handle_t handle, adjust_t *adj);
...@@ -250,9 +178,8 @@ int proc_read_io(char *buf, char **start, off_t pos, ...@@ -250,9 +178,8 @@ int proc_read_io(char *buf, char **start, off_t pos,
int proc_read_mem(char *buf, char **start, off_t pos, int proc_read_mem(char *buf, char **start, off_t pos,
int count, int *eof, void *data); int count, int *eof, void *data);
#define MAX_SOCK 8 extern struct rw_semaphore pcmcia_socket_list_rwsem;
extern socket_t sockets; extern struct list_head pcmcia_socket_list;
extern socket_info_t *socket_table[MAX_SOCK];
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
extern struct proc_dir_entry *proc_pccard; extern struct proc_dir_entry *proc_pccard;
......
...@@ -107,8 +107,7 @@ struct pcmcia_bus_socket { ...@@ -107,8 +107,7 @@ struct pcmcia_bus_socket {
struct work_struct removal; struct work_struct removal;
socket_bind_t *bind; socket_bind_t *bind;
struct device *socket_dev; struct device *socket_dev;
struct list_head socket_list; struct pcmcia_socket *parent;
unsigned int socket_no; /* deprecated */
}; };
#define SOCKET_PRESENT 0x01 #define SOCKET_PRESENT 0x01
...@@ -122,10 +121,6 @@ static dev_info_t dev_info = "Driver Services"; ...@@ -122,10 +121,6 @@ static dev_info_t dev_info = "Driver Services";
static int major_dev = -1; static int major_dev = -1;
/* list of all sockets registered with the pcmcia bus driver */
static DECLARE_RWSEM(bus_socket_list_rwsem);
static LIST_HEAD(bus_socket_list);
extern struct proc_dir_entry *proc_pccard; extern struct proc_dir_entry *proc_pccard;
/*====================================================================*/ /*====================================================================*/
...@@ -164,20 +159,6 @@ EXPORT_SYMBOL(pcmcia_register_driver); ...@@ -164,20 +159,6 @@ EXPORT_SYMBOL(pcmcia_register_driver);
*/ */
void pcmcia_unregister_driver(struct pcmcia_driver *driver) void pcmcia_unregister_driver(struct pcmcia_driver *driver)
{ {
socket_bind_t *b;
struct pcmcia_bus_socket *bus_sock;
if (driver->use_count > 0) {
/* Blank out any left-over device instances */
driver->attach = NULL; driver->detach = NULL;
down_read(&bus_socket_list_rwsem);
list_for_each_entry(bus_sock, &bus_socket_list, socket_list) {
for (b = bus_sock->bind; b; b = b->next)
if (b->driver == driver)
b->instance = NULL;
}
up_read(&bus_socket_list_rwsem);
}
driver_unregister(&driver->drv); driver_unregister(&driver->drv);
} }
EXPORT_SYMBOL(pcmcia_unregister_driver); EXPORT_SYMBOL(pcmcia_unregister_driver);
...@@ -319,14 +300,14 @@ static int bind_mtd(struct pcmcia_bus_socket *bus_sock, mtd_info_t *mtd_info) ...@@ -319,14 +300,14 @@ static int bind_mtd(struct pcmcia_bus_socket *bus_sock, mtd_info_t *mtd_info)
bind_req.dev_info = &mtd_info->dev_info; bind_req.dev_info = &mtd_info->dev_info;
bind_req.Attributes = mtd_info->Attributes; bind_req.Attributes = mtd_info->Attributes;
bind_req.Socket = bus_sock->socket_no; bind_req.Socket = bus_sock->parent;
bind_req.CardOffset = mtd_info->CardOffset; bind_req.CardOffset = mtd_info->CardOffset;
ret = pcmcia_bind_mtd(&bind_req); ret = pcmcia_bind_mtd(&bind_req);
if (ret != CS_SUCCESS) { if (ret != CS_SUCCESS) {
cs_error(NULL, BindMTD, ret); cs_error(NULL, BindMTD, ret);
printk(KERN_NOTICE "ds: unable to bind MTD '%s' to socket %d" printk(KERN_NOTICE "ds: unable to bind MTD '%s' to socket %d"
" offset 0x%x\n", " offset 0x%x\n",
(char *)bind_req.dev_info, bus_sock->socket_no, bind_req.CardOffset); (char *)bind_req.dev_info, bus_sock->parent->sock, bind_req.CardOffset);
return -ENODEV; return -ENODEV;
} }
return 0; return 0;
...@@ -351,7 +332,7 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) ...@@ -351,7 +332,7 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
if (!s) if (!s)
return -EINVAL; return -EINVAL;
DEBUG(2, "bind_request(%d, '%s')\n", s->socket_no, DEBUG(2, "bind_request(%d, '%s')\n", s->parent->sock,
(char *)bind_info->dev_info); (char *)bind_info->dev_info);
driver = get_pcmcia_driver(&bind_info->dev_info); driver = get_pcmcia_driver(&bind_info->dev_info);
if (!driver) if (!driver)
...@@ -366,14 +347,18 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) ...@@ -366,14 +347,18 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
return -EBUSY; return -EBUSY;
} }
bind_req.Socket = s->socket_no; if (!try_module_get(driver->owner))
return -EINVAL;
bind_req.Socket = s->parent;
bind_req.Function = bind_info->function; bind_req.Function = bind_info->function;
bind_req.dev_info = (dev_info_t *) driver->drv.name; bind_req.dev_info = (dev_info_t *) driver->drv.name;
ret = pcmcia_bind_device(&bind_req); ret = pcmcia_bind_device(&bind_req);
if (ret != CS_SUCCESS) { if (ret != CS_SUCCESS) {
cs_error(NULL, BindDevice, ret); cs_error(NULL, BindDevice, ret);
printk(KERN_NOTICE "ds: unable to bind '%s' to socket %d\n", printk(KERN_NOTICE "ds: unable to bind '%s' to socket %d\n",
(char *)dev_info, s->socket_no); (char *)dev_info, s->parent->sock);
module_put(driver->owner);
return -ENODEV; return -ENODEV;
} }
...@@ -383,6 +368,7 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) ...@@ -383,6 +368,7 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
if (!b) if (!b)
{ {
driver->use_count--; driver->use_count--;
module_put(driver->owner);
return -ENOMEM; return -ENOMEM;
} }
b->driver = driver; b->driver = driver;
...@@ -396,6 +382,7 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) ...@@ -396,6 +382,7 @@ static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
if (b->instance == NULL) { if (b->instance == NULL) {
printk(KERN_NOTICE "ds: unable to create instance " printk(KERN_NOTICE "ds: unable to create instance "
"of '%s'!\n", (char *)bind_info->dev_info); "of '%s'!\n", (char *)bind_info->dev_info);
module_put(driver->owner);
return -ENODEV; return -ENODEV;
} }
} }
...@@ -476,7 +463,7 @@ static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) ...@@ -476,7 +463,7 @@ static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
{ {
socket_bind_t **b, *c; socket_bind_t **b, *c;
DEBUG(2, "unbind_request(%d, '%s')\n", s->socket_no, DEBUG(2, "unbind_request(%d, '%s')\n", s->parent->sock,
(char *)bind_info->dev_info); (char *)bind_info->dev_info);
for (b = &s->bind; *b; b = &(*b)->next) for (b = &s->bind; *b; b = &(*b)->next)
if ((strcmp((char *)(*b)->driver->drv.name, if ((strcmp((char *)(*b)->driver->drv.name,
...@@ -492,9 +479,9 @@ static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) ...@@ -492,9 +479,9 @@ static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
if (c->instance) if (c->instance)
c->driver->detach(c->instance); c->driver->detach(c->instance);
} }
module_put(c->driver->owner);
*b = c->next; *b = c->next;
kfree(c); kfree(c);
return 0; return 0;
} /* unbind_request */ } /* unbind_request */
...@@ -832,13 +819,13 @@ static struct file_operations ds_fops = { ...@@ -832,13 +819,13 @@ static struct file_operations ds_fops = {
.poll = ds_poll, .poll = ds_poll,
}; };
static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int socket_nr) static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
{ {
struct pcmcia_socket *socket = class_dev->class_data;
client_reg_t client_reg; client_reg_t client_reg;
bind_req_t bind; bind_req_t bind;
struct pcmcia_bus_socket *s, *tmp_s; struct pcmcia_bus_socket *s;
int ret; int ret;
int i;
s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL); s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL);
if(!s) if(!s)
...@@ -855,28 +842,15 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock ...@@ -855,28 +842,15 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock
init_waitqueue_head(&s->queue); init_waitqueue_head(&s->queue);
init_waitqueue_head(&s->request); init_waitqueue_head(&s->request);
/* find the lowest, unused socket no. Please note that this is a
* temporary workaround until "struct pcmcia_socket" is introduced
* into cs.c which will include this number, and which will be
* accessible to ds.c directly */
i = 0;
next_try:
list_for_each_entry(tmp_s, &bus_socket_list, socket_list) {
if (tmp_s->socket_no == i) {
i++;
goto next_try;
}
}
s->socket_no = i;
/* initialize data */ /* initialize data */
s->socket_dev = dev; s->socket_dev = socket->dev.dev;
INIT_WORK(&s->removal, handle_removal, s); INIT_WORK(&s->removal, handle_removal, s);
s->parent = socket;
/* Set up hotline to Card Services */ /* Set up hotline to Card Services */
client_reg.dev_info = bind.dev_info = &dev_info; client_reg.dev_info = bind.dev_info = &dev_info;
bind.Socket = s->socket_no; bind.Socket = socket;
bind.Function = BIND_FN_ALL; bind.Function = BIND_FN_ALL;
ret = pcmcia_bind_device(&bind); ret = pcmcia_bind_device(&bind);
if (ret != CS_SUCCESS) { if (ret != CS_SUCCESS) {
...@@ -901,50 +875,26 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock ...@@ -901,50 +875,26 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock
return -EINVAL; return -EINVAL;
} }
list_add(&s->socket_list, &bus_socket_list); socket->pcmcia = s;
return 0; return 0;
} }
static int pcmcia_bus_add_socket_dev(struct class_device *class_dev) static void pcmcia_bus_remove_socket(struct class_device *class_dev)
{
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
unsigned int i;
unsigned int ret = 0;
if (!cls_d)
return -ENODEV;
down_write(&bus_socket_list_rwsem);
for (i = 0; i < cls_d->nsock; i++)
ret += pcmcia_bus_add_socket(class_dev->dev, i);
up_write(&bus_socket_list_rwsem);
return ret;
}
static void pcmcia_bus_remove_socket_dev(struct class_device *class_dev)
{ {
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev); struct pcmcia_socket *socket = class_dev->class_data;
struct list_head *list_loop;
struct list_head *tmp_storage;
if (!cls_d) if (!socket || !socket->pcmcia)
return; return;
flush_scheduled_work(); flush_scheduled_work();
down_write(&bus_socket_list_rwsem); pcmcia_deregister_client(socket->pcmcia->handle);
list_for_each_safe(list_loop, tmp_storage, &bus_socket_list) {
struct pcmcia_bus_socket *bus_sock = container_of(list_loop, struct pcmcia_bus_socket, socket_list); kfree(socket->pcmcia);
if (bus_sock->socket_dev == class_dev->dev) { socket->pcmcia = NULL;
pcmcia_deregister_client(bus_sock->handle);
list_del(&bus_sock->socket_list);
kfree(bus_sock);
}
}
up_write(&bus_socket_list_rwsem);
return; return;
} }
...@@ -952,8 +902,8 @@ static void pcmcia_bus_remove_socket_dev(struct class_device *class_dev) ...@@ -952,8 +902,8 @@ static void pcmcia_bus_remove_socket_dev(struct class_device *class_dev)
/* the pcmcia_bus_interface is used to handle pcmcia socket devices */ /* the pcmcia_bus_interface is used to handle pcmcia socket devices */
static struct class_interface pcmcia_bus_interface = { static struct class_interface pcmcia_bus_interface = {
.class = &pcmcia_socket_class, .class = &pcmcia_socket_class,
.add = &pcmcia_bus_add_socket_dev, .add = &pcmcia_bus_add_socket,
.remove = &pcmcia_bus_remove_socket_dev, .remove = &pcmcia_bus_remove_socket,
}; };
...@@ -1008,18 +958,13 @@ module_exit(exit_pcmcia_bus); ...@@ -1008,18 +958,13 @@ module_exit(exit_pcmcia_bus);
/* helpers for backwards-compatible functions */ /* helpers for backwards-compatible functions */
static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr) static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr)
{ {
struct pcmcia_bus_socket * s; struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr);
down_read(&bus_socket_list_rwsem); if (s && s->pcmcia)
list_for_each_entry(s, &bus_socket_list, socket_list) return s->pcmcia;
if (s->socket_no == nr) { else
up_read(&bus_socket_list_rwsem); return NULL;
return s;
}
up_read(&bus_socket_list_rwsem);
return NULL;
} }
/* backwards-compatible accessing of driver --- by name! */ /* backwards-compatible accessing of driver --- by name! */
......
...@@ -44,14 +44,12 @@ MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids); ...@@ -44,14 +44,12 @@ MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
static int i82092aa_socket_suspend (struct pci_dev *dev, u32 state) static int i82092aa_socket_suspend (struct pci_dev *dev, u32 state)
{ {
struct pcmcia_socket_class_data *cls_d = pci_get_drvdata(dev); return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
return pcmcia_socket_dev_suspend(cls_d, state, 0);
} }
static int i82092aa_socket_resume (struct pci_dev *dev) static int i82092aa_socket_resume (struct pci_dev *dev)
{ {
struct pcmcia_socket_class_data *cls_d = pci_get_drvdata(dev); return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
return pcmcia_socket_dev_resume(cls_d, RESUME_RESTORE_STATE);
} }
static struct pci_driver i82092aa_pci_drv = { static struct pci_driver i82092aa_pci_drv = {
...@@ -82,6 +80,7 @@ static struct pccard_operations i82092aa_operations = { ...@@ -82,6 +80,7 @@ static struct pccard_operations i82092aa_operations = {
/* The card can do upto 4 sockets, allocate a structure for each of them */ /* The card can do upto 4 sockets, allocate a structure for each of them */
struct socket_info { struct socket_info {
int number;
int card_state; /* 0 = no socket, int card_state; /* 0 = no socket,
1 = empty socket, 1 = empty socket,
2 = card but not initialized, 2 = card but not initialized,
...@@ -95,6 +94,7 @@ struct socket_info { ...@@ -95,6 +94,7 @@ struct socket_info {
/* callback to the driver of the card */ /* callback to the driver of the card */
void *info; /* to be passed to the handler */ void *info; /* to be passed to the handler */
struct pcmcia_socket socket;
struct pci_dev *dev; /* The PCI device for the socket */ struct pci_dev *dev; /* The PCI device for the socket */
}; };
...@@ -107,7 +107,6 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic ...@@ -107,7 +107,6 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
{ {
unsigned char configbyte; unsigned char configbyte;
int i, ret; int i, ret;
struct pcmcia_socket_class_data *cls_d;
enter("i82092aa_pci_probe"); enter("i82092aa_pci_probe");
...@@ -146,6 +145,8 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic ...@@ -146,6 +145,8 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
sockets[i].cap.map_size = 0x1000; sockets[i].cap.map_size = 0x1000;
sockets[i].cap.irq_mask = 0; sockets[i].cap.irq_mask = 0;
sockets[i].cap.pci_irq = dev->irq; sockets[i].cap.pci_irq = dev->irq;
sockets[i].number = i;
if (card_present(i)) { if (card_present(i)) {
sockets[i].card_state = 3; sockets[i].card_state = 3;
...@@ -166,26 +167,26 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic ...@@ -166,26 +167,26 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
goto err_out_free_res; goto err_out_free_res;
} }
pci_set_drvdata(dev, &sockets[i].socket);
cls_d = kmalloc(sizeof(*cls_d), GFP_KERNEL);
if (!cls_d) { for (i = 0; i<socket_count; i++) {
printk(KERN_ERR "i82092aa: kmalloc failed\n"); sockets[i].socket.dev.dev = &dev->dev;
goto err_out_free_irq; sockets[i].socket.ss_entry = &i82092aa_operations;
ret = pcmcia_register_socket(&sockets[i].socket);
if (ret) {
goto err_out_free_sockets;
}
} }
memset(cls_d, 0, sizeof(*cls_d));
cls_d->nsock = socket_count;
cls_d->ops = &i82092aa_operations;
pci_set_drvdata(dev, &cls_d);
cls_d->class_dev.class = &pcmcia_socket_class;
cls_d->class_dev.dev = &dev->dev;
strlcpy(cls_d->class_dev.class_id, dev->dev.name, BUS_ID_SIZE);
class_set_devdata(&cls_d->class_dev, cls_d);
class_device_register(&cls_d->class_dev);
leave("i82092aa_pci_probe"); leave("i82092aa_pci_probe");
return 0; return 0;
err_out_free_irq: err_out_free_sockets:
if (i) {
for (i--;i>=0;i--) {
pcmcia_unregister_socket(&sockets[i].socket);
}
}
free_irq(dev->irq, i82092aa_interrupt); free_irq(dev->irq, i82092aa_interrupt);
err_out_free_res: err_out_free_res:
release_region(pci_resource_start(dev, 0), 2); release_region(pci_resource_start(dev, 0), 2);
...@@ -196,16 +197,14 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic ...@@ -196,16 +197,14 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
static void __devexit i82092aa_pci_remove(struct pci_dev *dev) static void __devexit i82092aa_pci_remove(struct pci_dev *dev)
{ {
struct pcmcia_socket_class_data *cls_d = pci_get_drvdata(dev); struct pcmcia_socket *socket = pci_get_drvdata(dev);
enter("i82092aa_pci_remove"); enter("i82092aa_pci_remove");
free_irq(dev->irq, i82092aa_interrupt); free_irq(dev->irq, i82092aa_interrupt);
if (cls_d) { if (socket)
class_device_unregister(&cls_d->class_dev); pcmcia_unregister_socket(socket);
kfree(cls_d);
}
leave("i82092aa_pci_remove"); leave("i82092aa_pci_remove");
} }
...@@ -447,7 +446,7 @@ static void set_bridge_state(int sock) ...@@ -447,7 +446,7 @@ static void set_bridge_state(int sock)
static int i82092aa_init(unsigned int s) static int i82092aa_init(struct pcmcia_socket *sock)
{ {
int i; int i;
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
...@@ -456,21 +455,21 @@ static int i82092aa_init(unsigned int s) ...@@ -456,21 +455,21 @@ static int i82092aa_init(unsigned int s)
enter("i82092aa_init"); enter("i82092aa_init");
mem.sys_stop = 0x0fff; mem.sys_stop = 0x0fff;
i82092aa_set_socket(s, &dead_socket); i82092aa_set_socket(sock, &dead_socket);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
io.map = i; io.map = i;
i82092aa_set_io_map(s, &io); i82092aa_set_io_map(sock, &io);
} }
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
mem.map = i; mem.map = i;
i82092aa_set_mem_map(s, &mem); i82092aa_set_mem_map(sock, &mem);
} }
leave("i82092aa_init"); leave("i82092aa_init");
return 0; return 0;
} }
static int i82092aa_suspend(unsigned int sock) static int i82092aa_suspend(struct pcmcia_socket *sock)
{ {
int retval; int retval;
enter("i82092aa_suspend"); enter("i82092aa_suspend");
...@@ -479,8 +478,9 @@ static int i82092aa_suspend(unsigned int sock) ...@@ -479,8 +478,9 @@ static int i82092aa_suspend(unsigned int sock)
return retval; return retval;
} }
static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info) static int i82092aa_register_callback(struct pcmcia_socket *socket, void (*handler)(void *, unsigned int), void * info)
{ {
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
enter("i82092aa_register_callback"); enter("i82092aa_register_callback");
sockets[sock].handler = handler; sockets[sock].handler = handler;
sockets[sock].info = info; sockets[sock].info = info;
...@@ -488,8 +488,9 @@ static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *, ...@@ -488,8 +488,9 @@ static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *,
return 0; return 0;
} /* i82092aa_register_callback */ } /* i82092aa_register_callback */
static int i82092aa_inquire_socket(unsigned int sock, socket_cap_t *cap) static int i82092aa_inquire_socket(struct pcmcia_socket *socket, socket_cap_t *cap)
{ {
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
enter("i82092aa_inquire_socket"); enter("i82092aa_inquire_socket");
*cap = sockets[sock].cap; *cap = sockets[sock].cap;
leave("i82092aa_inquire_socket"); leave("i82092aa_inquire_socket");
...@@ -497,8 +498,9 @@ static int i82092aa_inquire_socket(unsigned int sock, socket_cap_t *cap) ...@@ -497,8 +498,9 @@ static int i82092aa_inquire_socket(unsigned int sock, socket_cap_t *cap)
} /* i82092aa_inquire_socket */ } /* i82092aa_inquire_socket */
static int i82092aa_get_status(unsigned int sock, u_int *value) static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)
{ {
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned int status; unsigned int status;
enter("i82092aa_get_status"); enter("i82092aa_get_status");
...@@ -539,8 +541,9 @@ static int i82092aa_get_status(unsigned int sock, u_int *value) ...@@ -539,8 +541,9 @@ static int i82092aa_get_status(unsigned int sock, u_int *value)
} }
static int i82092aa_get_socket(unsigned int sock, socket_state_t *state) static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state)
{ {
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned char reg,vcc,vpp; unsigned char reg,vcc,vpp;
enter("i82092aa_get_socket"); enter("i82092aa_get_socket");
...@@ -610,8 +613,9 @@ static int i82092aa_get_socket(unsigned int sock, socket_state_t *state) ...@@ -610,8 +613,9 @@ static int i82092aa_get_socket(unsigned int sock, socket_state_t *state)
return 0; return 0;
} }
static int i82092aa_set_socket(unsigned int sock, socket_state_t *state) static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state)
{ {
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned char reg; unsigned char reg;
enter("i82092aa_set_socket"); enter("i82092aa_set_socket");
...@@ -706,8 +710,9 @@ static int i82092aa_set_socket(unsigned int sock, socket_state_t *state) ...@@ -706,8 +710,9 @@ static int i82092aa_set_socket(unsigned int sock, socket_state_t *state)
return 0; return 0;
} }
static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io) static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io)
{ {
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned char map, ioctl; unsigned char map, ioctl;
enter("i82092aa_set_io_map"); enter("i82092aa_set_io_map");
...@@ -749,8 +754,9 @@ static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io) ...@@ -749,8 +754,9 @@ static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io)
return 0; return 0;
} }
static int i82092aa_set_mem_map(unsigned sock, struct pccard_mem_map *mem) static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem)
{ {
unsigned int sock = container_of(socket, struct socket_info, socket)->number;
unsigned short base, i; unsigned short base, i;
unsigned char map; unsigned char map;
...@@ -826,7 +832,7 @@ static int i82092aa_set_mem_map(unsigned sock, struct pccard_mem_map *mem) ...@@ -826,7 +832,7 @@ static int i82092aa_set_mem_map(unsigned sock, struct pccard_mem_map *mem)
return 0; return 0;
} }
static void i82092aa_proc_setup(unsigned int sock, struct proc_dir_entry *base) static void i82092aa_proc_setup(struct pcmcia_socket *socket, struct proc_dir_entry *base)
{ {
} }
......
...@@ -28,16 +28,16 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs); ...@@ -28,16 +28,16 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs);
static int i82092aa_get_status(unsigned int sock, u_int *value); static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value);
static int i82092aa_get_socket(unsigned int sock, socket_state_t *state); static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state);
static int i82092aa_set_socket(unsigned int sock, socket_state_t *state); static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state);
static int i82092aa_set_io_map(unsigned int sock, struct pccard_io_map *io); static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io);
static int i82092aa_set_mem_map(unsigned int sock, struct pccard_mem_map *mem); static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem);
static int i82092aa_init(unsigned int s); static int i82092aa_init(struct pcmcia_socket *socket);
static int i82092aa_suspend(unsigned int sock); static int i82092aa_suspend(struct pcmcia_socket *socket);
static int i82092aa_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info); static int i82092aa_register_callback(struct pcmcia_socket *socket, void (*handler)(void *, unsigned int), void * info);
static int i82092aa_inquire_socket(unsigned int sock, socket_cap_t *cap); static int i82092aa_inquire_socket(struct pcmcia_socket *socket, socket_cap_t *cap);
static void i82092aa_proc_setup(unsigned int sock, struct proc_dir_entry *base); static void i82092aa_proc_setup(struct pcmcia_socket *socket, struct proc_dir_entry *base);
#endif #endif
...@@ -91,7 +91,6 @@ static inline int _check_irq(int irq, int flags) ...@@ -91,7 +91,6 @@ static inline int _check_irq(int irq, int flags)
/* Parameters that can be set with 'insmod' */ /* Parameters that can be set with 'insmod' */
#ifdef CONFIG_ISA
/* Default base address for i82365sl and other ISA chips */ /* Default base address for i82365sl and other ISA chips */
static int i365_base = 0x3e0; static int i365_base = 0x3e0;
/* Should we probe at 0x3e2 for an extra ISA controller? */ /* Should we probe at 0x3e2 for an extra ISA controller? */
...@@ -103,7 +102,6 @@ static u_int irq_mask = 0xffff; ...@@ -103,7 +102,6 @@ static u_int irq_mask = 0xffff;
static int irq_list[16] = { -1 }; static int irq_list[16] = { -1 };
/* The card status change interrupt -- 0 means autoselect */ /* The card status change interrupt -- 0 means autoselect */
static int cs_irq = 0; static int cs_irq = 0;
#endif
/* Probe for safe interrupts? */ /* Probe for safe interrupts? */
static int do_scan = 1; static int do_scan = 1;
...@@ -122,14 +120,11 @@ static int setup_time = -1; ...@@ -122,14 +120,11 @@ static int setup_time = -1;
static int cmd_time = -1; static int cmd_time = -1;
static int recov_time = -1; static int recov_time = -1;
#ifdef CONFIG_ISA
/* Vadem options */ /* Vadem options */
static int async_clock = -1; static int async_clock = -1;
static int cable_mode = -1; static int cable_mode = -1;
static int wakeup = 0; static int wakeup = 0;
#endif
#ifdef CONFIG_ISA
MODULE_PARM(i365_base, "i"); MODULE_PARM(i365_base, "i");
MODULE_PARM(ignore, "i"); MODULE_PARM(ignore, "i");
MODULE_PARM(extra_sockets, "i"); MODULE_PARM(extra_sockets, "i");
...@@ -139,7 +134,6 @@ MODULE_PARM(cs_irq, "i"); ...@@ -139,7 +134,6 @@ MODULE_PARM(cs_irq, "i");
MODULE_PARM(async_clock, "i"); MODULE_PARM(async_clock, "i");
MODULE_PARM(cable_mode, "i"); MODULE_PARM(cable_mode, "i");
MODULE_PARM(wakeup, "i"); MODULE_PARM(wakeup, "i");
#endif
MODULE_PARM(do_scan, "i"); MODULE_PARM(do_scan, "i");
MODULE_PARM(poll_interval, "i"); MODULE_PARM(poll_interval, "i");
...@@ -164,8 +158,10 @@ typedef struct vg46x_state_t { ...@@ -164,8 +158,10 @@ typedef struct vg46x_state_t {
u_char ctl, ema; u_char ctl, ema;
} vg46x_state_t; } vg46x_state_t;
typedef struct socket_info_t { struct i82365_socket {
u_short type, flags; u_short type, flags;
struct pcmcia_socket socket;
unsigned int number;
socket_cap_t cap; socket_cap_t cap;
ioaddr_t ioaddr; ioaddr_t ioaddr;
u_short psock; u_short psock;
...@@ -179,26 +175,21 @@ typedef struct socket_info_t { ...@@ -179,26 +175,21 @@ typedef struct socket_info_t {
cirrus_state_t cirrus; cirrus_state_t cirrus;
vg46x_state_t vg46x; vg46x_state_t vg46x;
} state; } state;
} socket_info_t; };
/* Where we keep track of our sockets... */ /* Where we keep track of our sockets... */
static int sockets = 0; static int sockets = 0;
static socket_info_t socket[8] = { static struct i82365_socket socket[8] = {
{ 0, }, /* ... */ { 0, }, /* ... */
}; };
/* Default ISA interrupt mask */ /* Default ISA interrupt mask */
#define I365_MASK 0xdeb8 /* irq 15,14,12,11,10,9,7,5,4,3 */ #define I365_MASK 0xdeb8 /* irq 15,14,12,11,10,9,7,5,4,3 */
#ifdef CONFIG_ISA
static int grab_irq; static int grab_irq;
static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED; static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED;
#define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f) #define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f)
#define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f) #define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f)
#else
#define ISA_LOCK(n, f) do { } while (0)
#define ISA_UNLOCK(n, f) do { } while (0)
#endif
static struct timer_list poll_timer; static struct timer_list poll_timer;
...@@ -209,13 +200,11 @@ static struct timer_list poll_timer; ...@@ -209,13 +200,11 @@ static struct timer_list poll_timer;
PCI_COMMAND_MASTER|PCI_COMMAND_WAIT) PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
/* These definitions must match the pcic table! */ /* These definitions must match the pcic table! */
#ifdef CONFIG_ISA
typedef enum pcic_id { typedef enum pcic_id {
IS_I82365A, IS_I82365B, IS_I82365DF, IS_I82365A, IS_I82365B, IS_I82365DF,
IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469, IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
IS_PD6710, IS_PD672X, IS_VT83C469, IS_PD6710, IS_PD672X, IS_VT83C469,
} pcic_id; } pcic_id;
#endif
/* Flags for classifying groups of controllers */ /* Flags for classifying groups of controllers */
#define IS_VADEM 0x0001 #define IS_VADEM 0x0001
...@@ -237,7 +226,6 @@ typedef struct pcic_t { ...@@ -237,7 +226,6 @@ typedef struct pcic_t {
} pcic_t; } pcic_t;
static pcic_t pcic[] = { static pcic_t pcic[] = {
#ifdef CONFIG_ISA
{ "Intel i82365sl A step", 0 }, { "Intel i82365sl A step", 0 },
{ "Intel i82365sl B step", 0 }, { "Intel i82365sl B step", 0 },
{ "Intel i82365sl DF", IS_DF_PWR }, { "Intel i82365sl DF", IS_DF_PWR },
...@@ -249,7 +237,6 @@ static pcic_t pcic[] = { ...@@ -249,7 +237,6 @@ static pcic_t pcic[] = {
{ "Cirrus PD6710", IS_CIRRUS }, { "Cirrus PD6710", IS_CIRRUS },
{ "Cirrus PD672x", IS_CIRRUS }, { "Cirrus PD672x", IS_CIRRUS },
{ "VIA VT83C469", IS_CIRRUS|IS_VIA }, { "VIA VT83C469", IS_CIRRUS|IS_VIA },
#endif
}; };
#define PCIC_COUNT (sizeof(pcic)/sizeof(pcic_t)) #define PCIC_COUNT (sizeof(pcic)/sizeof(pcic_t))
...@@ -364,7 +351,7 @@ static void cirrus_set_state(u_short s) ...@@ -364,7 +351,7 @@ static void cirrus_set_state(u_short s)
static u_int __init cirrus_set_opts(u_short s, char *buf) static u_int __init cirrus_set_opts(u_short s, char *buf)
{ {
socket_info_t *t = &socket[s]; struct i82365_socket *t = &socket[s];
cirrus_state_t *p = &socket[s].state.cirrus; cirrus_state_t *p = &socket[s].state.cirrus;
u_int mask = 0xffff; u_int mask = 0xffff;
...@@ -421,8 +408,6 @@ static u_int __init cirrus_set_opts(u_short s, char *buf) ...@@ -421,8 +408,6 @@ static u_int __init cirrus_set_opts(u_short s, char *buf)
======================================================================*/ ======================================================================*/
#ifdef CONFIG_ISA
static void vg46x_get_state(u_short s) static void vg46x_get_state(u_short s)
{ {
vg46x_state_t *p = &socket[s].state.vg46x; vg46x_state_t *p = &socket[s].state.vg46x;
...@@ -464,9 +449,6 @@ static u_int __init vg46x_set_opts(u_short s, char *buf) ...@@ -464,9 +449,6 @@ static u_int __init vg46x_set_opts(u_short s, char *buf)
return 0xffff; return 0xffff;
} }
#endif
/*====================================================================== /*======================================================================
Generic routines to get and set controller options Generic routines to get and set controller options
...@@ -475,18 +457,16 @@ static u_int __init vg46x_set_opts(u_short s, char *buf) ...@@ -475,18 +457,16 @@ static u_int __init vg46x_set_opts(u_short s, char *buf)
static void get_bridge_state(u_short s) static void get_bridge_state(u_short s)
{ {
socket_info_t *t = &socket[s]; struct i82365_socket *t = &socket[s];
if (t->flags & IS_CIRRUS) if (t->flags & IS_CIRRUS)
cirrus_get_state(s); cirrus_get_state(s);
#ifdef CONFIG_ISA
else if (t->flags & IS_VADEM) else if (t->flags & IS_VADEM)
vg46x_get_state(s); vg46x_get_state(s);
#endif
} }
static void set_bridge_state(u_short s) static void set_bridge_state(u_short s)
{ {
socket_info_t *t = &socket[s]; struct i82365_socket *t = &socket[s];
if (t->flags & IS_CIRRUS) if (t->flags & IS_CIRRUS)
cirrus_set_state(s); cirrus_set_state(s);
else { else {
...@@ -494,10 +474,8 @@ static void set_bridge_state(u_short s) ...@@ -494,10 +474,8 @@ static void set_bridge_state(u_short s)
i365_set(s, I365_GENCTL, 0x00); i365_set(s, I365_GENCTL, 0x00);
} }
i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr); i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr);
#ifdef CONFIG_ISA
if (t->flags & IS_VADEM) if (t->flags & IS_VADEM)
vg46x_set_state(s); vg46x_set_state(s);
#endif
} }
static u_int __init set_bridge_opts(u_short s, u_short ns) static u_int __init set_bridge_opts(u_short s, u_short ns)
...@@ -515,10 +493,8 @@ static u_int __init set_bridge_opts(u_short s, u_short ns) ...@@ -515,10 +493,8 @@ static u_int __init set_bridge_opts(u_short s, u_short ns)
get_bridge_state(i); get_bridge_state(i);
if (socket[i].flags & IS_CIRRUS) if (socket[i].flags & IS_CIRRUS)
m = cirrus_set_opts(i, buf); m = cirrus_set_opts(i, buf);
#ifdef CONFIG_ISA
else if (socket[i].flags & IS_VADEM) else if (socket[i].flags & IS_VADEM)
m = vg46x_set_opts(i, buf); m = vg46x_set_opts(i, buf);
#endif
set_bridge_state(i); set_bridge_state(i);
printk(KERN_INFO " host opts [%d]:%s\n", i, printk(KERN_INFO " host opts [%d]:%s\n", i,
(*buf) ? buf : " none"); (*buf) ? buf : " none");
...@@ -571,7 +547,6 @@ static u_int __init test_irq(u_short sock, int irq) ...@@ -571,7 +547,6 @@ static u_int __init test_irq(u_short sock, int irq)
return (irq_hits != 1); return (irq_hits != 1);
} }
#ifdef CONFIG_ISA
static u_int __init isa_scan(u_short sock, u_int mask0) static u_int __init isa_scan(u_short sock, u_int mask0)
{ {
...@@ -617,7 +592,6 @@ static u_int __init isa_scan(u_short sock, u_int mask0) ...@@ -617,7 +592,6 @@ static u_int __init isa_scan(u_short sock, u_int mask0)
return mask1; return mask1;
} }
#endif /* CONFIG_ISA */
/*====================================================================*/ /*====================================================================*/
...@@ -630,7 +604,6 @@ static int to_cycles(int ns) ...@@ -630,7 +604,6 @@ static int to_cycles(int ns)
/*====================================================================*/ /*====================================================================*/
#ifdef CONFIG_ISA
static int __init identify(u_short port, u_short sock) static int __init identify(u_short port, u_short sock)
{ {
...@@ -691,8 +664,6 @@ static int __init identify(u_short port, u_short sock) ...@@ -691,8 +664,6 @@ static int __init identify(u_short port, u_short sock)
return type; return type;
} /* identify */ } /* identify */
#endif
/*====================================================================== /*======================================================================
See if a card is present, powered up, in IO mode, and already See if a card is present, powered up, in IO mode, and already
...@@ -737,7 +708,7 @@ static void __init add_pcic(int ns, int type) ...@@ -737,7 +708,7 @@ static void __init add_pcic(int ns, int type)
{ {
u_int mask = 0, i, base; u_int mask = 0, i, base;
int use_pci = 0, isa_irq = 0; int use_pci = 0, isa_irq = 0;
socket_info_t *t = &socket[sockets-ns]; struct i82365_socket *t = &socket[sockets-ns];
base = sockets-ns; base = sockets-ns;
if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365"); if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365");
...@@ -748,23 +719,17 @@ static void __init add_pcic(int ns, int type) ...@@ -748,23 +719,17 @@ static void __init add_pcic(int ns, int type)
t->ioaddr, t->psock*0x40); t->ioaddr, t->psock*0x40);
printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : "")); printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
#ifdef CONFIG_ISA
/* Set host options, build basic interrupt mask */ /* Set host options, build basic interrupt mask */
if (irq_list[0] == -1) if (irq_list[0] == -1)
mask = irq_mask; mask = irq_mask;
else else
for (i = mask = 0; i < 16; i++) for (i = mask = 0; i < 16; i++)
mask |= (1<<irq_list[i]); mask |= (1<<irq_list[i]);
#endif
mask &= I365_MASK & set_bridge_opts(base, ns); mask &= I365_MASK & set_bridge_opts(base, ns);
#ifdef CONFIG_ISA
/* Scan for ISA interrupts */ /* Scan for ISA interrupts */
mask = isa_scan(base, mask); mask = isa_scan(base, mask);
#else
printk(KERN_INFO " PCI card interrupts,"); printk(KERN_INFO " PCI card interrupts,");
#endif
#ifdef CONFIG_ISA
/* Poll if only two interrupts available */ /* Poll if only two interrupts available */
if (!use_pci && !poll_interval) { if (!use_pci && !poll_interval) {
u_int tmp = (mask & 0xff20); u_int tmp = (mask & 0xff20);
...@@ -786,7 +751,6 @@ static void __init add_pcic(int ns, int type) ...@@ -786,7 +751,6 @@ static void __init add_pcic(int ns, int type)
printk(" status change on irq %d\n", cs_irq); printk(" status change on irq %d\n", cs_irq);
} }
} }
#endif
if (!use_pci && !isa_irq) { if (!use_pci && !isa_irq) {
if (poll_interval == 0) if (poll_interval == 0)
...@@ -809,7 +773,6 @@ static void __init add_pcic(int ns, int type) ...@@ -809,7 +773,6 @@ static void __init add_pcic(int ns, int type)
/*====================================================================*/ /*====================================================================*/
#ifdef CONFIG_ISA
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static struct isapnp_device_id id_table[] __initdata = { static struct isapnp_device_id id_table[] __initdata = {
...@@ -902,7 +865,6 @@ static void __init isa_probe(void) ...@@ -902,7 +865,6 @@ static void __init isa_probe(void)
} }
} }
#endif
/*====================================================================*/ /*====================================================================*/
...@@ -940,9 +902,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev, ...@@ -940,9 +902,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev,
{ {
int i, j, csc; int i, j, csc;
u_int events, active; u_int events, active;
#ifdef CONFIG_ISA
u_long flags = 0; u_long flags = 0;
#endif
int handled = 0; int handled = 0;
DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq); DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq);
...@@ -1013,8 +973,9 @@ static void pcic_interrupt_wrapper(u_long data) ...@@ -1013,8 +973,9 @@ static void pcic_interrupt_wrapper(u_long data)
/*====================================================================*/ /*====================================================================*/
static int pcic_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info) static int pcic_register_callback(struct pcmcia_socket *s, void (*handler)(void *, unsigned int), void * info)
{ {
unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
socket[sock].handler = handler; socket[sock].handler = handler;
socket[sock].info = info; socket[sock].info = info;
return 0; return 0;
...@@ -1022,8 +983,9 @@ static int pcic_register_callback(unsigned int sock, void (*handler)(void *, uns ...@@ -1022,8 +983,9 @@ static int pcic_register_callback(unsigned int sock, void (*handler)(void *, uns
/*====================================================================*/ /*====================================================================*/
static int pcic_inquire_socket(unsigned int sock, socket_cap_t *cap) static int pcic_inquire_socket(struct pcmcia_socket *s, socket_cap_t *cap)
{ {
unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
*cap = socket[sock].cap; *cap = socket[sock].cap;
return 0; return 0;
} /* pcic_inquire_socket */ } /* pcic_inquire_socket */
...@@ -1048,7 +1010,6 @@ static int i365_get_status(u_short sock, u_int *value) ...@@ -1048,7 +1010,6 @@ static int i365_get_status(u_short sock, u_int *value)
*value |= (status & I365_CS_READY) ? SS_READY : 0; *value |= (status & I365_CS_READY) ? SS_READY : 0;
*value |= (status & I365_CS_POWERON) ? SS_POWERON : 0; *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
#ifdef CONFIG_ISA
if (socket[sock].type == IS_VG469) { if (socket[sock].type == IS_VG469) {
status = i365_get(sock, VG469_VSENSE); status = i365_get(sock, VG469_VSENSE);
if (socket[sock].psock & 1) { if (socket[sock].psock & 1) {
...@@ -1059,7 +1020,6 @@ static int i365_get_status(u_short sock, u_int *value) ...@@ -1059,7 +1020,6 @@ static int i365_get_status(u_short sock, u_int *value)
*value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD; *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
} }
} }
#endif
DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", sock, *value); DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", sock, *value);
return 0; return 0;
...@@ -1069,7 +1029,7 @@ static int i365_get_status(u_short sock, u_int *value) ...@@ -1069,7 +1029,7 @@ static int i365_get_status(u_short sock, u_int *value)
static int i365_get_socket(u_short sock, socket_state_t *state) static int i365_get_socket(u_short sock, socket_state_t *state)
{ {
socket_info_t *t = &socket[sock]; struct i82365_socket *t = &socket[sock];
u_char reg, vcc, vpp; u_char reg, vcc, vpp;
reg = i365_get(sock, I365_POWER); reg = i365_get(sock, I365_POWER);
...@@ -1141,7 +1101,7 @@ static int i365_get_socket(u_short sock, socket_state_t *state) ...@@ -1141,7 +1101,7 @@ static int i365_get_socket(u_short sock, socket_state_t *state)
static int i365_set_socket(u_short sock, socket_state_t *state) static int i365_set_socket(u_short sock, socket_state_t *state)
{ {
socket_info_t *t = &socket[sock]; struct i82365_socket *t = &socket[sock];
u_char reg; u_char reg;
DEBUG(1, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " DEBUG(1, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
...@@ -1337,7 +1297,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) ...@@ -1337,7 +1297,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
static int proc_read_info(char *buf, char **start, off_t pos, static int proc_read_info(char *buf, char **start, off_t pos,
int count, int *eof, void *data) int count, int *eof, void *data)
{ {
socket_info_t *s = data; struct i82365_socket *s = data;
char *p = buf; char *p = buf;
p += sprintf(p, "type: %s\npsock: %d\n", p += sprintf(p, "type: %s\npsock: %d\n",
pcic[s->type].name, s->psock); pcic[s->type].name, s->psock);
...@@ -1347,13 +1307,11 @@ static int proc_read_info(char *buf, char **start, off_t pos, ...@@ -1347,13 +1307,11 @@ static int proc_read_info(char *buf, char **start, off_t pos,
static int proc_read_exca(char *buf, char **start, off_t pos, static int proc_read_exca(char *buf, char **start, off_t pos,
int count, int *eof, void *data) int count, int *eof, void *data)
{ {
u_short sock = (socket_info_t *)data - socket; u_short sock = (struct i82365_socket *)data - socket;
char *p = buf; char *p = buf;
int i, top; int i, top;
#ifdef CONFIG_ISA
u_long flags = 0; u_long flags = 0;
#endif
ISA_LOCK(sock, flags); ISA_LOCK(sock, flags);
top = 0x40; top = 0x40;
for (i = 0; i < top; i += 4) { for (i = 0; i < top; i += 4) {
...@@ -1370,9 +1328,9 @@ static int proc_read_exca(char *buf, char **start, off_t pos, ...@@ -1370,9 +1328,9 @@ static int proc_read_exca(char *buf, char **start, off_t pos,
return (p - buf); return (p - buf);
} }
static void pcic_proc_setup(unsigned int sock, struct proc_dir_entry *base) static void pcic_proc_setup(struct pcmcia_socket *sock, struct proc_dir_entry *base)
{ {
socket_info_t *s = &socket[sock]; struct i82365_socket *s = container_of(sock, struct i82365_socket, socket);
if (s->flags & IS_ALIVE) if (s->flags & IS_ALIVE)
return; return;
...@@ -1398,15 +1356,8 @@ static void pcic_proc_remove(u_short sock) ...@@ -1398,15 +1356,8 @@ static void pcic_proc_remove(u_short sock)
/*====================================================================*/ /*====================================================================*/
/* /* this is horribly ugly... proper locking needs to be done here at
* The locking is rather broken. Why do we only lock for ISA, not for * some time... */
* all other cases? If there are reasons to lock, we should lock. Not
* this silly conditional.
*
* Plan: make it bug-for-bug compatible with the old stuff, and clean
* it up when the infrastructure is done.
*/
#ifdef CONFIG_ISA
#define LOCKED(x) do { \ #define LOCKED(x) do { \
int retval; \ int retval; \
unsigned long flags; \ unsigned long flags; \
...@@ -1415,13 +1366,12 @@ static void pcic_proc_remove(u_short sock) ...@@ -1415,13 +1366,12 @@ static void pcic_proc_remove(u_short sock)
spin_unlock_irqrestore(&isa_lock, flags); \ spin_unlock_irqrestore(&isa_lock, flags); \
return retval; \ return retval; \
} while (0) } while (0)
#else
#define LOCKED(x) return x
#endif
static int pcic_get_status(unsigned int sock, u_int *value) static int pcic_get_status(struct pcmcia_socket *s, u_int *value)
{ {
unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
if (socket[sock].flags & IS_ALIVE) { if (socket[sock].flags & IS_ALIVE) {
*value = 0; *value = 0;
return -EINVAL; return -EINVAL;
...@@ -1430,39 +1380,45 @@ static int pcic_get_status(unsigned int sock, u_int *value) ...@@ -1430,39 +1380,45 @@ static int pcic_get_status(unsigned int sock, u_int *value)
LOCKED(i365_get_status(sock, value)); LOCKED(i365_get_status(sock, value));
} }
static int pcic_get_socket(unsigned int sock, socket_state_t *state) static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state)
{ {
unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
if (socket[sock].flags & IS_ALIVE) if (socket[sock].flags & IS_ALIVE)
return -EINVAL; return -EINVAL;
LOCKED(i365_get_socket(sock, state)); LOCKED(i365_get_socket(sock, state));
} }
static int pcic_set_socket(unsigned int sock, socket_state_t *state) static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state)
{ {
unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
if (socket[sock].flags & IS_ALIVE) if (socket[sock].flags & IS_ALIVE)
return -EINVAL; return -EINVAL;
LOCKED(i365_set_socket(sock, state)); LOCKED(i365_set_socket(sock, state));
} }
static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io) static int pcic_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
{ {
unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
if (socket[sock].flags & IS_ALIVE) if (socket[sock].flags & IS_ALIVE)
return -EINVAL; return -EINVAL;
LOCKED(i365_set_io_map(sock, io)); LOCKED(i365_set_io_map(sock, io));
} }
static int pcic_set_mem_map(unsigned int sock, struct pccard_mem_map *mem) static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
{ {
unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
if (socket[sock].flags & IS_ALIVE) if (socket[sock].flags & IS_ALIVE)
return -EINVAL; return -EINVAL;
LOCKED(i365_set_mem_map(sock, mem)); LOCKED(i365_set_mem_map(sock, mem));
} }
static int pcic_init(unsigned int s) static int pcic_init(struct pcmcia_socket *s)
{ {
int i; int i;
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
...@@ -1481,7 +1437,7 @@ static int pcic_init(unsigned int s) ...@@ -1481,7 +1437,7 @@ static int pcic_init(unsigned int s)
return 0; return 0;
} }
static int pcic_suspend(unsigned int sock) static int pcic_suspend(struct pcmcia_socket *sock)
{ {
return pcic_set_socket(sock, &dead_socket); return pcic_set_socket(sock, &dead_socket);
} }
...@@ -1502,15 +1458,11 @@ static struct pccard_operations pcic_operations = { ...@@ -1502,15 +1458,11 @@ static struct pccard_operations pcic_operations = {
/*====================================================================*/ /*====================================================================*/
static struct pcmcia_socket_class_data i82365_data = {
.ops = &pcic_operations,
};
static struct device_driver i82365_driver = { static struct device_driver i82365_driver = {
.name = "i82365", .name = "i82365",
.bus = &platform_bus_type, .bus = &platform_bus_type,
/* .suspend = pcmcia_socket_dev_suspend, FIXME? */ .suspend = pcmcia_socket_dev_suspend,
/* .resume = pcmcia_socket_dev_resume, FIXME? */ .resume = pcmcia_socket_dev_resume,
}; };
static struct platform_device i82365_device = { static struct platform_device i82365_device = {
...@@ -1521,13 +1473,11 @@ static struct platform_device i82365_device = { ...@@ -1521,13 +1473,11 @@ static struct platform_device i82365_device = {
}, },
}; };
static struct class_device i82365_class_data = {
.class = &pcmcia_socket_class,
};
static int __init init_i82365(void) static int __init init_i82365(void)
{ {
servinfo_t serv; servinfo_t serv;
int i, ret;
pcmcia_get_card_services_info(&serv); pcmcia_get_card_services_info(&serv);
if (serv.Revision != CS_RELEASE_CODE) { if (serv.Revision != CS_RELEASE_CODE) {
printk(KERN_NOTICE "i82365: Card Services release " printk(KERN_NOTICE "i82365: Card Services release "
...@@ -1541,9 +1491,7 @@ static int __init init_i82365(void) ...@@ -1541,9 +1491,7 @@ static int __init init_i82365(void)
printk(KERN_INFO "Intel PCIC probe: "); printk(KERN_INFO "Intel PCIC probe: ");
sockets = 0; sockets = 0;
#ifdef CONFIG_ISA
isa_probe(); isa_probe();
#endif
if (sockets == 0) { if (sockets == 0) {
printk("not found.\n"); printk("not found.\n");
...@@ -1551,19 +1499,24 @@ static int __init init_i82365(void) ...@@ -1551,19 +1499,24 @@ static int __init init_i82365(void)
return -ENODEV; return -ENODEV;
} }
platform_device_register(&i82365_device);
/* Set up interrupt handler(s) */ /* Set up interrupt handler(s) */
#ifdef CONFIG_ISA
if (grab_irq != 0) if (grab_irq != 0)
request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt); request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
#endif
i82365_data.nsock = sockets; /* register sockets with the pcmcia core */
i82365_class_data.dev = &i82365_device.dev; for (i = 0; i < sockets; i++) {
i82365_class_data.class_data = &i82365_data; socket[i].socket.dev.dev = &i82365_device.dev;
strlcpy(i82365_class_data.class_id, "i82365", BUS_ID_SIZE); socket[i].socket.ss_entry = &pcic_operations;
socket[i].number = i;
platform_device_register(&i82365_device); ret = pcmcia_register_socket(&socket[i].socket);
class_device_register(&i82365_class_data); if (ret && i--) {
for (; i>= 0; i--)
pcmcia_unregister_socket(&socket[i].socket);
break;
}
}
/* Finally, schedule a polling interrupt */ /* Finally, schedule a polling interrupt */
if (poll_interval != 0) { if (poll_interval != 0) {
...@@ -1581,23 +1534,23 @@ static int __init init_i82365(void) ...@@ -1581,23 +1534,23 @@ static int __init init_i82365(void)
static void __exit exit_i82365(void) static void __exit exit_i82365(void)
{ {
int i; int i;
for (i = 0; i < sockets; i++) {
pcmcia_unregister_socket(&socket[i].socket);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
for (i = 0; i < sockets; i++) pcic_proc_remove(i); pcic_proc_remove(i);
#endif #endif
class_device_unregister(&i82365_class_data); }
platform_device_unregister(&i82365_device); platform_device_unregister(&i82365_device);
if (poll_interval != 0) if (poll_interval != 0)
del_timer_sync(&poll_timer); del_timer_sync(&poll_timer);
#ifdef CONFIG_ISA
if (grab_irq != 0) if (grab_irq != 0)
free_irq(cs_irq, pcic_interrupt); free_irq(cs_irq, pcic_interrupt);
#endif
for (i = 0; i < sockets; i++) { for (i = 0; i < sockets; i++) {
/* Turn off all interrupt sources! */ /* Turn off all interrupt sources! */
i365_set(i, I365_CSCINT, 0); i365_set(i, I365_CSCINT, 0);
release_region(socket[i].ioaddr, 2); release_region(socket[i].ioaddr, 2);
} }
#if defined(CONFIG_ISA) && defined(__ISAPNP__) #ifdef __ISAPNP__
if (i82365_pnpdev) if (i82365_pnpdev)
pnp_disable_dev(i82365_pnpdev); pnp_disable_dev(i82365_pnpdev);
#endif #endif
......
/*
* Generic PCI pccard driver interface.
*
* (C) Copyright 1999 Linus Torvalds
*
* This implements the common parts of PCI pccard drivers,
* notably detection and infrastructure conversion (ie change
* from socket index to "struct pci_dev" etc)
*
* This does NOT implement the actual low-level driver details,
* and this has on purpose been left generic enough that it can
* be used to set up a PCI PCMCIA controller (ie non-cardbus),
* or to set up a controller.
*
* See for example the "yenta" driver for PCI cardbus controllers
* conforming to the yenta cardbus specifications.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <pcmcia/ss.h>
#include <asm/io.h>
#include "pci_socket.h"
/*
* Arbitrary define. This is the array of active cardbus
* entries.
*/
#define MAX_SOCKETS (8)
static pci_socket_t pci_socket_array[MAX_SOCKETS];
static int pci_init_socket(unsigned int sock)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->init)
return socket->op->init(socket);
return -EINVAL;
}
static int pci_suspend_socket(unsigned int sock)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->suspend)
return socket->op->suspend(socket);
return -EINVAL;
}
static int pci_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
{
pci_socket_t *socket = pci_socket_array + sock;
socket->handler = handler;
socket->info = info;
return 0;
}
static int pci_inquire_socket(unsigned int sock, socket_cap_t *cap)
{
pci_socket_t *socket = pci_socket_array + sock;
*cap = socket->cap;
return 0;
}
static int pci_get_status(unsigned int sock, unsigned int *value)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->get_status)
return socket->op->get_status(socket, value);
*value = 0;
return -EINVAL;
}
static int pci_get_socket(unsigned int sock, socket_state_t *state)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->get_socket)
return socket->op->get_socket(socket, state);
return -EINVAL;
}
static int pci_set_socket(unsigned int sock, socket_state_t *state)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->set_socket)
return socket->op->set_socket(socket, state);
return -EINVAL;
}
static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->set_io_map)
return socket->op->set_io_map(socket, io);
return -EINVAL;
}
static int pci_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->set_mem_map)
return socket->op->set_mem_map(socket, mem);
return -EINVAL;
}
static void pci_proc_setup(unsigned int sock, struct proc_dir_entry *base)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->proc_setup)
socket->op->proc_setup(socket, base);
}
static struct pccard_operations pci_socket_operations = {
.owner = THIS_MODULE,
.init = pci_init_socket,
.suspend = pci_suspend_socket,
.register_callback = pci_register_callback,
.inquire_socket = pci_inquire_socket,
.get_status = pci_get_status,
.get_socket = pci_get_socket,
.set_socket = pci_set_socket,
.set_io_map = pci_set_io_map,
.set_mem_map = pci_set_mem_map,
.proc_setup = pci_proc_setup,
};
static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_socket_ops *ops)
{
pci_socket_t *socket = nr + pci_socket_array;
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.class_dev.class = &pcmcia_socket_class;
socket->cls_d.class_dev.dev = &dev->dev;
strlcpy(socket->cls_d.class_dev.class_id, dev->dev.bus_id, BUS_ID_SIZE);
class_set_devdata(&socket->cls_d.class_dev, &socket->cls_d);
/* prepare pci_socket_t */
socket->dev = dev;
socket->op = ops;
pci_set_drvdata(dev, socket);
spin_lock_init(&socket->event_lock);
err = socket->op->open(socket);
if (err) {
socket->dev = NULL;
pci_set_drvdata(dev, NULL);
} else {
class_device_register(&socket->cls_d.class_dev);
}
return err;
}
int cardbus_register(struct pci_dev *p_dev)
{
return 0;
}
static int __devinit
cardbus_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
int s;
for (s = 0; s < MAX_SOCKETS; s++) {
if (pci_socket_array [s].dev == 0) {
return add_pci_socket (s, dev, &yenta_operations);
}
}
return -ENODEV;
}
static void __devexit cardbus_remove (struct pci_dev *dev)
{
pci_socket_t *socket = pci_get_drvdata(dev);
/* note: we are already unregistered from the cs core */
class_device_unregister(&socket->cls_d.class_dev);
if (socket->op && socket->op->close)
socket->op->close(socket);
pci_set_drvdata(dev, NULL);
}
static int cardbus_suspend (struct pci_dev *dev, u32 state)
{
pci_socket_t *socket = pci_get_drvdata(dev);
return pcmcia_socket_dev_suspend(&socket->cls_d, state, 0);
}
static int cardbus_resume (struct pci_dev *dev)
{
pci_socket_t *socket = pci_get_drvdata(dev);
return pcmcia_socket_dev_resume(&socket->cls_d, RESUME_RESTORE_STATE);
}
static struct pci_device_id cardbus_table [] __devinitdata = { {
.class = PCI_CLASS_BRIDGE_CARDBUS << 8,
.class_mask = ~0,
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
}, { /* all zeroes */ }
};
MODULE_DEVICE_TABLE(pci, cardbus_table);
static struct pci_driver pci_cardbus_driver = {
.name = "cardbus",
.id_table = cardbus_table,
.probe = cardbus_probe,
.remove = __devexit_p(cardbus_remove),
.suspend = cardbus_suspend,
.resume = cardbus_resume,
};
static int __init pci_socket_init(void)
{
return pci_register_driver (&pci_cardbus_driver);
}
static void __exit pci_socket_exit (void)
{
pci_unregister_driver (&pci_cardbus_driver);
}
module_init(pci_socket_init);
module_exit(pci_socket_exit);
/*
* drivers/pcmcia/pci_socket.h
*
* (C) Copyright 1999 Linus Torvalds
*/
#ifndef __PCI_SOCKET_H
#define __PCI_SOCKET_H
struct pci_socket_ops;
struct socket_info_t;
typedef struct pci_socket {
struct pci_dev *dev;
int cb_irq, io_irq;
void *base;
void (*handler)(void *, unsigned int);
void *info;
struct pci_socket_ops *op;
socket_cap_t cap;
spinlock_t event_lock;
unsigned int events;
struct work_struct tq_task;
struct timer_list poll_timer;
struct pcmcia_socket_class_data cls_d;
/* A few words of private data for the low-level driver.. */
unsigned int private[8];
} pci_socket_t;
struct pci_socket_ops {
int (*open)(struct pci_socket *);
void (*close)(struct pci_socket *);
int (*init)(struct pci_socket *);
int (*suspend)(struct pci_socket *);
int (*get_status)(struct pci_socket *, unsigned int *);
int (*get_socket)(struct pci_socket *, socket_state_t *);
int (*set_socket)(struct pci_socket *, socket_state_t *);
int (*set_io_map)(struct pci_socket *, struct pccard_io_map *);
int (*set_mem_map)(struct pci_socket *, struct pccard_mem_map *);
void (*proc_setup)(struct pci_socket *, struct proc_dir_entry *base);
};
extern struct pci_socket_ops yenta_operations;
extern struct pci_socket_ops ricoh_operations;
#endif
...@@ -125,11 +125,26 @@ ...@@ -125,11 +125,26 @@
#define rl_mem(socket) ((socket)->private[3]) #define rl_mem(socket) ((socket)->private[3])
#define rl_config(socket) ((socket)->private[4]) #define rl_config(socket) ((socket)->private[4])
static int ricoh_init(struct pcmcia_socket *sock)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
config_writew(socket, RL5C4XX_MISC, rl_misc(socket));
config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(socket));
config_writew(socket, RL5C4XX_16BIT_IO_0, rl_io(socket));
config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket));
config_writew(socket, RL5C4XX_CONFIG, rl_config(socket));
return 0;
}
/* /*
* Magic Ricoh initialization code.. Save state at * Magic Ricoh initialization code.. Save state at
* beginning, re-initialize it after suspend. * beginning, re-initialize it after suspend.
*/ */
static int ricoh_open(pci_socket_t *socket) static int ricoh_override(struct yenta_socket *socket)
{ {
rl_misc(socket) = config_readw(socket, RL5C4XX_MISC); rl_misc(socket) = config_readw(socket, RL5C4XX_MISC);
rl_ctl(socket) = config_readw(socket, RL5C4XX_16BIT_CTL); rl_ctl(socket) = config_readw(socket, RL5C4XX_16BIT_CTL);
...@@ -146,35 +161,11 @@ static int ricoh_open(pci_socket_t *socket) ...@@ -146,35 +161,11 @@ static int ricoh_open(pci_socket_t *socket)
rl_config(socket) |= RL5C4XX_CONFIG_PREFETCH; rl_config(socket) |= RL5C4XX_CONFIG_PREFETCH;
} }
return 0; socket->socket.ss_entry->init = ricoh_init;
}
static int ricoh_init(pci_socket_t *socket)
{
yenta_init(socket);
config_writew(socket, RL5C4XX_MISC, rl_misc(socket));
config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(socket));
config_writew(socket, RL5C4XX_16BIT_IO_0, rl_io(socket));
config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket));
config_writew(socket, RL5C4XX_CONFIG, rl_config(socket));
return 0; return 0;
} }
static struct pci_socket_ops ricoh_ops = {
ricoh_open,
yenta_close,
ricoh_init,
yenta_suspend,
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
yenta_set_io_map,
yenta_set_mem_map,
yenta_proc_setup
};
#endif /* CONFIG_CARDBUS */ #endif /* CONFIG_CARDBUS */
#endif /* _LINUX_RICOH_H */ #endif /* _LINUX_RICOH_H */
...@@ -90,7 +90,7 @@ static DECLARE_MUTEX(rsrc_sem); ...@@ -90,7 +90,7 @@ static DECLARE_MUTEX(rsrc_sem);
typedef struct irq_info_t { typedef struct irq_info_t {
u_int Attributes; u_int Attributes;
int time_share, dyn_share; int time_share, dyn_share;
struct socket_info_t *Socket; struct pcmcia_socket *Socket;
} irq_info_t; } irq_info_t;
/* Table of IRQ assignments */ /* Table of IRQ assignments */
...@@ -341,7 +341,7 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num) ...@@ -341,7 +341,7 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num)
======================================================================*/ ======================================================================*/
/* Validation function for cards with a valid CIS */ /* Validation function for cards with a valid CIS */
static int cis_readable(socket_info_t *s, u_long base) static int cis_readable(struct pcmcia_socket *s, u_long base)
{ {
cisinfo_t info1, info2; cisinfo_t info1, info2;
int ret; int ret;
...@@ -364,7 +364,7 @@ static int cis_readable(socket_info_t *s, u_long base) ...@@ -364,7 +364,7 @@ static int cis_readable(socket_info_t *s, u_long base)
} }
/* Validation function for simple memory cards */ /* Validation function for simple memory cards */
static int checksum(socket_info_t *s, u_long base) static int checksum(struct pcmcia_socket *s, u_long base)
{ {
int i, a, b, d; int i, a, b, d;
s->cis_mem.sys_start = base; s->cis_mem.sys_start = base;
...@@ -372,7 +372,7 @@ static int checksum(socket_info_t *s, u_long base) ...@@ -372,7 +372,7 @@ static int checksum(socket_info_t *s, u_long base)
s->cis_virt = ioremap(base, s->cap.map_size); s->cis_virt = ioremap(base, s->cap.map_size);
s->cis_mem.card_start = 0; s->cis_mem.card_start = 0;
s->cis_mem.flags = MAP_ACTIVE; s->cis_mem.flags = MAP_ACTIVE;
s->ss_entry->set_mem_map(s->sock, &s->cis_mem); s->ss_entry->set_mem_map(s, &s->cis_mem);
/* Don't bother checking every word... */ /* Don't bother checking every word... */
a = 0; b = -1; a = 0; b = -1;
for (i = 0; i < s->cap.map_size; i += 44) { for (i = 0; i < s->cap.map_size; i += 44) {
...@@ -383,7 +383,7 @@ static int checksum(socket_info_t *s, u_long base) ...@@ -383,7 +383,7 @@ static int checksum(socket_info_t *s, u_long base)
return (b == -1) ? -1 : (a>>1); return (b == -1) ? -1 : (a>>1);
} }
static int checksum_match(socket_info_t *s, u_long base) static int checksum_match(struct pcmcia_socket *s, u_long base)
{ {
int a = checksum(s, base), b = checksum(s, base+s->cap.map_size); int a = checksum(s, base), b = checksum(s, base+s->cap.map_size);
return ((a == b) && (a >= 0)); return ((a == b) && (a >= 0));
...@@ -397,7 +397,7 @@ static int checksum_match(socket_info_t *s, u_long base) ...@@ -397,7 +397,7 @@ static int checksum_match(socket_info_t *s, u_long base)
======================================================================*/ ======================================================================*/
static int do_mem_probe(u_long base, u_long num, socket_info_t *s) static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
{ {
u_long i, j, bad, fail, step; u_long i, j, bad, fail, step;
...@@ -435,7 +435,7 @@ static int do_mem_probe(u_long base, u_long num, socket_info_t *s) ...@@ -435,7 +435,7 @@ static int do_mem_probe(u_long base, u_long num, socket_info_t *s)
#ifdef CONFIG_PCMCIA_PROBE #ifdef CONFIG_PCMCIA_PROBE
static u_long inv_probe(resource_map_t *m, socket_info_t *s) static u_long inv_probe(resource_map_t *m, struct pcmcia_socket *s)
{ {
u_long ok; u_long ok;
if (m == &mem_db) if (m == &mem_db)
...@@ -451,7 +451,7 @@ static u_long inv_probe(resource_map_t *m, socket_info_t *s) ...@@ -451,7 +451,7 @@ static u_long inv_probe(resource_map_t *m, socket_info_t *s)
return do_mem_probe(m->base, m->num, s); return do_mem_probe(m->base, m->num, s);
} }
void validate_mem(socket_info_t *s) void validate_mem(struct pcmcia_socket *s)
{ {
resource_map_t *m, *n; resource_map_t *m, *n;
static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
...@@ -497,7 +497,7 @@ void validate_mem(socket_info_t *s) ...@@ -497,7 +497,7 @@ void validate_mem(socket_info_t *s)
#else /* CONFIG_PCMCIA_PROBE */ #else /* CONFIG_PCMCIA_PROBE */
void validate_mem(socket_info_t *s) void validate_mem(struct pcmcia_socket *s)
{ {
resource_map_t *m, *n; resource_map_t *m, *n;
static int done = 0; static int done = 0;
...@@ -529,7 +529,7 @@ void validate_mem(socket_info_t *s) ...@@ -529,7 +529,7 @@ void validate_mem(socket_info_t *s)
======================================================================*/ ======================================================================*/
int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
char *name, socket_info_t *s) char *name, struct pcmcia_socket *s)
{ {
ioaddr_t try; ioaddr_t try;
resource_map_t *m; resource_map_t *m;
...@@ -556,7 +556,7 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, ...@@ -556,7 +556,7 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
} }
int find_mem_region(u_long *base, u_long num, u_long align, int find_mem_region(u_long *base, u_long num, u_long align,
int force_low, char *name, socket_info_t *s) int force_low, char *name, struct pcmcia_socket *s)
{ {
u_long try; u_long try;
resource_map_t *m; resource_map_t *m;
...@@ -726,7 +726,7 @@ void undo_irq(u_int Attributes, int irq) ...@@ -726,7 +726,7 @@ void undo_irq(u_int Attributes, int irq)
static int adjust_memory(adjust_t *adj) static int adjust_memory(adjust_t *adj)
{ {
u_long base, num; u_long base, num;
int i, ret; int ret;
base = adj->resource.memory.Base; base = adj->resource.memory.Base;
num = adj->resource.memory.Size; num = adj->resource.memory.Size;
...@@ -743,9 +743,11 @@ static int adjust_memory(adjust_t *adj) ...@@ -743,9 +743,11 @@ static int adjust_memory(adjust_t *adj)
case REMOVE_MANAGED_RESOURCE: case REMOVE_MANAGED_RESOURCE:
ret = sub_interval(&mem_db, base, num); ret = sub_interval(&mem_db, base, num);
if (ret == CS_SUCCESS) { if (ret == CS_SUCCESS) {
for (i = 0; i < sockets; i++) { struct pcmcia_socket *socket;
release_cis_mem(socket_table[i]); down_read(&pcmcia_socket_list_rwsem);
} list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
release_cis_mem(socket);
up_read(&pcmcia_socket_list_rwsem);
} }
break; break;
default: default:
......
...@@ -106,19 +106,10 @@ static struct device_driver sa11x0_pcmcia_driver = { ...@@ -106,19 +106,10 @@ static struct device_driver sa11x0_pcmcia_driver = {
.remove = sa11xx_drv_pcmcia_remove, .remove = sa11xx_drv_pcmcia_remove,
.name = "sa11x0-pcmcia", .name = "sa11x0-pcmcia",
.bus = &platform_bus_type, .bus = &platform_bus_type,
.devclass = &pcmcia_socket_class,
.suspend = pcmcia_socket_dev_suspend, .suspend = pcmcia_socket_dev_suspend,
.resume = pcmcia_socket_dev_resume, .resume = pcmcia_socket_dev_resume,
}; };
static struct platform_device sa11x0_pcmcia_device = {
.name = "sa11x0-pcmcia",
.id = 0,
.dev = {
.name = "Intel Corporation SA11x0 [PCMCIA]",
},
};
/* sa11x0_pcmcia_init() /* sa11x0_pcmcia_init()
* ^^^^^^^^^^^^^^^^^^^^ * ^^^^^^^^^^^^^^^^^^^^
* *
...@@ -129,16 +120,7 @@ static struct platform_device sa11x0_pcmcia_device = { ...@@ -129,16 +120,7 @@ static struct platform_device sa11x0_pcmcia_device = {
*/ */
static int __init sa11x0_pcmcia_init(void) static int __init sa11x0_pcmcia_init(void)
{ {
int ret; return driver_register(&sa11x0_pcmcia_driver);
ret = driver_register(&sa11x0_pcmcia_driver);
if (ret == 0) {
ret = platform_device_register(&sa11x0_pcmcia_device);
if (ret)
driver_unregister(&sa11x0_pcmcia_driver);
}
return ret;
} }
/* sa11x0_pcmcia_exit() /* sa11x0_pcmcia_exit()
...@@ -148,7 +130,6 @@ static int __init sa11x0_pcmcia_init(void) ...@@ -148,7 +130,6 @@ static int __init sa11x0_pcmcia_init(void)
*/ */
static void __exit sa11x0_pcmcia_exit(void) static void __exit sa11x0_pcmcia_exit(void)
{ {
platform_device_unregister(&sa11x0_pcmcia_device);
driver_unregister(&sa11x0_pcmcia_driver); driver_unregister(&sa11x0_pcmcia_driver);
} }
......
...@@ -69,6 +69,8 @@ static struct sa1100_pcmcia_socket sa1100_pcmcia_socket[SA1100_PCMCIA_MAX_SOCK]; ...@@ -69,6 +69,8 @@ static struct sa1100_pcmcia_socket sa1100_pcmcia_socket[SA1100_PCMCIA_MAX_SOCK];
#define PCMCIA_SOCKET(x) (sa1100_pcmcia_socket + (x)) #define PCMCIA_SOCKET(x) (sa1100_pcmcia_socket + (x))
#define to_sa1100_socket(x) container_of(x, struct sa1100_pcmcia_socket, socket)
/* /*
* sa1100_pcmcia_default_mecr_timing * sa1100_pcmcia_default_mecr_timing
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...@@ -226,9 +228,9 @@ sa1100_pcmcia_config_skt(struct sa1100_pcmcia_socket *skt, socket_state_t *state ...@@ -226,9 +228,9 @@ sa1100_pcmcia_config_skt(struct sa1100_pcmcia_socket *skt, socket_state_t *state
* *
* Returns: 0 * Returns: 0
*/ */
static int sa1100_pcmcia_sock_init(unsigned int sock) static int sa1100_pcmcia_sock_init(struct pcmcia_socket *sock)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, skt->nr); DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, skt->nr);
...@@ -248,9 +250,9 @@ static int sa1100_pcmcia_sock_init(unsigned int sock) ...@@ -248,9 +250,9 @@ static int sa1100_pcmcia_sock_init(unsigned int sock)
* *
* Returns: 0 * Returns: 0
*/ */
static int sa1100_pcmcia_suspend(unsigned int sock) static int sa1100_pcmcia_suspend(struct pcmcia_socket *sock)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
int ret; int ret;
DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, skt->nr); DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, skt->nr);
...@@ -348,11 +350,11 @@ static irqreturn_t sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *r ...@@ -348,11 +350,11 @@ static irqreturn_t sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *r
* Returns: 0 * Returns: 0
*/ */
static int static int
sa1100_pcmcia_register_callback(unsigned int sock, sa1100_pcmcia_register_callback(struct pcmcia_socket *sock,
void (*handler)(void *, unsigned int), void (*handler)(void *, unsigned int),
void *info) void *info)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
if (handler) { if (handler) {
if (!try_module_get(skt->ops->owner)) if (!try_module_get(skt->ops->owner))
...@@ -392,9 +394,9 @@ sa1100_pcmcia_register_callback(unsigned int sock, ...@@ -392,9 +394,9 @@ sa1100_pcmcia_register_callback(unsigned int sock,
* Return value is irrelevant; the pcmcia subsystem ignores it. * Return value is irrelevant; the pcmcia subsystem ignores it.
*/ */
static int static int
sa1100_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap) sa1100_pcmcia_inquire_socket(struct pcmcia_socket *sock, socket_cap_t *cap)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
int ret = -1; int ret = -1;
if (skt) { if (skt) {
...@@ -430,9 +432,9 @@ sa1100_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap) ...@@ -430,9 +432,9 @@ sa1100_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
* Returns: 0 * Returns: 0
*/ */
static int static int
sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status) sa1100_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
skt->status = sa1100_pcmcia_skt_state(skt); skt->status = sa1100_pcmcia_skt_state(skt);
*status = skt->status; *status = skt->status;
...@@ -450,9 +452,9 @@ sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status) ...@@ -450,9 +452,9 @@ sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status)
* Returns: 0 * Returns: 0
*/ */
static int static int
sa1100_pcmcia_get_socket(unsigned int sock, socket_state_t *state) sa1100_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr); DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
...@@ -472,9 +474,9 @@ sa1100_pcmcia_get_socket(unsigned int sock, socket_state_t *state) ...@@ -472,9 +474,9 @@ sa1100_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
* Returns: 0 * Returns: 0
*/ */
static int static int
sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state) sa1100_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr); DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
...@@ -508,9 +510,9 @@ sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state) ...@@ -508,9 +510,9 @@ sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
* Returns: 0 on success, -1 on error * Returns: 0 on success, -1 on error
*/ */
static int static int
sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map) sa1100_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
unsigned short speed = map->speed; unsigned short speed = map->speed;
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr); DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
...@@ -564,9 +566,9 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map) ...@@ -564,9 +566,9 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
* Returns: 0 on success, -1 on error * Returns: 0 on success, -1 on error
*/ */
static int static int
sa1100_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map) sa1100_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = to_sa1100_socket(sock);
struct resource *res; struct resource *res;
unsigned short speed = map->speed; unsigned short speed = map->speed;
...@@ -708,7 +710,7 @@ sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos, ...@@ -708,7 +710,7 @@ sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
* Returns: 0 on success, -1 on error * Returns: 0 on success, -1 on error
*/ */
static void static void
sa1100_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base) sa1100_pcmcia_proc_setup(struct pcmcia_socket *sock, struct proc_dir_entry *base)
{ {
struct proc_dir_entry *entry; struct proc_dir_entry *entry;
...@@ -717,7 +719,7 @@ sa1100_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base) ...@@ -717,7 +719,7 @@ sa1100_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
return; return;
} }
entry->read_proc = sa1100_pcmcia_proc_status; entry->read_proc = sa1100_pcmcia_proc_status;
entry->data = PCMCIA_SOCKET(sock); entry->data = to_sa1100_socket(sock);
} }
#else #else
#define sa1100_pcmcia_proc_setup NULL #define sa1100_pcmcia_proc_setup NULL
...@@ -800,22 +802,16 @@ static const char *skt_names[] = { ...@@ -800,22 +802,16 @@ static const char *skt_names[] = {
"PCMCIA socket 1", "PCMCIA socket 1",
}; };
struct skt_dev_info {
int nskt;
};
int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
{ {
struct pcmcia_socket_class_data *cls; struct skt_dev_info *sinfo;
unsigned int cpu_clock; unsigned int cpu_clock;
int ret, i; int ret, i;
cls = kmalloc(sizeof(struct pcmcia_socket_class_data), GFP_KERNEL);
if (!cls) {
ret = -ENOMEM;
goto out;
}
memset(cls, 0, sizeof(struct pcmcia_socket_class_data));
cls->ops = &sa11xx_pcmcia_operations;
cls->nsock = nr;
/* /*
* set default MECR calculation if the board specific * set default MECR calculation if the board specific
* code did not specify one... * code did not specify one...
...@@ -823,6 +819,15 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in ...@@ -823,6 +819,15 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
if (!ops->socket_get_timing) if (!ops->socket_get_timing)
ops->socket_get_timing = sa1100_pcmcia_default_mecr_timing; ops->socket_get_timing = sa1100_pcmcia_default_mecr_timing;
sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
if (!sinfo) {
ret = -ENOMEM;
goto out;
}
memset(sinfo, 0, sizeof(struct skt_dev_info));
sinfo->nskt = nr;
cpu_clock = cpufreq_get(0); cpu_clock = cpufreq_get(0);
/* /*
...@@ -832,6 +837,9 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in ...@@ -832,6 +837,9 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i); struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
memset(skt, 0, sizeof(*skt)); memset(skt, 0, sizeof(*skt));
skt->socket.ss_entry = &sa11xx_pcmcia_operations;
skt->socket.dev.dev = dev;
INIT_WORK(&skt->work, sa1100_pcmcia_task_handler, skt); INIT_WORK(&skt->work, sa1100_pcmcia_task_handler, skt);
init_timer(&skt->poll_timer); init_timer(&skt->poll_timer);
...@@ -898,16 +906,26 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in ...@@ -898,16 +906,26 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
goto out_err_6; goto out_err_6;
skt->status = sa1100_pcmcia_skt_state(skt); skt->status = sa1100_pcmcia_skt_state(skt);
ret = pcmcia_register_socket(&skt->socket);
if (ret)
goto out_err_7;
WARN_ON(skt->socket.sock != i);
add_timer(&skt->poll_timer); add_timer(&skt->poll_timer);
} }
dev->class_data = cls; dev_set_drvdata(dev, sinfo);
return 0; return 0;
do { do {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i); struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
del_timer_sync(&skt->poll_timer); del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
out_err_7:
flush_scheduled_work(); flush_scheduled_work();
ops->hw_shutdown(skt); ops->hw_shutdown(skt);
...@@ -925,7 +943,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in ...@@ -925,7 +943,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
i--; i--;
} while (i > 0); } while (i > 0);
kfree(cls); kfree(sinfo);
out: out:
return ret; return ret;
...@@ -934,19 +952,22 @@ EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe); ...@@ -934,19 +952,22 @@ EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
int sa11xx_drv_pcmcia_remove(struct device *dev) int sa11xx_drv_pcmcia_remove(struct device *dev)
{ {
struct pcmcia_socket_class_data *cls = dev->class_data; struct skt_dev_info *sinfo = dev_get_drvdata(dev);
int i; int i;
dev->class_data = NULL; dev_set_drvdata(dev, NULL);
for (i = 0; i < cls->nsock; i++) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(cls->sock_offset + i);
skt->ops->hw_shutdown(skt); for (i = 0; i < sinfo->nskt; i++) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
del_timer_sync(&skt->poll_timer); del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
flush_scheduled_work(); flush_scheduled_work();
skt->ops->hw_shutdown(skt);
sa1100_pcmcia_config_skt(skt, &dead_socket); sa1100_pcmcia_config_skt(skt, &dead_socket);
iounmap(skt->virt_io); iounmap(skt->virt_io);
...@@ -957,7 +978,7 @@ int sa11xx_drv_pcmcia_remove(struct device *dev) ...@@ -957,7 +978,7 @@ int sa11xx_drv_pcmcia_remove(struct device *dev)
release_resource(&skt->res_skt); release_resource(&skt->res_skt);
} }
kfree(cls); kfree(sinfo);
return 0; return 0;
} }
...@@ -977,7 +998,8 @@ static void sa1100_pcmcia_update_mecr(unsigned int clock) ...@@ -977,7 +998,8 @@ static void sa1100_pcmcia_update_mecr(unsigned int clock)
for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock) { for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
sa1100_pcmcia_set_mecr(skt, clock); if (skt->ops)
sa1100_pcmcia_set_mecr(skt, clock);
} }
} }
......
...@@ -44,6 +44,8 @@ struct pcmcia_state { ...@@ -44,6 +44,8 @@ struct pcmcia_state {
* use when responding to a Card Services query of some kind. * use when responding to a Card Services query of some kind.
*/ */
struct sa1100_pcmcia_socket { struct sa1100_pcmcia_socket {
struct pcmcia_socket socket;
/* /*
* Info from low level handler * Info from low level handler
*/ */
......
...@@ -115,19 +115,20 @@ static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs); ...@@ -115,19 +115,20 @@ static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs);
static void tcic_timer(u_long data); static void tcic_timer(u_long data);
static struct pccard_operations tcic_operations; static struct pccard_operations tcic_operations;
typedef struct socket_info_t { struct tcic_socket {
u_short psock; u_short psock;
void (*handler)(void *info, u_int events); void (*handler)(void *info, u_int events);
void *info; void *info;
u_char last_sstat; u_char last_sstat;
u_char id; u_char id;
} socket_info_t; struct pcmcia_socket socket;
};
static struct timer_list poll_timer; static struct timer_list poll_timer;
static int tcic_timer_pending; static int tcic_timer_pending;
static int sockets; static int sockets;
static socket_info_t socket_table[2]; static struct tcic_socket socket_table[2];
static socket_cap_t tcic_cap = { static socket_cap_t tcic_cap = {
/* only 16-bit cards, memory windows must be size-aligned */ /* only 16-bit cards, memory windows must be size-aligned */
...@@ -372,15 +373,11 @@ static int __init get_tcic_id(void) ...@@ -372,15 +373,11 @@ static int __init get_tcic_id(void)
/*====================================================================*/ /*====================================================================*/
static struct pcmcia_socket_class_data tcic_data = {
.ops = &tcic_operations,
};
static struct device_driver tcic_driver = { static struct device_driver tcic_driver = {
.name = "tcic-pcmcia", .name = "tcic-pcmcia",
.bus = &platform_bus_type, .bus = &platform_bus_type,
/* .suspend = pcmcia_socket_dev_suspend, FIXME? */ .suspend = pcmcia_socket_dev_suspend,
/* .resume = pcmcia_socket_dev_resume, FIXME? */ .resume = pcmcia_socket_dev_resume,
}; };
static struct platform_device tcic_device = { static struct platform_device tcic_device = {
...@@ -391,13 +388,10 @@ static struct platform_device tcic_device = { ...@@ -391,13 +388,10 @@ static struct platform_device tcic_device = {
}, },
}; };
static struct class_device tcic_class_data = {
.class = &pcmcia_socket_class,
};
static int __init init_tcic(void) static int __init init_tcic(void)
{ {
int i, sock; int i, sock, ret = 0;
u_int mask, scan; u_int mask, scan;
servinfo_t serv; servinfo_t serv;
...@@ -524,13 +518,17 @@ static int __init init_tcic(void) ...@@ -524,13 +518,17 @@ static int __init init_tcic(void)
/* jump start interrupt handler, if needed */ /* jump start interrupt handler, if needed */
tcic_interrupt(0, NULL, NULL); tcic_interrupt(0, NULL, NULL);
tcic_data.nsock = sockets;
tcic_class_data.dev = &tcic_device.dev;
tcic_class_data.class_data = &tcic_data;
strlcpy(tcic_class_data.class_id, "tcic-pcmcia", BUS_ID_SIZE);
platform_device_register(&tcic_device); platform_device_register(&tcic_device);
class_device_register(&tcic_class_data);
for (i = 0; i < sockets; i++) {
socket_table[i].socket.ss_entry = &tcic_operations;
socket_table[i].socket.dev.dev = &tcic_device.dev;
ret = pcmcia_register_socket(&socket_table[i].socket);
if (ret && i)
pcmcia_unregister_socket(&socket_table[0].socket);
}
return ret;
return 0; return 0;
...@@ -540,13 +538,19 @@ static int __init init_tcic(void) ...@@ -540,13 +538,19 @@ static int __init init_tcic(void)
static void __exit exit_tcic(void) static void __exit exit_tcic(void)
{ {
int i;
del_timer_sync(&poll_timer); del_timer_sync(&poll_timer);
if (cs_irq != 0) { if (cs_irq != 0) {
tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00); tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
free_irq(cs_irq, tcic_interrupt); free_irq(cs_irq, tcic_interrupt);
} }
release_region(tcic_base, 16); release_region(tcic_base, 16);
class_device_unregister(&tcic_class_data);
for (i = 0; i < sockets; i++) {
pcmcia_unregister_socket(&socket_table[i].socket);
}
platform_device_unregister(&tcic_device); platform_device_unregister(&tcic_device);
driver_unregister(&tcic_driver); driver_unregister(&tcic_driver);
} /* exit_tcic */ } /* exit_tcic */
...@@ -640,18 +644,19 @@ static void tcic_timer(u_long data) ...@@ -640,18 +644,19 @@ static void tcic_timer(u_long data)
/*====================================================================*/ /*====================================================================*/
static int tcic_register_callback(unsigned int lsock, void (*handler)(void *, unsigned int), void * info) static int tcic_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
{ {
socket_table[lsock].handler = handler; u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
socket_table[lsock].info = info; socket_table[psock].handler = handler;
socket_table[psock].info = info;
return 0; return 0;
} /* tcic_register_callback */ } /* tcic_register_callback */
/*====================================================================*/ /*====================================================================*/
static int tcic_get_status(unsigned int lsock, u_int *value) static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
{ {
u_short psock = socket_table[lsock].psock; u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_char reg; u_char reg;
tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT) tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
...@@ -675,7 +680,7 @@ static int tcic_get_status(unsigned int lsock, u_int *value) ...@@ -675,7 +680,7 @@ static int tcic_get_status(unsigned int lsock, u_int *value)
/*====================================================================*/ /*====================================================================*/
static int tcic_inquire_socket(unsigned int lsock, socket_cap_t *cap) static int tcic_inquire_socket(struct pcmcia_socket *sock, socket_cap_t *cap)
{ {
*cap = tcic_cap; *cap = tcic_cap;
return 0; return 0;
...@@ -683,9 +688,9 @@ static int tcic_inquire_socket(unsigned int lsock, socket_cap_t *cap) ...@@ -683,9 +688,9 @@ static int tcic_inquire_socket(unsigned int lsock, socket_cap_t *cap)
/*====================================================================*/ /*====================================================================*/
static int tcic_get_socket(unsigned int lsock, socket_state_t *state) static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
{ {
u_short psock = socket_table[lsock].psock; u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_char reg; u_char reg;
u_short scf1, scf2; u_short scf1, scf2;
...@@ -736,9 +741,9 @@ static int tcic_get_socket(unsigned int lsock, socket_state_t *state) ...@@ -736,9 +741,9 @@ static int tcic_get_socket(unsigned int lsock, socket_state_t *state)
/*====================================================================*/ /*====================================================================*/
static int tcic_set_socket(unsigned int lsock, socket_state_t *state) static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
{ {
u_short psock = socket_table[lsock].psock; u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_char reg; u_char reg;
u_short scf1, scf2; u_short scf1, scf2;
...@@ -811,9 +816,9 @@ static int tcic_set_socket(unsigned int lsock, socket_state_t *state) ...@@ -811,9 +816,9 @@ static int tcic_set_socket(unsigned int lsock, socket_state_t *state)
/*====================================================================*/ /*====================================================================*/
static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io) static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
{ {
u_short psock = socket_table[lsock].psock; u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_int addr; u_int addr;
u_short base, len, ioctl; u_short base, len, ioctl;
...@@ -848,9 +853,9 @@ static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io) ...@@ -848,9 +853,9 @@ static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io)
/*====================================================================*/ /*====================================================================*/
static int tcic_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem) static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
{ {
u_short psock = socket_table[lsock].psock; u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
u_short addr, ctl; u_short addr, ctl;
u_long base, len, mmap; u_long base, len, mmap;
...@@ -892,11 +897,11 @@ static int tcic_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem) ...@@ -892,11 +897,11 @@ static int tcic_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
/*====================================================================*/ /*====================================================================*/
static void tcic_proc_setup(unsigned int sock, struct proc_dir_entry *base) static void tcic_proc_setup(struct pcmcia_socket *sock, struct proc_dir_entry *base)
{ {
} }
static int tcic_init(unsigned int s) static int tcic_init(struct pcmcia_socket *s)
{ {
int i; int i;
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
...@@ -915,7 +920,7 @@ static int tcic_init(unsigned int s) ...@@ -915,7 +920,7 @@ static int tcic_init(unsigned int s)
return 0; return 0;
} }
static int tcic_suspend(unsigned int sock) static int tcic_suspend(struct pcmcia_socket *sock)
{ {
return tcic_set_socket(sock, &dead_socket); return tcic_set_socket(sock, &dead_socket);
} }
......
...@@ -136,6 +136,26 @@ ...@@ -136,6 +136,26 @@
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
static int ti_intctl(struct yenta_socket *socket)
{
u8 new, reg = exca_readb(socket, I365_INTCTL);
new = reg & ~I365_INTR_ENA;
if (socket->cb_irq)
new |= I365_INTR_ENA;
if (new != reg)
exca_writeb(socket, I365_INTCTL, new);
return 0;
}
static int ti_init(struct pcmcia_socket *sock)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
ti_intctl(socket);
return 0;
}
/* /*
* Generic TI init - TI has an extension for the * Generic TI init - TI has an extension for the
* INTCTL register that sets the PCI CSC interrupt. * INTCTL register that sets the PCI CSC interrupt.
...@@ -148,70 +168,28 @@ ...@@ -148,70 +168,28 @@
* This makes us correctly get PCI CSC interrupt * This makes us correctly get PCI CSC interrupt
* events. * events.
*/ */
static int ti_open(pci_socket_t *socket) static int ti_override(struct yenta_socket *socket)
{ {
u8 new, reg = exca_readb(socket, I365_INTCTL); u8 new, reg = exca_readb(socket, I365_INTCTL);
new = reg & ~I365_INTR_ENA; new = reg & ~I365_INTR_ENA;
if (new != reg) if (new != reg)
exca_writeb(socket, I365_INTCTL, new); exca_writeb(socket, I365_INTCTL, new);
socket->socket.ss_entry->init = ti_init;
return 0; return 0;
} }
static int ti_intctl(pci_socket_t *socket)
{
u8 new, reg = exca_readb(socket, I365_INTCTL);
new = reg & ~I365_INTR_ENA;
if (socket->cb_irq)
new |= I365_INTR_ENA;
if (new != reg)
exca_writeb(socket, I365_INTCTL, new);
return 0;
}
static int ti_init(pci_socket_t *socket)
{
yenta_init(socket);
ti_intctl(socket);
return 0;
}
static struct pci_socket_ops ti_ops = {
ti_open,
yenta_close,
ti_init,
yenta_suspend,
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
yenta_set_io_map,
yenta_set_mem_map,
yenta_proc_setup
};
#define ti_sysctl(socket) ((socket)->private[0]) #define ti_sysctl(socket) ((socket)->private[0])
#define ti_cardctl(socket) ((socket)->private[1]) #define ti_cardctl(socket) ((socket)->private[1])
#define ti_devctl(socket) ((socket)->private[2]) #define ti_devctl(socket) ((socket)->private[2])
#define ti_diag(socket) ((socket)->private[3]) #define ti_diag(socket) ((socket)->private[3])
#define ti_irqmux(socket) ((socket)->private[4]) #define ti_irqmux(socket) ((socket)->private[4])
static int ti113x_open(pci_socket_t *socket)
{
ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL);
ti_cardctl(socket) = config_readb(socket, TI113X_CARD_CONTROL);
ti_devctl(socket) = config_readb(socket, TI113X_DEVICE_CONTROL);
ti_cardctl(socket) &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); static int ti113x_init(struct pcmcia_socket *sock)
if (socket->cb_irq)
ti_cardctl(socket) |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
ti_open(socket);
return 0;
}
static int ti113x_init(pci_socket_t *socket)
{ {
yenta_init(socket); struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_init(sock);
config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket));
config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket)); config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket));
...@@ -220,35 +198,26 @@ static int ti113x_init(pci_socket_t *socket) ...@@ -220,35 +198,26 @@ static int ti113x_init(pci_socket_t *socket)
return 0; return 0;
} }
static struct pci_socket_ops ti113x_ops = { static int ti113x_override(struct yenta_socket *socket)
ti113x_open,
yenta_close,
ti113x_init,
yenta_suspend,
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
yenta_set_io_map,
yenta_set_mem_map,
yenta_proc_setup
};
static int ti1250_open(pci_socket_t *socket)
{ {
ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC); ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL);
ti_cardctl(socket) = config_readb(socket, TI113X_CARD_CONTROL);
ti_devctl(socket) = config_readb(socket, TI113X_DEVICE_CONTROL);
ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ); ti_cardctl(socket) &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
if (socket->cb_irq) if (socket->cb_irq)
ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ; ti_cardctl(socket) |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
ti113x_open(socket); ti_override(socket);
socket->socket.ss_entry->init = ti113x_init;
return 0; return 0;
} }
static int ti1250_init(pci_socket_t *socket)
static int ti1250_init(struct pcmcia_socket *sock)
{ {
yenta_init(socket); struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
ti113x_init(socket); yenta_init(sock);
ti113x_init(sock);
ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX); ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX);
ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */ ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */
if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE)) if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE))
...@@ -260,18 +229,17 @@ static int ti1250_init(pci_socket_t *socket) ...@@ -260,18 +229,17 @@ static int ti1250_init(pci_socket_t *socket)
return 0; return 0;
} }
static struct pci_socket_ops ti1250_ops = { static int ti1250_override(struct yenta_socket *socket)
ti1250_open, {
yenta_close, ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC);
ti1250_init,
yenta_suspend, ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ);
yenta_get_status, if (socket->cb_irq)
yenta_get_socket, ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
yenta_set_socket, ti113x_override(socket);
yenta_set_io_map, socket->socket.ss_entry->init = ti1250_init;
yenta_set_mem_map, return 0;
yenta_proc_setup }
};
#endif /* CONFIG_CARDBUS */ #endif /* CONFIG_CARDBUS */
......
/* /*
* Regular lowlevel cardbus driver ("yenta") * Regular cardbus driver ("yenta")
* *
* (C) Copyright 1999, 2000 Linus Torvalds * (C) Copyright 1999, 2000 Linus Torvalds
* *
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
* Aug 2002: Manfred Spraul <manfred@colorfullife.com> * Aug 2002: Manfred Spraul <manfred@colorfullife.com>
* Dynamically adjust the size of the bridge resource * Dynamically adjust the size of the bridge resource
* *
* May 2003: Dominik Brodowski <linux@brodo.de>
* Merge pci_socket.c and yenta.c into one file
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
...@@ -26,6 +28,7 @@ ...@@ -26,6 +28,7 @@
#include "yenta.h" #include "yenta.h"
#include "i82365.h" #include "i82365.h"
#if 0 #if 0
#define DEBUG(x,args...) printk("%s: " x, __FUNCTION__, ##args) #define DEBUG(x,args...) printk("%s: " x, __FUNCTION__, ##args)
#else #else
...@@ -41,20 +44,20 @@ ...@@ -41,20 +44,20 @@
* regular memory space ("cb_xxx"), configuration space * regular memory space ("cb_xxx"), configuration space
* ("config_xxx") and compatibility space ("exca_xxxx") * ("config_xxx") and compatibility space ("exca_xxxx")
*/ */
static inline u32 cb_readl(pci_socket_t *socket, unsigned reg) static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
{ {
u32 val = readl(socket->base + reg); u32 val = readl(socket->base + reg);
DEBUG("%p %04x %08x\n", socket, reg, val); DEBUG("%p %04x %08x\n", socket, reg, val);
return val; return val;
} }
static inline void cb_writel(pci_socket_t *socket, unsigned reg, u32 val) static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
{ {
DEBUG("%p %04x %08x\n", socket, reg, val); DEBUG("%p %04x %08x\n", socket, reg, val);
writel(val, socket->base + reg); writel(val, socket->base + reg);
} }
static inline u8 config_readb(pci_socket_t *socket, unsigned offset) static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
{ {
u8 val; u8 val;
pci_read_config_byte(socket->dev, offset, &val); pci_read_config_byte(socket->dev, offset, &val);
...@@ -62,7 +65,7 @@ static inline u8 config_readb(pci_socket_t *socket, unsigned offset) ...@@ -62,7 +65,7 @@ static inline u8 config_readb(pci_socket_t *socket, unsigned offset)
return val; return val;
} }
static inline u16 config_readw(pci_socket_t *socket, unsigned offset) static inline u16 config_readw(struct yenta_socket *socket, unsigned offset)
{ {
u16 val; u16 val;
pci_read_config_word(socket->dev, offset, &val); pci_read_config_word(socket->dev, offset, &val);
...@@ -70,7 +73,7 @@ static inline u16 config_readw(pci_socket_t *socket, unsigned offset) ...@@ -70,7 +73,7 @@ static inline u16 config_readw(pci_socket_t *socket, unsigned offset)
return val; return val;
} }
static inline u32 config_readl(pci_socket_t *socket, unsigned offset) static inline u32 config_readl(struct yenta_socket *socket, unsigned offset)
{ {
u32 val; u32 val;
pci_read_config_dword(socket->dev, offset, &val); pci_read_config_dword(socket->dev, offset, &val);
...@@ -78,32 +81,32 @@ static inline u32 config_readl(pci_socket_t *socket, unsigned offset) ...@@ -78,32 +81,32 @@ static inline u32 config_readl(pci_socket_t *socket, unsigned offset)
return val; return val;
} }
static inline void config_writeb(pci_socket_t *socket, unsigned offset, u8 val) static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
{ {
DEBUG("%p %04x %02x\n", socket, offset, val); DEBUG("%p %04x %02x\n", socket, offset, val);
pci_write_config_byte(socket->dev, offset, val); pci_write_config_byte(socket->dev, offset, val);
} }
static inline void config_writew(pci_socket_t *socket, unsigned offset, u16 val) static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
{ {
DEBUG("%p %04x %04x\n", socket, offset, val); DEBUG("%p %04x %04x\n", socket, offset, val);
pci_write_config_word(socket->dev, offset, val); pci_write_config_word(socket->dev, offset, val);
} }
static inline void config_writel(pci_socket_t *socket, unsigned offset, u32 val) static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
{ {
DEBUG("%p %04x %08x\n", socket, offset, val); DEBUG("%p %04x %08x\n", socket, offset, val);
pci_write_config_dword(socket->dev, offset, val); pci_write_config_dword(socket->dev, offset, val);
} }
static inline u8 exca_readb(pci_socket_t *socket, unsigned reg) static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
{ {
u8 val = readb(socket->base + 0x800 + reg); u8 val = readb(socket->base + 0x800 + reg);
DEBUG("%p %04x %02x\n", socket, reg, val); DEBUG("%p %04x %02x\n", socket, reg, val);
return val; return val;
} }
static inline u8 exca_readw(pci_socket_t *socket, unsigned reg) static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg)
{ {
u16 val; u16 val;
val = readb(socket->base + 0x800 + reg); val = readb(socket->base + 0x800 + reg);
...@@ -112,13 +115,13 @@ static inline u8 exca_readw(pci_socket_t *socket, unsigned reg) ...@@ -112,13 +115,13 @@ static inline u8 exca_readw(pci_socket_t *socket, unsigned reg)
return val; return val;
} }
static inline void exca_writeb(pci_socket_t *socket, unsigned reg, u8 val) static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
{ {
DEBUG("%p %04x %02x\n", socket, reg, val); DEBUG("%p %04x %02x\n", socket, reg, val);
writeb(val, socket->base + 0x800 + reg); writeb(val, socket->base + 0x800 + reg);
} }
static void exca_writew(pci_socket_t *socket, unsigned reg, u16 val) static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
{ {
DEBUG("%p %04x %04x\n", socket, reg, val); DEBUG("%p %04x %04x\n", socket, reg, val);
writeb(val, socket->base + 0x800 + reg); writeb(val, socket->base + 0x800 + reg);
...@@ -129,8 +132,9 @@ static void exca_writew(pci_socket_t *socket, unsigned reg, u16 val) ...@@ -129,8 +132,9 @@ static void exca_writew(pci_socket_t *socket, unsigned reg, u16 val)
* Ugh, mixed-mode cardbus and 16-bit pccard state: things depend * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
* on what kind of card is inserted.. * on what kind of card is inserted..
*/ */
static int yenta_get_status(pci_socket_t *socket, unsigned int *value) static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
unsigned int val; unsigned int val;
u32 state = cb_readl(socket, CB_SOCKET_STATE); u32 state = cb_readl(socket, CB_SOCKET_STATE);
...@@ -181,8 +185,9 @@ static int yenta_Vpp_power(u32 control) ...@@ -181,8 +185,9 @@ static int yenta_Vpp_power(u32 control)
} }
} }
static int yenta_get_socket(pci_socket_t *socket, socket_state_t *state) static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
u8 reg; u8 reg;
u32 control; u32 control;
...@@ -221,7 +226,7 @@ static int yenta_get_socket(pci_socket_t *socket, socket_state_t *state) ...@@ -221,7 +226,7 @@ static int yenta_get_socket(pci_socket_t *socket, socket_state_t *state)
return 0; return 0;
} }
static void yenta_set_power(pci_socket_t *socket, socket_state_t *state) static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)
{ {
u32 reg = 0; /* CB_SC_STPCLK? */ u32 reg = 0; /* CB_SC_STPCLK? */
switch (state->Vcc) { switch (state->Vcc) {
...@@ -238,8 +243,9 @@ static void yenta_set_power(pci_socket_t *socket, socket_state_t *state) ...@@ -238,8 +243,9 @@ static void yenta_set_power(pci_socket_t *socket, socket_state_t *state)
cb_writel(socket, CB_SOCKET_CONTROL, reg); cb_writel(socket, CB_SOCKET_CONTROL, reg);
} }
static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state) static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
u16 bridge; u16 bridge;
if (state->flags & SS_DEBOUNCED) { if (state->flags & SS_DEBOUNCED) {
...@@ -300,8 +306,9 @@ static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state) ...@@ -300,8 +306,9 @@ static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state)
return 0; return 0;
} }
static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io) static int yenta_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
int map; int map;
unsigned char ioctl, addr, enable; unsigned char ioctl, addr, enable;
...@@ -333,8 +340,9 @@ static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io) ...@@ -333,8 +340,9 @@ static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io)
return 0; return 0;
} }
static int yenta_set_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem) static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
int map; int map;
unsigned char addr, enable; unsigned char addr, enable;
unsigned int start, stop, card_start; unsigned int start, stop, card_start;
...@@ -386,12 +394,12 @@ static int yenta_set_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem) ...@@ -386,12 +394,12 @@ static int yenta_set_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem)
return 0; return 0;
} }
static void yenta_proc_setup(pci_socket_t *socket, struct proc_dir_entry *base) static void yenta_proc_setup(struct pcmcia_socket *sock, struct proc_dir_entry *base)
{ {
/* Not done yet */ /* Not done yet */
} }
static unsigned int yenta_events(pci_socket_t *socket) static unsigned int yenta_events(struct yenta_socket *socket)
{ {
u8 csc; u8 csc;
u32 cb_event; u32 cb_event;
...@@ -418,7 +426,7 @@ static unsigned int yenta_events(pci_socket_t *socket) ...@@ -418,7 +426,7 @@ static unsigned int yenta_events(pci_socket_t *socket)
static void yenta_bh(void *data) static void yenta_bh(void *data)
{ {
pci_socket_t *socket = data; struct yenta_socket *socket = data;
unsigned int events; unsigned int events;
spin_lock_irq(&socket->event_lock); spin_lock_irq(&socket->event_lock);
...@@ -432,7 +440,7 @@ static void yenta_bh(void *data) ...@@ -432,7 +440,7 @@ static void yenta_bh(void *data)
static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
unsigned int events; unsigned int events;
pci_socket_t *socket = (pci_socket_t *) dev_id; struct yenta_socket *socket = (struct yenta_socket *) dev_id;
events = yenta_events(socket); events = yenta_events(socket);
if (events) { if (events) {
...@@ -447,7 +455,7 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -447,7 +455,7 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static void yenta_interrupt_wrapper(unsigned long data) static void yenta_interrupt_wrapper(unsigned long data)
{ {
pci_socket_t *socket = (pci_socket_t *) data; struct yenta_socket *socket = (struct yenta_socket *) data;
yenta_interrupt(0, (void *)socket, NULL); yenta_interrupt(0, (void *)socket, NULL);
socket->poll_timer.expires = jiffies + HZ; socket->poll_timer.expires = jiffies + HZ;
...@@ -465,7 +473,7 @@ static void yenta_interrupt_wrapper(unsigned long data) ...@@ -465,7 +473,7 @@ static void yenta_interrupt_wrapper(unsigned long data)
*/ */
static u32 isa_interrupts = 0x0ef8; static u32 isa_interrupts = 0x0ef8;
static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask) static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
{ {
int i; int i;
unsigned long val; unsigned long val;
...@@ -509,7 +517,7 @@ static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask) ...@@ -509,7 +517,7 @@ static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask)
/* /*
* Set static data that doesn't need re-initializing.. * Set static data that doesn't need re-initializing..
*/ */
static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask) static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
{ {
socket->cap.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS; socket->cap.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
socket->cap.map_size = 0x1000; socket->cap.map_size = 0x1000;
...@@ -520,28 +528,38 @@ static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask ...@@ -520,28 +528,38 @@ static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask
printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq); printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq);
} }
static void yenta_clear_maps(pci_socket_t *socket) static int yenta_inquire_socket(struct pcmcia_socket *sock, socket_cap_t *cap)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
*cap = socket->cap;
return 0;
}
static void yenta_clear_maps(struct yenta_socket *socket)
{ {
int i; int i;
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
mem.sys_stop = 0x0fff; mem.sys_stop = 0x0fff;
yenta_set_socket(socket, &dead_socket); yenta_set_socket(&socket->socket, &dead_socket);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
io.map = i; io.map = i;
yenta_set_io_map(socket, &io); yenta_set_io_map(&socket->socket, &io);
} }
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
mem.map = i; mem.map = i;
yenta_set_mem_map(socket, &mem); yenta_set_mem_map(&socket->socket, &mem);
} }
} }
/* /*
* Initialize the standard cardbus registers * Initialize the standard cardbus registers
*/ */
static void yenta_config_init(pci_socket_t *socket) static void yenta_config_init(struct yenta_socket *socket)
{ {
u16 bridge; u16 bridge;
struct pci_dev *dev = socket->dev; struct pci_dev *dev = socket->dev;
...@@ -586,8 +604,9 @@ static void yenta_config_init(pci_socket_t *socket) ...@@ -586,8 +604,9 @@ static void yenta_config_init(pci_socket_t *socket)
} }
/* Called at resume and initialization events */ /* Called at resume and initialization events */
static int yenta_init(pci_socket_t *socket) static int yenta_init(struct pcmcia_socket *sock)
{ {
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_config_init(socket); yenta_config_init(socket);
yenta_clear_maps(socket); yenta_clear_maps(socket);
...@@ -596,9 +615,11 @@ static int yenta_init(pci_socket_t *socket) ...@@ -596,9 +615,11 @@ static int yenta_init(pci_socket_t *socket)
return 0; return 0;
} }
static int yenta_suspend(pci_socket_t *socket) static int yenta_suspend(struct pcmcia_socket *sock)
{ {
yenta_set_socket(socket, &dead_socket); struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
yenta_set_socket(sock, &dead_socket);
/* Disable interrupts */ /* Disable interrupts */
cb_writel(socket, CB_SOCKET_MASK, 0x0); cb_writel(socket, CB_SOCKET_MASK, 0x0);
...@@ -630,7 +651,7 @@ static int yenta_suspend(pci_socket_t *socket) ...@@ -630,7 +651,7 @@ static int yenta_suspend(pci_socket_t *socket)
#define BRIDGE_IO_MAX 256 #define BRIDGE_IO_MAX 256
#define BRIDGE_IO_MIN 32 #define BRIDGE_IO_MIN 32
static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type) static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
{ {
struct pci_bus *bus; struct pci_bus *bus;
struct resource *root, *res; struct resource *root, *res;
...@@ -711,7 +732,7 @@ static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type) ...@@ -711,7 +732,7 @@ static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type)
/* /*
* Allocate the bridge mappings for the device.. * Allocate the bridge mappings for the device..
*/ */
static void yenta_allocate_resources(pci_socket_t *socket) static void yenta_allocate_resources(struct yenta_socket *socket)
{ {
yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH); yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
yenta_allocate_res(socket, 1, IORESOURCE_MEM); yenta_allocate_res(socket, 1, IORESOURCE_MEM);
...@@ -719,10 +740,11 @@ static void yenta_allocate_resources(pci_socket_t *socket) ...@@ -719,10 +740,11 @@ static void yenta_allocate_resources(pci_socket_t *socket)
yenta_allocate_res(socket, 3, IORESOURCE_IO); /* PCI isn't clever enough to use this one yet */ yenta_allocate_res(socket, 3, IORESOURCE_IO); /* PCI isn't clever enough to use this one yet */
} }
/* /*
* Free the bridge mappings for the device.. * Free the bridge mappings for the device..
*/ */
static void yenta_free_resources(pci_socket_t *socket) static void yenta_free_resources(struct yenta_socket *socket)
{ {
int i; int i;
for (i=0;i<4;i++) { for (i=0;i<4;i++) {
...@@ -733,11 +755,15 @@ static void yenta_free_resources(pci_socket_t *socket) ...@@ -733,11 +755,15 @@ static void yenta_free_resources(pci_socket_t *socket)
res->start = res->end = 0; res->start = res->end = 0;
} }
} }
/* /*
* Close it down - release our resources and go home.. * Close it down - release our resources and go home..
*/ */
static void yenta_close(pci_socket_t *sock) static void yenta_close(struct pci_dev *dev)
{ {
struct yenta_socket *sock = pci_get_drvdata(dev);
/* Disable all events so we don't die in an IRQ storm */ /* Disable all events so we don't die in an IRQ storm */
cb_writel(sock, CB_SOCKET_MASK, 0x0); cb_writel(sock, CB_SOCKET_MASK, 0x0);
exca_writeb(sock, I365_CSCINT, 0); exca_writeb(sock, I365_CSCINT, 0);
...@@ -750,8 +776,37 @@ static void yenta_close(pci_socket_t *sock) ...@@ -750,8 +776,37 @@ static void yenta_close(pci_socket_t *sock)
if (sock->base) if (sock->base)
iounmap(sock->base); iounmap(sock->base);
yenta_free_resources(sock); yenta_free_resources(sock);
pcmcia_unregister_socket(&sock->socket);
pci_set_drvdata(dev, NULL);
} }
static int yenta_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
socket->handler = handler;
socket->info = info;
return 0;
}
static struct pccard_operations yenta_socket_operations = {
.owner = THIS_MODULE,
.init = yenta_init,
.suspend = yenta_suspend,
.register_callback = yenta_register_callback,
.inquire_socket = yenta_inquire_socket,
.get_status = yenta_get_status,
.get_socket = yenta_get_socket,
.set_socket = yenta_set_socket,
.set_io_map = yenta_set_io_map,
.set_mem_map = yenta_set_mem_map,
.proc_setup = yenta_proc_setup,
};
#include "ti113x.h" #include "ti113x.h"
#include "ricoh.h" #include "ricoh.h"
...@@ -760,49 +815,62 @@ static void yenta_close(pci_socket_t *sock) ...@@ -760,49 +815,62 @@ static void yenta_close(pci_socket_t *sock)
* initialization sequences etc details. List them here.. * initialization sequences etc details. List them here..
*/ */
#define PD(x,y) PCI_VENDOR_ID_##x, PCI_DEVICE_ID_##x##_##y #define PD(x,y) PCI_VENDOR_ID_##x, PCI_DEVICE_ID_##x##_##y
static struct cardbus_override_struct { struct cardbus_override_struct {
unsigned short vendor; unsigned short vendor;
unsigned short device; unsigned short device;
struct pci_socket_ops *op; int (*override) (struct yenta_socket *socket);
} cardbus_override[] = { } cardbus_override[] = {
{ PD(TI,1130), &ti113x_ops }, { PD(TI,1130), &ti113x_override },
{ PD(TI,1031), &ti_ops }, { PD(TI,1031), &ti_override },
{ PD(TI,1131), &ti113x_ops }, { PD(TI,1131), &ti113x_override },
{ PD(TI,1250), &ti1250_ops }, { PD(TI,1250), &ti1250_override },
{ PD(TI,1220), &ti_ops }, { PD(TI,1220), &ti_override },
{ PD(TI,1221), &ti_ops }, { PD(TI,1221), &ti_override },
{ PD(TI,1210), &ti_ops }, { PD(TI,1210), &ti_override },
{ PD(TI,1450), &ti_ops }, { PD(TI,1450), &ti_override },
{ PD(TI,1225), &ti_ops }, { PD(TI,1225), &ti_override },
{ PD(TI,1251A), &ti_ops }, { PD(TI,1251A), &ti_override },
{ PD(TI,1211), &ti_ops }, { PD(TI,1211), &ti_override },
{ PD(TI,1251B), &ti_ops }, { PD(TI,1251B), &ti_override },
{ PD(TI,1410), &ti1250_ops }, { PD(TI,1410), ti1250_override },
{ PD(TI,1420), &ti_ops }, { PD(TI,1420), &ti_override },
{ PD(TI,4410), &ti_ops }, { PD(TI,4410), &ti_override },
{ PD(TI,4451), &ti_ops }, { PD(TI,4451), &ti_override },
{ PD(RICOH,RL5C465), &ricoh_ops }, { PD(RICOH,RL5C465), &ricoh_override },
{ PD(RICOH,RL5C466), &ricoh_ops }, { PD(RICOH,RL5C466), &ricoh_override },
{ PD(RICOH,RL5C475), &ricoh_ops }, { PD(RICOH,RL5C475), &ricoh_override },
{ PD(RICOH,RL5C476), &ricoh_ops }, { PD(RICOH,RL5C476), &ricoh_override },
{ PD(RICOH,RL5C478), &ricoh_ops } { PD(RICOH,RL5C478), &ricoh_override },
{ }, /* all zeroes */
}; };
#define NR_OVERRIDES (sizeof(cardbus_override)/sizeof(struct cardbus_override_struct))
extern int cardbus_register(struct pci_dev *p_dev);
/* /*
* Initialize a cardbus controller. Make sure we have a usable * Initialize a cardbus controller. Make sure we have a usable
* interrupt, and that we can map the cardbus area. Fill in the * interrupt, and that we can map the cardbus area. Fill in the
* socket information structure.. * socket information structure..
*/ */
static int yenta_open(pci_socket_t *socket) static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id)
{ {
int i; struct yenta_socket *socket;
struct pci_dev *dev = socket->dev; struct cardbus_override_struct *d;
socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
if (!socket)
return -ENOMEM;
memset(socket, 0, sizeof(*socket));
/* prepare pcmcia_socket */
socket->socket.ss_entry = &yenta_socket_operations;
socket->socket.dev.dev = &dev->dev;
socket->socket.driver_data = socket;
/* prepare struct yenta_socket */
socket->dev = dev;
pci_set_drvdata(dev, socket);
spin_lock_init(&socket->event_lock);
/* /*
* Do some basic sanity checking.. * Do some basic sanity checking..
...@@ -833,16 +901,14 @@ static int yenta_open(pci_socket_t *socket) ...@@ -833,16 +901,14 @@ static int yenta_open(pci_socket_t *socket)
socket->cb_irq = dev->irq; socket->cb_irq = dev->irq;
/* Do we have special options for the device? */ /* Do we have special options for the device? */
for (i = 0; i < NR_OVERRIDES; i++) { d = cardbus_override;
struct cardbus_override_struct *d = cardbus_override+i; while (d->override) {
if (dev->vendor == d->vendor && dev->device == d->device) { if ((dev->vendor == d->vendor) && (dev->device == d->device)) {
socket->op = d->op; int retval = d->override(socket);
if (d->op->open) { if (retval < 0)
int retval = d->op->open(socket); return retval;
if (retval < 0)
return retval;
}
} }
d++;
} }
/* We must finish initialization here */ /* We must finish initialization here */
...@@ -864,23 +930,58 @@ static int yenta_open(pci_socket_t *socket) ...@@ -864,23 +930,58 @@ static int yenta_open(pci_socket_t *socket)
printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
/* Register it with the pcmcia layer.. */ /* Register it with the pcmcia layer.. */
return cardbus_register(dev); return pcmcia_register_socket(&socket->socket);
} }
/*
* Standard plain cardbus - no frills, no extensions static int yenta_dev_suspend (struct pci_dev *dev, u32 state)
*/ {
struct pci_socket_ops yenta_operations = { return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
yenta_open, }
yenta_close,
yenta_init,
yenta_suspend, static int yenta_dev_resume (struct pci_dev *dev)
yenta_get_status, {
yenta_get_socket, return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
yenta_set_socket, }
yenta_set_io_map,
yenta_set_mem_map,
yenta_proc_setup static struct pci_device_id yenta_table [] __devinitdata = { {
.class = PCI_CLASS_BRIDGE_CARDBUS << 8,
.class_mask = ~0,
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
}, { /* all zeroes */ }
}; };
EXPORT_SYMBOL(yenta_operations); MODULE_DEVICE_TABLE(pci, yenta_table);
static struct pci_driver yenta_cardbus_driver = {
.name = "yenta_cardbus",
.id_table = yenta_table,
.probe = yenta_probe,
.remove = __devexit_p(yenta_close),
.suspend = yenta_dev_suspend,
.resume = yenta_dev_resume,
};
static int __init yenta_socket_init(void)
{
return pci_register_driver (&yenta_cardbus_driver);
}
static void __exit yenta_socket_exit (void)
{
pci_unregister_driver (&yenta_cardbus_driver);
}
module_init(yenta_socket_init);
module_exit(yenta_socket_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#define __YENTA_H #define __YENTA_H
#include <asm/io.h> #include <asm/io.h>
#include "pci_socket.h"
#define CB_SOCKET_EVENT 0x00 #define CB_SOCKET_EVENT 0x00
#define CB_CSTSEVENT 0x00000001 /* Card status event */ #define CB_CSTSEVENT 0x00000001 /* Card status event */
...@@ -96,4 +95,23 @@ ...@@ -96,4 +95,23 @@
*/ */
#define CB_MEM_PAGE(map) (0x40 + (map)) #define CB_MEM_PAGE(map) (0x40 + (map))
struct yenta_socket {
struct pci_dev *dev;
int cb_irq, io_irq;
void *base;
void (*handler)(void *, unsigned int);
void *info;
socket_cap_t cap;
spinlock_t event_lock;
unsigned int events;
struct work_struct tq_task;
struct timer_list poll_timer;
struct pcmcia_socket socket;
/* A few words of private data for special stuff of overrides... */
unsigned int private[8];
};
#endif #endif
...@@ -316,7 +316,7 @@ typedef struct error_info_t { ...@@ -316,7 +316,7 @@ typedef struct error_info_t {
/* Special stuff for binding drivers to sockets */ /* Special stuff for binding drivers to sockets */
typedef struct bind_req_t { typedef struct bind_req_t {
socket_t Socket; struct pcmcia_socket *Socket;
u_char Function; u_char Function;
dev_info_t *dev_info; dev_info_t *dev_info;
} bind_req_t; } bind_req_t;
...@@ -325,7 +325,7 @@ typedef struct bind_req_t { ...@@ -325,7 +325,7 @@ typedef struct bind_req_t {
#define BIND_FN_ALL 0xff #define BIND_FN_ALL 0xff
typedef struct mtd_bind_t { typedef struct mtd_bind_t {
socket_t Socket; struct pcmcia_socket *Socket;
u_int Attributes; u_int Attributes;
u_int CardOffset; u_int CardOffset;
dev_info_t *dev_info; dev_info_t *dev_info;
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#define _LINUX_SS_H #define _LINUX_SS_H
#include <pcmcia/cs_types.h> #include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <linux/device.h> #include <linux/device.h>
/* Definitions for card status flags for GetStatus */ /* Definitions for card status flags for GetStatus */
...@@ -124,37 +126,138 @@ typedef struct cb_bridge_map { ...@@ -124,37 +126,138 @@ typedef struct cb_bridge_map {
/* /*
* Socket operations. * Socket operations.
*/ */
struct pcmcia_socket;
struct pccard_operations { struct pccard_operations {
struct module *owner; struct module *owner;
int (*init)(unsigned int sock); int (*init)(struct pcmcia_socket *sock);
int (*suspend)(unsigned int sock); int (*suspend)(struct pcmcia_socket *sock);
int (*register_callback)(unsigned int sock, void (*handler)(void *, unsigned int), void * info); int (*register_callback)(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info);
int (*inquire_socket)(unsigned int sock, socket_cap_t *cap); int (*inquire_socket)(struct pcmcia_socket *sock, socket_cap_t *cap);
int (*get_status)(unsigned int sock, u_int *value); int (*get_status)(struct pcmcia_socket *sock, u_int *value);
int (*get_socket)(unsigned int sock, socket_state_t *state); int (*get_socket)(struct pcmcia_socket *sock, socket_state_t *state);
int (*set_socket)(unsigned int sock, socket_state_t *state); int (*set_socket)(struct pcmcia_socket *sock, socket_state_t *state);
int (*set_io_map)(unsigned int sock, struct pccard_io_map *io); int (*set_io_map)(struct pcmcia_socket *sock, struct pccard_io_map *io);
int (*set_mem_map)(unsigned int sock, struct pccard_mem_map *mem); int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem);
void (*proc_setup)(unsigned int sock, struct proc_dir_entry *base); void (*proc_setup)(struct pcmcia_socket *sock, struct proc_dir_entry *base);
}; };
/* /*
* Calls to set up low-level "Socket Services" drivers * Calls to set up low-level "Socket Services" drivers
*/ */
struct pcmcia_socket;
struct pcmcia_socket_class_data { struct pcmcia_socket_class_data {
unsigned int nsock; /* number of sockets */ unsigned int nsock; /* number of sockets */
unsigned int sock_offset; /* socket # (which is unsigned int sock_offset; /* socket # (which is
* returned to driver) = sock_offset + (0, 1, .. , (nsock-1) */ * returned to driver) = sock_offset + (0, 1, .. , (nsock-1) */
struct pccard_operations *ops; /* see above */ struct pccard_operations *ops; /* see above */
void *s_info; /* socket_info_t */ struct pcmcia_socket *s_info;
struct class_device class_dev; /* generic class structure */ struct class_device class_dev; /* generic class structure */
}; };
typedef struct erase_busy_t {
eraseq_entry_t *erase;
client_handle_t client;
struct timer_list timeout;
struct erase_busy_t *prev, *next;
} erase_busy_t;
typedef struct io_window_t {
u_int Attributes;
ioaddr_t BasePort, NumPorts;
ioaddr_t InUse, Config;
} io_window_t;
#define WINDOW_MAGIC 0xB35C
typedef struct window_t {
u_short magic;
u_short index;
client_handle_t handle;
struct pcmcia_socket *sock;
u_long base;
u_long size;
pccard_mem_map ctl;
} window_t;
/* Maximum number of IO windows per socket */
#define MAX_IO_WIN 2
/* Maximum number of memory windows per socket */
#define MAX_WIN 4
struct config_t;
struct region_t;
struct pcmcia_socket {
spinlock_t lock;
struct pccard_operations * ss_entry;
socket_state_t socket;
socket_cap_t cap;
u_int state;
u_short functions;
u_short lock_count;
client_handle_t clients;
u_int real_clients;
pccard_mem_map cis_mem;
u_char *cis_virt;
struct config_t *config;
struct {
u_int AssignedIRQ;
u_int Config;
} irq;
io_window_t io[MAX_IO_WIN];
window_t win[MAX_WIN];
struct region_t *c_region, *a_region;
erase_busy_t erase_busy;
struct list_head cis_cache;
u_int fake_cis_len;
char *fake_cis;
struct list_head socket_list;
/* deprecated */
unsigned int sock; /* socket number */
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc;
#endif
/* state thread */
struct semaphore skt_sem; /* protects socket h/w state */
struct task_struct *thread;
struct completion thread_done;
wait_queue_head_t thread_wait;
spinlock_t thread_lock; /* protects thread_events */
unsigned int thread_events;
/* pcmcia (16-bit) */
struct pcmcia_bus_socket *pcmcia;
/* cardbus (32-bit) */
#ifdef CONFIG_CARDBUS
struct resource * cb_cis_res;
u_char *cb_cis_virt;
#endif
/* socket device */
struct class_device dev;
void *driver_data; /* data internal to the socket driver */
};
struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr);
extern int pcmcia_register_socket(struct pcmcia_socket *socket);
extern void pcmcia_unregister_socket(struct pcmcia_socket *socket);
extern struct class pcmcia_socket_class; extern struct class pcmcia_socket_class;
/* socket drivers are expected to use these callbacks in their .drv struct */ /* socket drivers are expected to use these callbacks in their .drv struct */
extern int pcmcia_socket_dev_suspend(struct pcmcia_socket_class_data *cls_d, u32 state, u32 level); extern int pcmcia_socket_dev_suspend(struct device *dev, u32 state, u32 level);
extern int pcmcia_socket_dev_resume(struct pcmcia_socket_class_data *cls_d, u32 level); extern int pcmcia_socket_dev_resume(struct device *dev, u32 level);
#endif /* _LINUX_SS_H */ #endif /* _LINUX_SS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment