patch-2.3.35 linux/drivers/pcmcia/i82365.c
Next file: linux/drivers/pcmcia/old-yenta.h
Previous file: linux/drivers/pcmcia/cs_internal.h
Back to the patch index
Back to the overall index
- Lines: 831
- Date:
Sun Dec 26 12:33:09 1999
- Orig file:
v2.3.34/linux/drivers/pcmcia/i82365.c
- Orig date:
Tue Dec 14 01:27:24 1999
diff -u --recursive --new-file v2.3.34/linux/drivers/pcmcia/i82365.c linux/drivers/pcmcia/i82365.c
@@ -66,7 +66,7 @@
#include "o2micro.h"
/* PCI-bus controllers */
-#include "yenta.h"
+#include "old-yenta.h"
#include "ti113x.h"
#include "smc34c90.h"
#include "topic.h"
@@ -159,8 +159,6 @@
#ifdef CONFIG_PCI
/* Scan PCI bus? */
static int do_pci_probe = 1;
-/* Default memory base address for CardBus controllers */
-static u_int cb_mem_base[] = { 0x68000000, 0xf8000000 };
static int fast_pci = -1;
static int hold_time = -1;
/* Override BIOS interrupt routing mode? */
@@ -173,7 +171,6 @@
static int cb_bus_step = 2;
static int cb_write_post = -1;
MODULE_PARM(do_pci_probe, "i");
-MODULE_PARM(cb_mem_base, "i");
MODULE_PARM(fast_pci, "i");
MODULE_PARM(hold_time, "i");
MODULE_PARM(irq_mode, "i");
@@ -249,11 +246,11 @@
struct proc_dir_entry *proc;
#endif
#ifdef CONFIG_PCI
- u_short vendor, device;
- u_char revision, bus, devfn;
+ struct pci_dev *pdev;
+ u_char revision;
u_short bcr;
u_char pci_lat, cb_lat, sub_bus;
- u_char cache, pmcs;
+ u_char cache;
u_int cb_phys;
char *cb_virt;
#endif
@@ -294,24 +291,10 @@
/*====================================================================*/
-#ifdef CONFIG_PCI
-
-#ifndef PCI_VENDOR_ID_INTEL
-#define PCI_VENDOR_ID_INTEL 0x8086
-#endif
-#ifndef PCI_VENDOR_ID_OMEGA
-#define PCI_VENDOR_ID_OMEGA 0x119b
-#endif
-#ifndef PCI_DEVICE_ID_OMEGA_PCMCIA
-#define PCI_DEVICE_ID_OMEGA_PCMCIA 0x1221
-#endif
-
/* Default settings for PCI command configuration register */
#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \
PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
-#endif
-
/* These definitions must match the pcic table! */
typedef enum pcic_id {
#ifdef CONFIG_ISA
@@ -379,9 +362,9 @@
{ "O2Micro OZ6730", IS_O2MICRO|IS_PCI|IS_VG_PWR,
PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6730 },
{ "Intel 82092AA", IS_PCI,
- PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_OMEGA_PCMCIA },
+ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82092AA_0 },
{ "Omega Micro 82C092G", IS_PCI,
- PCI_VENDOR_ID_OMEGA, PCI_DEVICE_ID_OMEGA_PCMCIA },
+ PCI_VENDOR_ID_OMEGA, PCI_DEVICE_ID_OMEGA_82C092G },
{ "Cirrus PD6832", IS_CIRRUS|IS_CARDBUS,
PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832 },
{ "O2Micro OZ6832/OZ6833", IS_O2MICRO|IS_CARDBUS|IS_VG_PWR,
@@ -443,12 +426,12 @@
/* Some PCI shortcuts */
-#define pci_readb pcibios_read_config_byte
-#define pci_writeb pcibios_write_config_byte
-#define pci_readw pcibios_read_config_word
-#define pci_writew pcibios_write_config_word
-#define pci_readl pcibios_read_config_dword
-#define pci_writel pcibios_write_config_dword
+#define config_readb(sock, r, v) pci_read_config_byte((sock)->pdev, r, v)
+#define config_readw(sock, r, v) pci_read_config_word((sock)->pdev, r, v)
+#define config_readl(sock, r, v) pci_read_config_dword((sock)->pdev, r, v)
+#define config_writeb(sock, r, v) pci_write_config_byte((sock)->pdev, r, v)
+#define config_writew(sock, r, v) pci_write_config_word((sock)->pdev, r, v)
+#define config_writel(sock, r, v) pci_write_config_dword((sock)->pdev, r, v)
#define cb_readb(s, r) readb(socket[s].cb_virt + (r))
#define cb_readl(s, r) readl(socket[s].cb_virt + (r))
@@ -701,21 +684,21 @@
{
socket_info_t *t = &socket[s];
ti113x_state_t *p = &socket[s].state.ti113x;
- pci_readl(t->bus, t->devfn, TI113X_SYSTEM_CONTROL, &p->sysctl);
- pci_readb(t->bus, t->devfn, TI113X_CARD_CONTROL, &p->cardctl);
- pci_readb(t->bus, t->devfn, TI113X_DEVICE_CONTROL, &p->devctl);
- pci_readb(t->bus, t->devfn, TI1250_DIAGNOSTIC, &p->diag);
+ config_readl(t, TI113X_SYSTEM_CONTROL, &p->sysctl);
+ config_readb(t, TI113X_CARD_CONTROL, &p->cardctl);
+ config_readb(t, TI113X_DEVICE_CONTROL, &p->devctl);
+ config_readb(t, TI1250_DIAGNOSTIC, &p->diag);
}
static void ti113x_set_state(u_short s)
{
socket_info_t *t = &socket[s];
ti113x_state_t *p = &socket[s].state.ti113x;
- pci_writel(t->bus, t->devfn, TI113X_SYSTEM_CONTROL, p->sysctl);
- pci_writeb(t->bus, t->devfn, TI113X_CARD_CONTROL, p->cardctl);
- pci_writeb(t->bus, t->devfn, TI113X_DEVICE_CONTROL, p->devctl);
- pci_writeb(t->bus, t->devfn, TI1250_MULTIMEDIA_CTL, 0);
- pci_writeb(t->bus, t->devfn, TI1250_DIAGNOSTIC, p->diag);
+ config_writel(t, TI113X_SYSTEM_CONTROL, p->sysctl);
+ config_writeb(t, TI113X_CARD_CONTROL, p->cardctl);
+ config_writeb(t, TI113X_DEVICE_CONTROL, p->devctl);
+ config_writeb(t, TI1250_MULTIMEDIA_CTL, 0);
+ config_writeb(t, TI1250_DIAGNOSTIC, p->diag);
i365_set_pair(s, TI113X_IO_OFFSET(0), 0);
i365_set_pair(s, TI113X_IO_OFFSET(1), 0);
}
@@ -822,20 +805,20 @@
{
socket_info_t *t = &socket[s];
rl5c4xx_state_t *p = &socket[s].state.rl5c4xx;
- pci_readw(t->bus, t->devfn, RL5C4XX_MISC, &p->misc);
- pci_readw(t->bus, t->devfn, RL5C4XX_16BIT_CTL, &p->ctl);
- pci_readw(t->bus, t->devfn, RL5C4XX_16BIT_IO_0, &p->io);
- pci_readw(t->bus, t->devfn, RL5C4XX_16BIT_MEM_0, &p->mem);
+ config_readw(t, RL5C4XX_MISC, &p->misc);
+ config_readw(t, RL5C4XX_16BIT_CTL, &p->ctl);
+ config_readw(t, RL5C4XX_16BIT_IO_0, &p->io);
+ config_readw(t, RL5C4XX_16BIT_MEM_0, &p->mem);
}
static void rl5c4xx_set_state(u_short s)
{
socket_info_t *t = &socket[s];
rl5c4xx_state_t *p = &socket[s].state.rl5c4xx;
- pci_writew(t->bus, t->devfn, RL5C4XX_MISC, p->misc);
- pci_writew(t->bus, t->devfn, RL5C4XX_16BIT_CTL, p->ctl);
- pci_writew(t->bus, t->devfn, RL5C4XX_16BIT_IO_0, p->io);
- pci_writew(t->bus, t->devfn, RL5C4XX_16BIT_MEM_0, p->mem);
+ config_writew(t, RL5C4XX_MISC, p->misc);
+ config_writew(t, RL5C4XX_16BIT_CTL, p->ctl);
+ config_writew(t, RL5C4XX_16BIT_IO_0, p->io);
+ config_writew(t, RL5C4XX_16BIT_MEM_0, p->mem);
}
static u_int __init rl5c4xx_set_opts(u_short s, char *buf)
@@ -986,20 +969,20 @@
{
socket_info_t *t = &socket[s];
topic_state_t *p = &socket[s].state.topic;
- pci_readb(t->bus, t->devfn, TOPIC_SLOT_CONTROL, &p->slot);
- pci_readb(t->bus, t->devfn, TOPIC_CARD_CONTROL, &p->ccr);
- pci_readb(t->bus, t->devfn, TOPIC_CARD_DETECT, &p->cdr);
- pci_readl(t->bus, t->devfn, TOPIC_REGISTER_CONTROL, &p->rcr);
+ config_readb(t, TOPIC_SLOT_CONTROL, &p->slot);
+ config_readb(t, TOPIC_CARD_CONTROL, &p->ccr);
+ config_readb(t, TOPIC_CARD_DETECT, &p->cdr);
+ config_readl(t, TOPIC_REGISTER_CONTROL, &p->rcr);
}
static void topic_set_state(u_short s)
{
socket_info_t *t = &socket[s];
topic_state_t *p = &socket[s].state.topic;
- pci_writeb(t->bus, t->devfn, TOPIC_SLOT_CONTROL, p->slot);
- pci_writeb(t->bus, t->devfn, TOPIC_CARD_CONTROL, p->ccr);
- pci_writeb(t->bus, t->devfn, TOPIC_CARD_DETECT, p->cdr);
- pci_writel(t->bus, t->devfn, TOPIC_REGISTER_CONTROL, p->rcr);
+ config_writeb(t, TOPIC_SLOT_CONTROL, p->slot);
+ config_writeb(t, TOPIC_CARD_CONTROL, p->ccr);
+ config_writeb(t, TOPIC_CARD_DETECT, p->cdr);
+ config_writel(t, TOPIC_REGISTER_CONTROL, p->rcr);
}
static int topic_set_irq_mode(u_short s, int pcsc, int pint)
@@ -1040,33 +1023,28 @@
{
socket_info_t *t = &socket[s];
- pci_readb(t->bus, t->devfn, PCI_CACHE_LINE_SIZE, &t->cache);
- pci_readb(t->bus, t->devfn, PCI_LATENCY_TIMER, &t->pci_lat);
- pci_readb(t->bus, t->devfn, CB_LATENCY_TIMER, &t->cb_lat);
- pci_readb(t->bus, t->devfn, CB_CARDBUS_BUS, &t->cap.cardbus);
- pci_readb(t->bus, t->devfn, CB_SUBORD_BUS, &t->sub_bus);
- pci_readw(t->bus, t->devfn, CB_BRIDGE_CONTROL, &t->bcr);
- {
- struct pci_dev *pdev = pci_find_slot(t->bus, t->devfn);
- t->cap.pci_irq = (pdev) ? pdev->irq : 0;
- }
- if (t->cap.pci_irq >= NR_IRQS) t->cap.pci_irq = 0;
+ config_readb(t, PCI_CACHE_LINE_SIZE, &t->cache);
+ config_readb(t, PCI_LATENCY_TIMER, &t->pci_lat);
+ config_readb(t, CB_LATENCY_TIMER, &t->cb_lat);
+ config_readb(t, CB_CARDBUS_BUS, &t->cap.cardbus);
+ config_readb(t, CB_SUBORD_BUS, &t->sub_bus);
+ config_readw(t, CB_BRIDGE_CONTROL, &t->bcr);
+ t->cap.pci_irq = t->pdev->irq;
}
static void cb_set_state(u_short s)
{
socket_info_t *t = &socket[s];
- if (t->pmcs)
- pci_writew(t->bus, t->devfn, t->pmcs, PCI_PMCS_PWR_STATE_D0);
- pci_writel(t->bus, t->devfn, CB_LEGACY_MODE_BASE, 0);
- pci_writel(t->bus, t->devfn, PCI_BASE_ADDRESS_0, t->cb_phys);
- pci_writew(t->bus, t->devfn, PCI_COMMAND, CMD_DFLT);
- pci_writeb(t->bus, t->devfn, PCI_CACHE_LINE_SIZE, t->cache);
- pci_writeb(t->bus, t->devfn, PCI_LATENCY_TIMER, t->pci_lat);
- pci_writeb(t->bus, t->devfn, CB_LATENCY_TIMER, t->cb_lat);
- pci_writeb(t->bus, t->devfn, CB_CARDBUS_BUS, t->cap.cardbus);
- pci_writeb(t->bus, t->devfn, CB_SUBORD_BUS, t->sub_bus);
- pci_writew(t->bus, t->devfn, CB_BRIDGE_CONTROL, t->bcr);
+ pci_set_power_state(t->pdev, 0); /* FIXME: Do we really need all of this? */
+ config_writel(t, CB_LEGACY_MODE_BASE, 0);
+ config_writel(t, PCI_BASE_ADDRESS_0, t->cb_phys);
+ config_writew(t, PCI_COMMAND, CMD_DFLT);
+ config_writeb(t, PCI_CACHE_LINE_SIZE, t->cache);
+ config_writeb(t, PCI_LATENCY_TIMER, t->pci_lat);
+ config_writeb(t, CB_LATENCY_TIMER, t->cb_lat);
+ config_writeb(t, CB_CARDBUS_BUS, t->cap.cardbus);
+ config_writeb(t, CB_SUBORD_BUS, t->sub_bus);
+ config_writew(t, CB_BRIDGE_CONTROL, t->bcr);
}
static int cb_get_irq_mode(u_short s)
@@ -1500,13 +1478,11 @@
printk(KERN_INFO " %s", pcic[type].name);
#ifdef CONFIG_PCI
if (t->flags & IS_UNKNOWN)
- printk(" [0x%04x 0x%04x]", t->vendor, t->device);
+ printk(" [0x%04x 0x%04x]", t->pdev->vendor, t->pdev->device);
if (t->flags & IS_CARDBUS)
- printk(" PCI-to-CardBus at bus %d slot %d, mem 0x%08x",
- t->bus, PCI_SLOT(t->devfn), t->cb_phys);
+ printk(" PCI-to-CardBus at %s, mem 0x%08x", t->pdev->slot_name, t->cb_phys);
else if (t->flags & IS_PCI)
- printk(" PCI-to-PCMCIA at bus %d slot %d, port %#x",
- t->bus, PCI_SLOT(t->devfn), t->ioaddr);
+ printk(" PCI-to-PCMCIA at %s, port %#x", t->pdev->slot_name, t->ioaddr);
else
#endif
printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
@@ -1596,107 +1572,50 @@
#ifdef CONFIG_PCI
-typedef struct pci_dev *pci_id_t;
-static int __init pci_lookup(u_int class, pci_id_t *id,
- u_char *bus, u_char *devfn)
-{
- if ((*id = pci_find_class(class<<8, *id)) != NULL) {
- *bus = (*id)->bus->number;
- *devfn = (*id)->devfn;
- return 0;
- } else return -1;
-}
-
-static void __init add_pci_bridge(int type, u_char bus, u_char devfn,
- u_short v, u_short d)
+static void __init add_pci_bridge(int type, struct pci_dev *dev)
{
socket_info_t *s = &socket[sockets];
u_short i, ns;
- u_int addr;
+ u32 addr = dev->resource[0].start;
if (type == PCIC_COUNT) type = IS_UNK_PCI;
- pci_readl(bus, devfn, PCI_BASE_ADDRESS_0, &addr);
- addr &= ~0x1;
- pci_writew(bus, devfn, PCI_COMMAND, CMD_DFLT);
+ pci_write_config_word(dev, PCI_COMMAND, CMD_DFLT);
for (i = ns = 0; i < ((type == IS_I82092AA) ? 4 : 2); i++) {
- s->bus = bus; s->devfn = devfn;
- s->vendor = v; s->device = d;
+ s->pdev = dev;
add_socket(addr, i, type);
ns++; s++;
}
add_pcic(ns, type);
}
-static void __init add_cb_bridge(int type, u_char bus, u_char devfn,
- u_short v, u_short d0)
+static void __init add_cb_bridge(int type, struct pci_dev *dev0)
{
socket_info_t *s = &socket[sockets];
- u_short d, ns, i;
- u_char a, b, r, max;
+ u_short i, ns;
+ u_char a, b;
- /* PCI bus enumeration is broken on some systems */
- for (ns = 0; ns < sockets; ns++)
- if ((socket[ns].bus == bus) && (socket[ns].devfn == devfn))
- return;
-
- if (type == PCIC_COUNT) type = IS_UNK_CARDBUS;
- pci_readb(bus, devfn, PCI_HEADER_TYPE, &a);
- pci_readb(bus, devfn, PCI_CLASS_REVISION, &r);
- max = (a & 0x80) ? 8 : 1;
- for (ns = 0; ns < max; ns++, s++, devfn++) {
- if (pci_readw(bus, devfn, PCI_DEVICE_ID, &d) || (d != d0))
- break;
- s->bus = bus; s->devfn = devfn;
- s->vendor = v; s->device = d; s->revision = r;
-
- /* Check for power management capabilities */
- pci_readb(bus, devfn, PCI_STATUS, &a);
- if (a & PCI_STATUS_CAPLIST) {
- pci_readb(bus, devfn, PCI_CB_CAPABILITY_POINTER, &b);
- while (b != 0) {
- pci_readb(bus, devfn, b+PCI_CAPABILITY_ID, &a);
- if (a == PCI_CAPABILITY_PM) {
- s->pmcs = b + PCI_PM_CONTROL_STATUS;
- break;
- }
- pci_readb(bus, devfn, b+PCI_NEXT_CAPABILITY, &b);
- }
- }
- /* If capability exists, make sure we're in D0 state */
- if (s->pmcs)
- pci_writew(bus, devfn, s->pmcs, PCI_PMCS_PWR_STATE_D0);
-
- /* Map CardBus registers if they are not already mapped */
- pci_writel(bus, devfn, CB_LEGACY_MODE_BASE, 0);
- pci_readl(bus, devfn, PCI_BASE_ADDRESS_0, &s->cb_phys);
- if (s->cb_phys == 0) {
- pci_writew(bus, devfn, PCI_COMMAND, CMD_DFLT);
- for (i = 0; i < sizeof(cb_mem_base)/sizeof(u_int); i++) {
- s->cb_phys = cb_mem_base[i];
- s->cb_virt = ioremap(s->cb_phys, 0x1000);
- pci_writel(bus, devfn, PCI_BASE_ADDRESS_0, s->cb_phys);
- /* Simple sanity checks */
- if (!(readb(s->cb_virt+0x800+I365_IDENT) & 0x70) &&
- !(readb(s->cb_virt+0x800+I365_CSC) &&
- readb(s->cb_virt+0x800+I365_CSC) &&
- readb(s->cb_virt+0x800+I365_CSC)))
- break;
- iounmap(s->cb_virt);
- }
- if (i == sizeof(cb_mem_base)/sizeof(u_int)) {
- pci_writel(bus, devfn, PCI_BASE_ADDRESS_0, 0);
- s->cb_phys = 0; s->cb_virt = NULL;
- printk("\n");
- printk(KERN_NOTICE " Bridge register mapping failed:"
- " check cb_mem_base setting\n");
+ if (type == PCIC_COUNT)
+ type = IS_UNK_CARDBUS;
+
+ for (ns = 0; ns < 8; ns++, s++) {
+ struct pci_dev *dev;
+
+ dev = pci_find_slot(dev0->bus->number, dev0->devfn + ns);
+ if (!dev)
break;
- }
- cb_mem_base[0] = cb_mem_base[i] + PAGE_SIZE;
- } else {
- s->cb_virt = ioremap(s->cb_phys, 0x1000);
+ s->pdev = dev;
+ pci_read_config_byte(dev, PCI_CLASS_REVISION, &s->revision);
+
+ /* Map CardBus registers if they are not already mapped */
+ pci_write_config_dword(dev, CB_LEGACY_MODE_BASE, 0);
+ s->cb_phys = dev->resource[0].start;
+ if (!s->cb_phys || !(s->cb_virt = ioremap(s->cb_phys, 0x1000))) {
+ printk("\n");
+ printk(KERN_ERR " No control registers found!\n");
+ break;
}
-
request_mem_region(s->cb_phys, 0x1000, "i82365");
+ s->cap.cb_bus = dev->subordinate;
add_socket(0, 0, type);
}
if (ns == 0) return;
@@ -1704,11 +1623,11 @@
s -= ns;
if (ns == 2) {
/* Nasty special check for bad bus mapping */
- pci_readb(bus, s[0].devfn, CB_CARDBUS_BUS, &a);
- pci_readb(bus, s[1].devfn, CB_CARDBUS_BUS, &b);
+ config_readb(&s[0], CB_CARDBUS_BUS, &a);
+ config_readb(&s[1], CB_CARDBUS_BUS, &b);
if (a == b) {
- pci_writeb(bus, s[0].devfn, CB_CARDBUS_BUS, 0);
- pci_writeb(bus, s[1].devfn, CB_CARDBUS_BUS, 0);
+ config_writeb(&s[0], CB_CARDBUS_BUS, 0);
+ config_writeb(&s[1], CB_CARDBUS_BUS, 0);
}
}
add_pcic(ns, type);
@@ -1728,43 +1647,19 @@
if (i == 200)
printk(KERN_NOTICE "i82365: card voltage interrogation"
" timed out!\n");
-
- /* Set up PCI bus bridge structures if needed */
- for (a = 0; a < ns; a++) {
- struct pci_dev *self = pci_find_slot(bus, s[a].devfn);
- struct pci_bus *child, *parent = self->bus;
- for (child = parent->children; child; child = child->next)
- if (child->number == s[a].cap.cardbus) break;
- if (!child) {
- child = kmalloc(sizeof(struct pci_bus), GFP_KERNEL);
- memset(child, 0, sizeof(struct pci_bus));
- child->self = self;
- child->primary = bus;
- child->number = child->secondary = s[a].cap.cardbus;
- child->subordinate = s[a].sub_bus;
- child->parent = parent;
- child->ops = parent->ops;
- child->next = parent->children;
- }
- s[a].cap.cb_bus = parent->children = child;
- }
}
-static void __init pci_probe(u_int class, void (add_fn)
- (int, u_char, u_char, u_short, u_short))
-{
- u_short i, v, d;
- u_char bus, devfn;
- pci_id_t id;
-
- id = 0;
- while (pci_lookup(class, &id, &bus, &devfn) == 0) {
- if (PCI_FUNC(devfn) != 0) continue;
- pci_readw(bus, devfn, PCI_VENDOR_ID, &v);
- pci_readw(bus, devfn, PCI_DEVICE_ID, &d);
+static void __init pci_probe(u_int class, void (add_fn)(int, struct pci_dev *))
+{
+ struct pci_dev *dev = NULL;
+ u_short i;
+
+ while ((dev = pci_find_class(class << 8, dev))) {
+ pci_enable_device(dev);
+ if (PCI_FUNC(dev->devfn) != 0) continue;
for (i = 0; i < PCIC_COUNT; i++)
- if ((pcic[i].vendor == v) && (pcic[i].device == d)) break;
- add_fn(i, bus, devfn, v, d);
+ if ((pcic[i].vendor == dev->vendor) && (pcic[i].device == dev->device)) break;
+ add_fn(i, dev);
}
}
@@ -1887,22 +1782,21 @@
/*====================================================================*/
-static int pcic_register_callback(u_short sock, ss_callback_t *call)
+static int pcic_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
{
- if (call == NULL) {
- socket[sock].handler = NULL;
+ socket[sock].handler = handler;
+ socket[sock].info = info;
+ if (handler == NULL) {
MOD_DEC_USE_COUNT;
} else {
MOD_INC_USE_COUNT;
- socket[sock].handler = call->handler;
- socket[sock].info = call->info;
}
return 0;
} /* pcic_register_callback */
/*====================================================================*/
-static int pcic_inquire_socket(u_short sock, socket_cap_t *cap)
+static int pcic_inquire_socket(unsigned int sock, socket_cap_t *cap)
{
*cap = socket[sock].cap;
return 0;
@@ -2398,7 +2292,7 @@
u_short bcr;
cb_get_power(sock, state);
- pci_readw(s->bus, s->devfn, CB_BRIDGE_CONTROL, &bcr);
+ config_readw(s, CB_BRIDGE_CONTROL, &bcr);
state->flags |= (bcr & CB_BCR_CB_RESET) ? SS_RESET : 0;
if (cb_get_irq_mode(sock) != 0)
state->io_irq = s->cap.pci_irq;
@@ -2414,7 +2308,7 @@
{
socket_info_t *s = &socket[sock];
u_int reg;
-
+
DEBUG(1, "yenta: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
"io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
@@ -2455,15 +2349,15 @@
if (map > 1) return -EINVAL;
m->flags &= MAP_IOSPACE;
map += (m->flags & MAP_IOSPACE) ? 2 : 0;
- pci_readl(s->bus, s->devfn, CB_MEM_BASE(map), &m->start);
- pci_readl(s->bus, s->devfn, CB_MEM_LIMIT(map), &m->stop);
+ config_readl(s, CB_MEM_BASE(map), &m->start);
+ config_readl(s, CB_MEM_LIMIT(map), &m->stop);
if (m->start || m->stop) {
m->flags |= MAP_ACTIVE;
m->stop |= (map > 1) ? 3 : 0x0fff;
}
if (map > 1) {
u_short bcr;
- pci_readw(s->bus, s->devfn, CB_BRIDGE_CONTROL, &bcr);
+ config_readw(s, CB_BRIDGE_CONTROL, &bcr);
m->flags |= (bcr & CB_BCR_PREFETCH(map)) ? MAP_PREFETCH : 0;
}
DEBUG(1, "yenta: GetBridge(%d, %d) = %#2.2x, %#4.4x-%#4.4x\n",
@@ -2490,17 +2384,17 @@
u_short bcr;
if ((m->start & 0x0fff) || ((m->stop & 0x0fff) != 0x0fff))
return -EINVAL;
- pci_readw(s->bus, s->devfn, CB_BRIDGE_CONTROL, &bcr);
+ config_readw(s, CB_BRIDGE_CONTROL, &bcr);
bcr &= ~CB_BCR_PREFETCH(map);
bcr |= (m->flags & MAP_PREFETCH) ? CB_BCR_PREFETCH(map) : 0;
- pci_writew(s->bus, s->devfn, CB_BRIDGE_CONTROL, bcr);
+ config_writew(s, CB_BRIDGE_CONTROL, bcr);
}
if (m->flags & MAP_ACTIVE) {
- pci_writel(s->bus, s->devfn, CB_MEM_BASE(map), m->start);
- pci_writel(s->bus, s->devfn, CB_MEM_LIMIT(map), m->stop);
+ config_writel(s, CB_MEM_BASE(map), m->start);
+ config_writel(s, CB_MEM_LIMIT(map), m->stop);
} else {
- pci_writel(s->bus, s->devfn, CB_IO_BASE(map), 0);
- pci_writel(s->bus, s->devfn, CB_IO_LIMIT(map), 0);
+ config_writel(s, CB_MEM_BASE(map), 0);
+ config_writel(s, CB_MEM_LIMIT(map), 0);
}
return 0;
}
@@ -2526,7 +2420,7 @@
#ifdef CONFIG_PCI
if (s->flags & (IS_PCI|IS_CARDBUS))
p += sprintf(p, "bus: %02x\ndevfn: %02x.%1x\n",
- s->bus, PCI_SLOT(s->devfn), PCI_FUNC(s->devfn));
+ s->pdev->bus->number, PCI_SLOT(s->pdev->devfn), PCI_FUNC(s->pdev->devfn));
if (s->flags & IS_CARDBUS)
p += sprintf(p, "cardbus: %02x\n", s->cap.cardbus);
#endif
@@ -2566,16 +2460,15 @@
int count, int *eof, void *data)
{
socket_info_t *s = data;
- u_char bus = s->bus, devfn = s->devfn;
char *p = buf;
u_int a, b, c, d;
int i;
for (i = 0; i < 0xc0; i += 0x10) {
- pci_readl(bus, devfn, i, &a);
- pci_readl(bus, devfn, i+4, &b);
- pci_readl(bus, devfn, i+8, &c);
- pci_readl(bus, devfn, i+12, &d);
+ config_readl(s, i, &a);
+ config_readl(s, i+4, &b);
+ config_readl(s, i+8, &c);
+ config_readl(s, i+12, &d);
p += sprintf(p, "%08x %08x %08x %08x\n", a, b, c, d);
}
return (p - buf);
@@ -2599,9 +2492,14 @@
}
#endif
-static void pcic_proc_setup(u_short sock, struct proc_dir_entry *base)
+static void pcic_proc_setup(unsigned int sock, struct proc_dir_entry *base)
{
+#ifdef CONFIG_PROC_FS
socket_info_t *s = &socket[sock];
+
+ if (s->flags & IS_ALIVE)
+ return;
+
create_proc_read_entry("info", 0, base, proc_read_info, s);
create_proc_read_entry("exca", 0, base, proc_read_exca, s);
#ifdef CONFIG_PCI
@@ -2613,6 +2511,7 @@
create_proc_read_entry("cardbus", 0, base, proc_read_cardbus, s);
#endif
s->proc = base;
+#endif
}
static void pcic_proc_remove(u_short sock)
@@ -2635,68 +2534,150 @@
/*====================================================================*/
-typedef int (*subfn_t)(u_short, void *);
+/*
+ * This looks like a lot of duplication, and it is. What we should REALLY
+ * have is separate functions for the separate cases, instead of having
+ * duplicate tests in them - and then have the test in the place that sets
+ * up the ss_entry function pointer table instead!
+ *
+ * For example, the IS_CARDBUS thing is something we know _statically_,
+ * and as such it is a waste of time and space to test it dynamically.
+ *
+ * Much of this goes away by splitting off the cases. One small step at a
+ * time..
+ */
-static subfn_t pcic_service_table[] = {
- (subfn_t)&pcic_register_callback,
- (subfn_t)&pcic_inquire_socket,
- (subfn_t)&i365_get_status,
- (subfn_t)&i365_get_socket,
- (subfn_t)&i365_set_socket,
- (subfn_t)&i365_get_io_map,
- (subfn_t)&i365_set_io_map,
- (subfn_t)&i365_get_mem_map,
- (subfn_t)&i365_set_mem_map,
#ifdef CONFIG_CARDBUS
- (subfn_t)&cb_get_bridge,
- (subfn_t)&cb_set_bridge,
+#define is_cardbus(sock) ((socket[(sock)].flags & IS_CARDBUS) && (cb_readl((sock), CB_SOCKET_STATE) & CB_SS_32BIT))
+#endif
+
+/*
+ * The locking is rather broken. Why do we only lock for ISA, not for
+ * all other cases? If there are reasons to lock, we should lock. Not
+ * this silly conditional.
+ *
+ * Plan: make it bug-for-bug compatible with the old stuff, and clean
+ * it up when the infrastructure is done.
+ */
+#ifdef CONFIG_ISA
+#define LOCKED(x) do { \
+ if (socket[(sock)].flags & IS_CARDBUS) return x; \
+ do { \
+ int retval; \
+ unsigned long flags; \
+ spin_lock_irqsave(&isa_lock, flags); \
+ retval = x; \
+ spin_unlock_irqrestore(&isa_lock, flags); \
+ return retval; \
+ } while (0); \
+} while (0)
#else
- NULL, NULL,
+#define LOCKED(x) return x
#endif
-#ifdef CONFIG_PROC_FS
- (subfn_t)&pcic_proc_setup
+
+
+static int pcic_get_status(unsigned int sock, u_int *value)
+{
+ if (socket[sock].flags & IS_ALIVE) {
+ *value = 0;
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_CARDBUS
+ if (is_cardbus(sock))
+ return cb_get_status(sock, value);
#endif
-};
+ LOCKED(i365_get_status(sock, value));
+}
+
+static int pcic_get_socket(unsigned int sock, socket_state_t *state)
+{
+ if (socket[sock].flags & IS_ALIVE)
+ return -EINVAL;
-#define NFUNC (sizeof(pcic_service_table)/sizeof(subfn_t))
+#ifdef CONFIG_CARDBUS
+ if (is_cardbus(sock))
+ return cb_get_socket(sock, state);
+#endif
+ LOCKED(i365_get_socket(sock, state));
+}
-static int pcic_service(u_int sock, u_int cmd, void *arg)
+static int pcic_set_socket(unsigned int sock, socket_state_t *state)
{
- subfn_t fn;
- int ret;
-#ifdef CONFIG_ISA
- u_long flags = 0;
+ if (socket[sock].flags & IS_ALIVE)
+ return -EINVAL;
+
+#ifdef CONFIG_CARDBUS
+ if (is_cardbus(sock))
+ return cb_set_socket(sock, state);
#endif
-
- DEBUG(2, "pcic_ioctl(%d, %d, 0x%p)\n", sock, cmd, arg);
+ LOCKED(i365_set_socket(sock, state));
+}
- if (cmd >= NFUNC)
- return -EINVAL;
+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)
+{
+ if (socket[sock].flags & IS_ALIVE)
+ return -EINVAL;
+
+ 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)
+{
+ if (socket[sock].flags & IS_ALIVE)
+ return -EINVAL;
+
+ LOCKED(i365_set_mem_map(sock, mem));
+}
- if (socket[sock].flags & IS_ALIVE) {
- if (cmd == SS_GetStatus)
- *(u_int *)arg = 0;
+static int pcic_get_bridge(unsigned int sock, struct cb_bridge_map *m)
+{
+#ifdef CONFIG_CARDBUS
+ return cb_get_bridge(sock, m);
+#else
return -EINVAL;
- }
-
- fn = pcic_service_table[cmd];
+#endif
+}
+
+static int pcic_set_bridge(unsigned int sock, struct cb_bridge_map *m)
+{
#ifdef CONFIG_CARDBUS
- if ((socket[sock].flags & IS_CARDBUS) &&
- (cb_readl(sock, CB_SOCKET_STATE) & CB_SS_32BIT)) {
- if (cmd == SS_GetStatus)
- fn = (subfn_t)&cb_get_status;
- else if (cmd == SS_GetSocket)
- fn = (subfn_t)&cb_get_socket;
- else if (cmd == SS_SetSocket)
- fn = (subfn_t)&cb_set_socket;
- }
+ return cb_set_bridge(sock, m);
+#else
+ return -EINVAL;
#endif
+}
- ISA_LOCK(sock, flags);
- ret = (fn == NULL) ? -EINVAL : fn(sock, arg);
- ISA_UNLOCK(sock, flags);
- return ret;
-} /* pcic_service */
+static struct pccard_operations pcic_operations = {
+ pcic_register_callback,
+ pcic_inquire_socket,
+ pcic_get_status,
+ pcic_get_socket,
+ pcic_set_socket,
+ pcic_get_io_map,
+ pcic_set_io_map,
+ pcic_get_mem_map,
+ pcic_set_mem_map,
+ pcic_get_bridge,
+ pcic_set_bridge,
+ pcic_proc_setup
+};
/*====================================================================*/
@@ -2714,7 +2695,7 @@
sockets = 0;
#ifdef CONFIG_PCI
- if (do_pci_probe && pcibios_present()) {
+ if (do_pci_probe) {
pci_probe(PCI_CLASS_BRIDGE_CARDBUS, add_cb_bridge);
pci_probe(PCI_CLASS_BRIDGE_PCMCIA, add_pci_bridge);
}
@@ -2746,7 +2727,7 @@
}
#endif
- if (register_ss_entry(sockets, &pcic_service) != 0)
+ if (register_ss_entry(sockets, &pcic_operations) != 0)
printk(KERN_NOTICE "i82365: register_ss_entry() failed\n");
/* Finally, schedule a polling interrupt */
@@ -2768,7 +2749,7 @@
#ifdef CONFIG_PROC_FS
for (i = 0; i < sockets; i++) pcic_proc_remove(i);
#endif
- unregister_ss_entry(&pcic_service);
+ unregister_ss_entry(&pcic_operations);
if (poll_interval != 0)
del_timer(&poll_timer);
#ifdef CONFIG_ISA
@@ -2805,4 +2786,3 @@
module_exit(exit_i82365);
/*====================================================================*/
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)