aboutsummaryrefslogtreecommitdiff
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/Kconfig3
-rw-r--r--drivers/pcmcia/Makefile20
-rw-r--r--drivers/pcmcia/au1000_generic.c2
-rw-r--r--drivers/pcmcia/au1000_generic.h2
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c1
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c1
-rw-r--r--drivers/pcmcia/cardbus.c2
-rw-r--r--drivers/pcmcia/cistpl.c297
-rw-r--r--drivers/pcmcia/cs.c78
-rw-r--r--drivers/pcmcia/cs_internal.h226
-rw-r--r--drivers/pcmcia/ds.c262
-rw-r--r--drivers/pcmcia/ds_internal.h23
-rw-r--r--drivers/pcmcia/hd64465_ss.c1
-rw-r--r--drivers/pcmcia/i82365.c2
-rw-r--r--drivers/pcmcia/m32r_cfc.c4
-rw-r--r--drivers/pcmcia/m32r_pcc.c4
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c4
-rw-r--r--drivers/pcmcia/o2micro.h10
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c120
-rw-r--r--drivers/pcmcia/pcmcia_resource.c381
-rw-r--r--drivers/pcmcia/pxa2xx_base.c45
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x255.c154
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x270.c14
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x2xx.c49
-rw-r--r--drivers/pcmcia/pxa2xx_palmld.c151
-rw-r--r--drivers/pcmcia/pxa2xx_trizeps4.c256
-rw-r--r--drivers/pcmcia/pxa2xx_viper.c179
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c67
-rw-r--r--drivers/pcmcia/soc_common.c8
-rw-r--r--drivers/pcmcia/soc_common.h3
-rw-r--r--drivers/pcmcia/socket_sysfs.c13
-rw-r--r--drivers/pcmcia/tcic.c2
-rw-r--r--drivers/pcmcia/ti113x.h78
-rw-r--r--drivers/pcmcia/yenta_socket.c86
34 files changed, 1787 insertions, 761 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index e0f884034c9..f57eeae3830 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -220,7 +220,8 @@ config PCMCIA_PXA2XX
tristate "PXA2xx support"
depends on ARM && ARCH_PXA && PCMCIA
depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
- || MACH_ARMCORE || ARCH_PXA_PALM)
+ || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
+ || ARCH_VIPER)
help
Say Y here to include support for the PXA2xx PCMCIA controller
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 269a9e913ba..74d1c906c5d 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -2,10 +2,6 @@
# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
#
-ifeq ($(CONFIG_PCMCIA_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
-
pcmcia_core-y += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
obj-$(CONFIG_PCCARD) += pcmcia_core.o
@@ -29,7 +25,6 @@ obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
-obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o pxa2xx_cs.o
obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
@@ -68,9 +63,14 @@ sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
-pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o
-pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
-pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
-pxa2xx_cs-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x270.o
-pxa2xx_cs-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
+pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o
+pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o
+pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
+pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
+pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
+pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o
+pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o
+pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
+pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
+obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y)
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 75e8f8505e4..fc1de46fd20 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -292,7 +292,7 @@ au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
skt->spd_io[map->map] = speed;
}
- map->start=(ioaddr_t)(u32)skt->virt_io;
+ map->start=(unsigned int)(u32)skt->virt_io;
map->stop=map->start+MAP_SIZE;
return 0;
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
index a53ef590251..13a4fbc5871 100644
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -116,7 +116,7 @@ struct au1000_pcmcia_socket {
struct resource res_attr;
void * virt_io;
- ioaddr_t phys_io;
+ unsigned int phys_io;
unsigned int phys_attr;
unsigned int phys_mem;
unsigned short speed_io, speed_attr, speed_mem;
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index aa1cd4d3aa2..d6b4bd1db7d 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -37,7 +37,6 @@
#include <pcmcia/ss.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/bus_ops.h>
-#include "cs_internal.h"
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 8a9b18cee84..9627390835c 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -41,7 +41,6 @@
#include <pcmcia/ss.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/bus_ops.h>
-#include "cs_internal.h"
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 911ca0e8dfc..db77e1f3309 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -238,7 +238,7 @@ int __ref cb_alloc(struct pcmcia_socket * s)
pci_bus_add_devices(bus);
s->irq.AssignedIRQ = s->pci_irq;
- return CS_SUCCESS;
+ return 0;
}
void cb_free(struct pcmcia_socket * s)
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 65129b54eb0..dcce9f5d846 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -92,7 +92,8 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag
if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s);
if (mem->res == NULL) {
- printk(KERN_NOTICE "cs: unable to map card memory!\n");
+ dev_printk(KERN_NOTICE, &s->dev,
+ "cs: unable to map card memory!\n");
return NULL;
}
s->cis_virt = NULL;
@@ -265,13 +266,13 @@ EXPORT_SYMBOL(pcmcia_write_cis_mem);
======================================================================*/
static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
- u_int len, void *ptr)
+ size_t len, void *ptr)
{
struct cis_cache_entry *cis;
int ret;
if (s->fake_cis) {
- if (s->fake_cis_len > addr+len)
+ if (s->fake_cis_len >= addr+len)
memcpy(ptr, s->fake_cis+addr, len);
else
memset(ptr, 0xff, len);
@@ -351,7 +352,9 @@ int verify_cis_cache(struct pcmcia_socket *s)
buf = kmalloc(256, GFP_KERNEL);
if (buf == NULL)
- return -1;
+ dev_printk(KERN_WARNING, &s->dev,
+ "no memory for verifying CIS\n");
+ return -ENOMEM;
list_for_each_entry(cis, &s->cis_cache, node) {
int len = cis->len;
@@ -380,18 +383,22 @@ int verify_cis_cache(struct pcmcia_socket *s)
======================================================================*/
-int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
+int pcmcia_replace_cis(struct pcmcia_socket *s,
+ const u8 *data, const size_t len)
{
- kfree(s->fake_cis);
- s->fake_cis = NULL;
- if (cis->Length > CISTPL_MAX_CIS_SIZE)
- return CS_BAD_SIZE;
- s->fake_cis = kmalloc(cis->Length, GFP_KERNEL);
- if (s->fake_cis == NULL)
- return CS_OUT_OF_RESOURCE;
- s->fake_cis_len = cis->Length;
- memcpy(s->fake_cis, cis->Data, cis->Length);
- return CS_SUCCESS;
+ if (len > CISTPL_MAX_CIS_SIZE) {
+ dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n");
+ return -EINVAL;
+ }
+ kfree(s->fake_cis);
+ s->fake_cis = kmalloc(len, GFP_KERNEL);
+ if (s->fake_cis == NULL) {
+ dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n");
+ return -ENOMEM;
+ }
+ s->fake_cis_len = len;
+ memcpy(s->fake_cis, data, len);
+ return 0;
}
EXPORT_SYMBOL(pcmcia_replace_cis);
@@ -418,9 +425,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *t
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
{
if (!s)
- return CS_BAD_HANDLE;
+ return -EINVAL;
if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
+ return -ENODEV;
tuple->TupleLink = tuple->Flags = 0;
#ifdef CONFIG_CARDBUS
if (s->state & SOCKET_CARDBUS) {
@@ -440,10 +447,10 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple
!(tuple->Attributes & TUPLE_RETURN_COMMON)) {
cisdata_t req = tuple->DesiredTuple;
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
- if (pccard_get_next_tuple(s, function, tuple) == CS_SUCCESS) {
+ if (pccard_get_next_tuple(s, function, tuple) == 0) {
tuple->DesiredTuple = CISTPL_LINKTARGET;
- if (pccard_get_next_tuple(s, function, tuple) != CS_SUCCESS)
- return CS_NO_MORE_ITEMS;
+ if (pccard_get_next_tuple(s, function, tuple) != 0)
+ return -ENOSPC;
} else
tuple->CISOffset = tuple->TupleLink = 0;
tuple->DesiredTuple = req;
@@ -498,9 +505,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
int ofs, i, attr;
if (!s)
- return CS_BAD_HANDLE;
+ return -EINVAL;
if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
+ return -ENODEV;
link[1] = tuple->TupleLink;
ofs = tuple->CISOffset + tuple->TupleLink;
@@ -519,7 +526,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
/* End of chain? Follow long link if possible */
if (link[0] == CISTPL_END) {
if ((ofs = follow_link(s, tuple)) < 0)
- return CS_NO_MORE_ITEMS;
+ return -ENOSPC;
attr = SPACE(tuple->Flags);
read_cis_cache(s, attr, ofs, 2, link);
}
@@ -577,13 +584,13 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
}
if (i == MAX_TUPLES) {
cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
- return CS_NO_MORE_ITEMS;
+ return -ENOSPC;
}
tuple->TupleCode = link[0];
tuple->TupleLink = link[1];
tuple->CISOffset = ofs + 2;
- return CS_SUCCESS;
+ return 0;
}
EXPORT_SYMBOL(pccard_get_next_tuple);
@@ -596,18 +603,18 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
u_int len;
if (!s)
- return CS_BAD_HANDLE;
+ return -EINVAL;
if (tuple->TupleLink < tuple->TupleOffset)
- return CS_NO_MORE_ITEMS;
+ return -ENOSPC;
len = tuple->TupleLink - tuple->TupleOffset;
tuple->TupleDataLen = tuple->TupleLink;
if (len == 0)
- return CS_SUCCESS;
+ return 0;
read_cis_cache(s, SPACE(tuple->Flags),
tuple->CISOffset + tuple->TupleOffset,
_MIN(len, tuple->TupleDataMax), tuple->TupleData);
- return CS_SUCCESS;
+ return 0;
}
EXPORT_SYMBOL(pccard_get_tuple_data);
@@ -640,25 +647,31 @@ static int parse_device(tuple_t *tuple, cistpl_device_t *device)
case 3: device->dev[i].speed = 150; break;
case 4: device->dev[i].speed = 100; break;
case 7:
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
device->dev[i].speed = SPEED_CVT(*p);
while (*p & 0x80)
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
break;
default:
- return CS_BAD_TUPLE;
+ return -EINVAL;
}
- if (++p == q) return CS_BAD_TUPLE;
- if (*p == 0xff) break;
+ if (++p == q)
+ return -EINVAL;
+ if (*p == 0xff)
+ break;
scale = *p & 7;
- if (scale == 7) return CS_BAD_TUPLE;
+ if (scale == 7)
+ return -EINVAL;
device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
device->ndev++;
- if (++p == q) break;
+ if (++p == q)
+ break;
}
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -667,12 +680,12 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
{
u_char *p;
if (tuple->TupleDataLen < 5)
- return CS_BAD_TUPLE;
+ return -EINVAL;
p = (u_char *) tuple->TupleData;
csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
csum->len = get_unaligned_le16(p + 2);
csum->sum = *(p + 4);
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -680,9 +693,9 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
{
if (tuple->TupleDataLen < 4)
- return CS_BAD_TUPLE;
+ return -EINVAL;
link->addr = get_unaligned_le32(tuple->TupleData);
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -697,13 +710,13 @@ static int parse_longlink_mfc(tuple_t *tuple,
link->nfn = *p; p++;
if (tuple->TupleDataLen <= link->nfn*5)
- return CS_BAD_TUPLE;
+ return -EINVAL;
for (i = 0; i < link->nfn; i++) {
link->fn[i].space = *p; p++;
link->fn[i].addr = get_unaligned_le32(p);
p += 4;
}
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -713,24 +726,27 @@ static int parse_strings(u_char *p, u_char *q, int max,
{
int i, j, ns;
- if (p == q) return CS_BAD_TUPLE;
+ if (p == q)
+ return -EINVAL;
ns = 0; j = 0;
for (i = 0; i < max; i++) {
- if (*p == 0xff) break;
+ if (*p == 0xff)
+ break;
ofs[i] = j;
ns++;
for (;;) {
s[j++] = (*p == 0xff) ? '\0' : *p;
if ((*p == '\0') || (*p == 0xff)) break;
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
}
if ((*p == 0xff) || (++p == q)) break;
}
if (found) {
*found = ns;
- return CS_SUCCESS;
+ return 0;
} else {
- return (ns == max) ? CS_SUCCESS : CS_BAD_TUPLE;
+ return (ns == max) ? 0 : -EINVAL;
}
}
@@ -745,7 +761,8 @@ static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
vers_1->major = *p; p++;
vers_1->minor = *p; p++;
- if (p >= q) return CS_BAD_TUPLE;
+ if (p >= q)
+ return -EINVAL;
return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
vers_1->str, vers_1->ofs, &vers_1->ns);
@@ -781,7 +798,7 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
p += 2;
}
jedec->nid = nid;
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -789,10 +806,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
{
if (tuple->TupleDataLen < 4)
- return CS_BAD_TUPLE;
+ return -EINVAL;
m->manf = get_unaligned_le16(tuple->TupleData);
m->card = get_unaligned_le16(tuple->TupleData + 2);
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -801,11 +818,11 @@ static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f)
{
u_char *p;
if (tuple->TupleDataLen < 2)
- return CS_BAD_TUPLE;
+ return -EINVAL;
p = (u_char *)tuple->TupleData;
f->func = p[0];
f->sysinit = p[1];
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -815,12 +832,12 @@ static int parse_funce(tuple_t *tuple, cistpl_funce_t *f)
u_char *p;
int i;
if (tuple->TupleDataLen < 1)
- return CS_BAD_TUPLE;
+ return -EINVAL;
p = (u_char *)tuple->TupleData;
f->type = p[0];
for (i = 1; i < tuple->TupleDataLen; i++)
f->data[i-1] = p[i];
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -834,7 +851,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config)
rasz = *p & 0x03;
rmsz = (*p & 0x3c) >> 2;
if (tuple->TupleDataLen < rasz+rmsz+4)
- return CS_BAD_TUPLE;
+ return -EINVAL;
config->last_idx = *(++p);
p++;
config->base = 0;
@@ -846,7 +863,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config)
for (i = 0; i <= rmsz; i++)
config->rmask[i>>2] += p[i] << (8*(i%4));
config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
- return CS_SUCCESS;
+ return 0;
}
/*======================================================================
@@ -1002,10 +1019,12 @@ static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem)
static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq)
{
- if (p == q) return NULL;
+ if (p == q)
+ return NULL;
irq->IRQInfo1 = *p; p++;
if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
- if (p+2 > q) return NULL;
+ if (p+2 > q)
+ return NULL;
irq->IRQInfo2 = (p[1]<<8) + p[0];
p += 2;
}
@@ -1026,7 +1045,8 @@ static int parse_cftable_entry(tuple_t *tuple,
if (*p & 0x40)
entry->flags |= CISTPL_CFTABLE_DEFAULT;
if (*p & 0x80) {
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
if (*p & 0x10)
entry->flags |= CISTPL_CFTABLE_BVDS;
if (*p & 0x20)
@@ -1040,30 +1060,35 @@ static int parse_cftable_entry(tuple_t *tuple,
entry->interface = 0;
/* Process optional features */
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
features = *p; p++;
/* Power options */
if ((features & 3) > 0) {
p = parse_power(p, q, &entry->vcc);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else
entry->vcc.present = 0;
if ((features & 3) > 1) {
p = parse_power(p, q, &entry->vpp1);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else
entry->vpp1.present = 0;
if ((features & 3) > 2) {
p = parse_power(p, q, &entry->vpp2);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else
entry->vpp2.present = 0;
/* Timing options */
if (features & 0x04) {
p = parse_timing(p, q, &entry->timing);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else {
entry->timing.wait = 0;
entry->timing.ready = 0;
@@ -1073,14 +1098,16 @@ static int parse_cftable_entry(tuple_t *tuple,
/* I/O window options */
if (features & 0x08) {
p = parse_io(p, q, &entry->io);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else
entry->io.nwin = 0;
/* Interrupt options */
if (features & 0x10) {
p = parse_irq(p, q, &entry->irq);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else
entry->irq.IRQInfo1 = 0;
@@ -1094,7 +1121,8 @@ static int parse_cftable_entry(tuple_t *tuple,
entry->mem.win[0].card_addr = 0;
entry->mem.win[0].host_addr = 0;
p += 2;
- if (p > q) return CS_BAD_TUPLE;
+ if (p > q)
+ return -EINVAL;
break;
case 0x40:
entry->mem.nwin = 1;
@@ -1102,26 +1130,30 @@ static int parse_cftable_entry(tuple_t *tuple,
entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
entry->mem.win[0].host_addr = 0;
p += 4;
- if (p > q) return CS_BAD_TUPLE;
+ if (p > q)
+ return -EINVAL;
break;
case 0x60:
p = parse_mem(p, q, &entry->mem);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
break;
}
/* Misc features */
if (features & 0x80) {
- if (p == q) return CS_BAD_TUPLE;
+ if (p == q)
+ return -EINVAL;
entry->flags |= (*p << 8);
while (*p & 0x80)
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
p++;
}
entry->subtuples = q-p;
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -1132,12 +1164,12 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
{
u_char *p;
if (tuple->TupleDataLen < 6)
- return CS_BAD_TUPLE;
+ return -EINVAL;
p = (u_char *)tuple->TupleData;
bar->attr = *p;
p += 2;
bar->size = get_unaligned_le32(p);
- return CS_SUCCESS;
+ return 0;
}
static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
@@ -1146,12 +1178,12 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
p = (u_char *)tuple->TupleData;
if ((*p != 3) || (tuple->TupleDataLen < 6))
- return CS_BAD_TUPLE;
+ return -EINVAL;
config->last_idx = *(++p);
p++;
config->base = get_unaligned_le32(p);
config->subtuples = tuple->TupleDataLen - 6;
- return CS_SUCCESS;
+ return 0;
}
static int parse_cftable_entry_cb(tuple_t *tuple,
@@ -1167,29 +1199,34 @@ static int parse_cftable_entry_cb(tuple_t *tuple,
entry->flags |= CISTPL_CFTABLE_DEFAULT;
/* Process optional features */
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
features = *p; p++;
/* Power options */
if ((features & 3) > 0) {
p = parse_power(p, q, &entry->vcc);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else
entry->vcc.present = 0;
if ((features & 3) > 1) {
p = parse_power(p, q, &entry->vpp1);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else
entry->vpp1.present = 0;
if ((features & 3) > 2) {
p = parse_power(p, q, &entry->vpp2);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else
entry->vpp2.present = 0;
/* I/O window options */
if (features & 0x08) {
- if (p == q) return CS_BAD_TUPLE;
+ if (p == q)
+ return -EINVAL;
entry->io = *p; p++;
} else
entry->io = 0;
@@ -1197,32 +1234,37 @@ static int parse_cftable_entry_cb(tuple_t *tuple,
/* Interrupt options */
if (features & 0x10) {
p = parse_irq(p, q, &entry->irq);
- if (p == NULL) return CS_BAD_TUPLE;
+ if (p == NULL)
+ return -EINVAL;
} else
entry->irq.IRQInfo1 = 0;
if (features & 0x20) {
- if (p == q) return CS_BAD_TUPLE;
+ if (p == q)
+ return -EINVAL;
entry->mem = *p; p++;
} else
entry->mem = 0;
/* Misc features */
if (features & 0x80) {
- if (p == q) return CS_BAD_TUPLE;
+ if (p == q)
+ return -EINVAL;
entry->flags |= (*p << 8);
if (*p & 0x80) {
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
entry->flags |= (*p << 16);
}
while (*p & 0x80)
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
p++;
}
entry->subtuples = q-p;
- return CS_SUCCESS;
+ return 0;
}
#endif
@@ -1248,7 +1290,7 @@ static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo)
p += 6;
}
geo->ngeo = n;
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -1258,7 +1300,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
u_char *p, *q;
if (tuple->TupleDataLen < 10)
- return CS_BAD_TUPLE;
+ return -EINVAL;
p = tuple->TupleData;
q = p + tuple->TupleDataLen;
@@ -1282,15 +1324,18 @@ static int parse_org(tuple_t *tuple, cistpl_org_t *org)
p = tuple->TupleData;
q = p + tuple->TupleDataLen;
- if (p == q) return CS_BAD_TUPLE;
+ if (p == q)
+ return -EINVAL;
org->data_org = *p;
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
for (i = 0; i < 30; i++) {
org->desc[i] = *p;
if (*p == '\0') break;
- if (++p == q) return CS_BAD_TUPLE;
+ if (++p == q)
+ return -EINVAL;
}
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
@@ -1300,7 +1345,7 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
u_char *p;
if (tuple->TupleDataLen < 10)
- return CS_BAD_TUPLE;
+ return -EINVAL;
p = tuple->TupleData;
@@ -1309,17 +1354,17 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
fmt->offset = get_unaligned_le32(p + 2);
fmt->length = get_unaligned_le32(p + 6);
- return CS_SUCCESS;
+ return 0;
}
/*====================================================================*/
-int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse)
+int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
{
- int ret = CS_SUCCESS;
+ int ret = 0;
if (tuple->TupleDataLen > tuple->TupleDataMax)
- return CS_BAD_TUPLE;
+ return -EINVAL;
switch (tuple->TupleCode) {
case CISTPL_DEVICE:
case CISTPL_DEVICE_A:
@@ -1387,15 +1432,17 @@ int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse)
break;
case CISTPL_NO_LINK:
case CISTPL_LINKTARGET:
- ret = CS_SUCCESS;
+ ret = 0;
break;
default:
- ret = CS_UNSUPPORTED_FUNCTION;
+ ret = -EINVAL;
break;
}
+ if (ret)
+ __cs_dbg(0, "parse_tuple failed %d\n", ret);
return ret;
}
-EXPORT_SYMBOL(pccard_parse_tuple);
+EXPORT_SYMBOL(pcmcia_parse_tuple);
/*======================================================================
@@ -1410,18 +1457,22 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
int ret;
buf = kmalloc(256, GFP_KERNEL);
- if (buf == NULL)
- return CS_OUT_OF_RESOURCE;
+ if (buf == NULL) {
+ dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
+ return -ENOMEM;
+ }
tuple.DesiredTuple = code;
tuple.Attributes = TUPLE_RETURN_COMMON;
ret = pccard_get_first_tuple(s, function, &tuple);
- if (ret != CS_SUCCESS) goto done;
+ if (ret != 0)
+ goto done;
tuple.TupleData = buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
ret = pccard_get_tuple_data(s, &tuple);
- if (ret != CS_SUCCESS) goto done;
- ret = pccard_parse_tuple(&tuple, parse);
+ if (ret != 0)
+ goto done;
+ ret = pcmcia_parse_tuple(&tuple, parse);
done:
kfree(buf);
return ret;
@@ -1446,37 +1497,40 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
int ret, reserved, dev_ok = 0, ident_ok = 0;
if (!s)
- return CS_BAD_HANDLE;
+ return -EINVAL;
tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
- if (tuple == NULL)
- return CS_OUT_OF_RESOURCE;
+ if (tuple == NULL) {
+ dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
+ return -ENOMEM;
+ }
p = kmalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL) {
- kfree(tuple);
- return CS_OUT_OF_RESOURCE;
+ kfree(tuple);
+ dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
+ return -ENOMEM;
}
count = reserved = 0;
tuple->DesiredTuple = RETURN_FIRST_TUPLE;
tuple->Attributes = TUPLE_RETURN_COMMON;
ret = pccard_get_first_tuple(s, function, tuple);
- if (ret != CS_SUCCESS)
+ if (ret != 0)
goto done;
/* First tuple should be DEVICE; we should really have either that
or a CFTABLE_ENTRY of some sort */
if ((tuple->TupleCode == CISTPL_DEVICE) ||
- (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) ||
- (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS))
+ (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == 0) ||
+ (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
dev_ok++;
/* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
tuple, for card identification. Certain old D-Link and Linksys
cards have only a broken VERS_2 tuple; hence the bogus test. */
- if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == CS_SUCCESS) ||
- (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == CS_SUCCESS) ||
- (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
+ if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) ||
+ (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) ||
+ (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC))
ident_ok++;
if (!dev_ok && !ident_ok)
@@ -1484,7 +1538,8 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
for (count = 1; count < MAX_TUPLES; count++) {
ret = pccard_get_next_tuple(s, function, tuple);
- if (ret != CS_SUCCESS) break;
+ if (ret != 0)
+ break;
if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
@@ -1499,6 +1554,6 @@ done:
*info = count;
kfree(tuple);
kfree(p);
- return CS_SUCCESS;
+ return 0;
}
EXPORT_SYMBOL(pccard_validate_cis);
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index d1207393fc3..c68c5d33828 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -61,7 +61,7 @@ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
/* Access speed for attribute memory windows */
INT_MODULE_PARM(cis_speed, 300); /* ns */
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug;
module_param(pc_debug, int, 0644);
@@ -247,7 +247,8 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
wait_for_completion(&socket->thread_done);
if (!socket->thread) {
- printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket);
+ dev_printk(KERN_WARNING, &socket->dev,
+ "PCMCIA: warning: socket thread did not start\n");
return -EIO;
}
@@ -366,16 +367,16 @@ static int socket_reset(struct pcmcia_socket *skt)
skt->ops->get_status(skt, &status);
if (!(status & SS_DETECT))
- return CS_NO_CARD;
+ return -ENODEV;
if (status & SS_READY)
- return CS_SUCCESS;
+ return 0;
msleep(unreset_check * 10);
}
cs_err(skt, "time out after reset.\n");
- return CS_GENERAL_FAILURE;
+ return -ETIMEDOUT;
}
/*
@@ -412,7 +413,8 @@ static void socket_shutdown(struct pcmcia_socket *s)
s->ops->get_status(s, &status);
if (status & SS_POWERON) {
- printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
+ dev_printk(KERN_ERR, &s->dev,
+ "*** DANGER *** unable to remove socket power\n");
}
cs_socket_put(s);
@@ -426,14 +428,14 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
skt->ops->get_status(skt, &status);
if (!(status & SS_DETECT))
- return CS_NO_CARD;
+ return -ENODEV;
msleep(initial_delay * 10);
for (i = 0; i < 100; i++) {
skt->ops->get_status(skt, &status);
if (!(status & SS_DETECT))
- return CS_NO_CARD;
+ return -ENODEV;
if (!(status & SS_PENDING))
break;
@@ -443,13 +445,13 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
if (status & SS_PENDING) {
cs_err(skt, "voltage interrogation timed out.\n");
- return CS_GENERAL_FAILURE;
+ return -ETIMEDOUT;
}
if (status & SS_CARDBUS) {
if (!(skt->features & SS_CAP_CARDBUS)) {
cs_err(skt, "cardbus cards are not supported.\n");
- return CS_BAD_TYPE;
+ return -EINVAL;
}
skt->state |= SOCKET_CARDBUS;
}
@@ -463,7 +465,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
skt->socket.Vcc = skt->socket.Vpp = 50;
else {
cs_err(skt, "unsupported voltage key.\n");
- return CS_BAD_TYPE;
+ return -EIO;
}
if (skt->power_hook)
@@ -480,7 +482,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
skt->ops->get_status(skt, &status);
if (!(status & SS_POWERON)) {
cs_err(skt, "unable to apply power.\n");
- return CS_BAD_TYPE;
+ return -EIO;
}
status = socket_reset(skt);
@@ -502,15 +504,16 @@ static int socket_insert(struct pcmcia_socket *skt)
cs_dbg(skt, 4, "insert\n");
if (!cs_socket_get(skt))
- return CS_NO_CARD;
+ return -ENODEV;
ret = socket_setup(skt, setup_delay);
- if (ret == CS_SUCCESS) {
+ if (ret == 0) {
skt->state |= SOCKET_PRESENT;
- printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n",
- (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
- skt->sock);
+ dev_printk(KERN_NOTICE, &skt->dev,
+ "pccard: %s card inserted into slot %d\n",
+ (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
+ skt->sock);
#ifdef CONFIG_CARDBUS
if (skt->state & SOCKET_CARDBUS) {
@@ -531,7 +534,7 @@ static int socket_insert(struct pcmcia_socket *skt)
static int socket_suspend(struct pcmcia_socket *skt)
{
if (skt->state & SOCKET_SUSPEND)
- return CS_IN_USE;
+ return -EBUSY;
send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
skt->socket = dead_socket;
@@ -540,7 +543,7 @@ static int socket_suspend(struct pcmcia_socket *skt)
skt->ops->suspend(skt);
skt->state |= SOCKET_SUSPEND;
- return CS_SUCCESS;
+ return 0;
}
/*
@@ -553,7 +556,7 @@ static int socket_resume(struct pcmcia_socket *skt)
int ret;
if (!(skt->state & SOCKET_SUSPEND))
- return CS_IN_USE;
+ return -EBUSY;
skt->socket = dead_socket;
skt->ops->init(skt);
@@ -565,7 +568,7 @@ static int socket_resume(struct pcmcia_socket *skt)
}
ret = socket_setup(skt, resume_delay);
- if (ret == CS_SUCCESS) {
+ if (ret == 0) {
/*
* FIXME: need a better check here for cardbus cards.
*/
@@ -590,12 +593,13 @@ static int socket_resume(struct pcmcia_socket *skt)
skt->state &= ~SOCKET_SUSPEND;
- return CS_SUCCESS;
+ return 0;
}
static void socket_remove(struct pcmcia_socket *skt)
{
- printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
+ dev_printk(KERN_NOTICE, &skt->dev,
+ "pccard: card ejected from slot %d\n", skt->sock);
socket_shutdown(skt);
}
@@ -641,8 +645,8 @@ static int pccardd(void *__skt)
/* register with the device core */
ret = device_register(&skt->dev);
if (ret) {
- printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
- skt);
+ dev_printk(KERN_WARNING, &skt->dev,
+ "PCMCIA: unable to register socket\n");
skt->thread = NULL;
complete(&skt->thread_done);
return 0;
@@ -748,7 +752,7 @@ EXPORT_SYMBOL(pccard_register_pcmcia);
* CIS register.
*/
-int pccard_reset_card(struct pcmcia_socket *skt)
+int pcmcia_reset_card(struct pcmcia_socket *skt)
{
int ret;
@@ -757,15 +761,15 @@ int pccard_reset_card(struct pcmcia_socket *skt)
mutex_lock(&skt->skt_mutex);
do {
if (!(skt->state & SOCKET_PRESENT)) {
- ret = CS_NO_CARD;
+ ret = -ENODEV;
break;
}
if (skt->state & SOCKET_SUSPEND) {
- ret = CS_IN_USE;
+ ret = -EBUSY;
break;
}
if (skt->state & SOCKET_CARDBUS) {
- ret = CS_UNSUPPORTED_FUNCTION;
+ ret = -EPERM;
break;
}
@@ -774,20 +778,20 @@ int pccard_reset_card(struct pcmcia_socket *skt)
send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
if (skt->callback)
skt->callback->suspend(skt);
- if (socket_reset(skt) == CS_SUCCESS) {
+ if (socket_reset(skt) == 0) {
send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
if (skt->callback)
skt->callback->resume(skt);
}
}
- ret = CS_SUCCESS;
+ ret = 0;
} while (0);
mutex_unlock(&skt->skt_mutex);
return ret;
} /* reset_card */
-EXPORT_SYMBOL(pccard_reset_card);
+EXPORT_SYMBOL(pcmcia_reset_card);
/* These shut down or wake up a socket. They are sort of user
@@ -802,11 +806,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
mutex_lock(&skt->skt_mutex);
do {
if (!(skt->state & SOCKET_PRESENT)) {
- ret = CS_NO_CARD;
+ ret = -ENODEV;
break;
}
if (skt->state & SOCKET_CARDBUS) {
- ret = CS_UNSUPPORTED_FUNCTION;
+ ret = -EPERM;
break;
}
if (skt->callback) {
@@ -832,11 +836,11 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
mutex_lock(&skt->skt_mutex);
do {
if (!(skt->state & SOCKET_PRESENT)) {
- ret = CS_NO_CARD;
+ ret = -ENODEV;
break;
}
if (skt->state & SOCKET_CARDBUS) {
- ret = CS_UNSUPPORTED_FUNCTION;
+ ret = -EPERM;
break;
}
ret = socket_resume(skt);
@@ -892,7 +896,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
ret = -EBUSY;
break;
}
- if (socket_insert(skt) == CS_NO_CARD) {
+ if (socket_insert(skt) == -ENODEV) {
ret = -ENODEV;
break;
}
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 63dc1a28bda..79615e6d540 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -1,5 +1,5 @@
/*
- * cs_internal.h
+ * cs_internal.h -- definitions internal to the PCMCIA core modules
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -10,6 +10,12 @@
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* (C) 1999 David A. Hinds
+ * (C) 2003 - 2008 Dominik Brodowski
+ *
+ *
+ * This file contains definitions _only_ needed by the PCMCIA core modules.
+ * It must not be included by PCMCIA socket drivers or by PCMCIA device
+ * drivers.
*/
#ifndef _LINUX_CS_INTERNAL_H
@@ -18,29 +24,24 @@
#include <linux/kref.h>
/* Flags in client state */
-#define CLIENT_CONFIG_LOCKED 0x0001
-#define CLIENT_IRQ_REQ 0x0002
-#define CLIENT_IO_REQ 0x0004
-#define CLIENT_UNBOUND 0x0008
-#define CLIENT_STALE 0x0010
#define CLIENT_WIN_REQ(i) (0x1<<(i))
-#define CLIENT_CARDBUS 0x8000
/* Each card function gets one of these guys */
typedef struct config_t {
struct kref ref;
- u_int state;
- u_int Attributes;
- u_int IntType;
- u_int ConfigBase;
- u_char Status, Pin, Copy, Option, ExtStatus;
- u_int CardValues;
- io_req_t io;
- struct {
- u_int Attributes;
- } irq;
+ unsigned int state;
+ unsigned int Attributes;
+ unsigned int IntType;
+ unsigned int ConfigBase;
+ unsigned char Status, Pin, Copy, Option, ExtStatus;
+ unsigned int CardValues;
+ io_req_t io;
+ struct {
+ u_int Attributes;
+ } irq;
} config_t;
+
struct cis_cache_entry {
struct list_head node;
unsigned int addr;
@@ -49,6 +50,30 @@ struct cis_cache_entry {
unsigned char cache[0];
};
+struct pccard_resource_ops {
+ int (*validate_mem) (struct pcmcia_socket *s);
+ int (*adjust_io_region) (struct resource *res,
+ unsigned long r_start,
+ unsigned long r_end,
+ struct pcmcia_socket *s);
+ struct resource* (*find_io) (unsigned long base, int num,
+ unsigned long align,
+ struct pcmcia_socket *s);
+ struct resource* (*find_mem) (unsigned long base, unsigned long num,
+ unsigned long align, int low,
+ struct pcmcia_socket *s);
+ int (*add_io) (struct pcmcia_socket *s,
+ unsigned int action,
+ unsigned long r_start,
+ unsigned long r_end);
+ int (*add_mem) (struct pcmcia_socket *s,
+ unsigned int action,
+ unsigned long r_start,
+ unsigned long r_end);
+ int (*init) (struct pcmcia_socket *s);
+ void (*exit) (struct pcmcia_socket *s);
+};
+
/* Flags in config state */
#define CONFIG_LOCKED 0x01
#define CONFIG_IRQ_REQ 0x02
@@ -59,7 +84,6 @@ struct cis_cache_entry {
#define SOCKET_INUSE 0x0010
#define SOCKET_SUSPEND 0x0080
#define SOCKET_WIN_REQ(i) (0x0100<<(i))
-#define SOCKET_REGION_INFO 0x4000
#define SOCKET_CARDBUS 0x8000
#define SOCKET_CARDBUS_CONFIG 0x10000
@@ -83,69 +107,153 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
}
}
-/* In cardbus.c */
-int cb_alloc(struct pcmcia_socket *s);
-void cb_free(struct pcmcia_socket *s);
-int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr);
+#ifdef CONFIG_PCMCIA_DEBUG
+extern int cs_debug_level(int);
-/* In cistpl.c */
-int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
- u_int addr, u_int len, void *ptr);
-void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
- u_int addr, u_int len, void *ptr);
-void release_cis_mem(struct pcmcia_socket *s);
-void destroy_cis_cache(struct pcmcia_socket *s);
+#define cs_dbg(skt, lvl, fmt, arg...) do { \
+ if (cs_debug_level(lvl)) \
+ dev_printk(KERN_DEBUG, &skt->dev, \
+ "cs: " fmt, ## arg); \
+} while (0)
+#define __cs_dbg(lvl, fmt, arg...) do { \
+ if (cs_debug_level(lvl)) \
+ printk(KERN_DEBUG \
+ "cs: " fmt, ## arg); \
+} while (0)
+
+#else
+#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
+#define __cs_dbg(lvl, fmt, arg...) do { } while (0)
+#endif
+
+#define cs_err(skt, fmt, arg...) \
+ dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg)
+
+
+/*
+ * Stuff internal to module "pcmcia_core":
+ */
+
+/* cistpl.c */
int verify_cis_cache(struct pcmcia_socket *s);
-int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);
-/* In rsrc_mgr */
-int pcmcia_validate_mem(struct pcmcia_socket *s);
-struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,
- struct pcmcia_socket *s);
-int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
- unsigned long r_end, struct pcmcia_socket *s);
-struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
- int low, struct pcmcia_socket *s);
+/* rsrc_mgr.c */
void release_resource_db(struct pcmcia_socket *s);
-/* In socket_sysfs.c */
+/* socket_sysfs.c */
extern int pccard_sysfs_add_socket(struct device *dev);
extern void pccard_sysfs_remove_socket(struct device *dev);
-/* In cs.c */
-extern struct rw_semaphore pcmcia_socket_list_rwsem;
-extern struct list_head pcmcia_socket_list;
-int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req);
-int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config);
-int pccard_reset_card(struct pcmcia_socket *skt);
+/* cardbus.c */
+int cb_alloc(struct pcmcia_socket *s);
+void cb_free(struct pcmcia_socket *s);
+int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
+ void *ptr);
+
+/*
+ * Stuff exported by module "pcmcia_core" to module "pcmcia"
+ */
+
struct pcmcia_callback{
struct module *owner;
- int (*event) (struct pcmcia_socket *s, event_t event, int priority);
+ int (*event) (struct pcmcia_socket *s,
+ event_t event, int priority);
void (*requery) (struct pcmcia_socket *s, int new_cis);
int (*suspend) (struct pcmcia_socket *s);
int (*resume) (struct pcmcia_socket *s);
};
+/* cs.c */
+extern struct rw_semaphore pcmcia_socket_list_rwsem;
+extern struct list_head pcmcia_socket_list;
+extern struct class pcmcia_socket_class;
+
+int pcmcia_get_window(struct pcmcia_socket *s,
+ window_handle_t *handle,
+ int idx,
+ win_req_t *req);
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
+struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
-#define cs_socket_name(skt) ((skt)->dev.bus_id)
+int pcmcia_suspend_card(struct pcmcia_socket *skt);
+int pcmcia_resume_card(struct pcmcia_socket *skt);
-#ifdef DEBUG
-extern int cs_debug_level(int);
+int pcmcia_eject_card(struct pcmcia_socket *skt);
+int pcmcia_insert_card(struct pcmcia_socket *skt);
-#define cs_dbg(skt, lvl, fmt, arg...) do { \
- if (cs_debug_level(lvl)) \
- printk(KERN_DEBUG "cs: %s: " fmt, \
- cs_socket_name(skt) , ## arg); \
-} while (0)
+struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt);
+void pcmcia_put_socket(struct pcmcia_socket *skt);
-#else
-#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
-#endif
+/* cistpl.c */
+int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
+ u_int addr, u_int len, void *ptr);
+void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
+ u_int addr, u_int len, void *ptr);
+void release_cis_mem(struct pcmcia_socket *s);
+void destroy_cis_cache(struct pcmcia_socket *s);
+int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
+ cisdata_t code, void *parse);
+int pcmcia_replace_cis(struct pcmcia_socket *s,
+ const u8 *data, const size_t len);
+int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function,
+ unsigned int *count);
-#define cs_err(skt, fmt, arg...) \
- printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg)
+/* rsrc_mgr.c */
+int pcmcia_validate_mem(struct pcmcia_socket *s);
+struct resource *pcmcia_find_io_region(unsigned long base,
+ int num,
+ unsigned long align,
+ struct pcmcia_socket *s);
+int pcmcia_adjust_io_region(struct resource *res,
+ unsigned long r_start,
+ unsigned long r_end,
+ struct pcmcia_socket *s);
+struct resource *pcmcia_find_mem_region(u_long base,
+ u_long num,
+ u_long align,
+ int low,
+ struct pcmcia_socket *s);
+
+/*
+ * Stuff internal to module "pcmcia".
+ */
+/* ds.c */
+extern struct bus_type pcmcia_bus_type;
+
+/* pcmcia_resource.c */
+extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
+
+#ifdef CONFIG_PCMCIA_IOCTL
+/* ds.c */
+extern spinlock_t pcmcia_dev_list_lock;
+
+extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev);
+extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
+
+struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
+ unsigned int function);
+
+/* pcmcia_ioctl.c */
+extern void __init pcmcia_setup_ioctl(void);
+extern void __exit pcmcia_cleanup_ioctl(void);
+extern void handle_event(struct pcmcia_socket *s, event_t event);
+extern int handle_request(struct pcmcia_socket *s, event_t event);
+
+#else /* CONFIG_PCMCIA_IOCTL */
+
+static inline void __init pcmcia_setup_ioctl(void) { return; }
+static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
+static inline void handle_event(struct pcmcia_socket *s, event_t event)
+{
+ return;
+}
+static inline int handle_request(struct pcmcia_socket *s, event_t event)
+{
+ return 0;
+}
+
+#endif /* CONFIG_PCMCIA_IOCTL */
#endif /* _LINUX_CS_INTERNAL_H */
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 4174d9656e3..79566025549 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -32,7 +32,6 @@
#include <pcmcia/ss.h>
#include "cs_internal.h"
-#include "ds_internal.h"
/*====================================================================*/
@@ -42,17 +41,22 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("PCMCIA Driver Services");
MODULE_LICENSE("GPL");
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
int ds_pc_debug;
module_param_named(pc_debug, ds_pc_debug, int, 0644);
#define ds_dbg(lvl, fmt, arg...) do { \
- if (ds_pc_debug > (lvl)) \
+ if (ds_pc_debug > (lvl)) \
printk(KERN_DEBUG "ds: " fmt , ## arg); \
} while (0)
+#define ds_dev_dbg(lvl, dev, fmt, arg...) do { \
+ if (ds_pc_debug > (lvl)) \
+ dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg); \
+} while (0)
#else
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
+#define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0)
#endif
spinlock_t pcmcia_dev_list_lock;
@@ -64,42 +68,19 @@ spinlock_t pcmcia_dev_list_lock;
/* String tables for error messages */
typedef struct lookup_t {
- int key;
- char *msg;
+ const int key;
+ const char *msg;
} lookup_t;
static const lookup_t error_table[] = {
- { CS_SUCCESS, "Operation succeeded" },
- { CS_BAD_ADAPTER, "Bad adapter" },
- { CS_BAD_ATTRIBUTE, "Bad attribute", },
- { CS_BAD_BASE, "Bad base address" },
- { CS_BAD_EDC, "Bad EDC" },
- { CS_BAD_IRQ, "Bad IRQ" },
- { CS_BAD_OFFSET, "Bad offset" },
- { CS_BAD_PAGE, "Bad page number" },
- { CS_READ_FAILURE, "Read failure" },
- { CS_BAD_SIZE, "Bad size" },
- { CS_BAD_SOCKET, "Bad socket" },
- { CS_BAD_TYPE, "Bad type" },
- { CS_BAD_VCC, "Bad Vcc" },
- { CS_BAD_VPP, "Bad Vpp" },
- { CS_BAD_WINDOW, "Bad window" },
- { CS_WRITE_FAILURE, "Write failure" },
- { CS_NO_CARD, "No card present" },
- { CS_UNSUPPORTED_FUNCTION, "Usupported function" },
- { CS_UNSUPPORTED_MODE, "Unsupported mode" },
- { CS_BAD_SPEED, "Bad speed" },
- { CS_BUSY, "Resource busy" },
- { CS_GENERAL_FAILURE, "General failure" },
- { CS_WRITE_PROTECTED, "Write protected" },
- { CS_BAD_ARG_LENGTH, "Bad argument length" },
- { CS_BAD_ARGS, "Bad arguments" },
- { CS_CONFIGURATION_LOCKED, "Configuration locked" },
- { CS_IN_USE, "Resource in use" },
- { CS_NO_MORE_ITEMS, "No more items" },
- { CS_OUT_OF_RESOURCE, "Out of resource" },
- { CS_BAD_HANDLE, "Bad handle" },
- { CS_BAD_TUPLE, "Bad CIS tuple" }
+ { 0, "Operation succeeded" },
+ { -EIO, "Input/Output error" },
+ { -ENODEV, "No card present" },
+ { -EINVAL, "Bad parameter" },
+ { -EACCES, "Configuration locked" },
+ { -EBUSY, "Resource in use" },
+ { -ENOSPC, "No more items" },
+ { -ENOMEM, "Out of resource" },
};
@@ -155,46 +136,32 @@ static const lookup_t service_table[] = {
{ ReplaceCIS, "ReplaceCIS" }
};
-
-static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err)
+const char *pcmcia_error_func(int func)
{
int i;
- char *serv;
-
- if (!p_dev)
- printk(KERN_NOTICE);
- 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)
- break;
- if (i < ARRAY_SIZE(service_table))
- serv = service_table[i].msg;
- else
- serv = "Unknown service number";
+ if (service_table[i].key == func)
+ return service_table[i].msg;
- for (i = 0; i < ARRAY_SIZE(error_table); i++)
- if (error_table[i].key == err->retcode)
- break;
- if (i < ARRAY_SIZE(error_table))
- printk("%s: %s\n", serv, error_table[i].msg);
- else
- printk("%s: Unknown error code %#x\n", serv, err->retcode);
+ return "Unknown service number";
+}
+EXPORT_SYMBOL(pcmcia_error_func);
- return CS_SUCCESS;
-} /* report_error */
+const char *pcmcia_error_ret(int ret)
+{
+ int i;
-/* end of code which was in cs.c before */
+ for (i = 0; i < ARRAY_SIZE(error_table); i++)
+ if (error_table[i].key == ret)
+ return error_table[i].msg;
+
+ return "unknown";
+}
+EXPORT_SYMBOL(pcmcia_error_ret);
/*======================================================================*/
-void cs_error(struct pcmcia_device *p_dev, int func, int ret)
-{
- error_info_t err = { func, ret };
- pcmcia_report_error(p_dev, &err);
-}
-EXPORT_SYMBOL(cs_error);
static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
@@ -391,7 +358,7 @@ static void pcmcia_release_function(struct kref *ref)
static void pcmcia_release_dev(struct device *dev)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
- ds_dbg(1, "releasing device %s\n", p_dev->dev.bus_id);
+ ds_dev_dbg(1, dev, "releasing device\n");
pcmcia_put_socket(p_dev->socket);
kfree(p_dev->devname);
kref_put(&p_dev->function_config->ref, pcmcia_release_function);
@@ -401,7 +368,7 @@ static void pcmcia_release_dev(struct device *dev)
static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
{
if (!s->pcmcia_state.device_add_pending) {
- ds_dbg(1, "scheduling to add %s secondary"
+ ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary"
" device to %d\n", mfc ? "mfc" : "pfc", s->sock);
s->pcmcia_state.device_add_pending = 1;
s->pcmcia_state.mfc_pfc = mfc;
@@ -427,8 +394,19 @@ static int pcmcia_device_probe(struct device * dev)
p_drv = to_pcmcia_drv(dev->driver);
s = p_dev->socket;
- ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id,
- p_drv->drv.name);
+ /* The PCMCIA code passes the match data in via dev->driver_data
+ * which is an ugly hack. Once the driver probe is called it may
+ * and often will overwrite the match data so we must save it first
+ *
+ * handle pseudo multifunction devices:
+ * there are at most two pseudo multifunction devices.
+ * if we're matching against the first, schedule a
+ * call which will then check whether there are two
+ * pseudo devices, and if not, add the second one.
+ */
+ did = p_dev->dev.driver_data;
+
+ ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name);
if ((!p_drv->probe) || (!p_dev->function_config) ||
(!try_module_get(p_drv->owner))) {
@@ -443,33 +421,27 @@ static int pcmcia_device_probe(struct device * dev)
p_dev->conf.ConfigBase = cis_config.base;
p_dev->conf.Present = cis_config.rmask[0];
} else {
- printk(KERN_INFO "pcmcia: could not parse base and rmask0 of CIS\n");
+ dev_printk(KERN_INFO, dev,
+ "pcmcia: could not parse base and rmask0 of CIS\n");
p_dev->conf.ConfigBase = 0;
p_dev->conf.Present = 0;
}
ret = p_drv->probe(p_dev);
if (ret) {
- ds_dbg(1, "binding %s to %s failed with %d\n",
- p_dev->dev.bus_id, p_drv->drv.name, ret);
+ ds_dev_dbg(1, dev, "binding to %s failed with %d\n",
+ p_drv->drv.name, ret);
goto put_module;
}
- /* handle pseudo multifunction devices:
- * there are at most two pseudo multifunction devices.
- * if we're matching against the first, schedule a
- * call which will then check whether there are two
- * pseudo devices, and if not, add the second one.
- */
- did = p_dev->dev.driver_data;
if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
(p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
pcmcia_add_device_later(p_dev->socket, 0);
- put_module:
+put_module:
if (ret)
module_put(p_drv->owner);
- put_dev:
+put_dev:
if (ret)
put_device(dev);
return (ret);
@@ -485,8 +457,9 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
struct pcmcia_device *tmp;
unsigned long flags;
- ds_dbg(2, "pcmcia_card_remove(%d) %s\n", s->sock,
- leftover ? leftover->devname : "");
+ ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev,
+ "pcmcia_card_remove(%d) %s\n", s->sock,
+ leftover ? leftover->devname : "");
if (!leftover)
s->device_count = 0;
@@ -503,7 +476,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
p_dev->_removed=1;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
- ds_dbg(2, "unregistering device %s\n", p_dev->dev.bus_id);
+ ds_dev_dbg(2, &p_dev->dev, "unregistering device\n");
device_unregister(&p_dev->dev);
}
@@ -520,7 +493,7 @@ static int pcmcia_device_remove(struct device * dev)
p_dev = to_pcmcia_dev(dev);
p_drv = to_pcmcia_drv(dev->driver);
- ds_dbg(1, "removing device %s\n", p_dev->dev.bus_id);
+ ds_dev_dbg(1, dev, "removing device\n");
/* If we're removing the primary module driving a
* pseudo multi-function card, we need to unbind
@@ -543,13 +516,15 @@ static int pcmcia_device_remove(struct device * dev)
/* check for proper unloading */
if (p_dev->_irq || p_dev->_io || p_dev->_locked)
- printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
- p_drv->drv.name);
+ dev_printk(KERN_INFO, dev,
+ "pcmcia: driver %s did not release config properly\n",
+ p_drv->drv.name);
for (i = 0; i < MAX_WIN; i++)
if (p_dev->_win & CLIENT_WIN_REQ(i))
- printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
- p_drv->drv.name);
+ dev_printk(KERN_INFO, dev,
+ "pcmcia: driver %s did not release window properly\n",
+ p_drv->drv.name);
/* references from pcmcia_probe_device */
pcmcia_put_dev(p_dev);
@@ -598,8 +573,9 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
}
if (!pccard_read_tuple(p_dev->socket, p_dev->func,
CISTPL_DEVICE_GEO, devgeo)) {
- ds_dbg(0, "mem device geometry probably means "
- "FUNCID_MEMORY\n");
+ ds_dev_dbg(0, &p_dev->dev,
+ "mem device geometry probably means "
+ "FUNCID_MEMORY\n");
p_dev->func_id = CISTPL_FUNCID_MEMORY;
p_dev->has_func_id = 1;
}
@@ -680,7 +656,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
if (!p_dev->devname)
goto err_free;
sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
- ds_dbg(3, "devname is %s\n", p_dev->devname);
+ ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname);
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
@@ -701,7 +677,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
if (!p_dev->function_config) {
- ds_dbg(3, "creating config_t for %s\n", p_dev->dev.bus_id);
+ ds_dev_dbg(3, &p_dev->dev, "creating config_t\n");
p_dev->function_config = kzalloc(sizeof(struct config_t),
GFP_KERNEL);
if (!p_dev->function_config)
@@ -709,8 +685,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
kref_init(&p_dev->function_config->ref);
}
- printk(KERN_NOTICE "pcmcia: registering new device %s\n",
- p_dev->devname);
+ dev_printk(KERN_NOTICE, &p_dev->dev,
+ "pcmcia: registering new device %s\n",
+ p_dev->devname);
pcmcia_device_query(p_dev);
@@ -745,19 +722,20 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
int ret = 0;
if (!(s->resource_setup_done)) {
- ds_dbg(3, "no resources available, delaying card_add\n");
+ ds_dev_dbg(3, &s->dev,
+ "no resources available, delaying card_add\n");
return -EAGAIN; /* try again, but later... */
}
if (pcmcia_validate_mem(s)) {
- ds_dbg(3, "validating mem resources failed, "
+ ds_dev_dbg(3, &s->dev, "validating mem resources failed, "
"delaying card_add\n");
return -EAGAIN; /* try again, but later... */
}
ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains);
if (ret || !no_chains) {
- ds_dbg(0, "invalid CIS or invalid resources\n");
+ ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n");
return -ENODEV;
}
@@ -778,7 +756,7 @@ static void pcmcia_delayed_add_device(struct work_struct *work)
{
struct pcmcia_socket *s =
container_of(work, struct pcmcia_socket, device_add);
- ds_dbg(1, "adding additional device to %d\n", s->sock);
+ ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock);
pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
s->pcmcia_state.device_add_pending = 0;
s->pcmcia_state.mfc_pfc = 0;
@@ -788,8 +766,7 @@ static int pcmcia_requery(struct device *dev, void * _data)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
if (!p_dev->dev.driver) {
- ds_dbg(1, "update device information for %s\n",
- p_dev->dev.bus_id);
+ ds_dev_dbg(1, dev, "update device information\n");
pcmcia_device_query(p_dev);
}
@@ -803,7 +780,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis)
unsigned long flags;
/* must be called with skt_mutex held */
- ds_dbg(0, "re-scanning socket %d\n", skt->sock);
+ ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock);
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
if (list_empty(&skt->devices_list))
@@ -854,17 +831,17 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
int ret = -ENOMEM;
int no_funcs;
int old_funcs;
- cisdump_t *cis;
cistpl_longlink_mfc_t mfc;
if (!filename)
return -EINVAL;
- ds_dbg(1, "trying to load CIS file %s\n", filename);
+ ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename);
if (strlen(filename) > (FIRMWARE_NAME_MAX - 1)) {
- printk(KERN_WARNING "pcmcia: CIS filename is too long [%s]\n",
- filename);
+ dev_printk(KERN_WARNING, &dev->dev,
+ "pcmcia: CIS filename is too long [%s]\n",
+ filename);
return -EINVAL;
}
@@ -873,23 +850,16 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
if (request_firmware(&fw, path, &dev->dev) == 0) {
if (fw->size >= CISTPL_MAX_CIS_SIZE) {
ret = -EINVAL;
- printk(KERN_ERR "pcmcia: CIS override is too big\n");
+ dev_printk(KERN_ERR, &dev->dev,
+ "pcmcia: CIS override is too big\n");
goto release;
}
- cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
- if (!cis) {
- ret = -ENOMEM;
- goto release;
- }
-
- cis->Length = fw->size + 1;
- memcpy(cis->Data, fw->data, fw->size);
-
- if (!pcmcia_replace_cis(s, cis))
+ if (!pcmcia_replace_cis(s, fw->data, fw->size))
ret = 0;
else {
- printk(KERN_ERR "pcmcia: CIS override failed\n");
+ dev_printk(KERN_ERR, &dev->dev,
+ "pcmcia: CIS override failed\n");
goto release;
}
@@ -993,14 +963,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
* after it has re-checked that there is no possible module
* with a prod_id/manf_id/card_id match.
*/
- ds_dbg(0, "skipping FUNC_ID match for %s until userspace "
- "interaction\n", dev->dev.bus_id);
+ ds_dev_dbg(0, &dev->dev,
+ "skipping FUNC_ID match until userspace interaction\n");
if (!dev->allow_func_id_match)
return 0;
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
- ds_dbg(0, "device %s needs a fake CIS\n", dev->dev.bus_id);
+ ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n");
if (!dev->socket->fake_cis)
pcmcia_load_firmware(dev, did->cisfile);
@@ -1032,11 +1002,9 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
/* match dynamic devices first */
spin_lock(&p_drv->dynids.lock);
list_for_each_entry(dynid, &p_drv->dynids.list, node) {
- ds_dbg(3, "trying to match %s to %s\n", dev->bus_id,
- drv->name);
+ ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
if (pcmcia_devmatch(p_dev, &dynid->id)) {
- ds_dbg(0, "matched %s to %s\n", dev->bus_id,
- drv->name);
+ ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
spin_unlock(&p_drv->dynids.lock);
return 1;
}
@@ -1046,18 +1014,15 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
#ifdef CONFIG_PCMCIA_IOCTL
/* matching by cardmgr */
if (p_dev->cardmgr == p_drv) {
- ds_dbg(0, "cardmgr matched %s to %s\n", dev->bus_id,
- drv->name);
+ ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name);
return 1;
}
#endif
while (did && did->match_flags) {
- ds_dbg(3, "trying to match %s to %s\n", dev->bus_id,
- drv->name);
+ ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
if (pcmcia_devmatch(p_dev, did)) {
- ds_dbg(0, "matched %s to %s\n", dev->bus_id,
- drv->name);
+ ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
return 1;
}
did++;
@@ -1263,7 +1228,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
if (p_dev->suspended)
return 0;
- ds_dbg(2, "suspending %s\n", dev->bus_id);
+ ds_dev_dbg(2, dev, "suspending\n");
if (dev->driver)
p_drv = to_pcmcia_drv(dev->driver);
@@ -1274,15 +1239,16 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
if (p_drv->suspend) {
ret = p_drv->suspend(p_dev);
if (ret) {
- printk(KERN_ERR "pcmcia: device %s (driver %s) did "
- "not want to go to sleep (%d)\n",
- p_dev->devname, p_drv->drv.name, ret);
+ dev_printk(KERN_ERR, dev,
+ "pcmcia: device %s (driver %s) did "
+ "not want to go to sleep (%d)\n",
+ p_dev->devname, p_drv->drv.name, ret);
goto out;
}
}
if (p_dev->device_no == p_dev->func) {
- ds_dbg(2, "releasing configuration for %s\n", dev->bus_id);
+ ds_dev_dbg(2, dev, "releasing configuration\n");
pcmcia_release_configuration(p_dev);
}
@@ -1302,7 +1268,7 @@ static int pcmcia_dev_resume(struct device * dev)
if (!p_dev->suspended)
return 0;
- ds_dbg(2, "resuming %s\n", dev->bus_id);
+ ds_dev_dbg(2, dev, "resuming\n");
if (dev->driver)
p_drv = to_pcmcia_drv(dev->driver);
@@ -1311,7 +1277,7 @@ static int pcmcia_dev_resume(struct device * dev)
goto out;
if (p_dev->device_no == p_dev->func) {
- ds_dbg(2, "requesting configuration for %s\n", dev->bus_id);
+ ds_dev_dbg(2, dev, "requesting configuration\n");
ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
if (ret)
goto out;
@@ -1353,14 +1319,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
static int pcmcia_bus_resume(struct pcmcia_socket *skt)
{
- ds_dbg(2, "resuming socket %d\n", skt->sock);
+ ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock);
bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
return 0;
}
static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
{
- ds_dbg(2, "suspending socket %d\n", skt->sock);
+ ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock);
if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
pcmcia_bus_suspend_callback)) {
pcmcia_bus_resume(skt);
@@ -1386,13 +1352,14 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
struct pcmcia_socket *s = pcmcia_get_socket(skt);
if (!s) {
- printk(KERN_ERR "PCMCIA obtaining reference to socket %p " \
- "failed, event 0x%x lost!\n", skt, event);
+ dev_printk(KERN_ERR, &skt->dev,
+ "PCMCIA obtaining reference to socket " \
+ "failed, event 0x%x lost!\n", event);
return -ENODEV;
}
- ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
- event, priority, skt);
+ ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
+ event, priority, skt);
switch (event) {
case CS_EVENT_CARD_REMOVAL:
@@ -1467,7 +1434,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
socket = pcmcia_get_socket(socket);
if (!socket) {
- printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket);
+ dev_printk(KERN_ERR, dev,
+ "PCMCIA obtaining reference to socket failed\n");
return -ENODEV;
}
@@ -1487,7 +1455,7 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback);
if (ret) {
- printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket);
+ dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
pcmcia_put_socket(socket);
return (ret);
}
diff --git a/drivers/pcmcia/ds_internal.h b/drivers/pcmcia/ds_internal.h
deleted file mode 100644
index 3a2b25e6ed7..00000000000
--- a/drivers/pcmcia/ds_internal.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* ds_internal.h - internal header for 16-bit PCMCIA devices management */
-
-extern spinlock_t pcmcia_dev_list_lock;
-extern struct bus_type pcmcia_bus_type;
-
-extern struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev);
-extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
-
-struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function);
-
-extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
-
-#ifdef CONFIG_PCMCIA_IOCTL
-extern void __init pcmcia_setup_ioctl(void);
-extern void __exit pcmcia_cleanup_ioctl(void);
-extern void handle_event(struct pcmcia_socket *s, event_t event);
-extern int handle_request(struct pcmcia_socket *s, event_t event);
-#else
-static inline void __init pcmcia_setup_ioctl(void) { return; }
-static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
-static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; }
-static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; }
-#endif
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index fb2bc1fb015..117dc12ab43 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -46,7 +46,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <pcmcia/ss.h>
-#include "cs_internal.h"
#define MODNAME "hd64465_ss"
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 68f6b2702bc..71653ab8489 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -63,7 +63,7 @@
#include "vg468.h"
#include "ricoh.h"
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
static const char version[] =
"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 3616da22715..2ab4f22c21d 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -38,7 +38,7 @@
#include "m32r_cfc.h"
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
static int m32r_cfc_debug;
module_param(m32r_cfc_debug, int, 0644);
#define debug(lvl, fmt, arg...) do { \
@@ -505,7 +505,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
}
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
if(state->flags & SS_IOCARD){
debug(3, ":IOCARD");
}
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 2b42b7155e3..2f108c23dbd 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -45,7 +45,7 @@
#define PCC_DEBUG_DBEX
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
static int m32r_pcc_debug;
module_param(m32r_pcc_debug, int, 0644);
#define debug(lvl, fmt, arg...) do { \
@@ -460,7 +460,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
pcc_set(sock,PCCSIGCR,reg);
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
if(state->flags & SS_IOCARD){
debug(3, ":IOCARD");
}
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index ff66604e90d..d1ad0966392 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -64,8 +64,8 @@
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
+#ifdef CONFIG_PCMCIA_DEBUG
+static int pc_debug;
module_param(pc_debug, int, 0);
#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
#else
diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h
index a234ce1967a..5554015a781 100644
--- a/drivers/pcmcia/o2micro.h
+++ b/drivers/pcmcia/o2micro.h
@@ -140,7 +140,8 @@ static int o2micro_override(struct yenta_socket *socket)
a = config_readb(socket, O2_RESERVED1);
b = config_readb(socket, O2_RESERVED2);
- printk(KERN_INFO "Yenta O2: res at 0x94/0xD4: %02x/%02x\n", a, b);
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "O2: res at 0x94/0xD4: %02x/%02x\n", a, b);
switch (socket->dev->device) {
/*
@@ -153,7 +154,9 @@ static int o2micro_override(struct yenta_socket *socket)
case PCI_DEVICE_ID_O2_6812:
case PCI_DEVICE_ID_O2_6832:
case PCI_DEVICE_ID_O2_6836:
- printk(KERN_INFO "Yenta O2: old bridge, disabling read prefetch/write burst\n");
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "Yenta O2: old bridge, disabling read "
+ "prefetch/write burst\n");
config_writeb(socket, O2_RESERVED1,
a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
config_writeb(socket, O2_RESERVED2,
@@ -161,7 +164,8 @@ static int o2micro_override(struct yenta_socket *socket)
break;
default:
- printk(KERN_INFO "Yenta O2: enabling read prefetch/write burst\n");
+ dev_printk(KERN_INFO , &socket->dev->dev,
+ "O2: enabling read prefetch/write burst\n");
config_writeb(socket, O2_RESERVED1,
a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
config_writeb(socket, O2_RESERVED2,
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 419f97fc9a6..1703b20cad5 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -38,7 +38,6 @@
#include <pcmcia/ss.h>
#include "cs_internal.h"
-#include "ds_internal.h"
static int major_dev = -1;
@@ -58,7 +57,7 @@ typedef struct user_info_t {
} user_info_t;
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
extern int ds_pc_debug;
#define ds_dbg(lvl, fmt, arg...) do { \
@@ -149,7 +148,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
irq = adj->resource.irq.IRQ;
if ((irq < 0) || (irq > 15))
- return CS_BAD_IRQ;
+ return -EINVAL;
if (adj->Action != REMOVE_MANAGED_RESOURCE)
return 0;
@@ -167,7 +166,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
#else
static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
- return CS_SUCCESS;
+ return 0;
}
#endif
@@ -175,7 +174,7 @@ static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
static int pcmcia_adjust_resource_info(adjust_t *adj)
{
struct pcmcia_socket *s;
- int ret = CS_UNSUPPORTED_FUNCTION;
+ int ret = -ENOSYS;
unsigned long flags;
down_read(&pcmcia_socket_list_rwsem);
@@ -248,7 +247,7 @@ static int pccard_get_status(struct pcmcia_socket *s,
if (s->state & SOCKET_SUSPEND)
status->CardState |= CS_EVENT_PM_SUSPEND;
if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
+ return -ENODEV;
c = (p_dev) ? p_dev->function_config : NULL;
@@ -274,7 +273,7 @@ static int pccard_get_status(struct pcmcia_socket *s,
status->CardState |=
(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
}
- return CS_SUCCESS;
+ return 0;
}
status->CardState |=
(val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
@@ -284,9 +283,81 @@ static int pccard_get_status(struct pcmcia_socket *s,
(val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
status->CardState |=
(val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
- return CS_SUCCESS;
+ return 0;
} /* pccard_get_status */
+int pccard_get_configuration_info(struct pcmcia_socket *s,
+ struct pcmcia_device *p_dev,
+ config_info_t *config)
+{
+ config_t *c;
+
+ if (!(s->state & SOCKET_PRESENT))
+ return -ENODEV;
+
+
+#ifdef CONFIG_CARDBUS
+ if (s->state & SOCKET_CARDBUS) {
+ memset(config, 0, sizeof(config_info_t));
+ config->Vcc = s->socket.Vcc;
+ config->Vpp1 = config->Vpp2 = s->socket.Vpp;
+ config->Option = s->cb_dev->subordinate->number;
+ if (s->state & SOCKET_CARDBUS_CONFIG) {
+ config->Attributes = CONF_VALID_CLIENT;
+ config->IntType = INT_CARDBUS;
+ config->AssignedIRQ = s->irq.AssignedIRQ;
+ if (config->AssignedIRQ)
+ config->Attributes |= CONF_ENABLE_IRQ;
+ if (s->io[0].res) {
+ config->BasePort1 = s->io[0].res->start;
+ config->NumPorts1 = s->io[0].res->end -
+ config->BasePort1 + 1;
+ }
+ }
+ return 0;
+ }
+#endif
+
+ if (p_dev) {
+ c = p_dev->function_config;
+ config->Function = p_dev->func;
+ } else {
+ c = NULL;
+ config->Function = 0;
+ }
+
+ if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
+ config->Attributes = 0;
+ config->Vcc = s->socket.Vcc;
+ config->Vpp1 = config->Vpp2 = s->socket.Vpp;
+ return 0;
+ }
+
+ config->Attributes = c->Attributes | CONF_VALID_CLIENT;
+ config->Vcc = s->socket.Vcc;
+ config->Vpp1 = config->Vpp2 = s->socket.Vpp;
+ config->IntType = c->IntType;
+ config->ConfigBase = c->ConfigBase;
+ config->Status = c->Status;
+ config->Pin = c->Pin;
+ config->Copy = c->Copy;
+ config->Option = c->Option;
+ config->ExtStatus = c->ExtStatus;
+ config->Present = config->CardValues = c->CardValues;
+ config->IRQAttributes = c->irq.Attributes;
+ config->AssignedIRQ = s->irq.AssignedIRQ;
+ config->BasePort1 = c->io.BasePort1;
+ config->NumPorts1 = c->io.NumPorts1;
+ config->Attributes1 = c->io.Attributes1;
+ config->BasePort2 = c->io.BasePort2;
+ config->NumPorts2 = c->io.NumPorts2;
+ config->Attributes2 = c->io.Attributes2;
+ config->IOAddrLines = c->io.IOAddrLines;
+
+ return 0;
+} /* pccard_get_configuration_info */
+
+
/*======================================================================
These manage a ring buffer of events pending for one user process
@@ -764,7 +835,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
case DS_GET_CONFIGURATION_INFO:
if (buf->config.Function &&
(buf->config.Function >= s->functions))
- ret = CS_BAD_ARGS;
+ ret = -EINVAL;
else {
struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
ret = pccard_get_configuration_info(s, p_dev, &buf->config);
@@ -787,15 +858,15 @@ static int ds_ioctl(struct inode * inode, struct file * file,
break;
case DS_PARSE_TUPLE:
buf->tuple.TupleData = buf->tuple_parse.data;
- ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
+ ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
break;
case DS_RESET_CARD:
- ret = pccard_reset_card(s);
+ ret = pcmcia_reset_card(s);
break;
case DS_GET_STATUS:
if (buf->status.Function &&
(buf->status.Function >= s->functions))
- ret = CS_BAD_ARGS;
+ ret = -EINVAL;
else {
struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
ret = pccard_get_status(s, p_dev, &buf->status);
@@ -826,7 +897,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
goto free_out;
}
- ret = CS_BAD_ARGS;
+ ret = -EINVAL;
if (!(buf->conf_reg.Function &&
(buf->conf_reg.Function >= s->functions))) {
@@ -867,7 +938,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
&buf->win_info.map);
break;
case DS_REPLACE_CIS:
- ret = pcmcia_replace_cis(s, &buf->cisdump);
+ ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
break;
case DS_BIND_REQUEST:
if (!capable(CAP_SYS_ADMIN)) {
@@ -889,22 +960,19 @@ static int ds_ioctl(struct inode * inode, struct file * file,
err = -EINVAL;
}
- if ((err == 0) && (ret != CS_SUCCESS)) {
+ if ((err == 0) && (ret != 0)) {
ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
switch (ret) {
- case CS_BAD_SOCKET: case CS_NO_CARD:
- err = -ENODEV; break;
- case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
- case CS_BAD_TUPLE:
- err = -EINVAL; break;
- case CS_IN_USE:
- err = -EBUSY; break;
- case CS_OUT_OF_RESOURCE:
+ case -ENODEV:
+ case -EINVAL:
+ case -EBUSY:
+ case -ENOSYS:
+ err = ret;
+ break;
+ case -ENOMEM:
err = -ENOSPC; break;
- case CS_NO_MORE_ITEMS:
+ case -ENOSPC:
err = -ENODATA; break;
- case CS_UNSUPPORTED_FUNCTION:
- err = -ENOSYS; break;
default:
err = -EIO; break;
}
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 4884a18cf9e..afea2b2558b 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -29,7 +29,6 @@
#include <pcmcia/ds.h>
#include "cs_internal.h"
-#include "ds_internal.h"
/* Access speed for IO windows */
@@ -44,16 +43,17 @@ static u8 pcmcia_used_irq[NR_IRQS];
#endif
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
extern int ds_pc_debug;
#define ds_dbg(skt, lvl, fmt, arg...) do { \
if (ds_pc_debug >= lvl) \
- printk(KERN_DEBUG "pcmcia_resource: %s: " fmt, \
- cs_socket_name(skt) , ## arg); \
+ dev_printk(KERN_DEBUG, &skt->dev, \
+ "pcmcia_resource: " fmt, \
+ ## arg); \
} while (0)
#else
-#define ds_dbg(lvl, fmt, arg...) do { } while (0)
+#define ds_dbg(skt, lvl, fmt, arg...) do { } while (0)
#endif
@@ -168,13 +168,13 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
u_char val;
if (!p_dev || !p_dev->function_config)
- return CS_NO_CARD;
+ return -EINVAL;
s = p_dev->socket;
c = p_dev->function_config;
if (!(c->state & CONFIG_LOCKED))
- return CS_CONFIGURATION_LOCKED;
+ return -EACCES;
addr = (c->ConfigBase + reg->Offset) >> 1;
@@ -188,93 +188,14 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
pcmcia_write_cis_mem(s, 1, addr, 1, &val);
break;
default:
- return CS_BAD_ARGS;
+ return -EINVAL;
break;
}
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_access_configuration_register */
EXPORT_SYMBOL(pcmcia_access_configuration_register);
-int pccard_get_configuration_info(struct pcmcia_socket *s,
- struct pcmcia_device *p_dev,
- config_info_t *config)
-{
- config_t *c;
-
- if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
-
-
-#ifdef CONFIG_CARDBUS
- if (s->state & SOCKET_CARDBUS) {
- memset(config, 0, sizeof(config_info_t));
- config->Vcc = s->socket.Vcc;
- config->Vpp1 = config->Vpp2 = s->socket.Vpp;
- config->Option = s->cb_dev->subordinate->number;
- if (s->state & SOCKET_CARDBUS_CONFIG) {
- config->Attributes = CONF_VALID_CLIENT;
- config->IntType = INT_CARDBUS;
- config->AssignedIRQ = s->irq.AssignedIRQ;
- if (config->AssignedIRQ)
- config->Attributes |= CONF_ENABLE_IRQ;
- if (s->io[0].res) {
- config->BasePort1 = s->io[0].res->start;
- config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1;
- }
- }
- return CS_SUCCESS;
- }
-#endif
-
- if (p_dev) {
- c = p_dev->function_config;
- config->Function = p_dev->func;
- } else {
- c = NULL;
- config->Function = 0;
- }
-
- if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
- config->Attributes = 0;
- config->Vcc = s->socket.Vcc;
- config->Vpp1 = config->Vpp2 = s->socket.Vpp;
- return CS_SUCCESS;
- }
-
- config->Attributes = c->Attributes | CONF_VALID_CLIENT;
- config->Vcc = s->socket.Vcc;
- config->Vpp1 = config->Vpp2 = s->socket.Vpp;
- config->IntType = c->IntType;
- config->ConfigBase = c->ConfigBase;
- config->Status = c->Status;
- config->Pin = c->Pin;
- config->Copy = c->Copy;
- config->Option = c->Option;
- config->ExtStatus = c->ExtStatus;
- config->Present = config->CardValues = c->CardValues;
- config->IRQAttributes = c->irq.Attributes;
- config->AssignedIRQ = s->irq.AssignedIRQ;
- config->BasePort1 = c->io.BasePort1;
- config->NumPorts1 = c->io.NumPorts1;
- config->Attributes1 = c->io.Attributes1;
- config->BasePort2 = c->io.BasePort2;
- config->NumPorts2 = c->io.NumPorts2;
- config->Attributes2 = c->io.Attributes2;
- config->IOAddrLines = c->io.IOAddrLines;
-
- return CS_SUCCESS;
-} /* pccard_get_configuration_info */
-
-int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
- config_info_t *config)
-{
- return pccard_get_configuration_info(p_dev->socket, p_dev,
- config);
-}
-EXPORT_SYMBOL(pcmcia_get_configuration_info);
-
-
/** pcmcia_get_window
*/
int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
@@ -284,12 +205,12 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
int w;
if (!s || !(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
+ return -ENODEV;
for (w = idx; w < MAX_WIN; w++)
if (s->state & SOCKET_WIN_REQ(w))
break;
if (w == MAX_WIN)
- return CS_NO_MORE_ITEMS;
+ return -EINVAL;
win = &s->win[w];
req->Base = win->ctl.res->start;
req->Size = win->ctl.res->end - win->ctl.res->start + 1;
@@ -304,7 +225,7 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
if (win->ctl.flags & MAP_USE_WAIT)
req->Attributes |= WIN_USE_WAIT;
*handle = win;
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_get_window */
EXPORT_SYMBOL(pcmcia_get_window);
@@ -316,10 +237,10 @@ EXPORT_SYMBOL(pcmcia_get_window);
int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
{
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
- return CS_BAD_HANDLE;
+ return -EINVAL;
req->Page = 0;
req->CardOffset = win->ctl.card_start;
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_get_mem_page */
EXPORT_SYMBOL(pcmcia_get_mem_page);
@@ -328,14 +249,18 @@ int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
{
struct pcmcia_socket *s;
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
- return CS_BAD_HANDLE;
- if (req->Page != 0)
- return CS_BAD_PAGE;
+ return -EINVAL;
s = win->sock;
+ if (req->Page != 0) {
+ ds_dbg(s, 0, "failure: requested page is zero\n");
+ return -EINVAL;
+ }
win->ctl.card_start = req->CardOffset;
- if (s->ops->set_mem_map(s, &win->ctl) != 0)
- return CS_BAD_OFFSET;
- return CS_SUCCESS;
+ if (s->ops->set_mem_map(s, &win->ctl) != 0) {
+ ds_dbg(s, 0, "failed to set_mem_map\n");
+ return -EIO;
+ }
+ return 0;
} /* pcmcia_map_mem_page */
EXPORT_SYMBOL(pcmcia_map_mem_page);
@@ -354,9 +279,9 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
c = p_dev->function_config;
if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
+ return -ENODEV;
if (!(c->state & CONFIG_LOCKED))
- return CS_CONFIGURATION_LOCKED;
+ return -EACCES;
if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
if (mod->Attributes & CONF_ENABLE_IRQ) {
@@ -369,20 +294,28 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
s->ops->set_socket(s, &s->socket);
}
- if (mod->Attributes & CONF_VCC_CHANGE_VALID)
- return CS_BAD_VCC;
+ if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
+ ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+ return -EINVAL;
+ }
/* We only allow changing Vpp1 and Vpp2 to the same value */
if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
if (mod->Vpp1 != mod->Vpp2)
- return CS_BAD_VPP;
+ ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n");
+ return -EINVAL;
s->socket.Vpp = mod->Vpp1;
- if (s->ops->set_socket(s, &s->socket))
- return CS_BAD_VPP;
+ if (s->ops->set_socket(s, &s->socket)) {
+ dev_printk(KERN_WARNING, &s->dev,
+ "Unable to set VPP\n");
+ return -EIO;
+ }
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
- (mod->Attributes & CONF_VPP2_CHANGE_VALID))
- return CS_BAD_VPP;
+ (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
+ ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+ return -EINVAL;
+ }
if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
pccard_io_map io_off = { 0, 0, 0, 0, 1 };
@@ -406,7 +339,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
}
}
- return CS_SUCCESS;
+ return 0;
} /* modify_configuration */
EXPORT_SYMBOL(pcmcia_modify_configuration);
@@ -441,7 +374,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
}
}
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_release_configuration */
@@ -459,7 +392,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
config_t *c = p_dev->function_config;
if (!p_dev->_io )
- return CS_BAD_HANDLE;
+ return -EINVAL;
p_dev->_io = 0;
@@ -467,7 +400,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
(c->io.NumPorts1 != req->NumPorts1) ||
(c->io.BasePort2 != req->BasePort2) ||
(c->io.NumPorts2 != req->NumPorts2))
- return CS_BAD_ARGS;
+ return -EINVAL;
c->state &= ~CONFIG_IO_REQ;
@@ -475,7 +408,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
if (req->NumPorts2)
release_io_space(s, req->BasePort2, req->NumPorts2);
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_release_io */
@@ -485,15 +418,19 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
config_t *c= p_dev->function_config;
if (!p_dev->_irq)
- return CS_BAD_HANDLE;
+ return -EINVAL;
p_dev->_irq = 0;
if (c->state & CONFIG_LOCKED)
- return CS_CONFIGURATION_LOCKED;
- if (c->irq.Attributes != req->Attributes)
- return CS_BAD_ATTRIBUTE;
- if (s->irq.AssignedIRQ != req->AssignedIRQ)
- return CS_BAD_IRQ;
+ return -EACCES;
+ if (c->irq.Attributes != req->Attributes) {
+ ds_dbg(s, 0, "IRQ attributes must match assigned ones\n");
+ return -EINVAL;
+ }
+ if (s->irq.AssignedIRQ != req->AssignedIRQ) {
+ ds_dbg(s, 0, "IRQ must match assigned one\n");
+ return -EINVAL;
+ }
if (--s->irq.Config == 0) {
c->state &= ~CONFIG_IRQ_REQ;
s->irq.AssignedIRQ = 0;
@@ -507,7 +444,7 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
pcmcia_used_irq[req->AssignedIRQ]--;
#endif
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_release_irq */
@@ -516,10 +453,10 @@ int pcmcia_release_window(window_handle_t win)
struct pcmcia_socket *s;
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
- return CS_BAD_HANDLE;
+ return -EINVAL;
s = win->sock;
if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
- return CS_BAD_HANDLE;
+ return -EINVAL;
/* Shut down memory window */
win->ctl.flags &= ~MAP_ACTIVE;
@@ -536,7 +473,7 @@ int pcmcia_release_window(window_handle_t win)
win->magic = 0;
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_release_window */
EXPORT_SYMBOL(pcmcia_release_window);
@@ -551,18 +488,23 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
pccard_io_map iomap;
if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
+ return -ENODEV;;
- if (req->IntType & INT_CARDBUS)
- return CS_UNSUPPORTED_MODE;
+ if (req->IntType & INT_CARDBUS) {
+ ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n");
+ return -EINVAL;
+ }
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
- return CS_CONFIGURATION_LOCKED;
+ return -EACCES;
/* Do power control. We don't allow changes in Vcc. */
s->socket.Vpp = req->Vpp;
- if (s->ops->set_socket(s, &s->socket))
- return CS_BAD_VPP;
+ if (s->ops->set_socket(s, &s->socket)) {
+ dev_printk(KERN_WARNING, &s->dev,
+ "Unable to set socket state\n");
+ return -EINVAL;
+ }
/* Pick memory or I/O card, DMA mode, interrupt */
c->IntType = req->IntType;
@@ -651,7 +593,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
c->state |= CONFIG_LOCKED;
p_dev->_locked = 1;
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_request_configuration */
EXPORT_SYMBOL(pcmcia_request_configuration);
@@ -667,37 +609,48 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
config_t *c;
if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
+ return -ENODEV;
if (!req)
- return CS_UNSUPPORTED_MODE;
+ return -EINVAL;
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
- return CS_CONFIGURATION_LOCKED;
- if (c->state & CONFIG_IO_REQ)
- return CS_IN_USE;
- if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))
- return CS_BAD_ATTRIBUTE;
+ return -EACCES;
+ if (c->state & CONFIG_IO_REQ) {
+ ds_dbg(s, 0, "IO already configured\n");
+ return -EBUSY;
+ }
+ if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
+ ds_dbg(s, 0, "bad attribute setting for IO region 1\n");
+ return -EINVAL;
+ }
if ((req->NumPorts2 > 0) &&
- (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))
- return CS_BAD_ATTRIBUTE;
+ (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
+ ds_dbg(s, 0, "bad attribute setting for IO region 2\n");
+ return -EINVAL;
+ }
+ ds_dbg(s, 1, "trying to allocate resource 1\n");
if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
- req->NumPorts1, req->IOAddrLines))
- return CS_IN_USE;
+ req->NumPorts1, req->IOAddrLines)) {
+ ds_dbg(s, 0, "allocation of resource 1 failed\n");
+ return -EBUSY;
+ }
if (req->NumPorts2) {
+ ds_dbg(s, 1, "trying to allocate resource 2\n");
if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
req->NumPorts2, req->IOAddrLines)) {
+ ds_dbg(s, 0, "allocation of resource 2 failed\n");
release_io_space(s, req->BasePort1, req->NumPorts1);
- return CS_IN_USE;
+ return -EBUSY;
}
}
c->io = *req;
c->state |= CONFIG_IO_REQ;
p_dev->_io = 1;
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_request_io */
EXPORT_SYMBOL(pcmcia_request_io);
@@ -723,16 +676,18 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
{
struct pcmcia_socket *s = p_dev->socket;
config_t *c;
- int ret = CS_IN_USE, irq = 0;
+ int ret = -EINVAL, irq = 0;
int type;
if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
+ return -ENODEV;
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
- return CS_CONFIGURATION_LOCKED;
- if (c->state & CONFIG_IRQ_REQ)
- return CS_IN_USE;
+ return -EACCES;
+ if (c->state & CONFIG_IRQ_REQ) {
+ ds_dbg(s, 0, "IRQ already configured\n");
+ return -EBUSY;
+ }
/* Decide what type of interrupt we are registering */
type = 0;
@@ -795,15 +750,19 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
}
if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
- if (request_irq(irq, req->Handler, type, p_dev->devname, req->Instance))
- return CS_IN_USE;
+ ret = request_irq(irq, req->Handler, type,
+ p_dev->devname, req->Instance);
+ if (ret)
+ return ret;
}
/* Make sure the fact the request type was overridden is passed back */
if (type == IRQF_SHARED && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) {
req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
- printk(KERN_WARNING "pcmcia: request for exclusive IRQ could not be fulfilled.\n");
- printk(KERN_WARNING "pcmcia: the driver needs updating to supported shared IRQ lines.\n");
+ dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: "
+ "request for exclusive IRQ could not be fulfilled.\n");
+ dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
+ "needs updating to supported shared IRQ lines.\n");
}
c->irq.Attributes = req->Attributes;
s->irq.AssignedIRQ = req->AssignedIRQ = irq;
@@ -816,7 +775,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
pcmcia_used_irq[irq]++;
#endif
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_request_irq */
EXPORT_SYMBOL(pcmcia_request_irq);
@@ -834,9 +793,11 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
int w;
if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
- if (req->Attributes & (WIN_PAGED | WIN_SHARED))
- return CS_BAD_ATTRIBUTE;
+ return -ENODEV;
+ if (req->Attributes & (WIN_PAGED | WIN_SHARED)) {
+ ds_dbg(s, 0, "bad attribute setting for iomem region\n");
+ return -EINVAL;
+ }
/* Window size defaults to smallest available */
if (req->Size == 0)
@@ -844,19 +805,25 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
align = (((s->features & SS_CAP_MEM_ALIGN) ||
(req->Attributes & WIN_STRICT_ALIGN)) ?
req->Size : s->map_size);
- if (req->Size & (s->map_size-1))
- return CS_BAD_SIZE;
+ if (req->Size & (s->map_size-1)) {
+ ds_dbg(s, 0, "invalid map size\n");
+ return -EINVAL;
+ }
if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
- (req->Base & (align-1)))
- return CS_BAD_BASE;
+ (req->Base & (align-1))) {
+ ds_dbg(s, 0, "invalid base address\n");
+ return -EINVAL;
+ }
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;
+ if (w == MAX_WIN) {
+ ds_dbg(s, 0, "all windows are used already\n");
+ return -EINVAL;
+ }
win = &s->win[w];
win->magic = WINDOW_MAGIC;
@@ -867,8 +834,10 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
if (!(s->features & SS_CAP_STATIC_MAP)) {
win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
(req->Attributes & WIN_MAP_BELOW_1MB), s);
- if (!win->ctl.res)
- return CS_IN_USE;
+ if (!win->ctl.res) {
+ ds_dbg(s, 0, "allocating mem region failed\n");
+ return -EINVAL;
+ }
}
(*p_dev)->_win |= CLIENT_WIN_REQ(w);
@@ -885,8 +854,10 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
if (req->Attributes & WIN_USE_WAIT)
win->ctl.flags |= MAP_USE_WAIT;
win->ctl.card_start = 0;
- if (s->ops->set_mem_map(s, &win->ctl) != 0)
- return CS_BAD_ARGS;
+ if (s->ops->set_mem_map(s, &win->ctl) != 0) {
+ ds_dbg(s, 0, "failed to set memory mapping\n");
+ return -EIO;
+ }
s->state |= SOCKET_WIN_REQ(w);
/* Return window handle */
@@ -897,7 +868,7 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
}
*wh = win;
- return CS_SUCCESS;
+ return 0;
} /* pcmcia_request_window */
EXPORT_SYMBOL(pcmcia_request_window);
@@ -909,3 +880,79 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
pcmcia_release_window(p_dev->win);
}
EXPORT_SYMBOL(pcmcia_disable_device);
+
+
+struct pcmcia_cfg_mem {
+ tuple_t tuple;
+ cisparse_t parse;
+ u8 buf[256];
+ cistpl_cftable_entry_t dflt;
+};
+
+/**
+ * pcmcia_loop_config() - loop over configuration options
+ * @p_dev: the struct pcmcia_device which we need to loop for.
+ * @conf_check: function to call for each configuration option.
+ * It gets passed the struct pcmcia_device, the CIS data
+ * describing the configuration option, and private data
+ * being passed to pcmcia_loop_config()
+ * @priv_data: private data to be passed to the conf_check function.
+ *
+ * pcmcia_loop_config() loops over all configuration options, and calls
+ * the driver-specific conf_check() for each one, checking whether
+ * it is a valid one.
+ */
+int pcmcia_loop_config(struct pcmcia_device *p_dev,
+ int (*conf_check) (struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data),
+ void *priv_data)
+{
+ struct pcmcia_cfg_mem *cfg_mem;
+
+ tuple_t *tuple;
+ int ret = -ENODEV;
+ unsigned int vcc;
+
+ cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
+ if (cfg_mem == NULL)
+ return -ENOMEM;
+
+ /* get the current Vcc setting */
+ vcc = p_dev->socket->socket.Vcc;
+
+ tuple = &cfg_mem->tuple;
+ tuple->TupleData = cfg_mem->buf;
+ tuple->TupleDataMax = 255;
+ tuple->TupleOffset = 0;
+ tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple->Attributes = 0;
+
+ ret = pcmcia_get_first_tuple(p_dev, tuple);
+ while (!ret) {
+ cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry;
+
+ if (pcmcia_get_tuple_data(p_dev, tuple))
+ goto next_entry;
+
+ if (pcmcia_parse_tuple(tuple, &cfg_mem->parse))
+ goto next_entry;
+
+ /* default values */
+ p_dev->conf.ConfigIndex = cfg->index;
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ cfg_mem->dflt = *cfg;
+
+ ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data);
+ if (!ret)
+ break;
+
+next_entry:
+ ret = pcmcia_get_next_tuple(p_dev, tuple);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pcmcia_loop_config);
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 1b07af5a2ed..bb9ddb9532e 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -30,12 +30,12 @@
#include <asm/system.h>
#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
+#include <asm/mach-types.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cistpl.h>
-#include "cs_internal.h"
#include "soc_common.h"
#include "pxa2xx_base.h"
@@ -166,18 +166,32 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
}
#endif
+static void pxa2xx_configure_sockets(struct device *dev)
+{
+ struct pcmcia_low_level *ops = dev->platform_data;
+
+ /*
+ * We have at least one socket, so set MECR:CIT
+ * (Card Is There)
+ */
+ MECR |= MECR_CIT;
+
+ /* Set MECR:NOS (Number Of Sockets) */
+ if (ops->nr > 1 || machine_is_viper())
+ MECR |= MECR_NOS;
+ else
+ MECR &= ~MECR_NOS;
+}
+
int __pxa2xx_drv_pcmcia_probe(struct device *dev)
{
int ret;
struct pcmcia_low_level *ops;
- int first, nr;
if (!dev || !dev->platform_data)
return -ENODEV;
ops = (struct pcmcia_low_level *)dev->platform_data;
- first = ops->first;
- nr = ops->nr;
/* Provide our PXA2xx specific timing routines. */
ops->set_timing = pxa2xx_pcmcia_set_timing;
@@ -185,21 +199,10 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
ops->frequency_change = pxa2xx_pcmcia_frequency_change;
#endif
- ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr);
+ ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr);
- if (ret == 0) {
- /*
- * We have at least one socket, so set MECR:CIT
- * (Card Is There)
- */
- MECR |= MECR_CIT;
-
- /* Set MECR:NOS (Number Of Sockets) */
- if (nr > 1)
- MECR |= MECR_NOS;
- else
- MECR &= ~MECR_NOS;
- }
+ if (!ret)
+ pxa2xx_configure_sockets(dev);
return ret;
}
@@ -223,11 +226,7 @@ static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t s
static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
{
- struct pcmcia_low_level *ops = dev->dev.platform_data;
- int nr = ops ? ops->nr : 0;
-
- MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
-
+ pxa2xx_configure_sockets(&dev->dev);
return pcmcia_socket_dev_resume(&dev->dev);
}
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
new file mode 100644
index 00000000000..7c8bcb47662
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -0,0 +1,154 @@
+/*
+ * linux/drivers/pcmcia/pxa/pxa_cm_x255.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Compulab Ltd., 2003, 2007, 2008
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <mach/pxa-regs.h>
+
+#include "soc_common.h"
+
+#define GPIO_PCMCIA_SKTSEL (54)
+#define GPIO_PCMCIA_S0_CD_VALID (16)
+#define GPIO_PCMCIA_S1_CD_VALID (17)
+#define GPIO_PCMCIA_S0_RDYINT (6)
+#define GPIO_PCMCIA_S1_RDYINT (8)
+#define GPIO_PCMCIA_RESET (9)
+
+#define PCMCIA_S0_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID)
+#define PCMCIA_S1_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S1_CD_VALID)
+#define PCMCIA_S0_RDYINT IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT)
+#define PCMCIA_S1_RDYINT IRQ_GPIO(GPIO_PCMCIA_S1_RDYINT)
+
+
+static struct pcmcia_irqs irqs[] = {
+ { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" },
+ { 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" },
+};
+
+static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+ int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
+ if (ret)
+ return ret;
+ gpio_direction_output(GPIO_PCMCIA_RESET, 0);
+
+ skt->irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
+ ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+ if (!ret)
+ gpio_free(GPIO_PCMCIA_RESET);
+
+ return ret;
+}
+
+static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
+{
+ soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+ gpio_free(GPIO_PCMCIA_RESET);
+}
+
+
+static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+ struct pcmcia_state *state)
+{
+ int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
+ int rdy = skt->nr ? GPIO_PCMCIA_S0_RDYINT : GPIO_PCMCIA_S1_RDYINT;
+
+ state->detect = !gpio_get_value(cd);
+ state->ready = !!gpio_get_value(rdy);
+ state->bvd1 = 1;
+ state->bvd2 = 1;
+ state->vs_3v = 0;
+ state->vs_Xv = 0;
+ state->wrprot = 0; /* not available */
+}
+
+
+static int cmx255_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+ const socket_state_t *state)
+{
+ switch (skt->nr) {
+ case 0:
+ if (state->flags & SS_RESET) {
+ gpio_set_value(GPIO_PCMCIA_SKTSEL, 0);
+ udelay(1);
+ gpio_set_value(GPIO_PCMCIA_RESET, 1);
+ udelay(10);
+ gpio_set_value(GPIO_PCMCIA_RESET, 0);
+ }
+ break;
+ case 1:
+ if (state->flags & SS_RESET) {
+ gpio_set_value(GPIO_PCMCIA_SKTSEL, 1);
+ udelay(1);
+ gpio_set_value(GPIO_PCMCIA_RESET, 1);
+ udelay(10);
+ gpio_set_value(GPIO_PCMCIA_RESET, 0);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static void cmx255_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void cmx255_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+
+static struct pcmcia_low_level cmx255_pcmcia_ops __initdata = {
+ .owner = THIS_MODULE,
+ .hw_init = cmx255_pcmcia_hw_init,
+ .hw_shutdown = cmx255_pcmcia_shutdown,
+ .socket_state = cmx255_pcmcia_socket_state,
+ .configure_socket = cmx255_pcmcia_configure_socket,
+ .socket_init = cmx255_pcmcia_socket_init,
+ .socket_suspend = cmx255_pcmcia_socket_suspend,
+ .nr = 1,
+};
+
+static struct platform_device *cmx255_pcmcia_device;
+
+int __init cmx255_pcmcia_init(void)
+{
+ int ret;
+
+ cmx255_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+
+ if (!cmx255_pcmcia_device)
+ return -ENOMEM;
+
+ ret = platform_device_add_data(cmx255_pcmcia_device, &cmx255_pcmcia_ops,
+ sizeof(cmx255_pcmcia_ops));
+
+ if (ret == 0) {
+ printk(KERN_INFO "Registering cm-x255 PCMCIA interface.\n");
+ ret = platform_device_add(cmx255_pcmcia_device);
+ }
+
+ if (ret)
+ platform_device_put(cmx255_pcmcia_device);
+
+ return ret;
+}
+
+void __exit cmx255_pcmcia_exit(void)
+{
+ platform_device_unregister(cmx255_pcmcia_device);
+}
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index bcff5cfed05..6c3aac37712 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -105,13 +105,10 @@ static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = {
static struct platform_device *cmx270_pcmcia_device;
-static int __init cmx270_pcmcia_init(void)
+int __init cmx270_pcmcia_init(void)
{
int ret;
- if (!machine_is_armcore())
- return -ENODEV;
-
cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
if (!cmx270_pcmcia_device)
@@ -131,14 +128,7 @@ static int __init cmx270_pcmcia_init(void)
return ret;
}
-static void __exit cmx270_pcmcia_exit(void)
+void __exit cmx270_pcmcia_exit(void)
{
platform_device_unregister(cmx270_pcmcia_device);
}
-
-module_init(cmx270_pcmcia_init);
-module_exit(cmx270_pcmcia_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
-MODULE_DESCRIPTION("CM-x270 PCMCIA driver");
diff --git a/drivers/pcmcia/pxa2xx_cm_x2xx.c b/drivers/pcmcia/pxa2xx_cm_x2xx.c
new file mode 100644
index 00000000000..4f09506ad8d
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_cm_x2xx.c
@@ -0,0 +1,49 @@
+/*
+ * linux/drivers/pcmcia/pxa/pxa_cm_x2xx.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Compulab Ltd., 2003, 2007, 2008
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ */
+
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/system.h>
+
+int cmx255_pcmcia_init(void);
+int cmx270_pcmcia_init(void);
+void cmx255_pcmcia_exit(void);
+void cmx270_pcmcia_exit(void);
+
+static int __init cmx2xx_pcmcia_init(void)
+{
+ int ret = -ENODEV;
+
+ if (machine_is_armcore() && cpu_is_pxa25x())
+ ret = cmx255_pcmcia_init();
+ else if (machine_is_armcore() && cpu_is_pxa27x())
+ ret = cmx270_pcmcia_init();
+
+ return ret;
+}
+
+static void __exit cmx2xx_pcmcia_exit(void)
+{
+ if (machine_is_armcore() && cpu_is_pxa25x())
+ cmx255_pcmcia_exit();
+ else if (machine_is_armcore() && cpu_is_pxa27x())
+ cmx270_pcmcia_exit();
+}
+
+module_init(cmx2xx_pcmcia_init);
+module_exit(cmx2xx_pcmcia_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
+MODULE_DESCRIPTION("CM-x2xx PCMCIA driver");
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c
new file mode 100644
index 00000000000..1736c67e547
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_palmld.c
@@ -0,0 +1,151 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_palmld.c
+ *
+ * Driver for Palm LifeDrive PCMCIA
+ *
+ * Copyright (C) 2006 Alex Osborne <ato@meshy.org>
+ * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <mach/palmld.h>
+#include "soc_common.h"
+
+static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR");
+ if (ret)
+ goto err1;
+ ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0);
+ if (ret)
+ goto err2;
+
+ ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST");
+ if (ret)
+ goto err2;
+ ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1);
+ if (ret)
+ goto err3;
+
+ ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY");
+ if (ret)
+ goto err3;
+ ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY);
+ if (ret)
+ goto err4;
+
+ skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
+ return 0;
+
+err4:
+ gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
+err3:
+ gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
+err2:
+ gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
+err1:
+ return ret;
+}
+
+static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+ gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
+ gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
+ gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
+}
+
+static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+ struct pcmcia_state *state)
+{
+ state->detect = 1; /* always inserted */
+ state->ready = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY);
+ state->bvd1 = 1;
+ state->bvd2 = 1;
+ state->wrprot = 0;
+ state->vs_3v = 1;
+ state->vs_Xv = 0;
+}
+
+static int palmld_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+ const socket_state_t *state)
+{
+ gpio_set_value(GPIO_NR_PALMLD_PCMCIA_POWER, 1);
+ gpio_set_value(GPIO_NR_PALMLD_PCMCIA_RESET,
+ !!(state->flags & SS_RESET));
+
+ return 0;
+}
+
+static void palmld_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void palmld_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level palmld_pcmcia_ops = {
+ .owner = THIS_MODULE,
+
+ .first = 0,
+ .nr = 2,
+
+ .hw_init = palmld_pcmcia_hw_init,
+ .hw_shutdown = palmld_pcmcia_hw_shutdown,
+
+ .socket_state = palmld_pcmcia_socket_state,
+ .configure_socket = palmld_pcmcia_configure_socket,
+
+ .socket_init = palmld_pcmcia_socket_init,
+ .socket_suspend = palmld_pcmcia_socket_suspend,
+};
+
+static struct platform_device *palmld_pcmcia_device;
+
+static int __init palmld_pcmcia_init(void)
+{
+ int ret;
+
+ if (!machine_is_palmld())
+ return -ENODEV;
+
+ palmld_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+ if (!palmld_pcmcia_device)
+ return -ENOMEM;
+
+ ret = platform_device_add_data(palmld_pcmcia_device, &palmld_pcmcia_ops,
+ sizeof(palmld_pcmcia_ops));
+
+ if (!ret)
+ ret = platform_device_add(palmld_pcmcia_device);
+
+ if (ret)
+ platform_device_put(palmld_pcmcia_device);
+
+ return ret;
+}
+
+static void __exit palmld_pcmcia_exit(void)
+{
+ platform_device_unregister(palmld_pcmcia_device);
+}
+
+module_init(palmld_pcmcia_init);
+module_exit(palmld_pcmcia_exit);
+
+MODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
+ " Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("PCMCIA support for Palm LifeDrive");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c
new file mode 100644
index 00000000000..36c7a0b324d
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_trizeps4.c
@@ -0,0 +1,256 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_trizeps4.c
+ *
+ * TRIZEPS PCMCIA specific routines.
+ *
+ * Author: Jürgen Schindele
+ * Created: 20 02, 2006
+ * Copyright: Jürgen Schindele
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa-regs.h>
+#include <mach/trizeps4.h>
+
+#include "soc_common.h"
+
+extern void board_pcmcia_power(int power);
+
+static struct pcmcia_irqs irqs[] = {
+ { 0, IRQ_GPIO(GPIO_PCD), "cs0_cd" }
+ /* on other baseboards we can have more inputs */
+};
+
+static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+ int ret, i;
+ /* we dont have voltage/card/ready detection
+ * so we dont need interrupts for it
+ */
+ switch (skt->nr) {
+ case 0:
+ if (gpio_request(GPIO_PRDY, "cf_irq") < 0) {
+ pr_err("%s: sock %d unable to request gpio %d\n", __func__,
+ skt->nr, GPIO_PRDY);
+ return -EBUSY;
+ }
+ if (gpio_direction_input(GPIO_PRDY) < 0) {
+ pr_err("%s: sock %d unable to set input gpio %d\n", __func__,
+ skt->nr, GPIO_PRDY);
+ gpio_free(GPIO_PRDY);
+ return -EINVAL;
+ }
+ skt->irq = IRQ_GPIO(GPIO_PRDY);
+ break;
+
+#ifndef CONFIG_MACH_TRIZEPS_CONXS
+ case 1:
+#endif
+ default:
+ break;
+ }
+ /* release the reset of this card */
+ pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->irq);
+
+ /* supplementory irqs for the socket */
+ for (i = 0; i < ARRAY_SIZE(irqs); i++) {
+ if (irqs[i].sock != skt->nr)
+ continue;
+ if (gpio_request(IRQ_TO_GPIO(irqs[i].irq), irqs[i].str) < 0) {
+ pr_err("%s: sock %d unable to request gpio %d\n",
+ __func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq));
+ ret = -EBUSY;
+ goto error;
+ }
+ if (gpio_direction_input(IRQ_TO_GPIO(irqs[i].irq)) < 0) {
+ pr_err("%s: sock %d unable to set input gpio %d\n",
+ __func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq));
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+ return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+error:
+ for (; i >= 0; i--) {
+ gpio_free(IRQ_TO_GPIO(irqs[i].irq));
+ }
+ return (ret);
+}
+
+static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+ int i;
+ /* free allocated gpio's */
+ gpio_free(GPIO_PRDY);
+ for (i = 0; i < ARRAY_SIZE(irqs); i++)
+ gpio_free(IRQ_TO_GPIO(irqs[i].irq));
+}
+
+static unsigned long trizeps_pcmcia_status[2];
+
+static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+ struct pcmcia_state *state)
+{
+ unsigned short status = 0, change;
+ status = CFSR_readw();
+ change = (status ^ trizeps_pcmcia_status[skt->nr]) &
+ ConXS_CFSR_BVD_MASK;
+ if (change) {
+ trizeps_pcmcia_status[skt->nr] = status;
+ if (status & ConXS_CFSR_BVD1) {
+ /* enable_irq empty */
+ } else {
+ /* disable_irq empty */
+ }
+ }
+
+ switch (skt->nr) {
+ case 0:
+ /* just fill in fix states */
+ state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1;
+ state->ready = gpio_get_value(GPIO_PRDY) ? 1 : 0;
+ state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0;
+ state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0;
+ state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1;
+ state->vs_Xv = (status & ConXS_CFSR_VS2) ? 0 : 1;
+ state->wrprot = 0; /* not available */
+ break;
+
+#ifndef CONFIG_MACH_TRIZEPS_CONXS
+ /* on ConXS we only have one slot. Second is inactive */
+ case 1:
+ state->detect = 0;
+ state->ready = 0;
+ state->bvd1 = 0;
+ state->bvd2 = 0;
+ state->vs_3v = 0;
+ state->vs_Xv = 0;
+ state->wrprot = 0;
+ break;
+
+#endif
+ }
+}
+
+static int trizeps_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+ const socket_state_t *state)
+{
+ int ret = 0;
+ unsigned short power = 0;
+
+ /* we do nothing here just check a bit */
+ switch (state->Vcc) {
+ case 0: power &= 0xfc; break;
+ case 33: power |= ConXS_BCR_S0_VCC_3V3; break;
+ case 50:
+ pr_err("%s(): Vcc 5V not supported in socket\n", __func__);
+ break;
+ default:
+ pr_err("%s(): bad Vcc %u\n", __func__, state->Vcc);
+ ret = -1;
+ }
+
+ switch (state->Vpp) {
+ case 0: power &= 0xf3; break;
+ case 33: power |= ConXS_BCR_S0_VPP_3V3; break;
+ case 120:
+ pr_err("%s(): Vpp 12V not supported in socket\n", __func__);
+ break;
+ default:
+ if (state->Vpp != state->Vcc) {
+ pr_err("%s(): bad Vpp %u\n", __func__, state->Vpp);
+ ret = -1;
+ }
+ }
+
+ switch (skt->nr) {
+ case 0: /* we only have 3.3V */
+ board_pcmcia_power(power);
+ break;
+
+#ifndef CONFIG_MACH_TRIZEPS_CONXS
+ /* on ConXS we only have one slot. Second is inactive */
+ case 1:
+#endif
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static void trizeps_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+ /* default is on */
+ board_pcmcia_power(0x9);
+}
+
+static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+ board_pcmcia_power(0x0);
+}
+
+static struct pcmcia_low_level trizeps_pcmcia_ops = {
+ .owner = THIS_MODULE,
+ .hw_init = trizeps_pcmcia_hw_init,
+ .hw_shutdown = trizeps_pcmcia_hw_shutdown,
+ .socket_state = trizeps_pcmcia_socket_state,
+ .configure_socket = trizeps_pcmcia_configure_socket,
+ .socket_init = trizeps_pcmcia_socket_init,
+ .socket_suspend = trizeps_pcmcia_socket_suspend,
+#ifdef CONFIG_MACH_TRIZEPS_CONXS
+ .nr = 1,
+#else
+ .nr = 2,
+#endif
+ .first = 0,
+};
+
+static struct platform_device *trizeps_pcmcia_device;
+
+static int __init trizeps_pcmcia_init(void)
+{
+ int ret;
+
+ trizeps_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+ if (!trizeps_pcmcia_device)
+ return -ENOMEM;
+
+ ret = platform_device_add_data(trizeps_pcmcia_device,
+ &trizeps_pcmcia_ops, sizeof(trizeps_pcmcia_ops));
+
+ if (ret == 0)
+ ret = platform_device_add(trizeps_pcmcia_device);
+
+ if (ret)
+ platform_device_put(trizeps_pcmcia_device);
+
+ return ret;
+}
+
+static void __exit trizeps_pcmcia_exit(void)
+{
+ platform_device_unregister(trizeps_pcmcia_device);
+}
+
+fs_initcall(trizeps_pcmcia_init);
+module_exit(trizeps_pcmcia_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Juergen Schindele");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c
new file mode 100644
index 00000000000..dd10481be7b
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_viper.c
@@ -0,0 +1,179 @@
+/*
+ * VIPER PCMCIA support
+ * Copyright 2004 Arcom Control Systems
+ *
+ * Maintained by Marc Zyngier <maz@misterjones.org>
+ * <marc.zyngier@altran.com>
+ *
+ * Based on:
+ * iPAQ h2200 PCMCIA support
+ * Copyright 2004 Koen Kooi <koen@vestingbar.nl>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <pcmcia/ss.h>
+
+#include <asm/irq.h>
+
+#include <mach/pxa-regs.h>
+#include <mach/viper.h>
+#include <asm/mach-types.h>
+
+#include "soc_common.h"
+#include "pxa2xx_base.h"
+
+static struct pcmcia_irqs irqs[] = {
+ { 0, gpio_to_irq(VIPER_CF_CD_GPIO), "PCMCIA_CD" }
+};
+
+static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+ unsigned long flags;
+
+ skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
+
+ if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
+ goto err_request_cd;
+
+ if (gpio_request(VIPER_CF_RDY_GPIO, "CF ready"))
+ goto err_request_rdy;
+
+ if (gpio_request(VIPER_CF_POWER_GPIO, "CF power"))
+ goto err_request_pwr;
+
+ local_irq_save(flags);
+
+ /* GPIO 82 is the CF power enable line. initially off */
+ if (gpio_direction_output(VIPER_CF_POWER_GPIO, 0) ||
+ gpio_direction_input(VIPER_CF_CD_GPIO) ||
+ gpio_direction_input(VIPER_CF_RDY_GPIO)) {
+ local_irq_restore(flags);
+ goto err_dir;
+ }
+
+ local_irq_restore(flags);
+
+ return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+err_dir:
+ gpio_free(VIPER_CF_POWER_GPIO);
+err_request_pwr:
+ gpio_free(VIPER_CF_RDY_GPIO);
+err_request_rdy:
+ gpio_free(VIPER_CF_CD_GPIO);
+err_request_cd:
+ printk(KERN_ERR "viper: Failed to setup PCMCIA GPIOs\n");
+ return -1;
+}
+
+/*
+ * Release all resources.
+ */
+static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+ soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+ gpio_free(VIPER_CF_POWER_GPIO);
+ gpio_free(VIPER_CF_RDY_GPIO);
+ gpio_free(VIPER_CF_CD_GPIO);
+}
+
+static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+ struct pcmcia_state *state)
+{
+ state->detect = gpio_get_value(VIPER_CF_CD_GPIO) ? 0 : 1;
+ state->ready = gpio_get_value(VIPER_CF_RDY_GPIO) ? 1 : 0;
+ state->bvd1 = 1;
+ state->bvd2 = 1;
+ state->wrprot = 0;
+ state->vs_3v = 1; /* Can only apply 3.3V */
+ state->vs_Xv = 0;
+}
+
+static int viper_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+ const socket_state_t *state)
+{
+ /* Silently ignore Vpp, output enable, speaker enable. */
+ viper_cf_rst(state->flags & SS_RESET);
+
+ /* Apply socket voltage */
+ switch (state->Vcc) {
+ case 0:
+ gpio_set_value(VIPER_CF_POWER_GPIO, 0);
+ break;
+ case 33:
+ gpio_set_value(VIPER_CF_POWER_GPIO, 1);
+ break;
+ default:
+ printk(KERN_ERR "%s: Unsupported Vcc:%d\n",
+ __func__, state->Vcc);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void viper_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void viper_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level viper_pcmcia_ops __initdata = {
+ .owner = THIS_MODULE,
+ .hw_init = viper_pcmcia_hw_init,
+ .hw_shutdown = viper_pcmcia_hw_shutdown,
+ .socket_state = viper_pcmcia_socket_state,
+ .configure_socket = viper_pcmcia_configure_socket,
+ .socket_init = viper_pcmcia_socket_init,
+ .socket_suspend = viper_pcmcia_socket_suspend,
+ .nr = 1,
+};
+
+static struct platform_device *viper_pcmcia_device;
+
+static int __init viper_pcmcia_init(void)
+{
+ int ret;
+
+ if (!machine_is_viper())
+ return -ENODEV;
+
+ viper_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+ if (!viper_pcmcia_device)
+ return -ENOMEM;
+
+ ret = platform_device_add_data(viper_pcmcia_device,
+ &viper_pcmcia_ops,
+ sizeof(viper_pcmcia_ops));
+
+ if (!ret)
+ ret = platform_device_add(viper_pcmcia_device);
+
+ if (ret)
+ platform_device_put(viper_pcmcia_device);
+
+ return ret;
+}
+
+static void __exit viper_pcmcia_exit(void)
+{
+ platform_device_unregister(viper_pcmcia_device);
+}
+
+module_init(viper_pcmcia_init);
+module_exit(viper_pcmcia_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 203e579ebbd..17f4ecf1c0c 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -122,19 +122,22 @@ static void free_region(struct resource *res)
static int add_interval(struct resource_map *map, u_long base, u_long num)
{
- struct resource_map *p, *q;
+ struct resource_map *p, *q;
- for (p = map; ; p = p->next) {
- if ((p != map) && (p->base+p->num-1 >= base))
- return -1;
- if ((p->next == map) || (p->next->base > base+num-1))
- break;
- }
- q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
- if (!q) return CS_OUT_OF_RESOURCE;
- q->base = base; q->num = num;
- q->next = p->next; p->next = q;
- return CS_SUCCESS;
+ for (p = map; ; p = p->next) {
+ if ((p != map) && (p->base+p->num-1 >= base))
+ return -1;
+ if ((p->next == map) || (p->next->base > base+num-1))
+ break;
+ }
+ q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
+ if (!q) {
+ printk(KERN_WARNING "out of memory to update resources\n");
+ return -ENOMEM;
+ }
+ q->base = base; q->num = num;
+ q->next = p->next; p->next = q;
+ return 0;
}
/*====================================================================*/
@@ -166,7 +169,10 @@ static int sub_interval(struct resource_map *map, u_long base, u_long num)
} else {
/* Split the block into two pieces */
p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
- if (!p) return CS_OUT_OF_RESOURCE;
+ if (!p) {
+ printk(KERN_WARNING "out of memory to update resources\n");
+ return -ENOMEM;
+ }
p->base = base+num;
p->num = q->base+q->num - p->base;
q->num = base - q->base;
@@ -174,7 +180,7 @@ static int sub_interval(struct resource_map *map, u_long base, u_long num)
}
}
}
- return CS_SUCCESS;
+ return 0;
}
/*======================================================================
@@ -194,13 +200,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
int any;
u_char *b, hole, most;
- printk(KERN_INFO "cs: IO port probe %#x-%#x:",
- base, base+num-1);
+ dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
+ base, base+num-1);
/* First, what does a floating port look like? */
b = kzalloc(256, GFP_KERNEL);
if (!b) {
- printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
+ dev_printk(KERN_ERR, &s->dev,
+ "do_io_probe: unable to kmalloc 256 bytes");
return;
}
for (i = base, most = 0; i < base+num; i += 8) {
@@ -366,8 +373,8 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
struct socket_data *s_data = s->resource_data;
u_long i, j, bad, fail, step;
- printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
- base, base+num-1);
+ dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
+ base, base+num-1);
bad = fail = 0;
step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
/* don't allow too large steps */
@@ -431,8 +438,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
if (probe_mask & MEM_PROBE_HIGH) {
if (inv_probe(s_data->mem_db.next, s) > 0)
return 0;
- printk(KERN_NOTICE "cs: warning: no high memory space "
- "available!\n");
+ dev_printk(KERN_NOTICE, &s->dev,
+ "cs: warning: no high memory space available!\n");
return -ENODEV;
}
@@ -794,10 +801,11 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
if (res->flags & IORESOURCE_IO) {
if (res == &ioport_resource)
continue;
- printk(KERN_INFO "pcmcia: parent PCI bridge I/O "
- "window: 0x%llx - 0x%llx\n",
- (unsigned long long)res->start,
- (unsigned long long)res->end);
+ dev_printk(KERN_INFO, &s->cb_dev->dev,
+ "pcmcia: parent PCI bridge I/O "
+ "window: 0x%llx - 0x%llx\n",
+ (unsigned long long)res->start,
+ (unsigned long long)res->end);
if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
done |= IORESOURCE_IO;
@@ -806,10 +814,11 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
if (res->flags & IORESOURCE_MEM) {
if (res == &iomem_resource)
continue;
- printk(KERN_INFO "pcmcia: parent PCI bridge Memory "
- "window: 0x%llx - 0x%llx\n",
- (unsigned long long)res->start,
- (unsigned long long)res->end);
+ dev_printk(KERN_INFO, &s->cb_dev->dev,
+ "pcmcia: parent PCI bridge Memory "
+ "window: 0x%llx - 0x%llx\n",
+ (unsigned long long)res->start,
+ (unsigned long long)res->end);
if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
done |= IORESOURCE_MEM;
}
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index c48f3f69bda..f49ac666615 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -54,7 +54,7 @@
#include <mach/pxa-regs.h>
#endif
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug;
module_param(pc_debug, int, 0644);
@@ -748,7 +748,9 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
add_timer(&skt->poll_timer);
- device_create_file(&skt->socket.dev, &dev_attr_status);
+ ret = device_create_file(&skt->socket.dev, &dev_attr_status);
+ if (ret)
+ goto out_err_8;
}
dev_set_drvdata(dev, sinfo);
@@ -758,6 +760,8 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
do {
skt = &sinfo->skt[i];
+ device_remove_file(&skt->socket.dev, &dev_attr_status);
+ out_err_8:
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 91ef6a0da3a..38c67375f36 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -15,7 +15,6 @@
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include <pcmcia/cistpl.h>
-#include "cs_internal.h"
struct device;
@@ -137,7 +136,7 @@ extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_lev
extern int soc_common_drv_pcmcia_remove(struct device *dev);
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
int lvl, const char *fmt, ...);
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 006a29e91d8..ff9a3bb3c88 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -316,27 +316,18 @@ static ssize_t pccard_store_cis(struct kobject *kobj,
char *buf, loff_t off, size_t count)
{
struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
- cisdump_t *cis;
int error;
if (off)
return -EINVAL;
- if (count >= 0x200)
+ if (count >= CISTPL_MAX_CIS_SIZE)
return -EINVAL;
if (!(s->state & SOCKET_PRESENT))
return -ENODEV;
- cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
- if (!cis)
- return -ENOMEM;
-
- cis->Length = count + 1;
- memcpy(cis->Data, buf, count);
-
- error = pcmcia_replace_cis(s, cis);
- kfree(cis);
+ error = pcmcia_replace_cis(s, buf, count);
if (error)
return -EIO;
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 5792bd5c54f..2a613e920fd 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -55,7 +55,7 @@
#include <pcmcia/ss.h>
#include "tcic.h"
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug;
module_param(pc_debug, int, 0644);
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 129db7bd06c..aaa70227bfb 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -339,8 +339,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
- printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
- pci_name(socket->dev), mfunc, devctl);
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: mfunc 0x%08x, devctl 0x%02x\n", mfunc, devctl);
/* make sure PCI interrupts are enabled before probing */
ti_init(socket);
@@ -354,8 +354,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
* We're here which means PCI interrupts are _not_ delivered. try to
* find the right setting (all serial or parallel)
*/
- printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",
- pci_name(socket->dev));
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: probing PCI interrupt failed, trying to fix\n");
/* for serial PCI make sure MFUNC3 is set to IRQSER */
if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {
@@ -379,8 +379,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
- printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts ok\n",
- pci_name(socket->dev));
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: all-serial interrupts ok\n");
mfunc_old = mfunc;
goto out;
}
@@ -395,8 +395,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
}
/* serial PCI interrupts not working fall back to parallel */
- printk(KERN_INFO "Yenta TI: socket %s falling back to parallel PCI interrupts\n",
- pci_name(socket->dev));
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: falling back to parallel PCI interrupts\n");
devctl &= ~TI113X_DCR_IMODE_MASK;
devctl |= TI113X_DCR_IMODE_SERIAL; /* serial ISA could be right */
config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
@@ -427,8 +427,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
mfunc_old = mfunc;
- printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",
- pci_name(socket->dev));
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: parallel PCI interrupts ok\n");
} else {
/* not working, back to old value */
mfunc = mfunc_old;
@@ -440,8 +440,9 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
out:
if (pci_irq_status < 1) {
socket->cb_irq = 0;
- printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",
- pci_name(socket->dev));
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "Yenta TI: no PCI interrupts. Fish. "
+ "Please report.\n");
}
}
@@ -513,8 +514,9 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
- printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
- pci_name(socket->dev), mfunc, devctl);
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: mfunc 0x%08x, devctl 0x%02x\n",
+ mfunc, devctl);
/* if IRQs are configured as tied, align irq of func1 with func0 */
sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
@@ -533,9 +535,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
* We're here which means PCI interrupts are _not_ delivered. try to
* find the right setting
*/
- printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",
- pci_name(socket->dev));
-
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: probing PCI interrupt failed, trying to fix\n");
/* if all serial: set INTRTIE, probe again */
if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {
@@ -544,8 +545,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
if (ti12xx_tie_interrupts(socket, &old_irq)) {
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
- printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts, tied ok\n",
- pci_name(socket->dev));
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: all-serial interrupts, tied ok\n");
goto out;
}
@@ -582,8 +583,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
- printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",
- pci_name(socket->dev));
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: parallel PCI interrupts ok\n");
goto out;
}
@@ -593,13 +594,13 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
if (pci_irq_status == -1)
goto out;
}
-
+
/* still nothing: set INTRTIE */
if (ti12xx_tie_interrupts(socket, &old_irq)) {
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
- printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts, tied ok\n",
- pci_name(socket->dev));
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: parallel PCI interrupts, tied ok\n");
goto out;
}
@@ -610,8 +611,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
out:
if (pci_irq_status < 1) {
socket->cb_irq = 0;
- printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",
- pci_name(socket->dev));
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "TI: no PCI interrupts. Fish. Please report.\n");
}
}
@@ -815,11 +816,13 @@ static int ti12xx_override(struct yenta_socket *socket)
/* make sure that memory burst is active */
val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL);
if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) {
- printk(KERN_INFO "Yenta: Disabling CLKRUN feature\n");
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "Disabling CLKRUN feature\n");
val |= TI113X_SCR_KEEPCLK;
}
if (!(val & TI122X_SCR_MRBURSTUP)) {
- printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n");
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "Enabling burst memory read transactions\n");
val |= TI122X_SCR_MRBURSTUP;
}
if (val_orig != val)
@@ -830,10 +833,12 @@ static int ti12xx_override(struct yenta_socket *socket)
* CSC interrupts to PCI rather than INTVAL.
*/
val = config_readb(socket, TI1250_DIAGNOSTIC);
- printk(KERN_INFO "Yenta: Using %s to route CSC interrupts to PCI\n",
- (val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
- printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n",
- (val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "Using %s to route CSC interrupts to PCI\n",
+ (val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "Routing CardBus interrupts to %s\n",
+ (val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
/* do irqrouting, depending on function */
if (PCI_FUNC(socket->dev->devfn) == 0)
@@ -858,8 +863,9 @@ static int ti1250_override(struct yenta_socket *socket)
diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
if (diag != old) {
- printk(KERN_INFO "Yenta: adjusting diagnostic: %02x -> %02x\n",
- old, diag);
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "adjusting diagnostic: %02x -> %02x\n",
+ old, diag);
config_writeb(socket, TI1250_DIAGNOSTIC, diag);
}
@@ -924,7 +930,9 @@ static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
/* default to clear TLTEnable bit, old behaviour */
test_c9 &= ~ENE_TEST_C9_TLTENABLE;
- printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9);
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "EnE: chaning testregister 0xC9, %02x -> %02x\n",
+ old_c9, test_c9);
config_writeb(socket, ENE_TEST_C9, test_c9);
}
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 0ab1fb65cdc..3ecd7c99d8e 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -38,11 +38,7 @@ static int pwr_irqs_off;
module_param(pwr_irqs_off, bool, 0644);
MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
-#if 0
-#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
-#else
-#define debug(x,args...)
-#endif
+#define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)
/* Don't ask.. */
#define to_cycles(ns) ((ns)/120)
@@ -69,13 +65,13 @@ MODULE_PARM_DESC (override_bios, "yenta ignore bios resource allocation");
static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
{
u32 val = readl(socket->base + reg);
- debug("%p %04x %08x\n", socket, reg, val);
+ debug("%04x %08x\n", socket, reg, val);
return val;
}
static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
{
- debug("%p %04x %08x\n", socket, reg, val);
+ debug("%04x %08x\n", socket, reg, val);
writel(val, socket->base + reg);
readl(socket->base + reg); /* avoid problems with PCI write posting */
}
@@ -84,7 +80,7 @@ static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
{
u8 val;
pci_read_config_byte(socket->dev, offset, &val);
- debug("%p %04x %02x\n", socket, offset, val);
+ debug("%04x %02x\n", socket, offset, val);
return val;
}
@@ -92,7 +88,7 @@ static inline u16 config_readw(struct yenta_socket *socket, unsigned offset)
{
u16 val;
pci_read_config_word(socket->dev, offset, &val);
- debug("%p %04x %04x\n", socket, offset, val);
+ debug("%04x %04x\n", socket, offset, val);
return val;
}
@@ -100,32 +96,32 @@ static inline u32 config_readl(struct yenta_socket *socket, unsigned offset)
{
u32 val;
pci_read_config_dword(socket->dev, offset, &val);
- debug("%p %04x %08x\n", socket, offset, val);
+ debug("%04x %08x\n", socket, offset, val);
return val;
}
static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
{
- debug("%p %04x %02x\n", socket, offset, val);
+ debug("%04x %02x\n", socket, offset, val);
pci_write_config_byte(socket->dev, offset, val);
}
static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
{
- debug("%p %04x %04x\n", socket, offset, val);
+ debug("%04x %04x\n", socket, offset, val);
pci_write_config_word(socket->dev, offset, val);
}
static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
{
- debug("%p %04x %08x\n", socket, offset, val);
+ debug("%04x %08x\n", socket, offset, val);
pci_write_config_dword(socket->dev, offset, val);
}
static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
{
u8 val = readb(socket->base + 0x800 + reg);
- debug("%p %04x %02x\n", socket, reg, val);
+ debug("%04x %02x\n", socket, reg, val);
return val;
}
@@ -134,20 +130,20 @@ static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg)
u16 val;
val = readb(socket->base + 0x800 + reg);
val |= readb(socket->base + 0x800 + reg + 1) << 8;
- debug("%p %04x %04x\n", socket, reg, val);
+ debug("%04x %04x\n", socket, reg, val);
return val;
}
static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
{
- debug("%p %04x %02x\n", socket, reg, val);
+ debug("%04x %02x\n", socket, reg, val);
writeb(val, socket->base + 0x800 + reg);
readb(socket->base + 0x800 + reg); /* PCI write posting... */
}
static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
{
- debug("%p %04x %04x\n", socket, reg, val);
+ debug("%04x %04x\n", socket, reg, val);
writeb(val, socket->base + 0x800 + reg);
writeb(val >> 8, socket->base + 0x800 + reg + 1);
@@ -207,7 +203,7 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
if (state & CB_CBCARD) {
- val |= SS_CARDBUS;
+ val |= SS_CARDBUS;
val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
@@ -650,8 +646,10 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
root = pci_find_parent_resource(socket->dev, res);
if (root && (request_resource(root, res) == 0))
return 0;
- printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
- pci_name(socket->dev), nr);
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "Preassigned resource %d busy or not available, "
+ "reconfiguring...\n",
+ nr);
}
if (type & IORESOURCE_IO) {
@@ -674,8 +672,9 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
return 1;
}
- printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
- pci_name(socket->dev), type);
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "no resource of type %x available, trying to continue...\n",
+ type);
res->start = res->end = res->flags = 0;
return 0;
}
@@ -923,7 +922,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
socket->probe_status = 0;
if (request_irq(socket->cb_irq, yenta_probe_handler, IRQF_SHARED, "yenta", socket)) {
- printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n");
+ dev_printk(KERN_WARNING, &socket->dev->dev,
+ "request_irq() in yenta_probe_cb_irq() failed!\n");
return -1;
}
@@ -960,8 +960,9 @@ static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_i
else
socket->socket.irq_mask = 0;
- printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
- socket->socket.irq_mask, socket->cb_irq);
+ dev_printk(KERN_INFO, &socket->dev->dev,
+ "ISA IRQ mask 0x%04x, PCI irq %d\n",
+ socket->socket.irq_mask, socket->cb_irq);
}
/*
@@ -1051,8 +1052,9 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
/* Show that the wanted subordinate number is not possible: */
if (cardbus_bridge->subordinate > upper_limit)
- printk(KERN_WARNING "Yenta: Upper limit for fixing this "
- "bridge's parent bridge: #%02x\n", upper_limit);
+ dev_printk(KERN_WARNING, &cardbus_bridge->dev,
+ "Upper limit for fixing this "
+ "bridge's parent bridge: #%02x\n", upper_limit);
/* If we have room to increase the bridge's subordinate number, */
if (bridge_to_fix->subordinate < upper_limit) {
@@ -1061,10 +1063,11 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
unsigned char subordinate_to_assign =
min(cardbus_bridge->subordinate, upper_limit);
- printk(KERN_INFO "Yenta: Raising subordinate bus# of parent "
- "bus (#%02x) from #%02x to #%02x\n",
- bridge_to_fix->number,
- bridge_to_fix->subordinate, subordinate_to_assign);
+ dev_printk(KERN_INFO, &bridge_to_fix->dev,
+ "Raising subordinate bus# of parent "
+ "bus (#%02x) from #%02x to #%02x\n",
+ bridge_to_fix->number,
+ bridge_to_fix->subordinate, subordinate_to_assign);
/* Save the new subordinate in the bus struct of the bridge */
bridge_to_fix->subordinate = subordinate_to_assign;
@@ -1091,8 +1094,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
* Bail out if so.
*/
if (!dev->subordinate) {
- printk(KERN_ERR "Yenta: no bus associated with %s! "
- "(try 'pci=assign-busses')\n", pci_name(dev));
+ dev_printk(KERN_ERR, &dev->dev, "no bus associated! "
+ "(try 'pci=assign-busses')\n");
return -ENODEV;
}
@@ -1127,7 +1130,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
goto disable;
if (!pci_resource_start(dev, 0)) {
- printk(KERN_ERR "No cardbus resource!\n");
+ dev_printk(KERN_ERR, &dev->dev, "No cardbus resource!\n");
ret = -ENODEV;
goto release;
}
@@ -1146,8 +1149,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
* report the subsystem vendor and device for help debugging
* the irq stuff...
*/
- printk(KERN_INFO "Yenta: CardBus bridge found at %s [%04x:%04x]\n",
- pci_name(dev), dev->subsystem_vendor, dev->subsystem_device);
+ dev_printk(KERN_INFO, &dev->dev, "CardBus bridge found [%04x:%04x]\n",
+ dev->subsystem_vendor, dev->subsystem_device);
yenta_config_init(socket);
@@ -1179,8 +1182,12 @@ 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");
+ dev_printk(KERN_INFO, &dev->dev,
+ "no PCI IRQ, CardBus support disabled for this "
+ "socket.\n");
+ dev_printk(KERN_INFO, &dev->dev,
+ "check your BIOS CardBus, BIOS IRQ or ACPI "
+ "settings.\n");
} else {
socket->socket.features |= SS_CAP_CARDBUS;
}
@@ -1188,7 +1195,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
/* Figure out what the dang thing can do for the PCMCIA layer... */
yenta_interrogate(socket);
yenta_get_socket_capabilities(socket, isa_interrupts);
- printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
+ dev_printk(KERN_INFO, &dev->dev,
+ "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
yenta_fixup_parent_bridge(dev->subordinate);