[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: pcmcia-support for gnumach-1
From: |
Stefan Siegl |
Subject: |
Re: pcmcia-support for gnumach-1 |
Date: |
Wed, 08 Feb 2006 22:48:08 +0100 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) |
Hi Alfred,
"Alfred M\. Szmidt" <ams@gnu.org> writes:
> An option would be to just send the diff between linux/src and
> linux/dev directory (i.e. glue code and modifications to the
> pcmcia-cs' files). Do you think that helps?
>
> Yes, that would help immensly. The unmodifed bits in pcmcia-cs aren't
> that interesting.
okay, still somewhat long, but here we go ...
let's see the pcmcia core first:
| Only in linux/src/drivers/pcmcia/: bulkmem.c
| Only in linux/src/drivers/pcmcia/: bulkmem.h
| Only in linux/src/drivers/pcmcia/: bus_ops.h
| Only in linux/src/drivers/pcmcia/: cardbus.c
| diff -x '*~' -bur --unidirectional-new-file
linux/src/drivers/pcmcia/cardmgr.c linux/dev/drivers/pcmcia/cardmgr.c
| --- linux/src/drivers/pcmcia/cardmgr.c 1970-01-01 01:00:00.000000000
+0100
| +++ linux/dev/drivers/pcmcia/cardmgr.c 2006-02-05 00:13:59.000000000
+0100
| @@ -0,0 +1,437 @@
| +/***
| + * slim cardmgr implementation (supporting only do_insert)
| + *
| + * This probably should be removed as soon as possible, we shouldn't have
| + * more cruft in kernel than Linux has. They've got the monolithic kernel :-/
| + */
currently cards are only detected by the manfid, a "real" userspace
cardmgr ought to detect by cis content, etc. as well (quite like
linux's implementation does)
| +
| +#include <linux/proc_fs.h>
| +#include <linux/pci.h>
| +#include <linux/timer.h>
| +#include <linux/sched.h>
| +
| +#include <asm/spinlock.h>
| +
| +#include "pcmcia_glue.h"
| +
| +#include <pcmcia/version.h>
| +#include <pcmcia/cs_types.h>
| +#include <pcmcia/cs.h>
| +#include <pcmcia/cistpl.h>
| +#include <pcmcia/ds.h>
| +
| +/* first of all: don't get confused with the `socket_info_t' types.
| + * Unfortunately pcmcia-cs has two different types of that name.
| + */
| +
| +/*
| + * further prepare to imitate the userspace cardmgr ...
| + */
| +#undef SOCKET_PRESENT
| +
| +#include "drivers.h"
| +#include "cards.h"
| +
| +/*====================================================================*/
| +
| +struct _card_info_t {
| + char *name;
| + manfid_ident_t manfid;
| + int binding;
| +};
| +typedef struct _card_info_t card_info_t;
| +
| +typedef struct socket_info_t {
| + int fd;
| + int state;
| + card_info_t *card;
| + bind_info_t *bind;
| +} socket_info_t;
| +
| +#define SOCKET_PRESENT 0x01
| +#define SOCKET_READY 0x02
| +#define SOCKET_HOTPLUG 0x04
| +
| +#include "resources.h"
| +
| +/*
| + * socket information gathered and used while processing card insertions
| + * (this is our local version, don't get confused with the cs.c one!!)
| + */
| +#define MAX_SOCKS 8
| +static struct socket_info_t socket[MAX_SOCKS];
| +static socket_t sockets;
| +
| +int poll_interval = 250;
| +static void pcic_interrupt_wrapper(u_long data);
| +static struct timer_list poll_timer = {
| + function: pcic_interrupt_wrapper
| +};
| +
| +/***
| + * adjust_resource (from wagi's oskit cardmgr)
| + */
| +static void
| +adjust_resource(void)
| +{
| + adjust_t al;
| + int ret;
| + char tmp[64];
| + int fd = socket[0].fd;
| + int i;
| +
| + for (i=0; i < adj_mem_table_size; i++)
| + {
| + al.Action = adj_mem_table[i].Action;
| + al.Resource = adj_mem_table[i].Resource;
| + al.Attributes = adj_mem_table[i].Attributes;
| + al.resource.memory.Base = adj_mem_table[i].Base;
| + al.resource.memory.Size = adj_mem_table[i].Size;
| +
| + ret = pcmcia_ioctl(fd, DS_ADJUST_RESOURCE_INFO, &al);
| + if (ret != 0)
| + {
| + sprintf (tmp, "memory %#lx-%#lx",
| + al.resource.memory.Base,
| + al.resource.memory.Base +
| + al.resource.memory.Size - 1);
| + printk (KERN_INFO
| + "Could not adjust resource: %s\n", tmp);
| + }
| + }
| +
| + for (i=0; i < adj_io_table_size; i++)
| + {
| + al.Action = adj_io_table[i].Action;
| + al.Resource = adj_io_table[i].Resource;
| + al.Attributes = adj_io_table[i].Attributes;
| + al.resource.io.BasePort = adj_io_table[i].BasePort;
| + al.resource.io.NumPorts = adj_io_table[i].NumPorts;
| + al.resource.io.IOAddrLines = adj_io_table[i].IOAddrLines;
| +
| + ret = pcmcia_ioctl(fd, DS_ADJUST_RESOURCE_INFO, &al);
| + if (ret != 0)
| + {
| + sprintf (tmp, "IO ports %#x-%#x",
| + al.resource.io.BasePort,
| + al.resource.io.BasePort +
| + al.resource.io.NumPorts - 1);
| + printk (KERN_INFO
| + "Could not adjust resource: %s\n", tmp);
| + }
| + }
| +
| + for (i=0; i < adj_irq_table_size; i++)
| + {
| + al.Action = adj_irq_table[i].Action;
| + al.Resource = adj_irq_table[i].Resource;
| + al.Attributes = adj_irq_table[i].Attributes;
| + al.resource.irq.IRQ = adj_irq_table[i].IRQ;
| +
| + ret = pcmcia_ioctl(fd, DS_ADJUST_RESOURCE_INFO, &al);
| + if (ret != 0)
| + {
| + sprintf(tmp, "irq %u", al.resource.irq.IRQ);
| + printk(KERN_INFO
| + "Could not adjust resource: %s\n", tmp);
| + }
| + }
| +}
| +
| +
| +
| +static int
| +init_sockets(void)
| +{
| + int fd, i;
| + servinfo_t serv;
| +
| + for (fd = -1, i = 0; i < MAX_SOCKS; i++)
| + {
| + fd = pcmcia_open(i, S_IFCHR); /* XXX S_IREAD|S_IWRITE */
| + if (fd < 0) break;
| + socket[i].fd = fd;
| + socket[i].state = 0;
| + }
| +
| + sockets = i;
| + if (sockets == 0)
| + {
| + printk(KERN_INFO "no sockets found!\n");
| + return -1;
| + }
| + else
| + {
| + printk(KERN_INFO "watching %d sockets\n", sockets);
| + }
| +
| + printk(KERN_DEBUG "DS_GET_CARD_SERVICES_INFO: &serv=%p\n", &serv);
| + if (pcmcia_ioctl(socket[0].fd, DS_GET_CARD_SERVICES_INFO, &serv) == 0)
| + {
| + printk(KERN_DEBUG "versions: serv.Rev=%04x, CS_REL_CD=%04x\n",
| + serv.Revision, CS_RELEASE_CODE);
| + if (serv.Revision != CS_RELEASE_CODE)
| + {
| + printk(KERN_INFO "Card Services release does not match\n");
| + return -1;
| + }
| + }
| + else
| + {
| + printk(KERN_INFO /* FIXME: _ERR */ "could not get CS revision
info!\n");
| + return -1;
| + }
| +
| + adjust_resource();
| + return 0;
| +}
| +
| +
| +
| +/*====================================================================*/
| +
| +static int get_tuple(int ns, cisdata_t code, ds_ioctl_arg_t *arg)
| +{
| + socket_info_t *s = &socket[ns];
| +
| + arg->tuple.DesiredTuple = code;
| + arg->tuple.Attributes = 0;
| +
| + if (pcmcia_ioctl(s->fd, DS_GET_FIRST_TUPLE, arg) != 0)
| + return -1;
| +
| + arg->tuple.TupleOffset = 0;
| + if (pcmcia_ioctl(s->fd, DS_GET_TUPLE_DATA, arg) != 0)
| + {
| + printk(KERN_INFO "error reading CIS data on socket %d\n", ns);
| + return -1;
| + }
| +
| + if (pcmcia_ioctl(s->fd, DS_PARSE_TUPLE, arg) != 0)
| + {
| + printk(KERN_INFO "error parsing CIS on socket %d\n", ns);
| + return -1;
| + }
| + return 0;
| +}
| +
| +
| +
| +
| +typedef struct pci_id {
| + u_short vendor, device;
| + struct pci_id *next;
| +} pci_id_t;
| +
| +static card_info_t *
| +lookup_card(int ns)
| +{
| + socket_info_t *s = &socket[ns];
| + ds_ioctl_arg_t arg;
| + card_info_t *card = NULL;
| + cistpl_vers_1_t *vers = NULL;
| + cistpl_manfid_t manfid = { 0, 0 };
| + cistpl_funcid_t funcid = { 0xff, 0xff };
| + int ret, has_cis = 0;
| + int i;
| +
| + /* Do we have a CIS structure? */
| + ret = pcmcia_ioctl(s->fd, DS_VALIDATE_CIS, &arg);
| + has_cis = ((ret == 0) && (arg.cisinfo.Chains > 0));
| +
| + /* Try to read VERS_1, MANFID tuples */
| + if (has_cis) {
| + if (get_tuple(ns, CISTPL_FUNCID, &arg) == 0) {
| + memcpy(&funcid, &arg.tuple_parse.parse.funcid, sizeof(funcid));
| + } else if (get_tuple(ns, CISTPL_DEVICE_GEO, &arg) == 0) {
| + funcid.func = CISTPL_FUNCID_MEMORY;
| + }
| +
| + if (get_tuple(ns, CISTPL_MANFID, &arg) == 0) {
| + memcpy(&manfid, &arg.tuple_parse.parse.manfid, sizeof(manfid));
| + }
| +
| + if (get_tuple(ns, CISTPL_VERS_1, &arg) == 0) {
| + vers = &arg.tuple_parse.parse.version_1;
| + }
| +
| + for (i = 0; i < card_table_size; i++) {
| + if ((manfid.manf == card_table[i].manfid.manf) ||
| + (manfid.card == card_table[i].manfid.card)) {
| +
| + card = (card_info_t *) kmalloc (sizeof(card_info_t), GFP_KERNEL);
| + if(! card)
| + {
| + printk(KERN_INFO /* FIXME: _ERR? */ "not enough momory.\n");
| + return NULL;
| + }
| +
| + memset(card, 0, sizeof(card_info_t));
| + card->name = card_table[i].name;
| + card->manfid = card_table[i].manfid;
| + card->binding = card_table[i].binding;
| + break;
| + }
| + }
| + }
| +
| + if (card) {
| + printk(KERN_INFO "socket %d: %s\n", ns, card->name);
| + /* log_card_info(vers, &manfid, &funcid, &pci_id); */
| + return card;
| + }
| +
| + printk(KERN_INFO "unsupported card in socket %d\n", ns);
| + Debugger();
| + return NULL;
| +}
| +
| +static void
| +do_insert (int sn)
| +{
| + socket_info_t *s = &socket[sn];
| + card_info_t *card;
| + int j, ret;
| +
| + /* Already identified? */
| + if (s->card != NULL)
| + return;
| +
| + printk(KERN_INFO "initializing socket %d\n", sn);
| + card = lookup_card(sn);
| +
| + /* Make sure we've learned something new before continuing */
| + if (card == s->card)
| + return;
| + s->card = card;
| +
| + if(device_table[card->binding].module_init)
| + {
| + /* module initialisation routine defined, so call it. */
| + (device_table[card->binding].module_init)();
| + }
| + else
| + {
| + printk(KERN_INFO "pccard driver not available.\n");
| + return;
| + }
| +
| + printk(KERN_INFO "binding socket %d(%s): %s\n",
| + sn, card->name, device_table[card->binding].name);
| +
| + s->bind = kmalloc (sizeof(bind_info_t), GFP_KERNEL);
| + if(! s->bind)
| + {
| + printk(KERN_INFO /* FIXME: _ERR? */ "not enough momory.\n");
| + return;
| + }
| +
| + memset(s->bind, 0, sizeof(bind_info_t));
| + strcpy((char *)s->bind->dev_info,
| + (char *)device_table[card->binding].name);
| + s->bind->function = 0;
| +
| + if (pcmcia_ioctl(s->fd, DS_BIND_REQUEST, s->bind) != 0)
| + {
| + printk(KERN_INFO "bind '%s' to socket %d failed\n",
| + device_table[card->binding].name, s->fd);
| + Debugger();
| + return;
| + }
| +
| + for (ret = j = 0; j < 10; j++)
| + {
| + ret = pcmcia_ioctl(s->fd, DS_GET_DEVICE_INFO, s->bind);
| + if (ret == 0)
| + break;
| +
| + __udelay(100000);
| + }
| +
| + if (ret != 0)
| + {
| + printk(KERN_INFO "get dev info on socket %d failed\n", s->fd);
| + Debugger();
| + pcmcia_ioctl(s->fd, DS_UNBIND_REQUEST, s->bind);
| + return;
| + }
| +
| + printk(KERN_INFO "cardmgr: dev_base=%p (before return of do_insert)\n",
| + dev_base);
| +}
| +
| +static void check_cards(void)
| + {
| + int i, event, ret;
| +
| + for (i = 0; i < sockets; i++)
| + {
| + ret = pcmcia_read(socket[i].fd, &event, 4);
| +
| + if (ret < 0)
| + printk(KERN_INFO "read(%d) failed\n", i);
| + if (ret != 4)
| + continue;
| +
| + switch (event)
| + {
| + /* case CS_EVENT_CARD_REMOVAL:
| + * socket[i].state = 0;
| + * do_remove(i);
| + * break;
| + */
| +
| + case CS_EVENT_CARD_INSERTION:
| + case CS_EVENT_INSERTION_REQUEST:
| + socket[i].state |= SOCKET_PRESENT;
| +
| + case CS_EVENT_CARD_RESET:
| + socket[i].state |= SOCKET_READY;
| + do_insert(i);
| + break;
| +
| + default:
| + printk(KERN_INFO "opps, unkown event (%d)\n", event);
| + }
| + }
| + }
| +
| +extern int console_loglevel;
| +
| +static void pcic_interrupt_wrapper(u_long data)
| +{
| + /* console_loglevel = 8; */
| + check_cards();
| + /* console_loglevel = 7; */
| +
| + poll_timer.expires = jiffies + poll_interval;
| + add_timer(&poll_timer);
| +}
| +
| +
| +/* ============================================================ */
| +int
| +cardmgr_simple (void)
| +{
| + if (init_sockets() != 0)
| + return -1;
| +
| + /* call check_cards(); somehow regularly ... */
| +
| +#if 0
| + int i;
| + for(i = 0; i < 20; i ++)
| + {
| + check_cards();
| + __udelay(1000000);
| + }
| +#else
| + init_timer(&poll_timer);
| + poll_timer.expires = jiffies + poll_interval;
| + add_timer(&poll_timer);
| +#endif
| +
| + return 0;
| +}
| diff -x '*~' -bur --unidirectional-new-file linux/src/drivers/pcmcia/cards.h
linux/dev/drivers/pcmcia/cards.h
| --- linux/src/drivers/pcmcia/cards.h 1970-01-01 01:00:00.000000000 +0100
| +++ linux/dev/drivers/pcmcia/cards.h 2006-02-04 21:53:54.000000000 +0100
| @@ -0,0 +1,22 @@
| +#ifndef _PCMCIA_CARDS_H_
| +#define _PCMCIA_CARDS_H_
| +
| +#include "drivers.h"
| +
| +typedef struct manfid_ident_t {
| + u_short manf;
| + u_short card;
| +} manfid_ident_t;
| +
| +struct card_table_t {
| + char *name;
| + manfid_ident_t manfid;
| + int binding;
| +} card_table[] = {
| + { "NE2000 Compatible Ethernet", { 0x0149, 0xC1AB }, DEV_PCNET },
| + { "3Com 3c562/3c563 Ethernet/Modem", { 0x0101, 0x0589 }, DEV_3C589 }
cards are currently only detected by their manfid, i.e. other cards
need to have an entry right above to be supported.
| +};
| +
| +int card_table_size = (sizeof(card_table) / sizeof(card_table[0]));
| +
| +#endif
| Only in linux/src/drivers/pcmcia/: cb_enabler.c
| Only in linux/src/drivers/pcmcia/: cirrus.h
| Only in linux/src/drivers/pcmcia/: ciscode.h
| Only in linux/src/drivers/pcmcia/: cisreg.h
| Only in linux/src/drivers/pcmcia/: cistpl.c
| Only in linux/src/drivers/pcmcia/: cistpl.h
| diff -x '*~' -bur --unidirectional-new-file
linux/src/drivers/pcmcia/clients/3c589_cs.c
linux/dev/drivers/pcmcia/clients/3c589_cs.c
| --- linux/src/drivers/pcmcia/clients/3c589_cs.c 2006-02-04
21:53:59.000000000 +0100
| +++ linux/dev/drivers/pcmcia/clients/3c589_cs.c 2006-02-04
21:53:54.000000000 +0100
| @@ -60,6 +60,20 @@
|
| #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
|
| +/* From pcmcia-cs's <linux/netdevice.h> */
| +#define skb_tx_check(dev, skb) \
| + do { if (skb == NULL) { dev_tint(dev); return 0; } \
| + if (skb->len <= 0) return 0; } while (0)
| +#define tx_timeout_check(dev, tx_timeout) \
| + do { if (test_and_set_bit(0, (void *)&(dev)->tbusy) != 0) { \
| + if (jiffies - (dev)->trans_start < TX_TIMEOUT) return 1; \
| + tx_timeout(dev); \
| + } } while (0)
| +#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb, FREE_WRITE)
| +#define net_device_stats enet_statistics
| +#define add_rx_bytes(stats, n) do { int x; x = (n); } while (0)
| +#define add_tx_bytes(stats, n) do { int x; x = (n); } while (0)
| +
this ought to be moved into the pcmcia_glue.h file since it's quite
generic and probably used in other drivers as well. afaik the 3com
driver doesn't work anyways right now, Michael is working on it though.
| /* The top five bits written to EL3_CMD are a command, the lower
| 11 bits are the parameter, if applicable. */
| enum c509cmd {
| @@ -1081,7 +1095,7 @@
|
| /*====================================================================*/
|
| -static int __init init_3c589_cs(void)
| +int init_3c589_cs(void)
| {
| servinfo_t serv;
| DEBUG(0, "%s\n", version);
| @@ -1094,14 +1108,3 @@
| register_pccard_driver(&dev_info, &tc589_attach, &tc589_detach);
| return 0;
| }
| -
| -static void __exit exit_3c589_cs(void)
| -{
| - DEBUG(0, "3c589_cs: unloading\n");
| - unregister_pccard_driver(&dev_info);
| - while (dev_list != NULL)
| - tc589_detach(dev_list);
| -}
| -
| -module_init(init_3c589_cs);
| -module_exit(exit_3c589_cs);
| diff -x '*~' -bur --unidirectional-new-file
linux/src/drivers/pcmcia/clients/pcnet_cs.c
linux/dev/drivers/pcmcia/clients/pcnet_cs.c
| --- linux/src/drivers/pcmcia/clients/pcnet_cs.c 2006-02-04
21:53:59.000000000 +0100
| +++ linux/dev/drivers/pcmcia/clients/pcnet_cs.c 2006-02-05
00:27:11.000000000 +0100
| @@ -40,10 +40,9 @@
| #include <asm/io.h>
| #include <asm/system.h>
| #include <asm/byteorder.h>
| -#include <asm/uaccess.h>
|
| #include <linux/netdevice.h>
| -#include <../drivers/net/8390.h>
| +#include <8390.h>
|
| #include <pcmcia/version.h>
| #include <pcmcia/cs_types.h>
| @@ -711,11 +710,20 @@
| } else {
| dev->if_port = 0;
| }
| +
| + printk(KERN_INFO "pcnet_cs: dev_base=%p (before register_netdev)\n",
| + dev_base);
| + if(dev_base)
| + printk(KERN_INFO "pcnet_cs: dev_base->name=%s\n", dev_base->name);
| +
| if (register_netdev(dev) != 0) {
| printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
| goto failed;
| }
|
| + printk(KERN_INFO "pcnet_cs: dev_base=%p (after register_netdev)\n",
| + dev_base);
| +
hmm, these printk ought to be removed :-)
| hw_info = get_hwinfo(link);
| if (hw_info == NULL)
| hw_info = get_prom(link);
| @@ -787,6 +795,10 @@
| for (i = 0; i < 6; i++)
| printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
| link->state &= ~DEV_CONFIG_PENDING;
| +
| + printk(KERN_INFO "pcnet_cs: dev_base=%p (before return)\n",
| + dev_base);
| + Debugger();
| return;
|
| cs_failed:
| @@ -1676,7 +1688,7 @@
|
| /*====================================================================*/
|
| -static int __init init_pcnet_cs(void)
| +int __init init_pcnet_cs(void)
| {
| servinfo_t serv;
| DEBUG(0, "%s\n", version);
| @@ -1690,13 +1702,3 @@
| return 0;
| }
|
| -static void __exit exit_pcnet_cs(void)
| -{
| - DEBUG(0, "pcnet_cs: unloading\n");
| - unregister_pccard_driver(&dev_info);
| - while (dev_list != NULL)
| - pcnet_detach(dev_list);
| -}
| -
| -module_init(init_pcnet_cs);
| -module_exit(exit_pcnet_cs);
| diff -x '*~' -bur --unidirectional-new-file linux/src/drivers/pcmcia/cs.c
linux/dev/drivers/pcmcia/cs.c
| --- linux/src/drivers/pcmcia/cs.c 2006-02-04 21:53:59.000000000 +0100
| +++ linux/dev/drivers/pcmcia/cs.c 2006-02-05 17:37:16.000000000 +0100
| @@ -1869,6 +1869,19 @@
| return CS_NO_CARD;
| if (req->Attributes & (WIN_PAGED | WIN_SHARED))
| return CS_BAD_ATTRIBUTE;
| +#ifdef MACH
| + if(! (req->Attributes & WIN_MAP_BELOW_1MB))
| + {
| + /*
| + * force the window to appear below 0x100000 though we don't have
| + * to vremap the memory (which unfortunately doesn't appear to work;
| + * at least for me it doesn't).
| + */
| + req->Attributes |= WIN_MAP_BELOW_1MB;
| + printk(KERN_INFO "cs: windows above 0x100000 cannot be "
| + "requested for now.\n");
| + }
| +#endif
|
| /* Window size defaults to smallest available */
| if (req->Size == 0)
| @@ -2322,7 +2335,7 @@
|
| #endif
|
| -static int __init init_pcmcia_cs(void)
| +int __init init_pcmcia_cs(void)
| {
| printk(KERN_INFO "%s\n", release);
| #ifdef UTS_RELEASE
| Only in linux/src/drivers/pcmcia/: cs.h
| Only in linux/src/drivers/pcmcia/: cs_internal.h
| Only in linux/src/drivers/pcmcia/: cs_types.h
| Only in linux/src/drivers/pcmcia/: driver_ops.h
| diff -x '*~' -bur --unidirectional-new-file
linux/src/drivers/pcmcia/drivers.h linux/dev/drivers/pcmcia/drivers.h
| --- linux/src/drivers/pcmcia/drivers.h 1970-01-01 01:00:00.000000000
+0100
| +++ linux/dev/drivers/pcmcia/drivers.h 2006-02-04 23:34:46.000000000
+0100
| @@ -0,0 +1,29 @@
| +#ifndef _PCMCIA_DRIVERS_H_
| +#define _PCMCIA_DRIVERS_H_
| +#define DEV_TYPE_NETWORK 0
| +
| +/* The order is important! */
| +#define DEV_PCNET 0
| +#define DEV_3C589 1
| +#define DEV_MAX 2 /* increment this for every added driver */
| +
| +int init_pcnet_cs(void);
| +int init_3c589_cs(void);
| +
| +typedef int (*func) (void);
| +
| +struct device_table_t {
| + char* name;
| + int type;
| + func module_init;
| + func module_exit;
| +} device_table[DEV_MAX] = {
| +#ifdef CONFIG_PCNET_CS
| + [0] = { "pcnet_cs", DEV_TYPE_NETWORK, init_pcnet_cs, NULL },
| +#endif
| +#ifdef CONFIG_3C589_CS
| + [1] = { "3c589_cs", DEV_TYPE_NETWORK, init_3c589_cs, NULL },
| +#endif
| +};
| +
| +#endif
| diff -x '*~' -bur --unidirectional-new-file linux/src/drivers/pcmcia/ds.c
linux/dev/drivers/pcmcia/ds.c
| --- linux/src/drivers/pcmcia/ds.c 2006-02-04 21:54:01.000000000 +0100
| +++ linux/dev/drivers/pcmcia/ds.c 2006-02-04 21:53:54.000000000 +0100
| @@ -515,6 +515,8 @@
| The user-mode PC Card device interface
|
| ======================================================================*/
| +#define FS_RELEASE_T void
| +#define FOPS
|
| static int ds_open(struct inode *inode, struct file *file)
| {
| @@ -586,9 +588,9 @@
|
| static ssize_t ds_read FOPS(struct inode *inode,
| struct file *file, char *buf,
| - size_t count, loff_t *ppos)
| + int count)
| {
| - socket_t i = MINOR(F_INODE(file)->i_rdev);
| + socket_t i = MINOR(inode->i_rdev);
| socket_info_t *s;
| user_info_t *user;
|
| @@ -603,6 +605,7 @@
| if (CHECK_USER(user))
| return -EIO;
|
| +#ifndef MACH
| if (queue_empty(user)) {
| interruptible_sleep_on(&s->queue);
| if (signal_pending(current))
| @@ -610,15 +613,25 @@
| }
| put_user(get_queued_event(user), (int *)buf);
| return 4;
| +#else
| + /* use non-blocking i/o */
| + if (queue_empty(user))
| + return 0;
| +
| + event_t ev = get_queued_event(user);
| + memcpy(buf, &ev, sizeof(event_t));
| +
| + return sizeof(event_t);
| +#endif
| } /* ds_read */
|
| /*====================================================================*/
|
| static ssize_t ds_write FOPS(struct inode *inode,
| struct file *file, const char *buf,
| - size_t count, loff_t *ppos)
| + int count)
| {
| - socket_t i = MINOR(F_INODE(file)->i_rdev);
| + socket_t i = MINOR(inode->i_rdev);
| socket_info_t *s;
| user_info_t *user;
|
| @@ -637,7 +650,11 @@
|
| if (s->req_pending) {
| s->req_pending--;
| +#ifndef MACH
| get_user(s->req_result, (int *)buf);
| +#else
| + s->req_result = get_user((int *) buf);
| +#endif
| if ((s->req_result != 0) || (s->req_pending == 0))
| wake_up_interruptible(&s->request);
| } else
| @@ -649,6 +666,7 @@
| /*====================================================================*/
|
| #if (LINUX_VERSION_CODE < VERSION(2,1,23))
| +#ifndef MACH
|
| static int ds_select(struct inode *inode, struct file *file,
| int sel_type, select_table *wait)
| @@ -673,6 +691,7 @@
| return 0;
| } /* ds_select */
|
| +#endif /* ! defined(MACH) */
| #else
|
| static u_int ds_poll(struct file *file, poll_table *wait)
| @@ -721,6 +740,7 @@
| if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
| return -EPERM;
|
| +#ifndef MACH
| if (cmd & IOC_IN) {
| err = verify_area(VERIFY_READ, (char *)arg, size);
| if (err) {
| @@ -736,9 +756,16 @@
| }
| }
|
| + if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size);
| +
| +#else /* defined(MACH) */
| +
| + if (cmd & IOC_IN) memcpy((char *) &buf, (char *) arg, size);
| +
| +#endif
| +
data already is in kernel space, i.e. verify_area would fail.
| err = ret = 0;
|
| - if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size);
|
| switch (cmd) {
| case DS_ADJUST_RESOURCE_INFO:
| @@ -857,7 +884,11 @@
| }
| }
|
| +#ifndef MACH
| if (cmd & IOC_OUT) copy_to_user((char *)arg, (char *)&buf, size);
| +#else
| + if (cmd & IOC_OUT) memcpy((char *) arg, (char *) &buf, size);
| +#endif
|
| return err;
| } /* ds_ioctl */
| @@ -871,7 +902,9 @@
| read: ds_read,
| write: ds_write,
| #if (LINUX_VERSION_CODE < VERSION(2,1,23))
| +#ifndef MACH
| select: ds_select
| +#endif
| #else
| poll: ds_poll
| #endif
| @@ -961,6 +994,7 @@
| }
| }
|
| +#ifndef MACH
| /* Set up character device for user mode clients */
| i = register_chrdev(0, "pcmcia", &ds_fops);
| if (i == -EBUSY)
| @@ -969,6 +1003,7 @@
| else
| major_dev = i;
| register_symtab(&ds_symtab);
| +#endif
|
| #ifdef HAS_PROC_BUS
| if (proc_pccard)
| @@ -1002,3 +1037,11 @@
| }
|
| #endif
| +
| +
| +/* export functions */
| +struct file_operations *
| +get_ds_fops(void)
| +{
| + return &ds_fops;
| +}
| Only in linux/src/drivers/pcmcia/: ds.h
| Only in linux/src/drivers/pcmcia/: ene.h
| Only in linux/src/drivers/pcmcia/: ftl.h
| diff -x '*~' -bur --unidirectional-new-file linux/src/drivers/pcmcia/i82365.c
linux/dev/drivers/pcmcia/i82365.c
| --- linux/src/drivers/pcmcia/i82365.c 2006-02-04 21:54:01.000000000 +0100
| +++ linux/dev/drivers/pcmcia/i82365.c 2006-02-04 21:53:55.000000000 +0100
| @@ -1171,8 +1171,20 @@
| return 1;
| }
| irq_hits = 0;
| +
| +#ifndef MACH
| __set_current_state(TASK_UNINTERRUPTIBLE);
| schedule_timeout(HZ/100);
| +#else
| + {
| + unsigned long flags;
| +
| + save_flags(flags);
| + sti();
| +
| + __udelay(10000);
| +#endif
| +
| if (irq_hits && !irq_shared) {
| free_irq(irq, socket);
| DEBUG(2, " spurious hit!\n");
| @@ -1187,7 +1199,7 @@
| cb_writel(s, CB_SOCKET_EVENT, -1);
| cb_writel(s, CB_SOCKET_MASK, CB_SM_CSTSCHG);
| cb_writel(s, CB_SOCKET_FORCE, CB_SE_CSTSCHG);
| - mdelay(1);
| + __udelay(10000);
| cb_writel(s, CB_SOCKET_EVENT, -1);
| cb_writel(s, CB_SOCKET_MASK, 0);
| } else
| @@ -1195,9 +1207,15 @@
| {
| i365_set(s, I365_CSCINT, I365_CSC_DETECT | (csc << 4));
| i365_bset(s, I365_GENCTL, I365_CTL_SW_IRQ);
| - mdelay(1);
| + __udelay(10000);
| + }
| +
| +#ifdef MACH
| + restore_flags(flags);
| }
|
| +#endif
| +
| free_irq(irq, socket);
|
| /* mask all interrupts */
| @@ -2456,7 +2474,7 @@
|
| /*====================================================================*/
|
| -static int __init init_i82365(void)
| +int __init init_i82365(void)
| {
| servinfo_t serv;
| CardServices(GetCardServicesInfo, &serv);
| Only in linux/src/drivers/pcmcia/: i82365.h
| Only in linux/src/drivers/pcmcia/: k_compat.h
| Only in linux/src/drivers/pcmcia/: mem_op.h
| Only in linux/src/drivers/pcmcia/: memory.h
| Only in linux/src/drivers/pcmcia/: o2micro.h
| diff -x '*~' -bur --unidirectional-new-file
linux/src/drivers/pcmcia/pci_fixup.c linux/dev/drivers/pcmcia/pci_fixup.c
| --- linux/src/drivers/pcmcia/pci_fixup.c 2006-02-04 21:54:01.000000000
+0100
| +++ linux/dev/drivers/pcmcia/pci_fixup.c 2006-02-04 21:53:55.000000000
+0100
| @@ -48,7 +48,9 @@
| ======================================================================*/
|
| #if (LINUX_VERSION_CODE < VERSION(2,1,0))
| +#ifndef MACH
| struct pci_dev *pci_devices = NULL;
| +#endif
| struct pci_bus pci_root = {
| parent: NULL,
| children: NULL,
| @@ -435,6 +437,8 @@
| {
| /* A few sanity checks to validate the bridge mapping */
| char *virt = ioremap(phys, 0x1000);
| + printk(KERN_INFO "check_cb_mapping: ioremap(%p, %x) -> %p\n",
| + phys, 0x1000, virt);
| int ret = ((readb(virt+0x800+I365_IDENT) & 0x70) ||
| (readb(virt+0x800+I365_CSC) &&
| readb(virt+0x800+I365_CSC) &&
| @@ -442,7 +446,9 @@
| int state = readl(virt+CB_SOCKET_STATE) >> 16;
| ret |= (state & ~0x3000) || !(state & 0x3000);
| ret |= readl(virt+CB_SOCKET_FORCE);
| + printk(KERN_INFO "check_cb_mapping: iounmap");
| iounmap(virt);
| + Debugger();
| return ret;
| }
|
| diff -x '*~' -bur --unidirectional-new-file linux/src/drivers/pcmcia/pcmcia.c
linux/dev/drivers/pcmcia/pcmcia.c
| --- linux/src/drivers/pcmcia/pcmcia.c 1970-01-01 01:00:00.000000000 +0100
| +++ linux/dev/drivers/pcmcia/pcmcia.c 2006-02-04 22:49:00.000000000 +0100
| @@ -0,0 +1,57 @@
| +/*
| + * gnumach pcmcia core initialization
| + *
| + * Copyright (C) 2006 Stefan Siegl <stesie@brokenpipe.de>
| + *
| + * This program is free software; you can redistribute it and/or modify
| + * it under the terms of the GNU General Public License as published by
| + * the Free Software Foundation; either version 2, or (at your option)
| + * any later version.
| + *
| + * This program is distributed in the hope that it will be useful,
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| + * GNU General Public License for more details.
| + *
| + * You should have received a copy of the GNU General Public License
| + * along with this program; if not, write to the Free Software
| + * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
| + */
| +
| +#include <linux/proc_fs.h>
| +#include <linux/pci.h>
| +
| +#include <asm/spinlock.h>
| +
| +#include "pcmcia_glue.h"
| +
| +#include <pcmcia/version.h>
| +#include <pcmcia/cs_types.h>
| +#include <pcmcia/ss.h>
| +#include <pcmcia/cs.h>
| +
| +extern int init_pcmcia_cs(void);
| +extern int init_i82365(void);
| +extern int init_pcmcia_ds(void);
| +
| +/* we want debugging message, the brute force way ... */
| +extern int console_loglevel;
| +
| +/*
| + * do pcmcia bridge initialisation
| + */
| +void
| +pcmcia_init(void)
| +{
| + init_pcmcia_cs();
| +
| +#ifdef CONFIG_I82365
| + init_i82365();
| +#endif
| +
| + init_pcmcia_ds();
| + cardmgr_simple();
| +}
| +
| +
| +
| diff -x '*~' -bur --unidirectional-new-file
linux/src/drivers/pcmcia/pcmcia_glue.c linux/dev/drivers/pcmcia/pcmcia_glue.c
| --- linux/src/drivers/pcmcia/pcmcia_glue.c 1970-01-01 01:00:00.000000000
+0100
| +++ linux/dev/drivers/pcmcia/pcmcia_glue.c 2006-02-04 21:53:55.000000000
+0100
| @@ -0,0 +1,91 @@
| +#include "pcmcia_glue.h"
| +
| +void
| +init_dev_name(struct net_device *dev, dev_node_t node)
| +{
| + /* just allocate some space for the device name,
| + * register_netdev will happily provide one to us
| + */
| + dev->name = kmalloc(8, GFP_KERNEL);
| + dev->name[0] = 0;
| +}
| +
| +
| +/*
| + * wagi's pcmcia glue ...
| + */
| +
| +#include <linux/fs.h> /* inode */
| +
| +#include <pcmcia/version.h>
| +#include <pcmcia/cs_types.h>
| +#include <pcmcia/cs.h>
| +#include <pcmcia/cistpl.h>
| +#include <pcmcia/ds.h>
| +
| +#define MAX_SOCKS 8 /* move to pcmcia_glue.h */
| +#include "pcmcia_glue.h"
| +
| +static struct inode inode[MAX_SOCKS];
| +static struct file file[MAX_SOCKS];
| +
| +/*
| + * file_operations defined in ds.c
| + */
| +struct file_operations* get_ds_fops(void); /* from ds.c */
| +static struct file_operations* ds_fops = NULL;
| +
| +int
| +pcmcia_open (int i, int flags)
| +{
| + int err;
| +
| + if (!ds_fops)
| + ds_fops = get_ds_fops();
| +
| + inode[i].i_rdev = i;
| + file[i].f_flags = flags;
| +
| + err = ds_fops->open(&inode[i], &file[i]);
| + if (err)
| + return -1;
| +
| + return i;
| +}
| +
| +int
| +pcmcia_read (int fd, void *buf, size_t count)
| +{
| + if (fd >= 0)
| + return ds_fops->read (&inode[fd], &file[fd], buf, count);
| + else
| + return -1;
| +}
| +
| +int
| +pcmcia_write (int fd, void *buf, size_t count)
| +{
| + if (fd >= 0)
| + return ds_fops->write (&inode[fd], &file[fd], buf, count);
| + else
| + return -1;
| +}
| +
| +int
| +pcmcia_close (int fd)
| +{
| + if (fd < 0)
| + return 1;
| +
| + ds_fops->release (&inode[fd], &file[fd]);
| + return 0;
| +}
| +
| +int
| +pcmcia_ioctl (int fd, int cmd, void *arg)
| +{
| + if (fd >= 0)
| + return ds_fops->ioctl (&inode[fd], &file[fd], cmd, (u_long)arg);
| + else
| + return 0;
| +}
| diff -x '*~' -bur --unidirectional-new-file
linux/src/drivers/pcmcia/pcmcia_glue.h linux/dev/drivers/pcmcia/pcmcia_glue.h
| --- linux/src/drivers/pcmcia/pcmcia_glue.h 1970-01-01 01:00:00.000000000
+0100
| +++ linux/dev/drivers/pcmcia/pcmcia_glue.h 2006-02-04 23:59:02.000000000
+0100
| @@ -0,0 +1,256 @@
| +#ifndef _PCMCIA_GLUE_H
| +#define _PCMCIA_GLUE_H
| +
| +#include <device-drivers.h>
| +#define PCMCIA_DEBUG 4
| +
| +/*
| + * linux kernel version handling ...
| + */
| +#include <linux/version.h>
| +#define UTS_VERSION "" /* wtf? */
| +#define KERNEL_VERSION(v,p,s) (((v)<<16)+(p<<8)+s)
| +
| +
| +/*
| + * some includes ...
| + */
| +#include <linux/malloc.h>
| +#include <pcmcia/driver_ops.h>
| +
| +
| +/*
| + * ioremap/iounmap from `linux/compatmac.h' ...
| + * (include only, if iounmap is not already defined, i.e. compatmac.h
included)
| + */
| +#include <linux/pci.h>
| +#include <linux/compatmac.h>
| +#define iounmap(x) (((long)x<0x100000)?0:vfree ((void*)x))
| +
| +
| +/*
| + * release_mem_region
| + * (these are implemented in rsrc_mgr.c)
| + */
| +extern int check_mem_region(u_long base, u_long num);
| +extern void request_mem_region(u_long base, u_long num, char *name);
| +extern void release_mem_region(u_long base, u_long num);
| +
| +
| +/*
| + * timer/delaying cruft (from pcmcia-cs package) ...
| + */
| +#include <linux/delay.h>
| +#define mod_timer(a, b) \
| + do { del_timer(a); (a)->expires = (b); add_timer(a); } while (0)
| +#define mdelay(x) \
| + do { int i; for (i=0;i<x;i++) __udelay(1000); } while (0)
| +
| +
| +
| +/* fix nameclash of `cb_alloc' and `cb_free'
| + *
| + * both, device/cirbuf.c and our cardbus.c use the symbols `cb_alloc' and
| + * `cb_free'. One time it means circular buffer, one time it means cardbus,
| + * therefore let's redefine our symbols to `cardbus_alloc' ...
| + */
| +
| +#define cb_alloc cardbus_alloc
| +#define cb_free cardbus_free
| +
| +
| +
| +/*
| + * `struct file'->private_data
| + *
| + * Linux has a field `private_data' in the `struct file' as defined in
| + * `linux/fs.h'. However gnumach doesn't supply that field. However there is
| + * a `f_object' field, which doesn't seem (to me) to be used, on the first
| + * sight. This might be wrong, so better refine this. FIXME
| + */
| +#define private_data f_object
| +
| +
| +/*
| + * gnumach's Linux glue code doesn't have `interruptible_sleep_on_timeout'.
| + * For the moment let's use the non-timeout variant :-/
| + */
| +#define interruptible_sleep_on_timeout(w,t) \
| + interruptible_sleep_on(w)
| +
| +/*
| + * FIXME, how to check for that?
| + *
| + * The macro implementation relies on current_set symbol, which doesn't
| + * appear to be available on gnumach.
| + */
| +#undef signal_pending
| +#define signal_pending(c) \
| + 0
| +
| +
| +/*
| + * byteorder stuff, is this correct this way?
| + * FIXME: this does not work on big-endian systems, does it? => asm-i386?
| + */
| +#include <asm/byteorder.h>
| +#ifndef le16_to_cpu
| +#define le16_to_cpu(x) (x)
| +#define le32_to_cpu(x) (x)
| +#endif
| +
this needs to be moved to asm
| +
| +
| +/*
| + * wake_up_interruptible
| + *
| + * FIXME: I don't have enough clue of the gnumach kernel, only that there
| + * is no such function. Therefore use plain wake_up for the moment. help!
| + */
| +#define wake_up_interruptible wake_up
| +
| +
| +/*
| + * ffs: find first bit set. This is defined the same way as
| + * the libc and compiler builtin ffs routines, therefore
| + * differs in spirit from the above ffz (man ffs).
| + *
| + * FIXME: this is really i386 dependant (that's the directory where it
| + * does come from), better move it somewhere there ...
needs to be moved back into asm-i386 ...
| + */
| +extern __inline__ int ffs(int x)
| +{
| + int r;
| +
| + __asm__("bsfl %1,%0\n\t"
| + "jnz 1f\n\t"
| + "movl $-1,%0\n"
| + "1:" : "=r" (r) : "g" (x));
| + return r + 1;
| +}
| +
| +
| +/* eliminate 4-arg versions from compatmac.h */
| +#undef pci_read_config_word
| +#undef pci_read_config_dword
| +
| +#define bus_number(pci_dev) ((pci_dev)->bus->number)
| +#define devfn_number(pci_dev) ((pci_dev)->devfn)
| +
| +#define pci_read_config_byte(pdev, where, valp) \
| + pcibios_read_config_byte(bus_number(pdev), devfn_number(pdev), where, valp)
| +#define pci_read_config_word(pdev, where, valp) \
| + pcibios_read_config_word(bus_number(pdev), devfn_number(pdev), where, valp)
| +#define pci_read_config_dword(pdev, where, valp) \
| + pcibios_read_config_dword(bus_number(pdev), devfn_number(pdev), where,
valp)
| +#define pci_write_config_byte(pdev, where, val) \
| + pcibios_write_config_byte(bus_number(pdev), devfn_number(pdev), where, val)
| +#define pci_write_config_word(pdev, where, val) \
| + pcibios_write_config_word(bus_number(pdev), devfn_number(pdev), where, val)
| +#define pci_write_config_dword(pdev, where, val) \
| + pcibios_write_config_dword(bus_number(pdev), devfn_number(pdev), where,
val)
| +
| +
| +/*
| + * from pcmcia-cs/include/linux/pci.h
| + */
| +#define pci_for_each_dev(p) for (p = pci_devices; p; p = p->next)
| +
| +
| +
| +/*
| + * these are defined in pci_fixup.c
| + */
| +extern struct pci_dev *pci_find_slot(u_int bus, u_int devfn);
| +extern struct pci_dev *pci_find_class(u_int class, struct pci_dev *from);
| +extern int pci_set_power_state(struct pci_dev *dev, int state);
| +extern int pci_enable_device(struct pci_dev *dev);
| +
| +extern u32 pci_irq_mask;
| +
| +
| +/* linux/netdevice.h uses `device', however the code uses `net_device'.
| + *
| + * even worse: to keep netdevice.h from defining device -> linux_device,
| + * we need to define MACH_INCLUDE, however this influences the other
| + * header files. Therefore we include all the files, which would be included
| + * from netdevice.h later on right now ... */
| +#define net_device device
| +#define linux_device device
| +#include <linux/config.h>
| +#include <linux/if.h>
| +#include <linux/if_ether.h>
| +#include <linux/skbuff.h>
| +#include <linux/interrupt.h>
| +#include <linux/notifier.h>
| +#define MACH_INCLUDE 1
| +#define __KERNEL__ 1
| +#include <linux/netdevice.h>
| +#undef MACH_INCLUDE
| +
| +
| +/*
| + * init_dev_name and copy_dev_name glue
| + */
| +extern void init_dev_name(struct net_device *dev, dev_node_t node);
| +#define copy_dev_name(node, dev) do { } while (0)
| +
| +
| +
| +/*
| + * some network interface glue ...
| + */
| +#define netif_stop_queue(dev) set_bit(0, (void *)&(dev)->tbusy)
| +#define netif_start_queue(dev) clear_bit(0, (void *)&(dev)->tbusy)
| +#define netif_wake_queue(dev) \
| + do { netif_start_queue(dev); mark_bh(NET_BH); } while (0)
| +#define netif_device_attach(dev) \
| + do { (dev)->start = 1; netif_start_queue(dev); } while (0)
| +#define netif_device_detach(dev) \
| + do { (dev)->start = 0; netif_stop_queue(dev); } while (0)
| +#define netif_device_present(dev) ((dev)->start)
| +#define netif_running(dev) ((dev)->start)
| +#define netif_mark_up(dev) do { (dev)->start = 1; } while (0)
| +#define netif_mark_down(dev) do { (dev)->start = 0; } while (0)
| +
| +
| +
| +/*
| + * FIXME: this is i386 dependant by the way ...
| + */
| +#define readw_ns(p) readw(p)
| +#define writew_ns(v,p) writew(v,p)
| +
| +
| +
| +
| +/*
| + * last but not least: our very own functions ...
| + */
| +int cardmgr_simple(void);
| +
| +int pcmcia_open (int i, int flags);
| +int pcmcia_read (int fd, void *buf, size_t count);
| +int pcmcia_write (int fd, void *buf, size_t count);
| +int pcmcia_close (int fd);
| +int pcmcia_ioctl (int fd, int cmd, void *arg);
| +
| +
| +
| +/*
| + * we compile everything directly into the gnumach kernel,
| + * there are no modules ...
| + */
| +#define MODULE_PARM(a,b)
| +#define MODULE_AUTHOR(a)
| +#define MODULE_DESCRIPTION(a)
| +#define MODULE_LICENSE(a)
| +
| +
| +/*
| + * debugging convenience ...
| + */
| +extern void Debugger(void);
| +
| +
| +#endif
| diff -x '*~' -bur --unidirectional-new-file
linux/src/drivers/pcmcia/resources.h linux/dev/drivers/pcmcia/resources.h
| --- linux/src/drivers/pcmcia/resources.h 1970-01-01 01:00:00.000000000
+0100
| +++ linux/dev/drivers/pcmcia/resources.h 2006-02-04 21:53:56.000000000
+0100
| @@ -0,0 +1,63 @@
| +#ifndef _PCMCIA_RESOURCES_H_
| +#define _PCMCIA_RESOURCES_H_
| +
| +#include <pcmcia/cs_types.h>
| +#include <pcmcia/cs.h>
| +
| +struct {
| + u_int Action;
| + u_int Resource;
| + u_int Attributes;
| + u_long Base;
| + u_long Size;
| +} adj_mem_table[] = {
| + {ADD_MANAGED_RESOURCE, RES_MEMORY_RANGE, 0,
| + 0xc0000, 0xfffff - 0xc0000 + 1},
| + {ADD_MANAGED_RESOURCE, RES_MEMORY_RANGE, 0,
| + 0xa0000000, 0xa0ffffff - 0xa0000000 + 1},
| + {ADD_MANAGED_RESOURCE, RES_MEMORY_RANGE, 0,
| + 0x60000000, 0x60ffffff - 0x60000000 + 1}
| +};
| +
| +int adj_mem_table_size = (sizeof(adj_mem_table) / sizeof(adj_mem_table[0]));
| +
| +
| +struct {
| + u_int Action;
| + u_int Resource;
| + u_int Attributes;
| + ioaddr_t BasePort;
| + ioaddr_t NumPorts;
| + u_int IOAddrLines;
| +} adj_io_table[] = {
| + {ADD_MANAGED_RESOURCE, RES_IO_RANGE, 0,
| + 0x100, 0x4ff - 0x100 + 1, 0},
| + {ADD_MANAGED_RESOURCE, RES_IO_RANGE, 0,
| + 0x800, 0x8ff - 0x800 + 1, 0},
| + {ADD_MANAGED_RESOURCE, RES_IO_RANGE, 0,
| + 0xc00, 0xcff - 0xc00 + 1, 0},
| + /* High port numbers do not always work */
| + /* {ADD_MANAGED_RESOURCE, RES_IO_RANGE, 0, */
| + /* 0x1000, 0x17ff - 0x1000 + 1}, */
| + /* Extra port range for IBM Token Ring */
| + {ADD_MANAGED_RESOURCE, RES_IO_RANGE, 0,
| + 0xa00, 0xa00 - 0xa00 + 1, 0}
| +};
| +
| +int adj_io_table_size = (sizeof(adj_io_table) / sizeof(adj_io_table[0]));
| +
| +
| +struct {
| + u_int Action;
| + u_int Resource;
| + u_int Attributes;
| + u_int IRQ;
| +} adj_irq_table[] = {
| + {REMOVE_MANAGED_RESOURCE, RES_IRQ, 0, 4}, /* First built-in serial port */
| + {REMOVE_MANAGED_RESOURCE, RES_IRQ, 0, 3}, /* Second built-in serial port
*/
| + {REMOVE_MANAGED_RESOURCE, RES_IRQ, 0, 7} /* First built-in parallel port
*/
| +};
| +
| +int adj_irq_table_size = (sizeof(adj_irq_table) / sizeof(adj_irq_table[0]));
| +
| +#endif
| Only in linux/src/drivers/pcmcia/: ricoh.h
| Only in linux/src/drivers/pcmcia/: rsrc_mgr.c
| Only in linux/src/drivers/pcmcia/: smc34c90.h
| Only in linux/src/drivers/pcmcia/: ss.h
| Only in linux/src/drivers/pcmcia/: ti113x.h
| Only in linux/src/drivers/pcmcia/: topic.h
| diff -x '*~' -bur --unidirectional-new-file
linux/src/drivers/pcmcia/version.h linux/dev/drivers/pcmcia/version.h
| --- linux/src/drivers/pcmcia/version.h 2006-02-04 21:54:02.000000000
+0100
| +++ linux/dev/drivers/pcmcia/version.h 2006-02-04 23:04:19.000000000
+0100
| @@ -5,9 +5,5 @@
|
| #define VERSION(v,p,s) (((v)<<16)+(p<<8)+s)
|
| -#ifdef CONFIG_PCMCIA
| -#include_next <pcmcia/version.h>
| -#else
| #define CS_RELEASE CS_PKG_RELEASE
| #define CS_RELEASE_CODE CS_PKG_RELEASE_CODE
| -#endif
| Only in linux/src/drivers/pcmcia/: vg468.h
| Only in linux/src/drivers/pcmcia/: yenta.h
further changes in the rest of the kernel:
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru
gnumach-20050801/i386/linux/Makefile.in gnumach-mine/i386/linux/Makefile.in
| --- gnumach-20050801/i386/linux/Makefile.in 2006-02-02 17:10:59.000000000
+0100
| +++ gnumach-mine/i386/linux/Makefile.in 2006-02-04 22:47:12.000000000
+0100
| @@ -79,6 +79,13 @@
| vpath %.c $(linuxsrcdir)/src/drivers/net
| vpath %.c $(linuxsrcdir)/src/net/core
|
| +linux-pcmcia-files = pcmcia.c cs.c ds.c cardbus.c cb_enabler.c rsrc_mgr.c \
| + bulkmem.c cistpl.c pci_fixup.c i82365.c cardmgr.c pcmcia_glue.c \
| + pcnet_cs.c 3c589_cs.c
| +vpath %.c $(linuxsrcdir)/dev/drivers/pcmcia
| +vpath %.c $(linuxsrcdir)/dev/drivers/pcmcia/clients
| +vpath %.c $(linuxsrcdir)/src/drivers/pcmcia
| +
| linux-pci-files = pci.c
| vpath %.c $(linuxsrcdir)/dev/drivers/pci
| vpath %.c $(linuxsrcdir)/src/drivers/pci
| @@ -94,7 +101,8 @@
|
|
| all-linux-files = $(linux-c-files) $(linux-block-files) \
| - $(linux-net-files) $(linux-pci-files) $(linux-scsi-files)
| + $(linux-net-files) $(linux-pcmcia-files) $(linux-pci-files) \
| + $(linux-scsi-files)
|
| # These are always used.
| linux-objs := $(subst .c,.o, $(linux-c-files) $(linux-pci-files)) genhd.o
| @@ -127,6 +135,11 @@
| -I$(linuxsrcdir)/src/drivers/block
| linux-net-flags = -I$(linuxsrcdir)/dev/drivers/net \
| -I$(linuxsrcdir)/src/drivers/net
| +linux-pcmcia-flags = -I$(linuxsrcdir)/dev/drivers/pcmcia \
| + -I$(linuxsrcdir)/src/drivers/pcmcia -include pcmcia_glue.h \
| + -I$(linuxsrcdir)/dev/drivers \
| + -I$(linuxsrcdir)/src/drivers \
| + -I$(linuxsrcdir)/src/drivers/net
| linux-pci-flags = -I$(linuxsrcdir)/dev/drivers/pci \
| -I$(linuxsrcdir)/src/drivers/pci
| linux-scsi-flags = -I$(linuxsrcdir)/dev/drivers/scsi \
| @@ -155,6 +168,10 @@
| echo $$i-linux-flags \
| '= $$(linux-gen-flags) $$(linux-net-flags)' >> $@; \
| done
| + for i in $(linux-pcmcia-files); do \
| + echo $$i-linux-flags \
| + '= $$(linux-gen-flags) $$(linux-pcmcia-flags)' >> $@; \
| + done
| for i in $(linux-pci-files); do \
| echo $$i-linux-flags \
| '= $$(linux-gen-flags) $$(linux-pci-flags)' >> $@; \
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru
gnumach-20050801/i386/linux/configure.ac gnumach-mine/i386/linux/configure.ac
| --- gnumach-20050801/i386/linux/configure.ac 2006-02-02 17:11:00.000000000
+0100
| +++ gnumach-mine/i386/linux/configure.ac 2006-02-05 02:19:28.000000000
+0100
| @@ -110,6 +110,11 @@
| AC_DRIVER_CLASS([net], [CONFIG_INET], [ \
| auto_irq.o net.o Space.o dev.o net_init.o pci-scan.o])
|
| +AC_DRIVER_CLASS([pcmcia], [CONFIG_PCMCIA], [ \
| + pcmcia.o cs.o ds.o rsrc_mgr.o bulkmem.o cistpl.o pci_fixup.o \
| + cardmgr.o pcmcia_glue.o])
| +
| +
| dnl Strictly speaking, we could have a `linux' option too, but it's
| dnl not possible to built a useful kernel without at least one Linux
| dnl driver, so that's not really necessary.
| @@ -235,5 +240,34 @@
| linux_DRIVER([tlan], [TLAN], [tlan], [net])
| linux_DRIVER([viarhine], [VIA_RHINE], [via-rhine], [net])
|
| +#
| +# pcmcia cruft ...
| +#
| +AC_ARG_ENABLE([pcmcia-isa],
| + AS_HELP_STRING([--enable-pcmcia-isa],
| + [enable support for pcmcia bridges on the isa bus]),
| + [test x"$enableval" = xno &&
| + AC_DEFINE([CONFIG_ISA], [], [enable isa bus support])])
| +
| +linux_DRIVER([cardbus], [CARDBUS], [cardbus], [pcmcia])
| +linux_DRIVER([i82365], [I82365], [i82365], [pcmcia])
| +
| +#
| +# pcmcia devices ...
| +#
| +linux_DRIVER([cb_enabler], [CB_ENABLER], [cb_enabler], [pcmcia])
| +AC_DRIVER([pcnet_cs], [CONFIG_PCNET_CS], [pcnet_cs.o 8390.o], [pcmcia])
| +linux_DRIVER([3c589_cs], [3C589_CS], [3c589_cs], [pcmcia])
| +
| +# if any bit of the pcmcia cruft has been enabled, make sure to
| +# include the network glue as well ...
| +if test "${driver_class_pcmcia_selected+set}" = set; then
| + if test "${driver_class_net_selected+set}" != set; then
| + driver_class_net_selected=yes
| + AC_DEFINE_UNQUOTED([$driver_class_net_option], [1])
| + device_drivers="$device_drivers $driver_class_net_files"
| + fi
| +fi
| +
| AC_CONFIG_FILES([Makefile])
| AC_OUTPUT
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru gnumach-20050801/kern/printf.c
gnumach-mine/kern/printf.c
| --- gnumach-20050801/kern/printf.c 2004-12-06 13:39:12.000000000 +0100
| +++ gnumach-mine/kern/printf.c 2006-02-04 21:53:54.000000000 +0100
| @@ -50,6 +50,7 @@
| *
| * %d decimal conversion
| * %u unsigned conversion
| + * %p pointer address
| * %x hexadecimal conversion
| * %X hexadecimal conversion with capital letters
| * %o octal conversion
| @@ -399,6 +400,7 @@
| base = 10;
| goto print_unsigned;
|
| + case 'p':
| case 'x':
| truncate = _doprnt_truncates;
| case 'X':
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru
gnumach-20050801/linux/dev/drivers/net/Space.c
gnumach-mine/linux/dev/drivers/net/Space.c
| --- gnumach-20050801/linux/dev/drivers/net/Space.c 2006-02-02
17:10:59.000000000 +0100
| +++ gnumach-mine/linux/dev/drivers/net/Space.c 2006-02-05
01:30:30.000000000 +0100
| @@ -299,6 +299,14 @@
| #ifdef CONFIG_LANCE
| && lance_probe(dev)
| #endif
| +#ifdef CONFIG_PCMCIA
| + /* this ought to be the last in the long row,
| + * make sure we exit with success in any case,
| + * to enable the whole glue stuff (as our devices
| + * might be added later on)
| + */
| + && 0
| +#endif
| && 1 ) {
| return 1; /* -ENODEV or -EAGAIN would be more accurate. */
| }
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru
gnumach-20050801/linux/dev/include/linux/init.h
gnumach-mine/linux/dev/include/linux/init.h
| --- gnumach-20050801/linux/dev/include/linux/init.h 1970-01-01
01:00:00.000000000 +0100
| +++ gnumach-mine/linux/dev/include/linux/init.h 2006-02-04
21:53:57.000000000 +0100
| @@ -0,0 +1,19 @@
| +#ifndef _COMPAT_INIT_H
| +#define _COMPAT_INIT_H
| +
| +#define __init
| +#define __initdata
| +#define __exit
| +#define __exitdata
| +#define __devinit
| +#define __devinitdata
| +#define __devexit
| +#define __devexitdata
| +#define module_init(x)
| +#define module_exit(x)
| +
| +#ifndef __devexit_p
| +#define __devexit_p(x) (x)
| +#endif
| +
| +#endif /* _COMPAT_INIT_H */
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru
gnumach-20050801/linux/dev/include/linux/module.h
gnumach-mine/linux/dev/include/linux/module.h
| --- gnumach-20050801/linux/dev/include/linux/module.h 1970-01-01
01:00:00.000000000 +0100
| +++ gnumach-mine/linux/dev/include/linux/module.h 2006-02-04
21:53:57.000000000 +0100
| @@ -0,0 +1,113 @@
| +/*
| + * Dynamic loading of modules into the kernel.
| + *
| + * Modified by Bjorn Ekwall <bj0rn@blox.se>
| + */
| +
| +#ifndef _LINUX_MODULE_H
| +#define _LINUX_MODULE_H
| +
| +#ifdef __GENKSYMS__
| +# define _set_ver(sym,vers) sym
| +# undef MODVERSIONS
| +# define MODVERSIONS
| +#else /* ! __GENKSYMS__ */
| +# if defined(MODVERSIONS) && !defined(MODULE) && defined(EXPORT_SYMTAB)
| +# define _set_ver(sym,vers) sym
| +# include <linux/modversions.h>
| +# endif
| +#endif /* __GENKSYMS__ */
| +
| +/* values of module.state */
| +#define MOD_UNINITIALIZED 0
| +#define MOD_RUNNING 1
| +#define MOD_DELETED 2
| +
| +/* maximum length of module name */
| +#define MOD_MAX_NAME 64
| +
| +/* magic marker for modules inserted from kerneld, to be auto-reaped */
| +#define MOD_AUTOCLEAN 0x40000000 /* big enough, but no sign problems... */
| +#define MOD_VISITED 0x20000000 /* Thanks Jacques! */
| +
| +/* maximum length of symbol name */
| +#define SYM_MAX_NAME 60
| +
| +struct kernel_sym { /* sent to "insmod" */
| + unsigned long value; /* value of symbol */
| + char name[SYM_MAX_NAME]; /* name of symbol */
| +};
| +
| +struct module_ref {
| + struct module *module;
| + struct module_ref *next;
| +};
| +
| +struct internal_symbol {
| + void *addr;
| + const char *name;
| + };
| +
| +struct symbol_table { /* received from "insmod" */
| + int size; /* total, including string table!!! */
| + int n_symbols;
| + int n_refs;
| + struct internal_symbol symbol[0]; /* actual size defined by n_symbols */
| + struct module_ref ref[0]; /* actual size defined by n_refs */
| +};
| +/*
| + * Note: The string table follows immediately after the symbol table in
memory!
| + */
| +
| +struct module {
| + struct module *next;
| + struct module_ref *ref; /* the list of modules that refer to me */
| + struct symbol_table *symtab;
| + const char *name;
| + int size; /* size of module in pages */
| + void* addr; /* address of module */
| + int state;
| + void (*cleanup)(void); /* cleanup routine */
| +};
| +
| +struct mod_routines {
| + int (*init)(void); /* initialization routine */
| + void (*cleanup)(void); /* cleanup routine */
| +};
| +
| +/*
| + * The first word of the module contains the use count.
| + */
| +#define GET_USE_COUNT(module) (* (long *) (module)->addr)
| +/*
| + * define the count variable, and usage macros.
| + */
| +
| +#ifdef MODULE
| +
| +extern long mod_use_count_;
| +#define MOD_INC_USE_COUNT (mod_use_count_++, mod_use_count_ |=
MOD_VISITED)
| +#define MOD_DEC_USE_COUNT (mod_use_count_--, mod_use_count_ |=
MOD_VISITED)
| +#define MOD_IN_USE ((mod_use_count_ & ~(MOD_AUTOCLEAN |
MOD_VISITED)) != 0)
| +
| +#ifndef __NO_VERSION__
| +#include <linux/version.h>
| +char kernel_version[]=UTS_RELEASE;
| +#endif
| +
| +#if defined(MODVERSIONS) && !defined(__GENKSYMS__)
| +int Using_Versions; /* gcc will handle this global (used as a flag)
correctly */
| +#endif
| +
| +#else
| +
| +#define MOD_INC_USE_COUNT do { } while (0)
| +#define MOD_DEC_USE_COUNT do { } while (0)
| +#define MOD_IN_USE 1
| +
| +#endif
| +
| +/* insert new symbol table */
| +#define register_symtab(symtab)
| +
| +#endif
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru
gnumach-20050801/linux/dev/include/linux/pm.h
gnumach-mine/linux/dev/include/linux/pm.h
| --- gnumach-20050801/linux/dev/include/linux/pm.h 1970-01-01
01:00:00.000000000 +0100
| +++ gnumach-mine/linux/dev/include/linux/pm.h 2006-02-04 21:53:58.000000000
+0100
| @@ -0,0 +1 @@
| +/* Dummy file. */
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru
gnumach-20050801/linux/dev/include/linux/slab.h
gnumach-mine/linux/dev/include/linux/slab.h
| --- gnumach-20050801/linux/dev/include/linux/slab.h 1970-01-01
01:00:00.000000000 +0100
| +++ gnumach-mine/linux/dev/include/linux/slab.h 2006-02-04
21:53:58.000000000 +0100
| @@ -0,0 +1,6 @@
| +#ifndef _COMPAT_SLAB_H
| +#define _COMPAT_SLAB_H
| +
| +#include <linux/malloc.h>
| +
| +#endif /* _COMPAT_SLAB_H */
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru gnumach-20050801/linux/dev/init/main.c
gnumach-mine/linux/dev/init/main.c
| --- gnumach-20050801/linux/dev/init/main.c 1999-04-26 07:49:06.000000000
+0200
| +++ gnumach-mine/linux/dev/init/main.c 2006-02-04 21:53:59.000000000
+0100
| @@ -103,6 +103,7 @@
| extern int prtnull ();
| extern int intnull ();
| extern void linux_sched_init (void);
| +extern void pcmcia_init (void);
|
|
| /*
| @@ -179,10 +180,17 @@
| #ifdef CONFIG_INET
| linux_net_emulation_init ();
| #endif
| +
| cli ();
| device_setup ();
|
| + /*
| + * Initialize pcmcia cruft.
| + */
| + pcmcia_init ();
| +
hmm, this ought to be #ifdef'd on CONFIG_PCMCIA ...
| restore_IRQ ();
| +
| linux_auto_config = 0;
| }
|
| diff -x pcmcia -x build-dbg -x build-dbg-ne2k -x debian -x '*~' -x
autom4te.cache -x configure -x old -Nbru
gnumach-20050801/linux/src/include/linux/wait.h
gnumach-mine/linux/src/include/linux/wait.h
| --- gnumach-20050801/linux/src/include/linux/wait.h 1999-04-26
07:57:22.000000000 +0200
| +++ gnumach-mine/linux/src/include/linux/wait.h 2006-02-04
21:54:02.000000000 +0100
| @@ -4,16 +4,26 @@
| #define WNOHANG 0x00000001
| #define WUNTRACED 0x00000002
|
| -#define __WCLONE 0x80000000
| +#define __WALL 0x40000000 /* Wait on all children,
regardless of type */
| +#define __WCLONE 0x80000000 /* Wait only on non-SIGCHLD children */
|
| #ifdef __KERNEL__
|
| +#include <asm/page.h>
| +
| struct wait_queue {
| struct task_struct * task;
| struct wait_queue * next;
| };
|
| +typedef struct wait_queue wait_queue_t;
| +typedef struct wait_queue *wait_queue_head_t;
| +
| #define WAIT_QUEUE_HEAD(x) ((struct wait_queue *)((x)-1))
| +#define DECLARE_WAITQUEUE(wait, current) struct wait_queue wait = {
current, NULL }
| +#define DECLARE_WAIT_QUEUE_HEAD(wait) wait_queue_head_t wait
| +#define init_waitqueue_head(x) *(x)=NULL
| +#define init_waitqueue_entry(q,p) ((q)->task)=(p)
|
| static inline void init_waitqueue(struct wait_queue **q)
| {
... I think that were the important parts of the patch.
cheers,
stesie
--
bombing for peace is like fucking for virginity ...