bug-hurd
[Top][All Lists]
Advanced

[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 ...




reply via email to

[Prev in Thread] Current Thread [Next in Thread]