summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/Kconfig17
-rw-r--r--drivers/pcmcia/au1000_generic.h1
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c1
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c1
-rw-r--r--drivers/pcmcia/cardbus.c1
-rw-r--r--drivers/pcmcia/cs.c16
-rw-r--r--drivers/pcmcia/cs_internal.h16
-rw-r--r--drivers/pcmcia/ds.c101
-rw-r--r--drivers/pcmcia/hd64465_ss.c1
-rw-r--r--drivers/pcmcia/i82365.c9
-rw-r--r--drivers/pcmcia/m32r_cfc.c1
-rw-r--r--drivers/pcmcia/m32r_pcc.c1
-rw-r--r--drivers/pcmcia/pcmcia_compat.c48
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c27
-rw-r--r--drivers/pcmcia/pcmcia_resource.c143
-rw-r--r--drivers/pcmcia/sa1100_generic.c1
-rw-r--r--drivers/pcmcia/soc_common.h1
-rw-r--r--drivers/pcmcia/socket_sysfs.c1
-rw-r--r--drivers/pcmcia/tcic.c1
-rw-r--r--drivers/pcmcia/ti113x.h4
-rw-r--r--drivers/pcmcia/yenta_socket.c174
21 files changed, 235 insertions, 331 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 52ea345..6485f75 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -1,8 +1,5 @@
#
-# PCMCIA bus subsystem configuration
-#
-# Right now the non-CardBus choices are not supported
-# by the integrated kernel driver.
+# PCCARD (PCMCIA/CardBus) bus subsystem configuration
#
menu "PCCARD (PCMCIA/CardBus) support"
@@ -32,7 +29,7 @@ config PCMCIA_DEBUG
The kernel command line options are:
pcmcia_core.pc_debug=N
- ds.pc_debug=N
+ pcmcia.pc_debug=N
sa11xx_core.pc_debug=N
The module option is called pc_debug=N
@@ -73,7 +70,7 @@ config PCMCIA_LOAD_CIS
If unsure, say Y.
config PCMCIA_IOCTL
- bool
+ bool "PCMCIA control ioctl (obsolete)"
depends on PCMCIA
default y
help
@@ -81,9 +78,8 @@ config PCMCIA_IOCTL
subsystem will be built. It is needed by cardmgr and cardctl
(pcmcia-cs) to function properly.
- If you do not use the new pcmciautils package, and have a
- yenta, Cirrus PD6729, i82092, i82365 or tcic compatible bridge,
- you need to say Y here to be able to use 16-bit PCMCIA cards.
+ You should use the new pcmciautils package instead (see
+ <file:Documentation/Changes> for location and details).
If unsure, say Y.
@@ -106,7 +102,8 @@ comment "PC-card bridges"
config YENTA
tristate "CardBus yenta-compatible bridge support"
- depends on CARDBUS
+ depends on PCI
+ select CARDBUS if !EMBEDDED
select PCCARD_NONSTATIC
---help---
This option enables support for CardBus host bridges. Virtually
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
index 417bc15..d5122b1e 100644
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -22,7 +22,6 @@
#define __ASM_AU1000_PCMCIA_H
/* include the world */
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index df19ce1..d414a3b 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -33,7 +33,6 @@
#include <linux/version.h>
#include <linux/types.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 1dfc776..f113b69 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -38,7 +38,6 @@
#include <linux/version.h>
#include <linux/types.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 3ccb524..1d755e2 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -31,7 +31,6 @@
#include <asm/io.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index e82859d..e39178f 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -33,7 +33,6 @@
#include <asm/irq.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
@@ -216,6 +215,13 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
list_add_tail(&socket->socket_list, &pcmcia_socket_list);
up_write(&pcmcia_socket_list_rwsem);
+#ifndef CONFIG_CARDBUS
+ /*
+ * If we do not support Cardbus, ensure that
+ * the Cardbus socket capability is disabled.
+ */
+ socket->features &= ~SS_CAP_CARDBUS;
+#endif
/* set proper values in socket->dev */
socket->dev.class_data = socket;
@@ -449,11 +455,11 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
}
if (status & SS_CARDBUS) {
+ if (!(skt->features & SS_CAP_CARDBUS)) {
+ cs_err(skt, "cardbus cards are not supported.\n");
+ return CS_BAD_TYPE;
+ }
skt->state |= SOCKET_CARDBUS;
-#ifndef CONFIG_CARDBUS
- cs_err(skt, "cardbus cards are not supported.\n");
- return CS_BAD_TYPE;
-#endif
}
/*
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 0b4c18e..6bbfbd0 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -99,23 +99,11 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
}
}
-#define CHECK_HANDLE(h) \
- (((h) == NULL) || ((h)->client_magic != CLIENT_MAGIC))
-
#define CHECK_SOCKET(s) \
(((s) >= sockets) || (socket_table[s]->ops == NULL))
-#define SOCKET(h) (h->Socket)
-#define CONFIG(h) (&SOCKET(h)->config[(h)->Function])
-
-#define CHECK_REGION(r) \
- (((r) == NULL) || ((r)->region_magic != REGION_MAGIC))
-
-#define CHECK_ERASEQ(q) \
- (((q) == NULL) || ((q)->eraseq_magic != ERASEQ_MAGIC))
-
-#define EVENT(h, e, p) \
- ((h)->event_handler((e), (p), &(h)->event_callback_args))
+#define SOCKET(h) (h->socket)
+#define CONFIG(h) (&SOCKET(h)->config[(h)->func])
/* In cardbus.c */
int cb_alloc(struct pcmcia_socket *s);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index cabddd4..3e3c6f1 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -158,17 +158,15 @@ static const lookup_t service_table[] = {
};
-static int pcmcia_report_error(client_handle_t handle, error_info_t *err)
+static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err)
{
int i;
char *serv;
- if (CHECK_HANDLE(handle))
+ if (!p_dev)
printk(KERN_NOTICE);
- else {
- struct pcmcia_device *p_dev = handle_to_pdev(handle);
+ else
printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id);
- }
for (i = 0; i < ARRAY_SIZE(service_table); i++)
if (service_table[i].key == err->func)
@@ -193,10 +191,10 @@ static int pcmcia_report_error(client_handle_t handle, error_info_t *err)
/*======================================================================*/
-void cs_error(client_handle_t handle, int func, int ret)
+void cs_error(struct pcmcia_device *p_dev, int func, int ret)
{
error_info_t err = { func, ret };
- pcmcia_report_error(handle, &err);
+ pcmcia_report_error(p_dev, &err);
}
EXPORT_SYMBOL(cs_error);
@@ -207,6 +205,10 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
unsigned int i;
u32 hash;
+ if (!p_drv->attach || !p_drv->event || !p_drv->detach)
+ printk(KERN_DEBUG "pcmcia: %s does misses a callback function",
+ p_drv->drv.name);
+
while (did && did->match_flags) {
for (i=0; i<4; i++) {
if (!did->prod_id[i])
@@ -376,7 +378,7 @@ static int pcmcia_device_probe(struct device * dev)
if (p_drv->attach) {
p_dev->instance = p_drv->attach();
- if ((!p_dev->instance) || (p_dev->client.state & CLIENT_UNBOUND)) {
+ if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) {
printk(KERN_NOTICE "ds: unable to create instance "
"of '%s'!\n", p_drv->drv.name);
ret = -EINVAL;
@@ -516,10 +518,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
/* compat */
- p_dev->client.client_magic = CLIENT_MAGIC;
- p_dev->client.Socket = s;
- p_dev->client.Function = function;
- p_dev->client.state = CLIENT_UNBOUND;
+ p_dev->state = CLIENT_UNBOUND;
/* Add to the list in pcmcia_bus_socket */
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
@@ -573,8 +572,6 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
else
no_funcs = 1;
- /* this doesn't handle multifunction devices on one pcmcia function
- * yet. */
for (i=0; i < no_funcs; i++)
pcmcia_device_add(s, i);
@@ -847,7 +844,7 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]);
pcmcia_device_stringattr(prod_id3, prod_id[2]);
pcmcia_device_stringattr(prod_id4, prod_id[3]);
-static ssize_t modalias_show(struct device *dev, char *buf)
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
int i;
@@ -914,6 +911,7 @@ struct send_event_data {
static int send_event_callback(struct device *dev, void * _data)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+ struct pcmcia_driver *p_drv;
struct send_event_data *data = _data;
/* we get called for all sockets, but may only pass the event
@@ -921,11 +919,16 @@ static int send_event_callback(struct device *dev, void * _data)
if (p_dev->socket != data->skt)
return 0;
- if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE))
+ p_drv = to_pcmcia_drv(p_dev->dev.driver);
+ if (!p_drv)
return 0;
- if (p_dev->client.EventMask & data->event)
- return EVENT(&p_dev->client, data->event, data->priority);
+ if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
+ return 0;
+
+ if (p_drv->event)
+ return p_drv->event(data->event, data->priority,
+ &p_dev->event_callback_args);
return 0;
}
@@ -987,11 +990,11 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
-int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
+int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req)
{
- client_t *client = NULL;
struct pcmcia_socket *s = NULL;
struct pcmcia_device *p_dev = NULL;
+ struct pcmcia_driver *p_drv = NULL;
/* Look for unbound client with matching dev_info */
down_read(&pcmcia_socket_list_rwsem);
@@ -1006,18 +1009,16 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
continue;
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
- struct pcmcia_driver *p_drv;
p_dev = pcmcia_get_dev(p_dev);
if (!p_dev)
continue;
- if (!(p_dev->client.state & CLIENT_UNBOUND) ||
+ if (!(p_dev->state & CLIENT_UNBOUND) ||
(!p_dev->dev.driver)) {
pcmcia_put_dev(p_dev);
continue;
}
p_drv = to_pcmcia_drv(p_dev->dev.driver);
if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) {
- client = &p_dev->client;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
goto found;
}
@@ -1028,26 +1029,20 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
}
found:
up_read(&pcmcia_socket_list_rwsem);
- if (!p_dev || !client)
+ if (!p_dev)
return -ENODEV;
pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */
- *handle = client;
- client->state &= ~CLIENT_UNBOUND;
- client->Socket = s;
- client->EventMask = req->EventMask;
- client->event_handler = req->event_handler;
- client->event_callback_args = req->event_callback_args;
- client->event_callback_args.client_handle = client;
+ *handle = p_dev;
+ p_dev->state &= ~CLIENT_UNBOUND;
+ p_dev->event_callback_args = req->event_callback_args;
+ p_dev->event_callback_args.client_handle = p_dev;
- if (s->state & SOCKET_CARDBUS)
- client->state |= CLIENT_CARDBUS;
- if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) &&
- (client->Function != BIND_FN_ALL)) {
+ if (!s->functions) {
cistpl_longlink_mfc_t mfc;
- if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc)
+ if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc)
== CS_SUCCESS)
s->functions = mfc.nfn;
else
@@ -1060,13 +1055,13 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
}
ds_dbg(1, "register_client(): client 0x%p, dev %s\n",
- client, p_dev->dev.bus_id);
- if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
- EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
+ p_dev, p_dev->dev.bus_id);
if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
- if (client->EventMask & CS_EVENT_CARD_INSERTION)
- EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+ if (p_drv->event)
+ p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW,
+ &p_dev->event_callback_args);
+
}
return CS_SUCCESS;
@@ -1099,7 +1094,7 @@ static int unbind_request(struct pcmcia_socket *s)
}
p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
list_del(&p_dev->socket_device_list);
- p_dev->client.state |= CLIENT_STALE;
+ p_dev->state |= CLIENT_STALE;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
device_unregister(&p_dev->dev);
@@ -1108,31 +1103,25 @@ static int unbind_request(struct pcmcia_socket *s)
return 0;
} /* unbind_request */
-int pcmcia_deregister_client(client_handle_t handle)
+int pcmcia_deregister_client(struct pcmcia_device *p_dev)
{
struct pcmcia_socket *s;
int i;
- struct pcmcia_device *p_dev = handle_to_pdev(handle);
-
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- ds_dbg(1, "deregister_client(%p)\n", handle);
+ s = p_dev->socket;
+ ds_dbg(1, "deregister_client(%p)\n", p_dev);
- if (handle->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
+ if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
goto warn_out;
for (i = 0; i < MAX_WIN; i++)
- if (handle->state & CLIENT_WIN_REQ(i))
+ if (p_dev->state & CLIENT_WIN_REQ(i))
goto warn_out;
- if (handle->state & CLIENT_STALE) {
- handle->client_magic = 0;
- handle->state &= ~CLIENT_STALE;
+ if (p_dev->state & CLIENT_STALE) {
+ p_dev->state &= ~CLIENT_STALE;
pcmcia_put_dev(p_dev);
} else {
- handle->state = CLIENT_UNBOUND;
- handle->event_handler = NULL;
+ p_dev->state = CLIENT_UNBOUND;
}
return CS_SUCCESS;
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 5ab55ae..316f8bc 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -43,7 +43,6 @@
#include <asm/hd64465/hd64465.h>
#include <asm/hd64465/io.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index d72f9a3..a713015 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -53,7 +53,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
@@ -698,14 +697,6 @@ static void __init add_pcic(int ns, int type)
struct i82365_socket *t = &socket[sockets-ns];
base = sockets-ns;
- if (t->ioaddr > 0) {
- if (!request_region(t->ioaddr, 2, "i82365")) {
- printk(KERN_ERR "i82365: IO region conflict at %#lx, not available\n",
- t->ioaddr);
- return;
- }
- }
-
if (base == 0) printk("\n");
printk(KERN_INFO " %s", pcic[type].name);
printk(" ISA-to-PCMCIA at port %#lx ofs 0x%02x",
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index b1111c6..65f3ee3 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -29,7 +29,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index c0997c4..7b14d7e 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -30,7 +30,6 @@
#include <asm/system.h>
#include <asm/addrspace.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/pcmcia_compat.c b/drivers/pcmcia/pcmcia_compat.c
index 1cc8331..ebb161c 100644
--- a/drivers/pcmcia/pcmcia_compat.c
+++ b/drivers/pcmcia/pcmcia_compat.c
@@ -18,7 +18,6 @@
#include <linux/init.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
@@ -28,64 +27,39 @@
#include "cs_internal.h"
-int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
+int pcmcia_get_first_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_get_first_tuple(s, handle->Function, tuple);
+ return pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple);
}
EXPORT_SYMBOL(pcmcia_get_first_tuple);
-int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
+int pcmcia_get_next_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_get_next_tuple(s, handle->Function, tuple);
+ return pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple);
}
EXPORT_SYMBOL(pcmcia_get_next_tuple);
-int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
+int pcmcia_get_tuple_data(struct pcmcia_device *p_dev, tuple_t *tuple)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_get_tuple_data(s, tuple);
+ return pccard_get_tuple_data(p_dev->socket, tuple);
}
EXPORT_SYMBOL(pcmcia_get_tuple_data);
-int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+int pcmcia_parse_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, cisparse_t *parse)
{
return pccard_parse_tuple(tuple, parse);
}
EXPORT_SYMBOL(pcmcia_parse_tuple);
-int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
+int pcmcia_validate_cis(struct pcmcia_device *p_dev, cisinfo_t *info)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_validate_cis(s, handle->Function, info);
+ return pccard_validate_cis(p_dev->socket, p_dev->func, info);
}
EXPORT_SYMBOL(pcmcia_validate_cis);
-int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
+int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req)
{
- struct pcmcia_socket *skt;
-
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- skt = SOCKET(handle);
- if (!skt)
- return CS_BAD_HANDLE;
-
- return pccard_reset_card(skt);
+ return pccard_reset_card(p_dev->socket);
}
EXPORT_SYMBOL(pcmcia_reset_card);
-
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index b883bc1..39ba640 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -31,7 +31,6 @@
#include <linux/workqueue.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -71,29 +70,6 @@ extern int ds_pc_debug;
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
#endif
-static const char *release = "Linux Kernel Card Services";
-
-/** pcmcia_get_card_services_info
- *
- * Return information about this version of Card Services
- */
-static int pcmcia_get_card_services_info(servinfo_t *info)
-{
- unsigned int socket_count = 0;
- struct list_head *tmp;
- info->Signature[0] = 'C';
- info->Signature[1] = 'S';
- 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->CSLevel = 0x0210;
- info->VendorString = (char *)release;
- return CS_SUCCESS;
-} /* get_card_services_info */
-
/* backwards-compatible accessing of driver --- by name! */
@@ -591,9 +567,6 @@ static int ds_ioctl(struct inode * inode, struct file * file,
case DS_ADJUST_RESOURCE_INFO:
ret = pcmcia_adjust_resource_info(&buf->adjust);
break;
- case DS_GET_CARD_SERVICES_INFO:
- ret = pcmcia_get_card_services_info(&buf->servinfo);
- break;
case DS_GET_CONFIGURATION_INFO:
if (buf->config.Function &&
(buf->config.Function >= s->functions))
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index c01dc6b..184f4f8 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -23,7 +23,6 @@
#include <linux/device.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
@@ -202,14 +201,11 @@ int pccard_access_configuration_register(struct pcmcia_socket *s,
return CS_SUCCESS;
} /* pccard_access_configuration_register */
-int pcmcia_access_configuration_register(client_handle_t handle,
+int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
conf_reg_t *reg)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_access_configuration_register(s, handle->Function, reg);
+ return pccard_access_configuration_register(p_dev->socket,
+ p_dev->func, reg);
}
EXPORT_SYMBOL(pcmcia_access_configuration_register);
@@ -271,17 +267,11 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
return CS_SUCCESS;
} /* pccard_get_configuration_info */
-int pcmcia_get_configuration_info(client_handle_t handle,
+int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
config_info_t *config)
{
- struct pcmcia_socket *s;
-
- if ((CHECK_HANDLE(handle)) || !config)
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- if (!s)
- return CS_BAD_HANDLE;
- return pccard_get_configuration_info(s, handle->Function, config);
+ return pccard_get_configuration_info(p_dev->socket, p_dev->func,
+ config);
}
EXPORT_SYMBOL(pcmcia_get_configuration_info);
@@ -382,10 +372,8 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
{
struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
s = SOCKET(handle);
- return pccard_get_status(s, handle->Function, status);
+ return pccard_get_status(s, handle->func, status);
}
EXPORT_SYMBOL(pcmcia_get_status);
@@ -426,16 +414,14 @@ EXPORT_SYMBOL(pcmcia_map_mem_page);
*
* Modify a locked socket configuration
*/
-int pcmcia_modify_configuration(client_handle_t handle,
+int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
modconf_t *mod)
{
struct pcmcia_socket *s;
config_t *c;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- c = CONFIG(handle);
+ s = p_dev->socket;
+ c = CONFIG(p_dev);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
if (!(c->state & CONFIG_LOCKED))
@@ -472,25 +458,18 @@ int pcmcia_modify_configuration(client_handle_t handle,
EXPORT_SYMBOL(pcmcia_modify_configuration);
-int pcmcia_release_configuration(client_handle_t handle)
+int pcmcia_release_configuration(struct pcmcia_device *p_dev)
{
pccard_io_map io = { 0, 0, 0, 0, 1 };
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
int i;
- if (CHECK_HANDLE(handle) ||
- !(handle->state & CLIENT_CONFIG_LOCKED))
+ if (!(p_dev->state & CLIENT_CONFIG_LOCKED))
return CS_BAD_HANDLE;
- handle->state &= ~CLIENT_CONFIG_LOCKED;
- s = SOCKET(handle);
-
-#ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS)
- return CS_SUCCESS;
-#endif
+ p_dev->state &= ~CLIENT_CONFIG_LOCKED;
- if (!(handle->state & CLIENT_STALE)) {
- config_t *c = CONFIG(handle);
+ if (!(p_dev->state & CLIENT_STALE)) {
+ config_t *c = CONFIG(p_dev);
if (--(s->lock_count) == 0) {
s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
s->socket.Vpp = 0;
@@ -523,22 +502,16 @@ EXPORT_SYMBOL(pcmcia_release_configuration);
* don't bother checking the port ranges against the current socket
* values.
*/
-int pcmcia_release_io(client_handle_t handle, io_req_t *req)
+int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
{
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
- if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))
+ if (!(p_dev->state & CLIENT_IO_REQ))
return CS_BAD_HANDLE;
- handle->state &= ~CLIENT_IO_REQ;
- s = SOCKET(handle);
-
-#ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS)
- return CS_SUCCESS;
-#endif
+ p_dev->state &= ~CLIENT_IO_REQ;
- if (!(handle->state & CLIENT_STALE)) {
- config_t *c = CONFIG(handle);
+ if (!(p_dev->state & CLIENT_STALE)) {
+ config_t *c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if ((c->io.BasePort1 != req->BasePort1) ||
@@ -558,16 +531,15 @@ int pcmcia_release_io(client_handle_t handle, io_req_t *req)
EXPORT_SYMBOL(pcmcia_release_io);
-int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
+int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))
+ struct pcmcia_socket *s = p_dev->socket;
+ if (!(p_dev->state & CLIENT_IRQ_REQ))
return CS_BAD_HANDLE;
- handle->state &= ~CLIENT_IRQ_REQ;
- s = SOCKET(handle);
+ p_dev->state &= ~CLIENT_IRQ_REQ;
- if (!(handle->state & CLIENT_STALE)) {
- config_t *c = CONFIG(handle);
+ if (!(p_dev->state & CLIENT_STALE)) {
+ config_t *c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if (c->irq.Attributes != req->Attributes)
@@ -623,29 +595,21 @@ int pcmcia_release_window(window_handle_t win)
EXPORT_SYMBOL(pcmcia_release_window);
-int pcmcia_request_configuration(client_handle_t handle,
+int pcmcia_request_configuration(struct pcmcia_device *p_dev,
config_req_t *req)
{
int i;
u_int base;
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
config_t *c;
pccard_io_map iomap;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
-#ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS)
- return CS_UNSUPPORTED_MODE;
-#endif
-
if (req->IntType & INT_CARDBUS)
return CS_UNSUPPORTED_MODE;
- c = CONFIG(handle);
+ c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
@@ -746,7 +710,7 @@ int pcmcia_request_configuration(client_handle_t handle,
}
c->state |= CONFIG_LOCKED;
- handle->state |= CLIENT_CONFIG_LOCKED;
+ p_dev->state |= CLIENT_CONFIG_LOCKED;
return CS_SUCCESS;
} /* pcmcia_request_configuration */
EXPORT_SYMBOL(pcmcia_request_configuration);
@@ -757,29 +721,17 @@ EXPORT_SYMBOL(pcmcia_request_configuration);
* Request_io() reserves ranges of port addresses for a socket.
* I have not implemented range sharing or alias addressing.
*/
-int pcmcia_request_io(client_handle_t handle, io_req_t *req)
+int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
{
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
config_t *c;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
- if (handle->state & CLIENT_CARDBUS) {
-#ifdef CONFIG_CARDBUS
- handle->state |= CLIENT_IO_REQ;
- return CS_SUCCESS;
-#else
- return CS_UNSUPPORTED_FUNCTION;
-#endif
- }
-
if (!req)
return CS_UNSUPPORTED_MODE;
- c = CONFIG(handle);
+ c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if (c->state & CONFIG_IO_REQ)
@@ -804,7 +756,7 @@ int pcmcia_request_io(client_handle_t handle, io_req_t *req)
c->io = *req;
c->state |= CONFIG_IO_REQ;
- handle->state |= CLIENT_IO_REQ;
+ p_dev->state |= CLIENT_IO_REQ;
return CS_SUCCESS;
} /* pcmcia_request_io */
EXPORT_SYMBOL(pcmcia_request_io);
@@ -827,19 +779,15 @@ static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)
}
#endif
-int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
+int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
{
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
config_t *c;
int ret = CS_IN_USE, irq = 0;
- struct pcmcia_device *p_dev = handle_to_pdev(handle);
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
- c = CONFIG(handle);
+ c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if (c->state & CONFIG_IRQ_REQ)
@@ -903,7 +851,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
s->irq.Config++;
c->state |= CONFIG_IRQ_REQ;
- handle->state |= CLIENT_IRQ_REQ;
+ p_dev->state |= CLIENT_IRQ_REQ;
#ifdef CONFIG_PCMCIA_PROBE
pcmcia_used_irq[irq]++;
@@ -919,16 +867,13 @@ EXPORT_SYMBOL(pcmcia_request_irq);
* Request_window() establishes a mapping between card memory space
* and system memory space.
*/
-int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)
+int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh)
{
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = (*p_dev)->socket;
window_t *win;
u_long align;
int w;
- if (CHECK_HANDLE(*handle))
- return CS_BAD_HANDLE;
- s = (*handle)->Socket;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
if (req->Attributes & (WIN_PAGED | WIN_SHARED))
@@ -957,7 +902,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
win = &s->win[w];
win->magic = WINDOW_MAGIC;
win->index = w;
- win->handle = *handle;
+ win->handle = *p_dev;
win->sock = s;
if (!(s->features & SS_CAP_STATIC_MAP)) {
@@ -966,7 +911,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
if (!win->ctl.res)
return CS_IN_USE;
}
- (*handle)->state |= CLIENT_WIN_REQ(w);
+ (*p_dev)->state |= CLIENT_WIN_REQ(w);
/* Configure the socket controller */
win->ctl.map = w+1;
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index f1bb791..e98bb3d 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -34,7 +34,6 @@
#include <linux/init.h>
#include <linux/config.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 700a155..6f14126 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -11,7 +11,6 @@
/* include the world */
#include <linux/cpufreq.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index fcef54c..1040a6c 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -29,7 +29,6 @@
#include <asm/irq.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index aacbbb5..d5a61ea 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -50,7 +50,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index c7ba998..fbe233e 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -154,8 +154,6 @@
#define ENE_TEST_C9 0xc9 /* 8bit */
#define ENE_TEST_C9_TLTENABLE 0x02
-#ifdef CONFIG_CARDBUS
-
/*
* Texas Instruments CardBus controller overrides.
*/
@@ -843,7 +841,5 @@ static int ti1250_override(struct yenta_socket *socket)
return ti12xx_override(socket);
}
-#endif /* CONFIG_CARDBUS */
-
#endif /* _LINUX_TI113X_H */
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 02b23ab..6837491 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -18,7 +18,6 @@
#include <linux/delay.h>
#include <linux/module.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
@@ -528,98 +527,144 @@ static int yenta_sock_suspend(struct pcmcia_socket *sock)
* Use an adaptive allocation for the memory resource,
* sometimes the memory behind pci bridges is limited:
* 1/8 of the size of the io window of the parent.
- * max 4 MB, min 16 kB.
+ * max 4 MB, min 16 kB. We try very hard to not get below
+ * the "ACC" values, though.
*/
#define BRIDGE_MEM_MAX 4*1024*1024
+#define BRIDGE_MEM_ACC 128*1024
#define BRIDGE_MEM_MIN 16*1024
-#define BRIDGE_IO_MAX 256
+#define BRIDGE_IO_MAX 512
+#define BRIDGE_IO_ACC 256
#define BRIDGE_IO_MIN 32
#ifndef PCIBIOS_MIN_CARDBUS_IO
#define PCIBIOS_MIN_CARDBUS_IO PCIBIOS_MIN_IO
#endif
-static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
+static int yenta_search_one_res(struct resource *root, struct resource *res,
+ u32 min)
+{
+ u32 align, size, start, end;
+
+ if (res->flags & IORESOURCE_IO) {
+ align = 1024;
+ size = BRIDGE_IO_MAX;
+ start = PCIBIOS_MIN_CARDBUS_IO;
+ end = ~0U;
+ } else {
+ unsigned long avail = root->end - root->start;
+ int i;
+ size = BRIDGE_MEM_MAX;
+ if (size > avail/8) {
+ size=(avail+1)/8;
+ /* round size down to next power of 2 */
+ i = 0;
+ while ((size /= 2) != 0)
+ i++;
+ size = 1 << i;
+ }
+ if (size < min)
+ size = min;
+ align = size;
+ start = PCIBIOS_MIN_MEM;
+ end = ~0U;
+ }
+
+ do {
+ if (allocate_resource(root, res, size, start, end, align,
+ NULL, NULL)==0) {
+ return 1;
+ }
+ size = size/2;
+ align = size;
+ } while (size >= min);
+
+ return 0;
+}
+
+
+static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
+ u32 min)
+{
+ int i;
+ for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
+ struct resource * root = socket->dev->bus->resource[i];
+ if (!root)
+ continue;
+
+ if ((res->flags ^ root->flags) &
+ (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH))
+ continue; /* Wrong type */
+
+ if (yenta_search_one_res(root, res, min))
+ return 1;
+ }
+ return 0;
+}
+
+static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
{
struct pci_bus *bus;
struct resource *root, *res;
u32 start, end;
- u32 align, size, min;
- unsigned offset;
unsigned mask;
res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
/* Already allocated? */
if (res->parent)
- return 0;
+ return;
/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
mask = ~0xfff;
if (type & IORESOURCE_IO)
mask = ~3;
- offset = 0x1c + 8*nr;
bus = socket->dev->subordinate;
res->name = bus->name;
res->flags = type;
- res->start = 0;
- res->end = 0;
- root = pci_find_parent_resource(socket->dev, res);
- if (!root)
- return;
-
- start = config_readl(socket, offset) & mask;
- end = config_readl(socket, offset+4) | ~mask;
+ start = config_readl(socket, addr_start) & mask;
+ end = config_readl(socket, addr_end) | ~mask;
if (start && end > start && !override_bios) {
res->start = start;
res->end = end;
- if (request_resource(root, res) == 0)
+ root = pci_find_parent_resource(socket->dev, res);
+ if (root && (request_resource(root, res) == 0))
return;
- printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n",
+ printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
pci_name(socket->dev), nr);
- res->start = res->end = 0;
}
if (type & IORESOURCE_IO) {
- align = 1024;
- size = BRIDGE_IO_MAX;
- min = BRIDGE_IO_MIN;
- start = PCIBIOS_MIN_CARDBUS_IO;
- end = ~0U;
+ if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) ||
+ (yenta_search_res(socket, res, BRIDGE_IO_ACC)) ||
+ (yenta_search_res(socket, res, BRIDGE_IO_MIN))) {
+ config_writel(socket, addr_start, res->start);
+ config_writel(socket, addr_end, res->end);
+ }
} else {
- unsigned long avail = root->end - root->start;
- int i;
- size = BRIDGE_MEM_MAX;
- if (size > avail/8) {
- size=(avail+1)/8;
- /* round size down to next power of 2 */
- i = 0;
- while ((size /= 2) != 0)
- i++;
- size = 1 << i;
+ if (type & IORESOURCE_PREFETCH) {
+ if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
+ (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
+ (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
+ config_writel(socket, addr_start, res->start);
+ config_writel(socket, addr_end, res->end);
+ }
+ /* Approximating prefetchable by non-prefetchable */
+ res->flags = IORESOURCE_MEM;
}
- if (size < BRIDGE_MEM_MIN)
- size = BRIDGE_MEM_MIN;
- min = BRIDGE_MEM_MIN;
- align = size;
- start = PCIBIOS_MIN_MEM;
- end = ~0U;
- }
-
- do {
- if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) {
- config_writel(socket, offset, res->start);
- config_writel(socket, offset+4, res->end);
- return;
+ if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
+ (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
+ (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
+ config_writel(socket, addr_start, res->start);
+ config_writel(socket, addr_end, res->end);
}
- size = size/2;
- align = size;
- } while (size >= min);
+ }
+
printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
- pci_name(socket->dev), type);
- res->start = res->end = 0;
+ pci_name(socket->dev), type);
+ res->start = res->end = res->flags = 0;
}
/*
@@ -627,10 +672,14 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
*/
static void yenta_allocate_resources(struct yenta_socket *socket)
{
- yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
- yenta_allocate_res(socket, 1, IORESOURCE_MEM);
- yenta_allocate_res(socket, 2, IORESOURCE_IO);
- yenta_allocate_res(socket, 3, IORESOURCE_IO); /* PCI isn't clever enough to use this one yet */
+ yenta_allocate_res(socket, 0, IORESOURCE_IO,
+ PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
+ yenta_allocate_res(socket, 1, IORESOURCE_IO,
+ PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
+ yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
+ PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
+ yenta_allocate_res(socket, 3, IORESOURCE_MEM,
+ PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
}
@@ -869,14 +918,11 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
*/
static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
{
- socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
- socket->socket.map_size = 0x1000;
socket->socket.pci_irq = socket->cb_irq;
if (isa_probe)
socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
else
socket->socket.irq_mask = 0;
- socket->socket.cb_dev = socket->dev;
printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
socket->socket.irq_mask, socket->cb_irq);
@@ -942,6 +988,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
socket->socket.dev.dev = &dev->dev;
socket->socket.driver_data = socket;
socket->socket.owner = THIS_MODULE;
+ socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
+ socket->socket.map_size = 0x1000;
+ socket->socket.cb_dev = dev;
/* prepare struct yenta_socket */
socket->dev = dev;
@@ -1012,6 +1061,10 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
socket->poll_timer.data = (unsigned long)socket;
socket->poll_timer.expires = jiffies + HZ;
add_timer(&socket->poll_timer);
+ printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n"
+ KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
+ } else {
+ socket->socket.features |= SS_CAP_CARDBUS;
}
/* Figure out what the dang thing can do for the PCMCIA layer... */
@@ -1052,6 +1105,7 @@ static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state)
pci_save_state(dev);
pci_read_config_dword(dev, 16*4, &socket->saved_state[0]);
pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
+ pci_disable_device(dev);
/*
* Some laptops (IBM T22) do not like us putting the Cardbus
@@ -1075,6 +1129,8 @@ static int yenta_dev_resume (struct pci_dev *dev)
pci_restore_state(dev);
pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
+ pci_enable_device(dev);
+ pci_set_master(dev);
if (socket->type && socket->type->restore_state)
socket->type->restore_state(socket);
OpenPOWER on IntegriCloud