summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/cs.c')
-rw-r--r--drivers/pcmcia/cs.c126
1 files changed, 81 insertions, 45 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index d44d505ca..bd671c1b2 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -2,7 +2,7 @@
PCMCIA Card Services -- core services
- cs.c 1.235 1999/11/11 17:52:05
+ cs.c 1.247 2000/01/15 04:30:35
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
@@ -59,7 +59,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/bus_ops.h>
-
#include "cs_internal.h"
#include "rsrc_mgr.h"
@@ -72,28 +71,40 @@ static int handle_apm_event(apm_event_t event);
int pc_debug = PCMCIA_DEBUG;
MODULE_PARM(pc_debug, "i");
static const char *version =
-"cs.c 1.235 1999/11/11 17:52:05 (David Hinds)";
+"cs.c 1.247 2000/01/15 04:30:35 (David Hinds)";
#endif
-static const char *release = "Linux PCMCIA Card Services " CS_RELEASE;
-#ifdef MODULE
-static const char *kernel = "kernel build: " UTS_RELEASE " " UTS_VERSION;
-#endif
-static const char *options = "options: "
#ifdef CONFIG_PCI
-" [pci]"
+#define PCI_OPT " [pci]"
+#else
+#define PCI_OPT ""
#endif
#ifdef CONFIG_CARDBUS
-" [cardbus]"
+#define CB_OPT " [cardbus]"
+#else
+#define CB_OPT ""
#endif
#ifdef CONFIG_APM
-" [apm]"
+#define APM_OPT " [apm]"
+#else
+#define APM_OPT ""
#endif
#if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && \
- !defined(CONFIG_APM) && !defined(CONFIG_PNP_BIOS)
-" none"
+ !defined(CONFIG_APM)
+#define OPTIONS " none"
+#else
+#define OPTIONS PCI_OPT CB_OPT APM_OPT
+#endif
+
+static const char *release = "Linux PCMCIA Card Services " CS_RELEASE;
+#ifdef MODULE
+static const char *kernel = "kernel build: " UTS_RELEASE " " UTS_VERSION;
#endif
-;
+static const char *options = "options: " OPTIONS;
+
+MODULE_AUTHOR("David Hinds <dhinds@pcmcia.sourceforge.org>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services " CS_RELEASE
+ "\n options:" OPTIONS);
/*====================================================================*/
@@ -263,11 +274,6 @@ static int set_socket(socket_info_t *s, socket_state_t *state)
return s->ss_entry->set_socket(s->sock, state);
}
-static int get_io_map(socket_info_t *s, struct pccard_io_map *io)
-{
- return s->ss_entry->get_io_map(s->sock, io);
-}
-
static int set_io_map(socket_info_t *s, struct pccard_io_map *io)
{
return s->ss_entry->set_io_map(s->sock, io);
@@ -734,18 +740,18 @@ static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base,
int i;
ioaddr_t try, align;
- align = (*base) ? (1<<lines) : 1;
+ align = (*base) ? (lines ? 1<<lines : 0) : 1;
if (align && (align < num)) {
- printk(KERN_INFO "odd IO request: num %04x align %04x\n",
- num, align);
- if (*base)
+ if (*base) {
+ DEBUG(0, "odd IO request: num %04x align %04x\n",
+ num, align);
align = 0;
- else
+ } else
while (align && (align < num)) align <<= 1;
}
if (*base & ~(align-1)) {
- printk(KERN_INFO "odd IO request: base %04x align %04x\n",
- *base, align);
+ DEBUG(0, "odd IO request: base %04x align %04x\n",
+ *base, align);
align = 0;
}
for (i = 0; i < MAX_IO_WIN; i++) {
@@ -862,6 +868,7 @@ int pcmcia_bind_device(bind_req_t *req)
s = SOCKET(req);
client = (client_t *)kmalloc(sizeof(client_t), GFP_KERNEL);
+ if (!client) return CS_OUT_OF_RESOURCE;
memset(client, '\0', sizeof(client_t));
client->client_magic = CLIENT_MAGIC;
strncpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
@@ -1122,18 +1129,18 @@ int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req)
if (win->ctl.flags & MAP_ACTIVE)
req->Attributes |= WIN_ENABLE;
if (win->ctl.flags & MAP_16BIT)
- req->Attributes |= WIN_DATA_WIDTH;
+ req->Attributes |= WIN_DATA_WIDTH_16;
if (win->ctl.flags & MAP_USE_WAIT)
req->Attributes |= WIN_USE_WAIT;
*handle = win;
return CS_SUCCESS;
} /* get_window */
-int pcmcia_get_first_window(client_handle_t *handle, win_req_t *req)
+int pcmcia_get_first_window(window_handle_t *win, win_req_t *req)
{
- if ((handle == NULL) || CHECK_HANDLE(*handle))
+ if ((win == NULL) || ((*win)->magic != WINDOW_MAGIC))
return CS_BAD_HANDLE;
- return pcmcia_get_window((window_handle_t *)handle, 0, req);
+ return pcmcia_get_window(win, 0, req);
}
int pcmcia_get_next_window(window_handle_t *win, win_req_t *req)
@@ -1143,6 +1150,29 @@ int pcmcia_get_next_window(window_handle_t *win, win_req_t *req)
return pcmcia_get_window(win, (*win)->index+1, req);
}
+/*=====================================================================
+
+ Return the PCI device associated with a card..
+
+======================================================================*/
+
+#ifdef CONFIG_CARDBUS
+
+struct pci_bus *pcmcia_lookup_bus(client_handle_t handle)
+{
+ socket_info_t *s;
+
+ if (CHECK_HANDLE(handle))
+ return NULL;
+ s = SOCKET(handle);
+ if (!(s->state & SOCKET_CARDBUS))
+ return NULL;
+
+ return s->cap.cb_dev->subordinate;
+}
+
+#endif
+
/*======================================================================
Get the current socket state bits. We don't support the latched
@@ -1308,7 +1338,7 @@ int pcmcia_modify_window(window_handle_t win, modwin_t *req)
win->ctl.flags |= MAP_ATTRIB;
if (req->Attributes & WIN_ENABLE)
win->ctl.flags |= MAP_ACTIVE;
- if (req->Attributes & WIN_DATA_WIDTH)
+ if (req->Attributes & WIN_DATA_WIDTH_16)
win->ctl.flags |= MAP_16BIT;
if (req->Attributes & WIN_USE_WAIT)
win->ctl.flags |= MAP_USE_WAIT;
@@ -1403,7 +1433,7 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
int pcmcia_release_configuration(client_handle_t handle)
{
- pccard_io_map io;
+ pccard_io_map io = { 0, 0, 0, 0, 1 };
socket_info_t *s;
int i;
@@ -1437,8 +1467,6 @@ int pcmcia_release_configuration(client_handle_t handle)
if (s->io[i].Config != 0)
continue;
io.map = i;
- get_io_map(s, &io);
- io.flags &= ~MAP_ACTIVE;
set_io_map(s, &io);
}
c->state &= ~CONFIG_LOCKED;
@@ -1840,7 +1868,8 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
{
socket_info_t *s;
window_t *win;
- int w, align;
+ u_long align;
+ int w;
if (CHECK_HANDLE(*handle))
return CS_BAD_HANDLE;
@@ -1850,16 +1879,25 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
if (req->Attributes & (WIN_PAGED | WIN_SHARED))
return CS_BAD_ATTRIBUTE;
- for (w = 0; w < MAX_WIN; w++)
- if (!(s->state & SOCKET_WIN_REQ(w))) break;
- if (w == MAX_WIN)
- return CS_OUT_OF_RESOURCE;
-
/* Window size defaults to smallest available */
if (req->Size == 0)
req->Size = s->cap.map_size;
+ align = (((s->cap.features & SS_CAP_MEM_ALIGN) ||
+ (req->Attributes & WIN_STRICT_ALIGN)) ?
+ req->Size : s->cap.map_size);
+ if (req->Size & (s->cap.map_size-1))
+ return CS_BAD_SIZE;
+ if (req->Base & (align-1))
+ return CS_BAD_BASE;
+ if (req->Base)
+ align = 0;
/* Allocate system memory window */
+ for (w = 0; w < MAX_WIN; w++)
+ if (!(s->state & SOCKET_WIN_REQ(w))) break;
+ if (w == MAX_WIN)
+ return CS_OUT_OF_RESOURCE;
+
win = &s->win[w];
win->magic = WINDOW_MAGIC;
win->index = w;
@@ -1867,10 +1905,8 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
win->sock = s;
win->base = req->Base;
win->size = req->Size;
- align = ((s->cap.features & SS_CAP_MEM_ALIGN) ||
- (req->Attributes & WIN_STRICT_ALIGN));
- if (find_mem_region(&win->base, win->size,
- (align ? req->Size : s->cap.map_size),
+
+ if (find_mem_region(&win->base, win->size, align,
(req->Attributes & WIN_MAP_BELOW_1MB) ||
!(s->cap.features & SS_CAP_PAGE_REGS),
(*handle)->dev_info))
@@ -1886,7 +1922,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
win->ctl.flags |= MAP_ATTRIB;
if (req->Attributes & WIN_ENABLE)
win->ctl.flags |= MAP_ACTIVE;
- if (req->Attributes & WIN_DATA_WIDTH)
+ if (req->Attributes & WIN_DATA_WIDTH_16)
win->ctl.flags |= MAP_16BIT;
if (req->Attributes & WIN_USE_WAIT)
win->ctl.flags |= MAP_USE_WAIT;