Commit 811bbb96 authored by Russell King's avatar Russell King

Merge flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5-pci

into flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5-pcmcia
parents b4f6270e d18b4712
...@@ -76,7 +76,6 @@ ...@@ -76,7 +76,6 @@
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/bus_ops.h>
#ifdef CONFIG_SYNCLINK_SYNCPPP_MODULE #ifdef CONFIG_SYNCLINK_SYNCPPP_MODULE
#define CONFIG_SYNCLINK_SYNCPPP 1 #define CONFIG_SYNCLINK_SYNCPPP 1
...@@ -241,7 +240,6 @@ typedef struct _mgslpc_info { ...@@ -241,7 +240,6 @@ typedef struct _mgslpc_info {
dev_link_t link; dev_link_t link;
dev_node_t node; dev_node_t node;
int stop; int stop;
struct bus_operations *bus;
/* SPPP/Cisco HDLC device parts */ /* SPPP/Cisco HDLC device parts */
int netcount; int netcount;
...@@ -826,7 +824,6 @@ static int mgslpc_event(event_t event, int priority, ...@@ -826,7 +824,6 @@ static int mgslpc_event(event_t event, int priority,
break; break;
case CS_EVENT_CARD_INSERTION: case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
info->bus = args->bus;
mgslpc_config(link); mgslpc_config(link);
break; break;
case CS_EVENT_PM_SUSPEND: case CS_EVENT_PM_SUSPEND:
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/bus_ops.h>
MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards"); MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
MODULE_AUTHOR("Klaus Lichtenwalder"); MODULE_AUTHOR("Klaus Lichtenwalder");
...@@ -163,17 +162,12 @@ static dev_link_t *dev_list = NULL; ...@@ -163,17 +162,12 @@ static dev_link_t *dev_list = NULL;
"stopped" due to a power management event, or card ejection. The "stopped" due to a power management event, or card ejection. The
device IO routines can use a flag like this to throttle IO to a device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it. card that is not ready to accept it.
The bus_operations pointer is used on platforms for which we need
to use special socket-specific versions of normal IO primitives
(inb, outb, readb, writeb, etc) for card IO.
*/ */
typedef struct local_info_t { typedef struct local_info_t {
dev_link_t link; dev_link_t link;
dev_node_t node; dev_node_t node;
int busy; int busy;
struct bus_operations *bus;
} local_info_t; } local_info_t;
/*====================================================================*/ /*====================================================================*/
...@@ -522,7 +516,6 @@ static int elsa_cs_event(event_t event, int priority, ...@@ -522,7 +516,6 @@ static int elsa_cs_event(event_t event, int priority,
break; break;
case CS_EVENT_CARD_INSERTION: case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
dev->bus = args->bus;
elsa_cs_config(link); elsa_cs_config(link);
break; break;
case CS_EVENT_PM_SUSPEND: case CS_EVENT_PM_SUSPEND:
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/bus_ops.h>
MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards"); MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
MODULE_AUTHOR("Marcus Niemann"); MODULE_AUTHOR("Marcus Niemann");
...@@ -171,17 +170,12 @@ static dev_link_t *dev_list = NULL; ...@@ -171,17 +170,12 @@ static dev_link_t *dev_list = NULL;
"stopped" due to a power management event, or card ejection. The "stopped" due to a power management event, or card ejection. The
device IO routines can use a flag like this to throttle IO to a device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it. card that is not ready to accept it.
The bus_operations pointer is used on platforms for which we need
to use special socket-specific versions of normal IO primitives
(inb, outb, readb, writeb, etc) for card IO.
*/ */
typedef struct local_info_t { typedef struct local_info_t {
dev_link_t link; dev_link_t link;
dev_node_t node; dev_node_t node;
int stop; int stop;
struct bus_operations *bus;
} local_info_t; } local_info_t;
/*====================================================================*/ /*====================================================================*/
...@@ -620,7 +614,6 @@ static int sedlbauer_event(event_t event, int priority, ...@@ -620,7 +614,6 @@ static int sedlbauer_event(event_t event, int priority,
break; break;
case CS_EVENT_CARD_INSERTION: case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
dev->bus = args->bus;
sedlbauer_config(link); sedlbauer_config(link);
break; break;
case CS_EVENT_PM_SUSPEND: case CS_EVENT_PM_SUSPEND:
......
...@@ -29,6 +29,9 @@ ifdef CONFIG_HOTPLUG_PCI_CPCI ...@@ -29,6 +29,9 @@ ifdef CONFIG_HOTPLUG_PCI_CPCI
obj-y += setup-bus.o obj-y += setup-bus.o
endif endif
# Hotplug (eg, cardbus) now requires setup-bus
obj-$(CONFIG_HOTPLUG) += setup-bus.o
ifndef CONFIG_X86 ifndef CONFIG_X86
obj-y += syscall.o obj-y += syscall.o
endif endif
......
...@@ -87,5 +87,9 @@ config PCMCIA_SA1111 ...@@ -87,5 +87,9 @@ config PCMCIA_SA1111
tristate "SA1111 support" tristate "SA1111 support"
depends on PCMCIA_SA1100 && SA1111 depends on PCMCIA_SA1100 && SA1111
config PCMCIA_PROBE
bool
default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X
endmenu endmenu
...@@ -2,46 +2,43 @@ ...@@ -2,46 +2,43 @@
# Makefile for the kernel pcmcia subsystem (c/o David Hinds) # Makefile for the kernel pcmcia subsystem (c/o David Hinds)
# #
obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o
ifeq ($(CONFIG_CARDBUS),y) ifeq ($(CONFIG_CARDBUS),y)
obj-$(CONFIG_PCMCIA) += yenta_socket.o obj-$(CONFIG_PCMCIA) += yenta_socket.o
endif endif
obj-$(CONFIG_I82365) += i82365.o obj-$(CONFIG_I82365) += i82365.o
obj-$(CONFIG_I82092) += i82092.o obj-$(CONFIG_I82092) += i82092.o
obj-$(CONFIG_TCIC) += tcic.o obj-$(CONFIG_TCIC) += tcic.o
obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa1111_cs.o obj-$(CONFIG_PCMCIA_SA1111) += sa1111_cs.o
yenta_socket-objs := pci_socket.o yenta.o yenta_socket-y += pci_socket.o yenta.o
pcmcia_core-objs-y := cistpl.o rsrc_mgr.o bulkmem.o cs.o pcmcia_core-y += cistpl.o rsrc_mgr.o bulkmem.o cs.o
pcmcia_core-objs-$(CONFIG_CARDBUS) += cardbus.o pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
pcmcia_core-objs := $(pcmcia_core-objs-y)
sa1111_cs-objs-y := sa1111_generic.o sa1111_cs-y += sa1111_generic.o
sa1111_cs-objs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o sa1111_cs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o
sa1111_cs-objs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
sa1111_cs-objs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o
sa1111_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER) += sa1100_graphicsmaster.o sa1111_cs-$(CONFIG_SA1100_GRAPHICSMASTER) += sa1100_graphicsmaster.o
sa1111_cs-objs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o
sa1111_cs-objs-$(CONFIG_SA1100_PFS168) += sa1100_pfs168.o sa1111_cs-$(CONFIG_SA1100_PFS168) += sa1100_pfs168.o
sa1111_cs-objs-$(CONFIG_SA1100_PT_SYSTEM3) += sa1100_system3.o sa1111_cs-$(CONFIG_SA1100_PT_SYSTEM3) += sa1100_system3.o
sa1111_cs-objs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o sa1111_cs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o
sa1111_cs-objs := $(sa1111_cs-objs-y)
sa1100_cs-objs-y := sa1100_generic.o sa1100_cs-y += sa1100_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
sa1100_cs-objs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET) += sa1100_flexanet.o sa1100_cs-$(CONFIG_SA1100_FLEXANET) += sa1100_flexanet.o
sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD) += sa1100_freebird.o sa1100_cs-$(CONFIG_SA1100_FREEBIRD) += sa1100_freebird.o
sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSCLIENT) += sa1100_graphicsclient.o sa1100_cs-$(CONFIG_SA1100_GRAPHICSCLIENT) += sa1100_graphicsclient.o
sa1100_cs-objs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
sa1100_cs-objs-$(CONFIG_SA1100_PANGOLIN) += sa1100_pangolin.o sa1100_cs-$(CONFIG_SA1100_PANGOLIN) += sa1100_pangolin.o
sa1100_cs-objs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
sa1100_cs-objs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
sa1100_cs-objs-$(CONFIG_SA1100_STORK) += sa1100_stork.o sa1100_cs-$(CONFIG_SA1100_STORK) += sa1100_stork.o
sa1100_cs-objs-$(CONFIG_SA1100_TRIZEPS) += sa1100_trizeps.o sa1100_cs-$(CONFIG_SA1100_TRIZEPS) += sa1100_trizeps.o
sa1100_cs-objs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o sa1100_cs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o
sa1100_cs-objs := $(sa1100_cs-objs-y)
...@@ -87,10 +87,6 @@ static int pc_debug = PCMCIA_DEBUG; ...@@ -87,10 +87,6 @@ static int pc_debug = PCMCIA_DEBUG;
#define PCDATA_CODE_TYPE 0x0014 #define PCDATA_CODE_TYPE 0x0014
#define PCDATA_INDICATOR 0x0015 #define PCDATA_INDICATOR 0x0015
typedef struct cb_config_t {
struct pci_dev *dev[8];
} cb_config_t;
/*===================================================================== /*=====================================================================
Expansion ROM's have a special layout, and pointers specify an Expansion ROM's have a special layout, and pointers specify an
...@@ -173,11 +169,10 @@ int read_cb_mem(socket_info_t * s, int space, u_int addr, u_int len, void *ptr) ...@@ -173,11 +169,10 @@ int read_cb_mem(socket_info_t * s, int space, u_int addr, u_int len, void *ptr)
DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len); DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len);
if (!s->cb_config) dev = pci_find_slot(s->cap.cb_dev->subordinate->number, 0);
if (!dev)
goto fail; goto fail;
dev = s->cb_config->dev[0];
/* Config space? */ /* Config space? */
if (space == 0) { if (space == 0) {
if (addr + len > 0x100) if (addr + len > 0x100)
...@@ -219,171 +214,61 @@ int read_cb_mem(socket_info_t * s, int space, u_int addr, u_int len, void *ptr) ...@@ -219,171 +214,61 @@ int read_cb_mem(socket_info_t * s, int space, u_int addr, u_int len, void *ptr)
=====================================================================*/ =====================================================================*/
int cb_alloc(socket_info_t * s) /*
* Since there is only one interrupt available to CardBus
* devices, all devices downstream of this device must
* be using this IRQ.
*/
static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
{ {
struct pci_bus *bus; struct pci_dev *dev;
u_short vend, v, dev;
u_char i, hdr, fn;
cb_config_t *c;
int irq;
bus = s->cap.cb_dev->subordinate;
pci_bus_read_config_word(bus, 0, PCI_VENDOR_ID, &vend);
pci_bus_read_config_word(bus, 0, PCI_DEVICE_ID, &dev);
printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, "
"device 0x%04x\n", bus->number, vend, dev);
pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr);
fn = 1;
if (hdr & 0x80) {
do {
if (pci_bus_read_config_word(bus, fn, PCI_VENDOR_ID, &v) ||
!v || v == 0xffff)
break;
fn++;
} while (fn < 8);
}
s->functions = fn;
c = kmalloc(sizeof(struct cb_config_t), GFP_ATOMIC);
if (!c)
return CS_OUT_OF_RESOURCE;
memset(c, 0, sizeof(struct cb_config_t));
for (i = 0; i < fn; i++) {
c->dev[i] = kmalloc(sizeof(struct pci_dev), GFP_ATOMIC);
if (!c->dev[i]) {
for (; i--; )
kfree(c->dev[i]);
kfree(c);
return CS_OUT_OF_RESOURCE;
}
memset(c->dev[i], 0, sizeof(struct pci_dev));
}
irq = s->cap.pci_irq; list_for_each_entry(dev, &bus->devices, bus_list) {
for (i = 0; i < fn; i++) {
struct pci_dev *dev = c->dev[i];
u8 irq_pin; u8 irq_pin;
int r;
dev->bus = bus;
dev->sysdata = bus->sysdata;
dev->dev.parent = bus->dev;
dev->dev.bus = &pci_bus_type;
dev->devfn = i;
pci_read_config_word(dev, PCI_VENDOR_ID, &dev->vendor);
pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
dev->hdr_type = hdr & 0x7f;
dev->dma_mask = 0xffffffff;
dev->dev.dma_mask = &dev->dma_mask;
pci_setup_device(dev);
strcpy(dev->dev.bus_id, dev->slot_name);
/* We need to assign resources for expansion ROM. */
for (r = 0; r < 7; r++) {
struct resource *res = dev->resource + r;
if (res->flags)
pci_assign_resource(dev, r);
}
/* Does this function have an interrupt at all? */
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
if (irq_pin) if (irq_pin) {
dev->irq = irq; dev->irq = irq;
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
/* pci_enable_device needs to be called after pci_assign_resource */ }
/* because it returns an error if (!res->start && res->end). */
if (pci_enable_device(dev))
continue;
if (irq_pin)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
device_register(&dev->dev);
pci_insert_device(dev, bus);
}
s->cb_config = c;
s->irq.AssignedIRQ = irq;
return CS_SUCCESS;
}
void cb_free(socket_info_t * s)
{
cb_config_t *c = s->cb_config;
if (c) {
s->cb_config = NULL;
pci_remove_behind_bridge(s->cap.cb_dev);
kfree(c); if (dev->subordinate)
printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number); cardbus_assign_irqs(dev->subordinate, irq);
} }
} }
/*===================================================================== int cb_alloc(socket_info_t * s)
cb_enable() has the job of configuring a socket for a Cardbus
card, and initializing the card's PCI configuration registers.
It first sets up the Cardbus bridge windows, for IO and memory
accesses. Then, it initializes each card function's base address
registers, interrupt line register, and command register.
It is called as part of the RequestConfiguration card service.
It should be called after a previous call to cb_config() (via the
RequestIO service).
======================================================================*/
void cb_enable(socket_info_t * s)
{ {
struct pci_bus *bus = s->cap.cb_dev->subordinate;
struct pci_dev *dev; struct pci_dev *dev;
u_char i; unsigned int max, pass;
DEBUG(0, "cs: cb_enable(bus %d)\n", s->cap.cb_dev->subordinate->number); s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
// pcibios_fixup_bus(bus);
/* Configure bridge */
cb_release_cis_mem(s); max = bus->secondary;
for (pass = 0; pass < 2; pass++)
/* Set up PCI interrupt and command registers */ list_for_each_entry(dev, &bus->devices, bus_list)
for (i = 0; i < s->functions; i++) { if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
dev = s->cb_config->dev[i]; dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
pci_write_config_byte(dev, PCI_COMMAND, PCI_COMMAND_MASTER | max = pci_scan_bridge(bus, dev, max, pass);
PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, /*
L1_CACHE_BYTES / 4); * Size all resources below the CardBus controller.
} */
pci_bus_size_bridges(bus);
if (s->irq.AssignedIRQ) { pci_bus_assign_resources(bus);
for (i = 0; i < s->functions; i++) { cardbus_assign_irqs(bus, s->cap.pci_irq);
dev = s->cb_config->dev[i]; pci_enable_bridges(bus);
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, pci_bus_add_devices(bus);
s->irq.AssignedIRQ);
} s->irq.AssignedIRQ = s->cap.pci_irq;
s->socket.io_irq = s->irq.AssignedIRQ; return CS_SUCCESS;
s->ss_entry->set_socket(s->sock, &s->socket);
}
} }
/*====================================================================== void cb_free(socket_info_t * s)
cb_disable() unconfigures a Cardbus card previously set up by
cb_enable().
It is called from the ReleaseConfiguration service.
======================================================================*/
void cb_disable(socket_info_t * s)
{ {
DEBUG(0, "cs: cb_disable(bus %d)\n", s->cap.cb_dev->subordinate->number); struct pci_dev *bridge = s->cap.cb_dev;
/* Turn off bridge windows */ pci_remove_behind_bridge(bridge);
cb_release_cis_mem(s);
} }
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <pcmcia/cs_types.h> #include <pcmcia/cs_types.h>
#include <pcmcia/bus_ops.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h> #include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h> #include <pcmcia/bulkmem.h>
...@@ -83,6 +82,52 @@ static const u_int exponent[] = { ...@@ -83,6 +82,52 @@ static const u_int exponent[] = {
INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */
void release_cis_mem(socket_info_t *s)
{
if (s->cis_mem.sys_start != 0) {
s->cis_mem.flags &= ~MAP_ACTIVE;
s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
if (!(s->cap.features & SS_CAP_STATIC_MAP))
release_mem_region(s->cis_mem.sys_start, s->cap.map_size);
iounmap(s->cis_virt);
s->cis_mem.sys_start = 0;
s->cis_virt = NULL;
}
}
/*
* Map the card memory at "card_offset" into virtual space.
* If flags & MAP_ATTRIB, map the attribute space, otherwise
* map the memory space.
*/
static unsigned char *
set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags)
{
pccard_mem_map *mem = &s->cis_mem;
if (!(s->cap.features & SS_CAP_STATIC_MAP) &&
mem->sys_start == 0) {
int low = !(s->cap.features & SS_CAP_PAGE_REGS);
validate_mem(s);
mem->sys_start = 0;
if (find_mem_region(&mem->sys_start, s->cap.map_size,
s->cap.map_size, low, "card services", s)) {
printk(KERN_NOTICE "cs: unable to map card memory!\n");
return NULL;
}
mem->sys_stop = mem->sys_start+s->cap.map_size-1;
s->cis_virt = ioremap(mem->sys_start, s->cap.map_size);
}
mem->card_start = card_offset;
mem->flags = flags;
s->ss_entry->set_mem_map(s->sock, mem);
if (s->cap.features & SS_CAP_STATIC_MAP) {
if (s->cis_virt)
iounmap(s->cis_virt);
s->cis_virt = ioremap(mem->sys_start, s->cap.map_size);
}
return s->cis_virt;
}
/*====================================================================== /*======================================================================
Low-level functions to read and write CIS memory. I think the Low-level functions to read and write CIS memory. I think the
...@@ -94,60 +139,60 @@ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ ...@@ -94,60 +139,60 @@ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */
#define IS_ATTR 1 #define IS_ATTR 1
#define IS_INDIRECT 8 #define IS_INDIRECT 8
static int setup_cis_mem(socket_info_t *s);
static void set_cis_map(socket_info_t *s, pccard_mem_map *mem)
{
s->ss_entry->set_mem_map(s->sock, mem);
if (s->cap.features & SS_CAP_STATIC_MAP) {
if (s->cis_virt)
bus_iounmap(s->cap.bus, s->cis_virt);
s->cis_virt = bus_ioremap(s->cap.bus, mem->sys_start,
s->cap.map_size);
}
}
int read_cis_mem(socket_info_t *s, int attr, u_int addr, int read_cis_mem(socket_info_t *s, int attr, u_int addr,
u_int len, void *ptr) u_int len, void *ptr)
{ {
pccard_mem_map *mem = &s->cis_mem; u_char *sys, *end, *buf = ptr;
u_char *sys, *buf = ptr;
DEBUG(3, "cs: read_cis_mem(%d, %#x, %u)\n", attr, addr, len); DEBUG(3, "cs: read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
if (setup_cis_mem(s) != 0) {
memset(ptr, 0xff, len);
return -1;
}
mem->flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
if (attr & IS_INDIRECT) { if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed /* Indirect accesses use a bunch of special registers at fixed
locations in common memory */ locations in common memory */
u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN; u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
if (attr & IS_ATTR) { addr *= 2; flags = ICTRL0_AUTOINC; } if (attr & IS_ATTR) {
mem->card_start = 0; mem->flags = MAP_ACTIVE; addr *= 2;
set_cis_map(s, mem); flags = ICTRL0_AUTOINC;
sys = s->cis_virt; }
bus_writeb(s->cap.bus, flags, sys+CISREG_ICTRL0);
bus_writeb(s->cap.bus, addr & 0xff, sys+CISREG_IADDR0); sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
bus_writeb(s->cap.bus, (addr>>8) & 0xff, sys+CISREG_IADDR1); if (!sys) {
bus_writeb(s->cap.bus, (addr>>16) & 0xff, sys+CISREG_IADDR2); memset(ptr, 0xff, len);
bus_writeb(s->cap.bus, (addr>>24) & 0xff, sys+CISREG_IADDR3); return -1;
}
writeb(flags, sys+CISREG_ICTRL0);
writeb(addr & 0xff, sys+CISREG_IADDR0);
writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
for ( ; len > 0; len--, buf++) for ( ; len > 0; len--, buf++)
*buf = bus_readb(s->cap.bus, sys+CISREG_IDATA0); *buf = readb(sys+CISREG_IDATA0);
} else { } else {
u_int inc = 1; u_int inc = 1, card_offset, flags;
if (attr) { mem->flags |= MAP_ATTRIB; inc++; addr *= 2; }
sys += (addr & (s->cap.map_size-1)); flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
mem->card_start = addr & ~(s->cap.map_size-1); if (attr) {
flags |= MAP_ATTRIB;
inc++;
addr *= 2;
}
card_offset = addr & ~(s->cap.map_size-1);
while (len) { while (len) {
set_cis_map(s, mem); sys = set_cis_map(s, card_offset, flags);
sys = s->cis_virt + (addr & (s->cap.map_size-1)); if (!sys) {
memset(ptr, 0xff, len);
return -1;
}
end = sys + s->cap.map_size;
sys = sys + (addr & (s->cap.map_size-1));
for ( ; len > 0; len--, buf++, sys += inc) { for ( ; len > 0; len--, buf++, sys += inc) {
if (sys == s->cis_virt+s->cap.map_size) break; if (sys == end)
*buf = bus_readb(s->cap.bus, sys); break;
*buf = readb(sys);
} }
mem->card_start += s->cap.map_size; card_offset += s->cap.map_size;
addr = 0; addr = 0;
} }
} }
...@@ -160,134 +205,56 @@ int read_cis_mem(socket_info_t *s, int attr, u_int addr, ...@@ -160,134 +205,56 @@ int read_cis_mem(socket_info_t *s, int attr, u_int addr,
void write_cis_mem(socket_info_t *s, int attr, u_int addr, void write_cis_mem(socket_info_t *s, int attr, u_int addr,
u_int len, void *ptr) u_int len, void *ptr)
{ {
pccard_mem_map *mem = &s->cis_mem; u_char *sys, *end, *buf = ptr;
u_char *sys, *buf = ptr;
DEBUG(3, "cs: write_cis_mem(%d, %#x, %u)\n", attr, addr, len); DEBUG(3, "cs: write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
if (setup_cis_mem(s) != 0) return;
mem->flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
if (attr & IS_INDIRECT) { if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed /* Indirect accesses use a bunch of special registers at fixed
locations in common memory */ locations in common memory */
u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN; u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
if (attr & IS_ATTR) { addr *= 2; flags = ICTRL0_AUTOINC; } if (attr & IS_ATTR) {
mem->card_start = 0; mem->flags = MAP_ACTIVE; addr *= 2;
set_cis_map(s, mem); flags = ICTRL0_AUTOINC;
sys = s->cis_virt;
bus_writeb(s->cap.bus, flags, sys+CISREG_ICTRL0);
bus_writeb(s->cap.bus, addr & 0xff, sys+CISREG_IADDR0);
bus_writeb(s->cap.bus, (addr>>8) & 0xff, sys+CISREG_IADDR1);
bus_writeb(s->cap.bus, (addr>>16) & 0xff, sys+CISREG_IADDR2);
bus_writeb(s->cap.bus, (addr>>24) & 0xff, sys+CISREG_IADDR3);
for ( ; len > 0; len--, buf++)
bus_writeb(s->cap.bus, *buf, sys+CISREG_IDATA0);
} else {
int inc = 1;
if (attr & IS_ATTR) { mem->flags |= MAP_ATTRIB; inc++; addr *= 2; }
mem->card_start = addr & ~(s->cap.map_size-1);
while (len) {
set_cis_map(s, mem);
sys = s->cis_virt + (addr & (s->cap.map_size-1));
for ( ; len > 0; len--, buf++, sys += inc) {
if (sys == s->cis_virt+s->cap.map_size) break;
bus_writeb(s->cap.bus, *buf, sys);
}
mem->card_start += s->cap.map_size;
addr = 0;
} }
}
}
/*======================================================================
This is tricky... when we set up CIS memory, we try to validate
the memory window space allocations.
======================================================================*/
/* Scratch pointer to the socket we use for validation */ sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
static socket_info_t *vs = NULL; if (!sys)
return; /* FIXME: Error */
/* Validation function for cards with a valid CIS */ writeb(flags, sys+CISREG_ICTRL0);
static int cis_readable(u_long base) writeb(addr & 0xff, sys+CISREG_IADDR0);
{ writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
cisinfo_t info1, info2; writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
int ret; writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
vs->cis_mem.sys_start = base; for ( ; len > 0; len--, buf++)
vs->cis_mem.sys_stop = base+vs->cap.map_size-1; writeb(*buf, sys+CISREG_IDATA0);
vs->cis_virt = bus_ioremap(vs->cap.bus, base, vs->cap.map_size); } else {
ret = pcmcia_validate_cis(vs->clients, &info1); u_int inc = 1, card_offset, flags;
/* invalidate mapping and CIS cache */
bus_iounmap(vs->cap.bus, vs->cis_virt); vs->cis_used = 0;
if ((ret != 0) || (info1.Chains == 0))
return 0;
vs->cis_mem.sys_start = base+vs->cap.map_size;
vs->cis_mem.sys_stop = base+2*vs->cap.map_size-1;
vs->cis_virt = bus_ioremap(vs->cap.bus, base+vs->cap.map_size,
vs->cap.map_size);
ret = pcmcia_validate_cis(vs->clients, &info2);
bus_iounmap(vs->cap.bus, vs->cis_virt); vs->cis_used = 0;
return ((ret == 0) && (info1.Chains == info2.Chains));
}
/* Validation function for simple memory cards */ flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
static int checksum(u_long base) if (attr & IS_ATTR) {
{ flags |= MAP_ATTRIB;
int i, a, b, d; inc++;
vs->cis_mem.sys_start = base; addr *= 2;
vs->cis_mem.sys_stop = base+vs->cap.map_size-1; }
vs->cis_virt = bus_ioremap(vs->cap.bus, base, vs->cap.map_size);
vs->cis_mem.card_start = 0;
vs->cis_mem.flags = MAP_ACTIVE;
vs->ss_entry->set_mem_map(vs->sock, &vs->cis_mem);
/* Don't bother checking every word... */
a = 0; b = -1;
for (i = 0; i < vs->cap.map_size; i += 44) {
d = bus_readl(vs->cap.bus, vs->cis_virt+i);
a += d; b &= d;
}
bus_iounmap(vs->cap.bus, vs->cis_virt);
return (b == -1) ? -1 : (a>>1);
}
static int checksum_match(u_long base) card_offset = addr & ~(s->cap.map_size-1);
{ while (len) {
int a = checksum(base), b = checksum(base+vs->cap.map_size); sys = set_cis_map(s, card_offset, flags);
return ((a == b) && (a >= 0)); if (!sys)
} return; /* FIXME: error */
static int setup_cis_mem(socket_info_t *s) end = sys + s->cap.map_size;
{ sys = sys + (addr & (s->cap.map_size-1));
if (!(s->cap.features & SS_CAP_STATIC_MAP) && for ( ; len > 0; len--, buf++, sys += inc) {
(s->cis_mem.sys_start == 0)) { if (sys == end)
int low = !(s->cap.features & SS_CAP_PAGE_REGS); break;
vs = s; writeb(*buf, sys);
validate_mem(cis_readable, checksum_match, low, s); }
s->cis_mem.sys_start = 0; card_offset += s->cap.map_size;
vs = NULL; addr = 0;
if (find_mem_region(&s->cis_mem.sys_start, s->cap.map_size,
s->cap.map_size, low, "card services", s)) {
printk(KERN_NOTICE "cs: unable to map card memory!\n");
return -1;
} }
s->cis_mem.sys_stop = s->cis_mem.sys_start+s->cap.map_size-1;
s->cis_virt = bus_ioremap(s->cap.bus, s->cis_mem.sys_start,
s->cap.map_size);
}
return 0;
}
void release_cis_mem(socket_info_t *s)
{
if (s->cis_mem.sys_start != 0) {
s->cis_mem.flags &= ~MAP_ACTIVE;
s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
if (!(s->cap.features & SS_CAP_STATIC_MAP))
release_mem_region(s->cis_mem.sys_start, s->cap.map_size);
bus_iounmap(s->cap.bus, s->cis_virt);
s->cis_mem.sys_start = 0;
s->cis_virt = NULL;
} }
} }
...@@ -427,11 +394,9 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple) ...@@ -427,11 +394,9 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
tuple->TupleLink = tuple->Flags = 0; tuple->TupleLink = tuple->Flags = 0;
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
if (s->state & SOCKET_CARDBUS) { if (s->state & SOCKET_CARDBUS) {
struct pci_dev *dev = s->cap.cb_dev;
u_int ptr; u_int ptr;
struct pci_dev *dev = pci_find_slot (s->cap.cb_dev->subordinate->number, 0); pci_bus_read_config_dword(dev->subordinate, 0, PCI_CARDBUS_CIS, &ptr);
if (!dev)
return CS_BAD_HANDLE;
pci_read_config_dword(dev, 0x28, &ptr);
tuple->CISOffset = ptr & ~7; tuple->CISOffset = ptr & ~7;
SPACE(tuple->Flags) = (ptr & 7); SPACE(tuple->Flags) = (ptr & 7);
} else } else
......
...@@ -59,7 +59,6 @@ ...@@ -59,7 +59,6 @@
#include <pcmcia/bulkmem.h> #include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/bus_ops.h>
#include "cs_internal.h" #include "cs_internal.h"
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -622,8 +621,10 @@ static void unreset_socket(socket_info_t *s) ...@@ -622,8 +621,10 @@ static void unreset_socket(socket_info_t *s)
send_event(s, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW); send_event(s, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
} else if (s->state & SOCKET_SETUP_PENDING) { } else if (s->state & SOCKET_SETUP_PENDING) {
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
if (s->state & SOCKET_CARDBUS) if (s->state & SOCKET_CARDBUS) {
cb_alloc(s); cb_alloc(s);
s->state |= SOCKET_CARDBUS_CONFIG;
}
#endif #endif
send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
s->state &= ~SOCKET_SETUP_PENDING; s->state &= ~SOCKET_SETUP_PENDING;
...@@ -1077,7 +1078,7 @@ int pcmcia_get_configuration_info(client_handle_t handle, ...@@ -1077,7 +1078,7 @@ int pcmcia_get_configuration_info(client_handle_t handle,
config->Vcc = s->socket.Vcc; config->Vcc = s->socket.Vcc;
config->Vpp1 = config->Vpp2 = s->socket.Vpp; config->Vpp1 = config->Vpp2 = s->socket.Vpp;
config->Option = s->cap.cb_dev->subordinate->number; config->Option = s->cap.cb_dev->subordinate->number;
if (s->cb_config) { if (s->state & SOCKET_CARDBUS_CONFIG) {
config->Attributes = CONF_VALID_CLIENT; config->Attributes = CONF_VALID_CLIENT;
config->IntType = INT_CARDBUS; config->IntType = INT_CARDBUS;
config->AssignedIRQ = s->irq.AssignedIRQ; config->AssignedIRQ = s->irq.AssignedIRQ;
...@@ -1473,7 +1474,6 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) ...@@ -1473,7 +1474,6 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
client->event_handler = req->event_handler; client->event_handler = req->event_handler;
client->event_callback_args = req->event_callback_args; client->event_callback_args = req->event_callback_args;
client->event_callback_args.client_handle = client; client->event_callback_args.client_handle = client;
client->event_callback_args.bus = s->cap.bus;
if (s->state & SOCKET_CARDBUS) if (s->state & SOCKET_CARDBUS)
client->state |= CLIENT_CARDBUS; client->state |= CLIENT_CARDBUS;
...@@ -1522,11 +1522,8 @@ int pcmcia_release_configuration(client_handle_t handle) ...@@ -1522,11 +1522,8 @@ int pcmcia_release_configuration(client_handle_t handle)
s = SOCKET(handle); s = SOCKET(handle);
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
if (handle->state & CLIENT_CARDBUS) { if (handle->state & CLIENT_CARDBUS)
cb_disable(s);
s->lock_count = 0;
return CS_SUCCESS; return CS_SUCCESS;
}
#endif #endif
if (!(handle->state & CLIENT_STALE)) { if (!(handle->state & CLIENT_STALE)) {
...@@ -1573,9 +1570,8 @@ int pcmcia_release_io(client_handle_t handle, io_req_t *req) ...@@ -1573,9 +1570,8 @@ int pcmcia_release_io(client_handle_t handle, io_req_t *req)
s = SOCKET(handle); s = SOCKET(handle);
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
if (handle->state & CLIENT_CARDBUS) { if (handle->state & CLIENT_CARDBUS)
return CS_SUCCESS; return CS_SUCCESS;
}
#endif #endif
if (!(handle->state & CLIENT_STALE)) { if (!(handle->state & CLIENT_STALE)) {
...@@ -1622,10 +1618,10 @@ int pcmcia_release_irq(client_handle_t handle, irq_req_t *req) ...@@ -1622,10 +1618,10 @@ int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
} }
if (req->Attributes & IRQ_HANDLE_PRESENT) { if (req->Attributes & IRQ_HANDLE_PRESENT) {
bus_free_irq(s->cap.bus, req->AssignedIRQ, req->Instance); free_irq(req->AssignedIRQ, req->Instance);
} }
#ifdef CONFIG_ISA #ifdef CONFIG_PCMCIA_PROBE
if (req->AssignedIRQ != s->cap.pci_irq) if (req->AssignedIRQ != s->cap.pci_irq)
undo_irq(req->Attributes, req->AssignedIRQ); undo_irq(req->Attributes, req->AssignedIRQ);
#endif #endif
...@@ -1678,16 +1674,8 @@ int pcmcia_request_configuration(client_handle_t handle, ...@@ -1678,16 +1674,8 @@ int pcmcia_request_configuration(client_handle_t handle,
return CS_NO_CARD; return CS_NO_CARD;
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
if (handle->state & CLIENT_CARDBUS) { if (handle->state & CLIENT_CARDBUS)
if (!(req->IntType & INT_CARDBUS)) return CS_UNSUPPORTED_MODE;
return CS_UNSUPPORTED_MODE;
if (s->lock_count != 0)
return CS_CONFIGURATION_LOCKED;
cb_enable(s);
handle->state |= CLIENT_CONFIG_LOCKED;
s->lock_count++;
return CS_SUCCESS;
}
#endif #endif
if (req->IntType & INT_CARDBUS) if (req->IntType & INT_CARDBUS)
...@@ -1887,7 +1875,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) ...@@ -1887,7 +1875,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
if (!s->cap.irq_mask) { if (!s->cap.irq_mask) {
irq = s->cap.pci_irq; irq = s->cap.pci_irq;
ret = (irq) ? 0 : CS_IN_USE; ret = (irq) ? 0 : CS_IN_USE;
#ifdef CONFIG_ISA #ifdef CONFIG_PCMCIA_PROBE
} else if (s->irq.AssignedIRQ != 0) { } else if (s->irq.AssignedIRQ != 0) {
/* If the interrupt is already assigned, it must match */ /* If the interrupt is already assigned, it must match */
irq = s->irq.AssignedIRQ; irq = s->irq.AssignedIRQ;
...@@ -1917,7 +1905,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) ...@@ -1917,7 +1905,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
if (ret != 0) return ret; if (ret != 0) return ret;
if (req->Attributes & IRQ_HANDLE_PRESENT) { if (req->Attributes & IRQ_HANDLE_PRESENT) {
if (bus_request_irq(s->cap.bus, irq, req->Handler, if (request_irq(irq, req->Handler,
((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
(s->functions > 1) || (s->functions > 1) ||
(irq == s->cap.pci_irq)) ? SA_SHIRQ : 0, (irq == s->cap.pci_irq)) ? SA_SHIRQ : 0,
......
...@@ -136,7 +136,6 @@ typedef struct socket_info_t { ...@@ -136,7 +136,6 @@ typedef struct socket_info_t {
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
struct resource * cb_cis_res; struct resource * cb_cis_res;
u_char *cb_cis_virt; u_char *cb_cis_virt;
struct cb_config_t *cb_config;
#endif #endif
struct { struct {
u_int AssignedIRQ; u_int AssignedIRQ;
...@@ -176,6 +175,7 @@ typedef struct socket_info_t { ...@@ -176,6 +175,7 @@ typedef struct socket_info_t {
#define SOCKET_IO_REQ(i) (0x1000<<(i)) #define SOCKET_IO_REQ(i) (0x1000<<(i))
#define SOCKET_REGION_INFO 0x4000 #define SOCKET_REGION_INFO 0x4000
#define SOCKET_CARDBUS 0x8000 #define SOCKET_CARDBUS 0x8000
#define SOCKET_CARDBUS_CONFIG 0x10000
#define CHECK_HANDLE(h) \ #define CHECK_HANDLE(h) \
(((h) == NULL) || ((h)->client_magic != CLIENT_MAGIC)) (((h) == NULL) || ((h)->client_magic != CLIENT_MAGIC))
...@@ -198,8 +198,6 @@ typedef struct socket_info_t { ...@@ -198,8 +198,6 @@ typedef struct socket_info_t {
/* In cardbus.c */ /* In cardbus.c */
int cb_alloc(socket_info_t *s); int cb_alloc(socket_info_t *s);
void cb_free(socket_info_t *s); void cb_free(socket_info_t *s);
void cb_enable(socket_info_t *s);
void cb_disable(socket_info_t *s);
int read_cb_mem(socket_info_t *s, int space, u_int addr, u_int len, void *ptr); int read_cb_mem(socket_info_t *s, int space, u_int addr, u_int len, void *ptr);
void cb_release_cis_mem(socket_info_t *s); void cb_release_cis_mem(socket_info_t *s);
...@@ -234,8 +232,7 @@ int write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf); ...@@ -234,8 +232,7 @@ int write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf);
int copy_memory(memory_handle_t handle, copy_op_t *req); int copy_memory(memory_handle_t handle, copy_op_t *req);
/* In rsrc_mgr */ /* In rsrc_mgr */
void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long), void validate_mem(socket_info_t *s);
int force_low, socket_info_t *s);
int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
char *name, socket_info_t *s); char *name, socket_info_t *s);
int find_mem_region(u_long *base, u_long num, u_long align, int find_mem_region(u_long *base, u_long num, u_long align,
......
...@@ -599,21 +599,6 @@ static int hs_set_socket(unsigned int sock, socket_state_t *state) ...@@ -599,21 +599,6 @@ static int hs_set_socket(unsigned int sock, socket_state_t *state)
/*============================================================*/ /*============================================================*/
static int hs_get_io_map(unsigned int sock, struct pccard_io_map *io)
{
hs_socket_t *sp = &hs_sockets[sock];
int map = io->map;
DPRINTK("hs_get_io_map(%d, %d)\n", sock, map);
if (map >= MAX_IO_WIN)
return -EINVAL;
*io = sp->io_maps[map];
return 0;
}
/*============================================================*/
static int hs_set_io_map(unsigned int sock, struct pccard_io_map *io) static int hs_set_io_map(unsigned int sock, struct pccard_io_map *io)
{ {
hs_socket_t *sp = &hs_sockets[sock]; hs_socket_t *sp = &hs_sockets[sock];
...@@ -696,21 +681,6 @@ static int hs_set_io_map(unsigned int sock, struct pccard_io_map *io) ...@@ -696,21 +681,6 @@ static int hs_set_io_map(unsigned int sock, struct pccard_io_map *io)
/*============================================================*/ /*============================================================*/
static int hs_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{
hs_socket_t *sp = &hs_sockets[sock];
int map = mem->map;
DPRINTK("hs_get_mem_map(%d, %d)\n", sock, map);
if (map >= MAX_WIN)
return -EINVAL;
*mem = sp->mem_maps[map];
return 0;
}
/*============================================================*/
static int hs_set_mem_map(unsigned int sock, struct pccard_mem_map *mem) static int hs_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{ {
hs_socket_t *sp = &hs_sockets[sock]; hs_socket_t *sp = &hs_sockets[sock];
...@@ -894,9 +864,7 @@ static struct pccard_operations hs_operations = { ...@@ -894,9 +864,7 @@ static struct pccard_operations hs_operations = {
.get_status = hs_get_status, .get_status = hs_get_status,
.get_socket = hs_get_socket, .get_socket = hs_get_socket,
.set_socket = hs_set_socket, .set_socket = hs_set_socket,
.get_io_map = hs_get_io_map,
.set_io_map = hs_set_io_map, .set_io_map = hs_set_io_map,
.get_mem_map = hs_get_mem_map,
.set_mem_map = hs_set_mem_map, .set_mem_map = hs_set_mem_map,
.proc_setup = hs_proc_setup, .proc_setup = hs_proc_setup,
}; };
......
...@@ -63,9 +63,7 @@ static struct pccard_operations i82092aa_operations = { ...@@ -63,9 +63,7 @@ static struct pccard_operations i82092aa_operations = {
.get_status = i82092aa_get_status, .get_status = i82092aa_get_status,
.get_socket = i82092aa_get_socket, .get_socket = i82092aa_get_socket,
.set_socket = i82092aa_set_socket, .set_socket = i82092aa_set_socket,
.get_io_map = i82092aa_get_io_map,
.set_io_map = i82092aa_set_io_map, .set_io_map = i82092aa_set_io_map,
.get_mem_map = i82092aa_get_mem_map,
.set_mem_map = i82092aa_set_mem_map, .set_mem_map = i82092aa_set_mem_map,
.proc_setup = i82092aa_proc_setup, .proc_setup = i82092aa_proc_setup,
}; };
...@@ -688,34 +686,6 @@ static int i82092aa_set_socket(unsigned int sock, socket_state_t *state) ...@@ -688,34 +686,6 @@ static int i82092aa_set_socket(unsigned int sock, socket_state_t *state)
return 0; return 0;
} }
static int i82092aa_get_io_map(unsigned int sock, struct pccard_io_map *io)
{
unsigned char map, ioctl, addr;
enter("i82092aa_get_io_map");
map = io->map;
if (map > 1) {
leave("i82092aa_get_io_map with -EINVAL");
return -EINVAL;
}
/* FIXME: How does this fit in with the PCI resource (re)allocation */
io->start = indirect_read16(sock, I365_IO(map)+I365_W_START);
io->stop = indirect_read16(sock, I365_IO(map)+I365_W_START);
ioctl = indirect_read(sock,I365_IOCTL); /* IOCREG: I/O Control Register */
addr = indirect_read(sock,I365_ADDRWIN); /* */
io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0; /* check this out later */
io->flags = 0;
if (addr & I365_IOCTL_16BIT(map))
io->flags |= MAP_AUTOSZ;
leave("i82092aa_get_io_map");
return 0;
}
static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io) static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io)
{ {
unsigned char map, ioctl; unsigned char map, ioctl;
...@@ -759,64 +729,6 @@ static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io) ...@@ -759,64 +729,6 @@ static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io)
return 0; return 0;
} }
static int i82092aa_get_mem_map(unsigned sock, struct pccard_mem_map *mem)
{
unsigned short base, i;
unsigned char map, addr;
enter("i82092aa_get_mem_map");
mem->flags = 0;
mem->speed = 0;
map = mem->map;
if (map > 4) {
leave("i82092aa_get_mem_map: -EINVAL");
return -EINVAL;
}
addr = indirect_read(sock, I365_ADDRWIN);
if (addr & I365_ENA_MEM(map))
mem->flags |= MAP_ACTIVE; /* yes this mapping is active */
base = I365_MEM(map);
/* Find the start address - this register also has mapping info */
i = indirect_read16(sock,base+I365_W_START);
if (i & I365_MEM_16BIT)
mem->flags |= MAP_16BIT;
if (i & I365_MEM_0WS)
mem->flags |= MAP_0WS;
mem->sys_start = ((unsigned long)(i & 0x0fff) << 12);
/* Find the end address - this register also has speed info */
i = indirect_read16(sock,base+I365_W_STOP);
if (i & I365_MEM_WS0)
mem->speed = 1;
if (i & I365_MEM_WS1)
mem->speed += 2;
mem->speed = to_ns(mem->speed);
mem->sys_stop = ( (unsigned long)(i & 0x0fff) << 12) + 0x0fff;
/* Find the card start address, also some more MAP attributes */
i = indirect_read16(sock, base+I365_W_OFF);
if (i & I365_MEM_WRPROT)
mem->flags |= MAP_WRPROT;
if (i & I365_MEM_REG)
mem->flags |= MAP_ATTRIB;
mem->card_start = ( (unsigned long)(i & 0x3fff)<12) + mem->sys_start;
mem->card_start &= 0x3ffffff;
printk("Card %i is from %lx to %lx \n",sock,mem->sys_start,mem->sys_stop);
leave("i82092aa_get_mem_map");
return 0;
}
static int i82092aa_set_mem_map(unsigned sock, struct pccard_mem_map *mem) static int i82092aa_set_mem_map(unsigned sock, struct pccard_mem_map *mem)
{ {
unsigned short base, i; unsigned short base, i;
......
...@@ -29,9 +29,7 @@ static void i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs); ...@@ -29,9 +29,7 @@ static void i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs);
static int i82092aa_get_status(unsigned int sock, u_int *value); static int i82092aa_get_status(unsigned int sock, u_int *value);
static int i82092aa_get_socket(unsigned int sock, socket_state_t *state); static int i82092aa_get_socket(unsigned int sock, socket_state_t *state);
static int i82092aa_set_socket(unsigned int sock, socket_state_t *state); static int i82092aa_set_socket(unsigned int sock, socket_state_t *state);
static int i82092aa_get_io_map(unsigned int sock, struct pccard_io_map *io);
static int i82092aa_set_io_map(unsigned int sock, struct pccard_io_map *io); static int i82092aa_set_io_map(unsigned int sock, struct pccard_io_map *io);
static int i82092aa_get_mem_map(unsigned int sock, struct pccard_mem_map *mem);
static int i82092aa_set_mem_map(unsigned int sock, struct pccard_mem_map *mem); static int i82092aa_set_mem_map(unsigned int sock, struct pccard_mem_map *mem);
static int i82092aa_init(unsigned int s); static int i82092aa_init(unsigned int s);
static int i82092aa_suspend(unsigned int sock); static int i82092aa_suspend(unsigned int sock);
......
...@@ -1250,29 +1250,6 @@ static int i365_set_socket(u_short sock, socket_state_t *state) ...@@ -1250,29 +1250,6 @@ static int i365_set_socket(u_short sock, socket_state_t *state)
/*====================================================================*/ /*====================================================================*/
static int i365_get_io_map(u_short sock, struct pccard_io_map *io)
{
u_char map, ioctl, addr;
map = io->map;
if (map > 1) return -EINVAL;
io->start = i365_get_pair(sock, I365_IO(map)+I365_W_START);
io->stop = i365_get_pair(sock, I365_IO(map)+I365_W_STOP);
ioctl = i365_get(sock, I365_IOCTL);
addr = i365_get(sock, I365_ADDRWIN);
io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0;
io->flags = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0;
io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;
io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;
io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;
DEBUG(1, "i82365: GetIOMap(%d, %d) = %#2.2x, %d ns, "
"%#4.4x-%#4.4x\n", sock, map, io->flags, io->speed,
io->start, io->stop);
return 0;
} /* i365_get_io_map */
/*====================================================================*/
static int i365_set_io_map(u_short sock, struct pccard_io_map *io) static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
{ {
u_char map, ioctl; u_char map, ioctl;
...@@ -1302,42 +1279,6 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io) ...@@ -1302,42 +1279,6 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
/*====================================================================*/ /*====================================================================*/
static int i365_get_mem_map(u_short sock, struct pccard_mem_map *mem)
{
u_short base, i;
u_char map, addr;
map = mem->map;
if (map > 4) return -EINVAL;
addr = i365_get(sock, I365_ADDRWIN);
mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0;
base = I365_MEM(map);
i = i365_get_pair(sock, base+I365_W_START);
mem->flags |= (i & I365_MEM_16BIT) ? MAP_16BIT : 0;
mem->flags |= (i & I365_MEM_0WS) ? MAP_0WS : 0;
mem->sys_start = ((u_long)(i & 0x0fff) << 12);
i = i365_get_pair(sock, base+I365_W_STOP);
mem->speed = (i & I365_MEM_WS0) ? 1 : 0;
mem->speed += (i & I365_MEM_WS1) ? 2 : 0;
mem->speed = to_ns(mem->speed);
mem->sys_stop = ((u_long)(i & 0x0fff) << 12) + 0x0fff;
i = i365_get_pair(sock, base+I365_W_OFF);
mem->flags |= (i & I365_MEM_WRPROT) ? MAP_WRPROT : 0;
mem->flags |= (i & I365_MEM_REG) ? MAP_ATTRIB : 0;
mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start;
mem->card_start &= 0x3ffffff;
DEBUG(1, "i82365: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5."
"5lx, %#5.5x\n", sock, mem->map, mem->flags, mem->speed,
mem->sys_start, mem->sys_stop, mem->card_start);
return 0;
} /* i365_get_mem_map */
/*====================================================================*/
static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
{ {
u_short base, i; u_short base, i;
...@@ -1506,14 +1447,6 @@ static int pcic_set_socket(unsigned int sock, socket_state_t *state) ...@@ -1506,14 +1447,6 @@ static int pcic_set_socket(unsigned int sock, socket_state_t *state)
LOCKED(i365_set_socket(sock, state)); LOCKED(i365_set_socket(sock, state));
} }
static int pcic_get_io_map(unsigned int sock, struct pccard_io_map *io)
{
if (socket[sock].flags & IS_ALIVE)
return -EINVAL;
LOCKED(i365_get_io_map(sock, io));
}
static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io) static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io)
{ {
if (socket[sock].flags & IS_ALIVE) if (socket[sock].flags & IS_ALIVE)
...@@ -1522,14 +1455,6 @@ static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io) ...@@ -1522,14 +1455,6 @@ static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io)
LOCKED(i365_set_io_map(sock, io)); LOCKED(i365_set_io_map(sock, io));
} }
static int pcic_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{
if (socket[sock].flags & IS_ALIVE)
return -EINVAL;
LOCKED(i365_get_mem_map(sock, mem));
}
static int pcic_set_mem_map(unsigned int sock, struct pccard_mem_map *mem) static int pcic_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{ {
if (socket[sock].flags & IS_ALIVE) if (socket[sock].flags & IS_ALIVE)
...@@ -1571,9 +1496,7 @@ static struct pccard_operations pcic_operations = { ...@@ -1571,9 +1496,7 @@ static struct pccard_operations pcic_operations = {
.get_status = pcic_get_status, .get_status = pcic_get_status,
.get_socket = pcic_get_socket, .get_socket = pcic_get_socket,
.set_socket = pcic_set_socket, .set_socket = pcic_set_socket,
.get_io_map = pcic_get_io_map,
.set_io_map = pcic_set_io_map, .set_io_map = pcic_set_io_map,
.get_mem_map = pcic_get_mem_map,
.set_mem_map = pcic_set_mem_map, .set_mem_map = pcic_set_mem_map,
.proc_setup = pcic_proc_setup, .proc_setup = pcic_proc_setup,
}; };
......
...@@ -105,15 +105,6 @@ static int pci_set_socket(unsigned int sock, socket_state_t *state) ...@@ -105,15 +105,6 @@ static int pci_set_socket(unsigned int sock, socket_state_t *state)
return -EINVAL; return -EINVAL;
} }
static int pci_get_io_map(unsigned int sock, struct pccard_io_map *io)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->get_io_map)
return socket->op->get_io_map(socket, io);
return -EINVAL;
}
static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io) static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io)
{ {
pci_socket_t *socket = pci_socket_array + sock; pci_socket_t *socket = pci_socket_array + sock;
...@@ -123,15 +114,6 @@ static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io) ...@@ -123,15 +114,6 @@ static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io)
return -EINVAL; return -EINVAL;
} }
static int pci_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{
pci_socket_t *socket = pci_socket_array + sock;
if (socket->op && socket->op->get_mem_map)
return socket->op->get_mem_map(socket, mem);
return -EINVAL;
}
static int pci_set_mem_map(unsigned int sock, struct pccard_mem_map *mem) static int pci_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{ {
pci_socket_t *socket = pci_socket_array + sock; pci_socket_t *socket = pci_socket_array + sock;
...@@ -158,9 +140,7 @@ static struct pccard_operations pci_socket_operations = { ...@@ -158,9 +140,7 @@ static struct pccard_operations pci_socket_operations = {
.get_status = pci_get_status, .get_status = pci_get_status,
.get_socket = pci_get_socket, .get_socket = pci_get_socket,
.set_socket = pci_set_socket, .set_socket = pci_set_socket,
.get_io_map = pci_get_io_map,
.set_io_map = pci_set_io_map, .set_io_map = pci_set_io_map,
.get_mem_map = pci_get_mem_map,
.set_mem_map = pci_set_mem_map, .set_mem_map = pci_set_mem_map,
.proc_setup = pci_proc_setup, .proc_setup = pci_proc_setup,
}; };
......
...@@ -37,9 +37,7 @@ struct pci_socket_ops { ...@@ -37,9 +37,7 @@ struct pci_socket_ops {
int (*get_status)(struct pci_socket *, unsigned int *); int (*get_status)(struct pci_socket *, unsigned int *);
int (*get_socket)(struct pci_socket *, socket_state_t *); int (*get_socket)(struct pci_socket *, socket_state_t *);
int (*set_socket)(struct pci_socket *, socket_state_t *); int (*set_socket)(struct pci_socket *, socket_state_t *);
int (*get_io_map)(struct pci_socket *, struct pccard_io_map *);
int (*set_io_map)(struct pci_socket *, struct pccard_io_map *); int (*set_io_map)(struct pci_socket *, struct pccard_io_map *);
int (*get_mem_map)(struct pci_socket *, struct pccard_mem_map *);
int (*set_mem_map)(struct pci_socket *, struct pccard_mem_map *); int (*set_mem_map)(struct pci_socket *, struct pccard_mem_map *);
void (*proc_setup)(struct pci_socket *, struct proc_dir_entry *base); void (*proc_setup)(struct pci_socket *, struct proc_dir_entry *base);
}; };
......
...@@ -170,9 +170,7 @@ static struct pci_socket_ops ricoh_ops = { ...@@ -170,9 +170,7 @@ static struct pci_socket_ops ricoh_ops = {
yenta_get_status, yenta_get_status,
yenta_get_socket, yenta_get_socket,
yenta_set_socket, yenta_set_socket,
yenta_get_io_map,
yenta_set_io_map, yenta_set_io_map,
yenta_get_mem_map,
yenta_set_mem_map, yenta_set_mem_map,
yenta_proc_setup yenta_proc_setup
}; };
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
INT_MODULE_PARM(probe_mem, 1); /* memory probe? */ INT_MODULE_PARM(probe_mem, 1); /* memory probe? */
#ifdef CONFIG_ISA #ifdef CONFIG_PCMCIA_PROBE
INT_MODULE_PARM(probe_io, 1); /* IO port probe? */ INT_MODULE_PARM(probe_io, 1); /* IO port probe? */
INT_MODULE_PARM(mem_limit, 0x10000); INT_MODULE_PARM(mem_limit, 0x10000);
#endif #endif
...@@ -83,7 +83,9 @@ static resource_map_t mem_db = { 0, 0, &mem_db }; ...@@ -83,7 +83,9 @@ static resource_map_t mem_db = { 0, 0, &mem_db };
/* IO port resource database */ /* IO port resource database */
static resource_map_t io_db = { 0, 0, &io_db }; static resource_map_t io_db = { 0, 0, &io_db };
#ifdef CONFIG_ISA static DECLARE_MUTEX(rsrc_sem);
#ifdef CONFIG_PCMCIA_PROBE
typedef struct irq_info_t { typedef struct irq_info_t {
u_int Attributes; u_int Attributes;
...@@ -269,7 +271,7 @@ static int sub_interval(resource_map_t *map, u_long base, u_long num) ...@@ -269,7 +271,7 @@ static int sub_interval(resource_map_t *map, u_long base, u_long num)
======================================================================*/ ======================================================================*/
#ifdef CONFIG_ISA #ifdef CONFIG_PCMCIA_PROBE
static void do_io_probe(ioaddr_t base, ioaddr_t num) static void do_io_probe(ioaddr_t base, ioaddr_t num)
{ {
...@@ -331,6 +333,62 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num) ...@@ -331,6 +333,62 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num)
} }
#endif #endif
/*======================================================================
This is tricky... when we set up CIS memory, we try to validate
the memory window space allocations.
======================================================================*/
/* Validation function for cards with a valid CIS */
static int cis_readable(socket_info_t *s, u_long base)
{
cisinfo_t info1, info2;
int ret;
s->cis_mem.sys_start = base;
s->cis_mem.sys_stop = base+s->cap.map_size-1;
s->cis_virt = ioremap(base, s->cap.map_size);
ret = pcmcia_validate_cis(s->clients, &info1);
/* invalidate mapping and CIS cache */
iounmap(s->cis_virt);
s->cis_used = 0;
if ((ret != 0) || (info1.Chains == 0))
return 0;
s->cis_mem.sys_start = base+s->cap.map_size;
s->cis_mem.sys_stop = base+2*s->cap.map_size-1;
s->cis_virt = ioremap(base+s->cap.map_size, s->cap.map_size);
ret = pcmcia_validate_cis(s->clients, &info2);
iounmap(s->cis_virt);
s->cis_used = 0;
return ((ret == 0) && (info1.Chains == info2.Chains));
}
/* Validation function for simple memory cards */
static int checksum(socket_info_t *s, u_long base)
{
int i, a, b, d;
s->cis_mem.sys_start = base;
s->cis_mem.sys_stop = base+s->cap.map_size-1;
s->cis_virt = ioremap(base, s->cap.map_size);
s->cis_mem.card_start = 0;
s->cis_mem.flags = MAP_ACTIVE;
s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
/* Don't bother checking every word... */
a = 0; b = -1;
for (i = 0; i < s->cap.map_size; i += 44) {
d = readl(s->cis_virt+i);
a += d; b &= d;
}
iounmap(s->cis_virt);
return (b == -1) ? -1 : (a>>1);
}
static int checksum_match(socket_info_t *s, u_long base)
{
int a = checksum(s, base), b = checksum(s, base+s->cap.map_size);
return ((a == b) && (a >= 0));
}
/*====================================================================== /*======================================================================
The memory probe. If the memory list includes a 64K-aligned block The memory probe. If the memory list includes a 64K-aligned block
...@@ -339,9 +397,7 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num) ...@@ -339,9 +397,7 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num)
======================================================================*/ ======================================================================*/
static int do_mem_probe(u_long base, u_long num, static int do_mem_probe(u_long base, u_long num, socket_info_t *s)
int (*is_valid)(u_long), int (*do_cksum)(u_long),
socket_info_t *s)
{ {
u_long i, j, bad, fail, step; u_long i, j, bad, fail, step;
...@@ -349,18 +405,21 @@ static int do_mem_probe(u_long base, u_long num, ...@@ -349,18 +405,21 @@ static int do_mem_probe(u_long base, u_long num,
base, base+num-1); base, base+num-1);
bad = fail = 0; bad = fail = 0;
step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff); step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
/* cis_readable wants to map 2x map_size */
if (step < 2 * s->cap.map_size)
step = 2 * s->cap.map_size;
for (i = j = base; i < base+num; i = j + step) { for (i = j = base; i < base+num; i = j + step) {
if (!fail) { if (!fail) {
for (j = i; j < base+num; j += step) for (j = i; j < base+num; j += step)
if ((check_mem_resource(j, step, s->cap.cb_dev) == 0) && if ((check_mem_resource(j, step, s->cap.cb_dev) == 0) &&
is_valid(j)) cis_readable(s, j))
break; break;
fail = ((i == base) && (j == base+num)); fail = ((i == base) && (j == base+num));
} }
if (fail) { if (fail) {
for (j = i; j < base+num; j += 2*step) for (j = i; j < base+num; j += 2*step)
if ((check_mem_resource(j, 2*step, s->cap.cb_dev) == 0) && if ((check_mem_resource(j, 2*step, s->cap.cb_dev) == 0) &&
do_cksum(j) && do_cksum(j+step)) checksum_match(s, j) && checksum_match(s, j + step))
break; break;
} }
if (i != j) { if (i != j) {
...@@ -374,16 +433,14 @@ static int do_mem_probe(u_long base, u_long num, ...@@ -374,16 +433,14 @@ static int do_mem_probe(u_long base, u_long num,
return (num - bad); return (num - bad);
} }
#ifdef CONFIG_ISA #ifdef CONFIG_PCMCIA_PROBE
static u_long inv_probe(int (*is_valid)(u_long), static u_long inv_probe(resource_map_t *m, socket_info_t *s)
int (*do_cksum)(u_long),
resource_map_t *m, socket_info_t *s)
{ {
u_long ok; u_long ok;
if (m == &mem_db) if (m == &mem_db)
return 0; return 0;
ok = inv_probe(is_valid, do_cksum, m->next, s); ok = inv_probe(m->next, s);
if (ok) { if (ok) {
if (m->base >= 0x100000) if (m->base >= 0x100000)
sub_interval(&mem_db, m->base, m->num); sub_interval(&mem_db, m->base, m->num);
...@@ -391,32 +448,36 @@ static u_long inv_probe(int (*is_valid)(u_long), ...@@ -391,32 +448,36 @@ static u_long inv_probe(int (*is_valid)(u_long),
} }
if (m->base < 0x100000) if (m->base < 0x100000)
return 0; return 0;
return do_mem_probe(m->base, m->num, is_valid, do_cksum, s); return do_mem_probe(m->base, m->num, s);
} }
void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long), void validate_mem(socket_info_t *s)
int force_low, socket_info_t *s)
{ {
resource_map_t *m, *n; resource_map_t *m, *n;
static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
static int hi = 0, lo = 0; static int hi = 0, lo = 0;
u_long b, i, ok = 0; u_long b, i, ok = 0;
int force_low = !(s->cap.features & SS_CAP_PAGE_REGS);
if (!probe_mem) return;
if (!probe_mem)
return;
down(&rsrc_sem);
/* We do up to four passes through the list */ /* We do up to four passes through the list */
if (!force_low) { if (!force_low) {
if (hi++ || (inv_probe(is_valid, do_cksum, mem_db.next, s) > 0)) if (hi++ || (inv_probe(mem_db.next, s) > 0))
return; goto out;
printk(KERN_NOTICE "cs: warning: no high memory space " printk(KERN_NOTICE "cs: warning: no high memory space "
"available!\n"); "available!\n");
} }
if (lo++) return; if (lo++)
goto out;
for (m = mem_db.next; m != &mem_db; m = n) { for (m = mem_db.next; m != &mem_db; m = n) {
n = m->next; n = m->next;
/* Only probe < 1 MB */ /* Only probe < 1 MB */
if (m->base >= 0x100000) continue; if (m->base >= 0x100000) continue;
if ((m->base | m->num) & 0xffff) { if ((m->base | m->num) & 0xffff) {
ok += do_mem_probe(m->base, m->num, is_valid, do_cksum, s); ok += do_mem_probe(m->base, m->num, s);
continue; continue;
} }
/* Special probe for 64K-aligned block */ /* Special probe for 64K-aligned block */
...@@ -426,28 +487,31 @@ void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long), ...@@ -426,28 +487,31 @@ void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
if (ok >= mem_limit) if (ok >= mem_limit)
sub_interval(&mem_db, b, 0x10000); sub_interval(&mem_db, b, 0x10000);
else else
ok += do_mem_probe(b, 0x10000, is_valid, do_cksum, s); ok += do_mem_probe(b, 0x10000, s);
} }
} }
} }
out:
up(&rsrc_sem);
} }
#else /* CONFIG_ISA */ #else /* CONFIG_PCMCIA_PROBE */
void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long), void validate_mem(socket_info_t *s)
int force_low, socket_info_t *s)
{ {
resource_map_t *m; resource_map_t *m;
static int done = 0; static int done = 0;
if (!probe_mem || done++) if (probe_mem && done++ == 0) {
return; down(&rsrc_sem);
for (m = mem_db.next; m != &mem_db; m = m->next) for (m = mem_db.next; m != &mem_db; m = m->next)
if (do_mem_probe(m->base, m->num, is_valid, do_cksum, s)) if (do_mem_probe(m->base, m->num, s))
return; break;
up(&rsrc_sem);
}
} }
#endif /* CONFIG_ISA */ #endif /* CONFIG_PCMCIA_PROBE */
/*====================================================================== /*======================================================================
...@@ -467,7 +531,9 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, ...@@ -467,7 +531,9 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
{ {
ioaddr_t try; ioaddr_t try;
resource_map_t *m; resource_map_t *m;
int ret = -1;
down(&rsrc_sem);
for (m = io_db.next; m != &io_db; m = m->next) { for (m = io_db.next; m != &io_db; m = m->next) {
try = (m->base & ~(align-1)) + *base; try = (m->base & ~(align-1)) + *base;
for (try = (try >= m->base) ? try : try+align; for (try = (try >= m->base) ? try : try+align;
...@@ -475,12 +541,16 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, ...@@ -475,12 +541,16 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
try += align) { try += align) {
if (request_io_resource(try, num, name, s->cap.cb_dev) == 0) { if (request_io_resource(try, num, name, s->cap.cb_dev) == 0) {
*base = try; *base = try;
return 0; ret = 0;
goto out;
} }
if (!align) break; if (!align)
break;
} }
} }
return -1; out:
up(&rsrc_sem);
return ret;
} }
int find_mem_region(u_long *base, u_long num, u_long align, int find_mem_region(u_long *base, u_long num, u_long align,
...@@ -488,26 +558,35 @@ int find_mem_region(u_long *base, u_long num, u_long align, ...@@ -488,26 +558,35 @@ int find_mem_region(u_long *base, u_long num, u_long align,
{ {
u_long try; u_long try;
resource_map_t *m; resource_map_t *m;
int ret = -1;
down(&rsrc_sem);
while (1) { while (1) {
for (m = mem_db.next; m != &mem_db; m = m->next) { for (m = mem_db.next; m != &mem_db; m = m->next) {
/* first pass >1MB, second pass <1MB */ /* first pass >1MB, second pass <1MB */
if ((force_low != 0) ^ (m->base < 0x100000)) continue; if ((force_low != 0) ^ (m->base < 0x100000))
continue;
try = (m->base & ~(align-1)) + *base; try = (m->base & ~(align-1)) + *base;
for (try = (try >= m->base) ? try : try+align; for (try = (try >= m->base) ? try : try+align;
(try >= m->base) && (try+num <= m->base+m->num); (try >= m->base) && (try+num <= m->base+m->num);
try += align) { try += align) {
if (request_mem_resource(try, num, name, s->cap.cb_dev) == 0) { if (request_mem_resource(try, num, name, s->cap.cb_dev) == 0) {
*base = try; *base = try;
return 0; ret = 0;
goto out;
} }
if (!align) break; if (!align)
break;
} }
} }
if (force_low) break; if (force_low)
break;
force_low++; force_low++;
} }
return -1; out:
up(&rsrc_sem);
return ret;
} }
/*====================================================================== /*======================================================================
...@@ -518,7 +597,7 @@ int find_mem_region(u_long *base, u_long num, u_long align, ...@@ -518,7 +597,7 @@ int find_mem_region(u_long *base, u_long num, u_long align,
======================================================================*/ ======================================================================*/
#ifdef CONFIG_ISA #ifdef CONFIG_PCMCIA_PROBE
static void fake_irq(int i, void *d, struct pt_regs *r) { } static void fake_irq(int i, void *d, struct pt_regs *r) { }
static inline int check_irq(int irq) static inline int check_irq(int irq)
...@@ -532,66 +611,89 @@ static inline int check_irq(int irq) ...@@ -532,66 +611,89 @@ static inline int check_irq(int irq)
int try_irq(u_int Attributes, int irq, int specific) int try_irq(u_int Attributes, int irq, int specific)
{ {
irq_info_t *info = &irq_table[irq]; irq_info_t *info = &irq_table[irq];
int ret = 0;
down(&rsrc_sem);
if (info->Attributes & RES_ALLOCATED) { if (info->Attributes & RES_ALLOCATED) {
switch (Attributes & IRQ_TYPE) { switch (Attributes & IRQ_TYPE) {
case IRQ_TYPE_EXCLUSIVE: case IRQ_TYPE_EXCLUSIVE:
return CS_IN_USE; ret = CS_IN_USE;
break;
case IRQ_TYPE_TIME: case IRQ_TYPE_TIME:
if ((info->Attributes & RES_IRQ_TYPE) if ((info->Attributes & RES_IRQ_TYPE)
!= RES_IRQ_TYPE_TIME) != RES_IRQ_TYPE_TIME) {
return CS_IN_USE; ret = CS_IN_USE;
if (Attributes & IRQ_FIRST_SHARED) break;
return CS_BAD_ATTRIBUTE; }
if (Attributes & IRQ_FIRST_SHARED) {
ret = CS_BAD_ATTRIBUTE;
break;
}
info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED; info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
info->time_share++; info->time_share++;
break; break;
case IRQ_TYPE_DYNAMIC_SHARING: case IRQ_TYPE_DYNAMIC_SHARING:
if ((info->Attributes & RES_IRQ_TYPE) if ((info->Attributes & RES_IRQ_TYPE)
!= RES_IRQ_TYPE_DYNAMIC) != RES_IRQ_TYPE_DYNAMIC) {
return CS_IN_USE; ret = CS_IN_USE;
if (Attributes & IRQ_FIRST_SHARED) break;
return CS_BAD_ATTRIBUTE; }
if (Attributes & IRQ_FIRST_SHARED) {
ret = CS_BAD_ATTRIBUTE;
break;
}
info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED; info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
info->dyn_share++; info->dyn_share++;
break; break;
} }
} else { } else {
if ((info->Attributes & RES_RESERVED) && !specific) if ((info->Attributes & RES_RESERVED) && !specific) {
return CS_IN_USE; ret = CS_IN_USE;
if (check_irq(irq) != 0) goto out;
return CS_IN_USE; }
if (check_irq(irq) != 0) {
ret = CS_IN_USE;
goto out;
}
switch (Attributes & IRQ_TYPE) { switch (Attributes & IRQ_TYPE) {
case IRQ_TYPE_EXCLUSIVE: case IRQ_TYPE_EXCLUSIVE:
info->Attributes |= RES_ALLOCATED; info->Attributes |= RES_ALLOCATED;
break; break;
case IRQ_TYPE_TIME: case IRQ_TYPE_TIME:
if (!(Attributes & IRQ_FIRST_SHARED)) if (!(Attributes & IRQ_FIRST_SHARED)) {
return CS_BAD_ATTRIBUTE; ret = CS_BAD_ATTRIBUTE;
break;
}
info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED; info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
info->time_share = 1; info->time_share = 1;
break; break;
case IRQ_TYPE_DYNAMIC_SHARING: case IRQ_TYPE_DYNAMIC_SHARING:
if (!(Attributes & IRQ_FIRST_SHARED)) if (!(Attributes & IRQ_FIRST_SHARED)) {
return CS_BAD_ATTRIBUTE; ret = CS_BAD_ATTRIBUTE;
break;
}
info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED; info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
info->dyn_share = 1; info->dyn_share = 1;
break; break;
} }
} }
return 0; out:
up(&rsrc_sem);
return ret;
} }
#endif #endif
/*====================================================================*/ /*====================================================================*/
#ifdef CONFIG_ISA #ifdef CONFIG_PCMCIA_PROBE
void undo_irq(u_int Attributes, int irq) void undo_irq(u_int Attributes, int irq)
{ {
irq_info_t *info; irq_info_t *info;
info = &irq_table[irq]; info = &irq_table[irq];
down(&rsrc_sem);
switch (Attributes & IRQ_TYPE) { switch (Attributes & IRQ_TYPE) {
case IRQ_TYPE_EXCLUSIVE: case IRQ_TYPE_EXCLUSIVE:
info->Attributes &= RES_RESERVED; info->Attributes &= RES_RESERVED;
...@@ -607,6 +709,7 @@ void undo_irq(u_int Attributes, int irq) ...@@ -607,6 +709,7 @@ void undo_irq(u_int Attributes, int irq)
info->Attributes &= RES_RESERVED; info->Attributes &= RES_RESERVED;
break; break;
} }
up(&rsrc_sem);
} }
#endif #endif
...@@ -629,6 +732,8 @@ static int adjust_memory(adjust_t *adj) ...@@ -629,6 +732,8 @@ static int adjust_memory(adjust_t *adj)
return CS_BAD_SIZE; return CS_BAD_SIZE;
ret = CS_SUCCESS; ret = CS_SUCCESS;
down(&rsrc_sem);
switch (adj->Action) { switch (adj->Action) {
case ADD_MANAGED_RESOURCE: case ADD_MANAGED_RESOURCE:
ret = add_interval(&mem_db, base, num); ret = add_interval(&mem_db, base, num);
...@@ -647,6 +752,7 @@ static int adjust_memory(adjust_t *adj) ...@@ -647,6 +752,7 @@ static int adjust_memory(adjust_t *adj)
default: default:
ret = CS_UNSUPPORTED_FUNCTION; ret = CS_UNSUPPORTED_FUNCTION;
} }
up(&rsrc_sem);
return ret; return ret;
} }
...@@ -655,7 +761,7 @@ static int adjust_memory(adjust_t *adj) ...@@ -655,7 +761,7 @@ static int adjust_memory(adjust_t *adj)
static int adjust_io(adjust_t *adj) static int adjust_io(adjust_t *adj)
{ {
int base, num; int base, num, ret = CS_SUCCESS;
base = adj->resource.io.BasePort; base = adj->resource.io.BasePort;
num = adj->resource.io.NumPorts; num = adj->resource.io.NumPorts;
...@@ -664,11 +770,14 @@ static int adjust_io(adjust_t *adj) ...@@ -664,11 +770,14 @@ static int adjust_io(adjust_t *adj)
if ((num <= 0) || (base+num > 0x10000) || (base+num <= base)) if ((num <= 0) || (base+num > 0x10000) || (base+num <= base))
return CS_BAD_SIZE; return CS_BAD_SIZE;
down(&rsrc_sem);
switch (adj->Action) { switch (adj->Action) {
case ADD_MANAGED_RESOURCE: case ADD_MANAGED_RESOURCE:
if (add_interval(&io_db, base, num) != 0) if (add_interval(&io_db, base, num) != 0) {
return CS_IN_USE; ret = CS_IN_USE;
#ifdef CONFIG_ISA break;
}
#ifdef CONFIG_PCMCIA_PROBE
if (probe_io) if (probe_io)
do_io_probe(base, num); do_io_probe(base, num);
#endif #endif
...@@ -677,18 +786,20 @@ static int adjust_io(adjust_t *adj) ...@@ -677,18 +786,20 @@ static int adjust_io(adjust_t *adj)
sub_interval(&io_db, base, num); sub_interval(&io_db, base, num);
break; break;
default: default:
return CS_UNSUPPORTED_FUNCTION; ret = CS_UNSUPPORTED_FUNCTION;
break; break;
} }
up(&rsrc_sem);
return CS_SUCCESS; return ret;
} }
/*====================================================================*/ /*====================================================================*/
static int adjust_irq(adjust_t *adj) static int adjust_irq(adjust_t *adj)
{ {
#ifdef CONFIG_ISA int ret = CS_SUCCESS;
#ifdef CONFIG_PCMCIA_PROBE
int irq; int irq;
irq_info_t *info; irq_info_t *info;
...@@ -696,33 +807,41 @@ static int adjust_irq(adjust_t *adj) ...@@ -696,33 +807,41 @@ static int adjust_irq(adjust_t *adj)
if ((irq < 0) || (irq > 15)) if ((irq < 0) || (irq > 15))
return CS_BAD_IRQ; return CS_BAD_IRQ;
info = &irq_table[irq]; info = &irq_table[irq];
down(&rsrc_sem);
switch (adj->Action) { switch (adj->Action) {
case ADD_MANAGED_RESOURCE: case ADD_MANAGED_RESOURCE:
if (info->Attributes & RES_REMOVED) if (info->Attributes & RES_REMOVED)
info->Attributes &= ~(RES_REMOVED|RES_ALLOCATED); info->Attributes &= ~(RES_REMOVED|RES_ALLOCATED);
else else
if (adj->Attributes & RES_ALLOCATED) if (adj->Attributes & RES_ALLOCATED) {
return CS_IN_USE; ret = CS_IN_USE;
break;
}
if (adj->Attributes & RES_RESERVED) if (adj->Attributes & RES_RESERVED)
info->Attributes |= RES_RESERVED; info->Attributes |= RES_RESERVED;
else else
info->Attributes &= ~RES_RESERVED; info->Attributes &= ~RES_RESERVED;
break; break;
case REMOVE_MANAGED_RESOURCE: case REMOVE_MANAGED_RESOURCE:
if (info->Attributes & RES_REMOVED) if (info->Attributes & RES_REMOVED) {
return 0; ret = 0;
if (info->Attributes & RES_ALLOCATED) break;
return CS_IN_USE; }
if (info->Attributes & RES_ALLOCATED) {
ret = CS_IN_USE;
break;
}
info->Attributes |= RES_ALLOCATED|RES_REMOVED; info->Attributes |= RES_ALLOCATED|RES_REMOVED;
info->Attributes &= ~RES_RESERVED; info->Attributes &= ~RES_RESERVED;
break; break;
default: default:
return CS_UNSUPPORTED_FUNCTION; ret = CS_UNSUPPORTED_FUNCTION;
break; break;
} }
up(&rsrc_sem);
#endif #endif
return CS_SUCCESS; return ret;
} }
/*====================================================================*/ /*====================================================================*/
......
...@@ -52,7 +52,6 @@ ...@@ -52,7 +52,6 @@
#include <pcmcia/cs_types.h> #include <pcmcia/cs_types.h>
#include <pcmcia/cs.h> #include <pcmcia/cs.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/bus_ops.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -567,31 +566,6 @@ sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state) ...@@ -567,31 +566,6 @@ sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
} /* sa1100_pcmcia_set_socket() */ } /* sa1100_pcmcia_set_socket() */
/* sa1100_pcmcia_get_io_map()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the get_io_map() operation for the in-kernel PCMCIA
* service (formerly SS_GetIOMap in Card Services). Just returns an
* I/O map descriptor which was assigned earlier by a set_io_map().
*
* Returns: 0 on success, -1 if the map index was out of range
*/
static int
sa1100_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
int ret = -1;
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
if (map->map < MAX_IO_WIN) {
*map = skt->io_map[map->map];
ret = 0;
}
return ret;
}
/* sa1100_pcmcia_set_io_map() /* sa1100_pcmcia_set_io_map()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the set_io_map() operation for the in-kernel PCMCIA * Implements the set_io_map() operation for the in-kernel PCMCIA
...@@ -646,32 +620,6 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map) ...@@ -646,32 +620,6 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
} /* sa1100_pcmcia_set_io_map() */ } /* sa1100_pcmcia_set_io_map() */
/* sa1100_pcmcia_get_mem_map()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the get_mem_map() operation for the in-kernel PCMCIA
* service (formerly SS_GetMemMap in Card Services). Just returns a
* memory map descriptor which was assigned earlier by a
* set_mem_map() request.
*
* Returns: 0 on success, -1 if the map index was out of range
*/
static int
sa1100_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
{
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
int ret = -1;
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
if (map->map < MAX_WIN) {
*map = skt->pc_mem_map[map->map];
ret = 0;
}
return ret;
}
/* sa1100_pcmcia_set_mem_map() /* sa1100_pcmcia_set_mem_map()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the set_mem_map() operation for the in-kernel PCMCIA * Implements the set_mem_map() operation for the in-kernel PCMCIA
...@@ -841,9 +789,7 @@ static struct pccard_operations sa1100_pcmcia_operations = { ...@@ -841,9 +789,7 @@ static struct pccard_operations sa1100_pcmcia_operations = {
.get_status = sa1100_pcmcia_get_status, .get_status = sa1100_pcmcia_get_status,
.get_socket = sa1100_pcmcia_get_socket, .get_socket = sa1100_pcmcia_get_socket,
.set_socket = sa1100_pcmcia_set_socket, .set_socket = sa1100_pcmcia_set_socket,
.get_io_map = sa1100_pcmcia_get_io_map,
.set_io_map = sa1100_pcmcia_set_io_map, .set_io_map = sa1100_pcmcia_set_io_map,
.get_mem_map = sa1100_pcmcia_get_mem_map,
.set_mem_map = sa1100_pcmcia_set_mem_map, .set_mem_map = sa1100_pcmcia_set_mem_map,
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
.proc_setup = sa1100_pcmcia_proc_setup .proc_setup = sa1100_pcmcia_proc_setup
......
...@@ -806,44 +806,6 @@ static int tcic_set_socket(unsigned int lsock, socket_state_t *state) ...@@ -806,44 +806,6 @@ static int tcic_set_socket(unsigned int lsock, socket_state_t *state)
/*====================================================================*/ /*====================================================================*/
static int tcic_get_io_map(unsigned int lsock, struct pccard_io_map *io)
{
u_short psock = socket_table[lsock].psock;
u_short base, ioctl;
u_int addr;
if (io->map > 1) return -EINVAL;
tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
addr = TCIC_IWIN(psock, io->map);
tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
base = tcic_getw(TCIC_DATA);
tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
ioctl = tcic_getw(TCIC_DATA);
if (ioctl & TCIC_ICTL_TINY)
io->start = io->stop = base;
else {
io->start = base & (base-1);
io->stop = io->start + (base ^ (base-1));
}
io->speed = to_ns(ioctl & TCIC_ICTL_WSCNT_MASK);
io->flags = (ioctl & TCIC_ICTL_ENA) ? MAP_ACTIVE : 0;
switch (ioctl & TCIC_ICTL_BW_MASK) {
case TCIC_ICTL_BW_DYN:
io->flags |= MAP_AUTOSZ; break;
case TCIC_ICTL_BW_16:
io->flags |= MAP_16BIT; break;
default:
break;
}
DEBUG(1, "tcic: GetIOMap(%d, %d) = %#2.2x, %d ns, "
"%#4.4x-%#4.4x\n", lsock, io->map, io->flags,
io->speed, io->start, io->stop);
return 0;
} /* tcic_get_io_map */
/*====================================================================*/
static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io) static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io)
{ {
u_short psock = socket_table[lsock].psock; u_short psock = socket_table[lsock].psock;
...@@ -881,51 +843,6 @@ static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io) ...@@ -881,51 +843,6 @@ static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io)
/*====================================================================*/ /*====================================================================*/
static int tcic_get_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
{
u_short psock = socket_table[lsock].psock;
u_short addr, ctl;
u_long base, mmap;
if (mem->map > 3) return -EINVAL;
tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
addr = TCIC_MWIN(psock, mem->map);
tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
base = tcic_getw(TCIC_DATA);
if (base & TCIC_MBASE_4K_BIT) {
mem->sys_start = base & TCIC_MBASE_HA_MASK;
mem->sys_stop = mem->sys_start;
} else {
base &= TCIC_MBASE_HA_MASK;
mem->sys_start = (base & (base-1));
mem->sys_stop = mem->sys_start + (base ^ (base-1));
}
mem->sys_start = mem->sys_start << TCIC_MBASE_HA_SHFT;
mem->sys_stop = (mem->sys_stop << TCIC_MBASE_HA_SHFT) + 0x0fff;
tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
mmap = tcic_getw(TCIC_DATA);
mem->flags = (mmap & TCIC_MMAP_REG) ? MAP_ATTRIB : 0;
mmap &= TCIC_MMAP_CA_MASK;
mem->card_start = mem->sys_start + (mmap << TCIC_MMAP_CA_SHFT);
mem->card_start &= 0x3ffffff;
tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
ctl = tcic_getw(TCIC_DATA);
mem->flags |= (ctl & TCIC_MCTL_ENA) ? MAP_ACTIVE : 0;
mem->flags |= (ctl & TCIC_MCTL_B8) ? 0 : MAP_16BIT;
mem->flags |= (ctl & TCIC_MCTL_WP) ? MAP_WRPROT : 0;
mem->speed = to_ns(ctl & TCIC_MCTL_WSCNT_MASK);
DEBUG(1, "tcic: GetMemMap(%d, %d) = %#2.2x, %d ns, "
"%#5.5lx-%#5.5lx, %#5.5x\n", lsock, mem->map, mem->flags,
mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
return 0;
} /* tcic_get_mem_map */
/*====================================================================*/
static int tcic_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem) static int tcic_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
{ {
u_short psock = socket_table[lsock].psock; u_short psock = socket_table[lsock].psock;
...@@ -1007,9 +924,7 @@ static struct pccard_operations tcic_operations = { ...@@ -1007,9 +924,7 @@ static struct pccard_operations tcic_operations = {
.get_status = tcic_get_status, .get_status = tcic_get_status,
.get_socket = tcic_get_socket, .get_socket = tcic_get_socket,
.set_socket = tcic_set_socket, .set_socket = tcic_set_socket,
.get_io_map = tcic_get_io_map,
.set_io_map = tcic_set_io_map, .set_io_map = tcic_set_io_map,
.get_mem_map = tcic_get_mem_map,
.set_mem_map = tcic_set_mem_map, .set_mem_map = tcic_set_mem_map,
.proc_setup = tcic_proc_setup, .proc_setup = tcic_proc_setup,
}; };
......
...@@ -185,9 +185,7 @@ static struct pci_socket_ops ti_ops = { ...@@ -185,9 +185,7 @@ static struct pci_socket_ops ti_ops = {
yenta_get_status, yenta_get_status,
yenta_get_socket, yenta_get_socket,
yenta_set_socket, yenta_set_socket,
yenta_get_io_map,
yenta_set_io_map, yenta_set_io_map,
yenta_get_mem_map,
yenta_set_mem_map, yenta_set_mem_map,
yenta_proc_setup yenta_proc_setup
}; };
...@@ -230,9 +228,7 @@ static struct pci_socket_ops ti113x_ops = { ...@@ -230,9 +228,7 @@ static struct pci_socket_ops ti113x_ops = {
yenta_get_status, yenta_get_status,
yenta_get_socket, yenta_get_socket,
yenta_set_socket, yenta_set_socket,
yenta_get_io_map,
yenta_set_io_map, yenta_set_io_map,
yenta_get_mem_map,
yenta_set_mem_map, yenta_set_mem_map,
yenta_proc_setup yenta_proc_setup
}; };
...@@ -272,9 +268,7 @@ static struct pci_socket_ops ti1250_ops = { ...@@ -272,9 +268,7 @@ static struct pci_socket_ops ti1250_ops = {
yenta_get_status, yenta_get_status,
yenta_get_socket, yenta_get_socket,
yenta_set_socket, yenta_set_socket,
yenta_get_io_map,
yenta_set_io_map, yenta_set_io_map,
yenta_get_mem_map,
yenta_set_mem_map, yenta_set_mem_map,
yenta_proc_setup yenta_proc_setup
}; };
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "i82365.h" #include "i82365.h"
#if 0 #if 0
#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args) #define DEBUG(x,args...) printk("%s: " x, __FUNCTION__, ##args)
#else #else
#define DEBUG(x,args...) #define DEBUG(x,args...)
#endif #endif
...@@ -300,29 +300,6 @@ static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state) ...@@ -300,29 +300,6 @@ static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state)
return 0; return 0;
} }
static int yenta_get_io_map(pci_socket_t *socket, struct pccard_io_map *io)
{
int map;
unsigned char ioctl, addr;
map = io->map;
if (map > 1)
return -EINVAL;
io->start = exca_readw(socket, I365_IO(map)+I365_W_START);
io->stop = exca_readw(socket, I365_IO(map)+I365_W_STOP);
ioctl = exca_readb(socket, I365_IOCTL);
addr = exca_readb(socket, I365_ADDRWIN);
io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0;
io->flags = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0;
io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;
io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;
io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;
return 0;
}
static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io) static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io)
{ {
int map; int map;
...@@ -356,41 +333,6 @@ static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io) ...@@ -356,41 +333,6 @@ static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io)
return 0; return 0;
} }
static int yenta_get_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem)
{
int map;
unsigned char addr;
unsigned int start, stop, page, offset;
map = mem->map;
if (map > 4)
return -EINVAL;
addr = exca_readb(socket, I365_ADDRWIN);
mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0;
start = exca_readw(socket, I365_MEM(map) + I365_W_START);
mem->flags |= (start & I365_MEM_16BIT) ? MAP_16BIT : 0;
mem->flags |= (start & I365_MEM_0WS) ? MAP_0WS : 0;
start = (start & 0x0fff) << 12;
stop = exca_readw(socket, I365_MEM(map) + I365_W_STOP);
mem->speed = to_ns(stop >> 14);
stop = ((stop & 0x0fff) << 12) + 0x0fff;
offset = exca_readw(socket, I365_MEM(map) + I365_W_OFF);
mem->flags |= (offset & I365_MEM_WRPROT) ? MAP_WRPROT : 0;
mem->flags |= (offset & I365_MEM_REG) ? MAP_ATTRIB : 0;
offset = ((offset & 0x3fff) << 12) + start;
mem->card_start = offset & 0x3ffffff;
page = exca_readb(socket, CB_MEM_PAGE(map)) << 24;
mem->sys_start = start + page;
mem->sys_stop = start + page;
return 0;
}
static int yenta_set_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem) static int yenta_set_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem)
{ {
int map; int map;
...@@ -572,7 +514,6 @@ static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask ...@@ -572,7 +514,6 @@ static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask
socket->cap.pci_irq = socket->cb_irq; socket->cap.pci_irq = socket->cb_irq;
socket->cap.irq_mask = yenta_probe_irq(socket, isa_irq_mask); socket->cap.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
socket->cap.cb_dev = socket->dev; socket->cap.cb_dev = socket->dev;
socket->cap.bus = NULL;
printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq); printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq);
} }
...@@ -935,9 +876,7 @@ struct pci_socket_ops yenta_operations = { ...@@ -935,9 +876,7 @@ struct pci_socket_ops yenta_operations = {
yenta_get_status, yenta_get_status,
yenta_get_socket, yenta_get_socket,
yenta_set_socket, yenta_set_socket,
yenta_get_io_map,
yenta_set_io_map, yenta_set_io_map,
yenta_get_mem_map,
yenta_set_mem_map, yenta_set_mem_map,
yenta_proc_setup yenta_proc_setup
}; };
......
...@@ -62,7 +62,6 @@ ...@@ -62,7 +62,6 @@
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/bus_ops.h>
#include "nsp_cs.h" #include "nsp_cs.h"
...@@ -93,7 +92,6 @@ typedef struct scsi_info_t { ...@@ -93,7 +92,6 @@ typedef struct scsi_info_t {
int ndev; int ndev;
dev_node_t node[8]; dev_node_t node[8];
int stop; int stop;
struct bus_operations *bus;
} scsi_info_t; } scsi_info_t;
...@@ -1948,7 +1946,6 @@ static int nsp_cs_event(event_t event, ...@@ -1948,7 +1946,6 @@ static int nsp_cs_event(event_t event,
case CS_EVENT_CARD_INSERTION: case CS_EVENT_CARD_INSERTION:
DEBUG(0, " event: insert\n"); DEBUG(0, " event: insert\n");
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
info->bus = args->bus;
nsp_cs_config(link); nsp_cs_config(link);
break; break;
......
/* /* now empty */
* bus_ops.h 1.10 2000/06/12 21:55:41 #warning please remove the reference to this file
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License
* at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and
* limitations under the License.
*
* The initial developer of the original code is David A. Hinds
* <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in which
* case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the MPL or the GPL.
*/
#ifndef _LINUX_BUS_OPS_H
#define _LINUX_BUS_OPS_H
#include <linux/config.h>
#ifdef CONFIG_VIRTUAL_BUS
typedef struct bus_operations {
void *priv;
u32 (*b_in)(void *bus, u32 port, s32 sz);
void (*b_ins)(void *bus, u32 port, void *buf,
u32 count, s32 sz);
void (*b_out)(void *bus, u32 val, u32 port, s32 sz);
void (*b_outs)(void *bus, u32 port, void *buf,
u32 count, s32 sz);
void *(*b_ioremap)(void *bus, u_long ofs, u_long sz);
void (*b_iounmap)(void *bus, void *addr);
u32 (*b_read)(void *bus, void *addr, s32 sz);
void (*b_write)(void *bus, u32 val, void *addr, s32 sz);
void (*b_copy_from)(void *bus, void *d, void *s, u32 count);
void (*b_copy_to)(void *bus, void *d, void *s, u32 count);
int (*b_request_irq)(void *bus, u_int irq,
void (*handler)(int, void *,
struct pt_regs *),
u_long flags, const char *device,
void *dev_id);
void (*b_free_irq)(void *bus, u_int irq, void *dev_id);
} bus_operations;
#define bus_inb(b,p) (b)->b_in((b),(p),0)
#define bus_inw(b,p) (b)->b_in((b),(p),1)
#define bus_inl(b,p) (b)->b_in((b),(p),2)
#define bus_inw_ns(b,p) (b)->b_in((b),(p),-1)
#define bus_inl_ns(b,p) (b)->b_in((b),(p),-2)
#define bus_insb(b,p,a,c) (b)->b_ins((b),(p),(a),(c),0)
#define bus_insw(b,p,a,c) (b)->b_ins((b),(p),(a),(c),1)
#define bus_insl(b,p,a,c) (b)->b_ins((b),(p),(a),(c),2)
#define bus_insw_ns(b,p,a,c) (b)->b_ins((b),(p),(a),(c),-1)
#define bus_insl_ns(b,p,a,c) (b)->b_ins((b),(p),(a),(c),-2)
#define bus_outb(b,v,p) (b)->b_out((b),(v),(p),0)
#define bus_outw(b,v,p) (b)->b_out((b),(v),(p),1)
#define bus_outl(b,v,p) (b)->b_out((b),(v),(p),2)
#define bus_outw_ns(b,v,p) (b)->b_out((b),(v),(p),-1)
#define bus_outl_ns(b,v,p) (b)->b_out((b),(v),(p),-2)
#define bus_outsb(b,p,a,c) (b)->b_outs((b),(p),(a),(c),0)
#define bus_outsw(b,p,a,c) (b)->b_outs((b),(p),(a),(c),1)
#define bus_outsl(b,p,a,c) (b)->b_outs((b),(p),(a),(c),2)
#define bus_outsw_ns(b,p,a,c) (b)->b_outs((b),(p),(a),(c),-1)
#define bus_outsl_ns(b,p,a,c) (b)->b_outs((b),(p),(a),(c),-2)
#define bus_readb(b,a) (b)->b_read((b),(a),0)
#define bus_readw(b,a) (b)->b_read((b),(a),1)
#define bus_readl(b,a) (b)->b_read((b),(a),2)
#define bus_readw_ns(b,a) (b)->b_read((b),(a),-1)
#define bus_readl_ns(b,a) (b)->b_read((b),(a),-2)
#define bus_writeb(b,v,a) (b)->b_write((b),(v),(a),0)
#define bus_writew(b,v,a) (b)->b_write((b),(v),(a),1)
#define bus_writel(b,v,a) (b)->b_write((b),(v),(a),2)
#define bus_writew_ns(b,v,a) (b)->b_write((b),(v),(a),-1)
#define bus_writel_ns(b,v,a) (b)->b_write((b),(v),(a),-2)
#define bus_ioremap(b,s,n) (b)->b_ioremap((b),(s),(n))
#define bus_iounmap(b,a) (b)->b_iounmap((b),(a))
#define bus_memcpy_fromio(b,d,s,n) (b)->b_copy_from((b),(d),(s),(n))
#define bus_memcpy_toio(b,d,s,n) (b)->b_copy_to((b),(d),(s),(n))
#define bus_request_irq(b,i,h,f,n,d) \
(b)->b_request_irq((b),(i),(h),(f),(n),(d))
#define bus_free_irq(b,i,d) (b)->b_free_irq((b),(i),(d))
#else
#define bus_inb(b,p) inb(p)
#define bus_inw(b,p) inw(p)
#define bus_inl(b,p) inl(p)
#define bus_inw_ns(b,p) inw_ns(p)
#define bus_inl_ns(b,p) inl_ns(p)
#define bus_insb(b,p,a,c) insb(p,a,c)
#define bus_insw(b,p,a,c) insw(p,a,c)
#define bus_insl(b,p,a,c) insl(p,a,c)
#define bus_insw_ns(b,p,a,c) insw_ns(p,a,c)
#define bus_insl_ns(b,p,a,c) insl_ns(p,a,c)
#define bus_outb(b,v,p) outb(b,v,p)
#define bus_outw(b,v,p) outw(b,v,p)
#define bus_outl(b,v,p) outl(b,v,p)
#define bus_outw_ns(b,v,p) outw_ns(b,v,p)
#define bus_outl_ns(b,v,p) outl_ns(b,v,p)
#define bus_outsb(b,p,a,c) outsb(p,a,c)
#define bus_outsw(b,p,a,c) outsw(p,a,c)
#define bus_outsl(b,p,a,c) outsl(p,a,c)
#define bus_outsw_ns(b,p,a,c) outsw_ns(p,a,c)
#define bus_outsl_ns(b,p,a,c) outsl_ns(p,a,c)
#define bus_readb(b,a) readb(a)
#define bus_readw(b,a) readw(a)
#define bus_readl(b,a) readl(a)
#define bus_readw_ns(b,a) readw_ns(a)
#define bus_readl_ns(b,a) readl_ns(a)
#define bus_writeb(b,v,a) writeb(v,a)
#define bus_writew(b,v,a) writew(v,a)
#define bus_writel(b,v,a) writel(v,a)
#define bus_writew_ns(b,v,a) writew_ns(v,a)
#define bus_writel_ns(b,v,a) writel_ns(v,a)
#define bus_ioremap(b,s,n) ioremap(s,n)
#define bus_iounmap(b,a) iounmap(a)
#define bus_memcpy_fromio(b,d,s,n) memcpy_fromio(d,s,n)
#define bus_memcpy_toio(b,d,s,n) memcpy_toio(d,s,n)
#define bus_request_irq(b,i,h,f,n,d) request_irq((i),(h),(f),(n),(d))
#define bus_free_irq(b,i,d) free_irq((i),(d))
#endif /* CONFIG_VIRTUAL_BUS */
#endif /* _LINUX_BUS_OPS_H */
...@@ -98,7 +98,6 @@ typedef struct event_callback_args_t { ...@@ -98,7 +98,6 @@ typedef struct event_callback_args_t {
void *buffer; void *buffer;
void *misc; void *misc;
void *client_data; void *client_data;
struct bus_operations *bus;
} event_callback_args_t; } event_callback_args_t;
/* for GetConfigurationInfo */ /* for GetConfigurationInfo */
......
...@@ -58,7 +58,6 @@ typedef struct socket_cap_t { ...@@ -58,7 +58,6 @@ typedef struct socket_cap_t {
ioaddr_t io_offset; ioaddr_t io_offset;
u_char pci_irq; u_char pci_irq;
struct pci_dev *cb_dev; struct pci_dev *cb_dev;
struct bus_operations *bus;
} socket_cap_t; } socket_cap_t;
/* InquireSocket capabilities */ /* InquireSocket capabilities */
...@@ -134,9 +133,7 @@ struct pccard_operations { ...@@ -134,9 +133,7 @@ struct pccard_operations {
int (*get_status)(unsigned int sock, u_int *value); int (*get_status)(unsigned int sock, u_int *value);
int (*get_socket)(unsigned int sock, socket_state_t *state); int (*get_socket)(unsigned int sock, socket_state_t *state);
int (*set_socket)(unsigned int sock, socket_state_t *state); int (*set_socket)(unsigned int sock, socket_state_t *state);
int (*get_io_map)(unsigned int sock, struct pccard_io_map *io);
int (*set_io_map)(unsigned int sock, struct pccard_io_map *io); int (*set_io_map)(unsigned int sock, struct pccard_io_map *io);
int (*get_mem_map)(unsigned int sock, struct pccard_mem_map *mem);
int (*set_mem_map)(unsigned int sock, struct pccard_mem_map *mem); int (*set_mem_map)(unsigned int sock, struct pccard_mem_map *mem);
void (*proc_setup)(unsigned int sock, struct proc_dir_entry *base); void (*proc_setup)(unsigned int sock, struct proc_dir_entry *base);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment