Hi Alfred, "Alfred M\. Szmidt" <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> | + * | + * 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 <[EMAIL PROTECTED]> | + */ | + | +#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 ... _______________________________________________ Bug-hurd mailing list Bug-hurd@gnu.org http://lists.gnu.org/mailman/listinfo/bug-hurd