diff options
Diffstat (limited to 'drivers/pcmcia')
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); |