Subversion Repositories shark

Rev

Rev 436 | Rev 462 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed


#include <ll/i386/hw-instr.h>
#include <ll/i386/cons.h>

#include <linuxcomp.h>

#include <linux/time.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <linux/ctype.h>
#include <linux/device.h>

unsigned char _ctype[] = {
_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
                                                                                                                             


int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);

struct resource ioport_resource = {
        .name   = "PCI IO",
        .start  = 0x0000,
        .end    = IO_SPACE_LIMIT,
        .flags  = IORESOURCE_IO,
};

struct resource iomem_resource = {
        .name   = "PCI mem",
        .start  = 0UL,
        .end    = ~0UL,
        .flags  = IORESOURCE_MEM,
};

/* Return the conflict entry if you can't request it */
static struct resource * __request_resource(struct resource *root, struct resource *new)
{
        unsigned long start = new->start;
        unsigned long end = new->end;
        struct resource *tmp, **p;

        if (end < start)
                return root;
        if (start < root->start)
                return root;
        if (end > root->end)
                return root;
        p = &root->child;
        for (;;) {
                tmp = *p;
                if (!tmp || tmp->start > end) {
                        new->sibling = tmp;
                        *p = new;
                        new->parent = root;
                        return NULL;
                }
                p = &tmp->sibling;
                if (tmp->end < start)
                        continue;
                return tmp;
        }
}

static int __release_resource(struct resource *old)
{
        struct resource *tmp, **p;

        p = &old->parent->child;
        for (;;) {
                tmp = *p;
                if (!tmp)
                        break;
                if (tmp == old) {
                        *p = tmp->sibling;
                        old->parent = NULL;
                        return 0;
                }
                p = &tmp->sibling;
        }
        return -EINVAL;
}

int release_resource(struct resource *old)
{
        int retval;

        retval = __release_resource(old);
       
        return retval;
}

int request_resource(struct resource *root, struct resource *new)
{
        struct resource *conflict;
       
        conflict = __request_resource(root, new);

        return conflict ? -EBUSY : 0;
}



struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name)
{
        struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);

        if (res) {
                memset(res, 0, sizeof(*res));
                res->name = name;
                res->start = start;
                res->end = start + n - 1;
                res->flags = IORESOURCE_BUSY;

                for (;;) {
                        struct resource *conflict;

                        conflict = __request_resource(parent, res);
                        if (!conflict)
                                break;
                        if (conflict != parent) {
                                parent = conflict;
                                if (!(conflict->flags & IORESOURCE_BUSY))
                                        continue;
                        }

                        /* Uhhuh, that didn't work out.. */
                        kfree(res);
                        res = NULL;
                        break;
                }
        }
        return res;
}

void __release_region(struct resource *parent, unsigned long start, unsigned long n)
{
        struct resource **p;
        unsigned long end;

        p = &parent->child;
        end = start + n - 1;

        for (;;) {
                struct resource *res = *p;

                if (!res)
                        break;
                if (res->start <= start && res->end >= end) {
                        if (!(res->flags & IORESOURCE_BUSY)) {
                                p = &res->child;
                                continue;
                        }
                        if (res->start != start || res->end != end)
                                break;
                        *p = res->sibling;
                        kfree(res);
                        return;
                }
                p = &res->sibling;
        }
        printk(KERN_WARNING "Trying to free nonexistent resource <%08lx-%08lx>\n", start, end);
}

static int find_resource(struct resource *root, struct resource *new,
                         unsigned long size,
                         unsigned long min, unsigned long max,
                         unsigned long align,
                         void (*alignf)(void *, struct resource *,
                                        unsigned long, unsigned long),
                         void *alignf_data)
{
        struct resource *this = root->child;

        new->start = root->start;
        /*
         * Skip past an allocated resource that starts at 0, since the assignment
         * of this->start - 1 to new->end below would cause an underflow.
         */

        if (this && this->start == 0) {
                new->start = this->end + 1;
                this = this->sibling;
        }
        for(;;) {
                if (this)
                        new->end = this->start - 1;
                else
                        new->end = root->end;
                if (new->start < min)
                        new->start = min;
                if (new->end > max)
                        new->end = max;
                new->start = (new->start + align - 1) & ~(align - 1);
                if (alignf)
                        alignf(alignf_data, new, size, align);
                if (new->start < new->end && new->end - new->start + 1 >= size) {
                        new->end = new->start + size - 1;
                        return 0;
                }
                if (!this)
                        break;
                new->start = this->end + 1;
                this = this->sibling;
        }
        return -EBUSY;
}

int allocate_resource(struct resource *root, struct resource *new,
                      unsigned long size,
                      unsigned long min, unsigned long max,
                      unsigned long align,
                      void (*alignf)(void *, struct resource *,
                                     unsigned long, unsigned long),
                      void *alignf_data)
{
        int err;

       
        err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
        if (err >= 0 && __request_resource(root, new))
                err = -EBUSY;
       
        return err;
}

void device_initialize(struct device *dev)
{
        kobject_init(&dev->kobj);
        INIT_LIST_HEAD(&dev->node);
        INIT_LIST_HEAD(&dev->children);
        INIT_LIST_HEAD(&dev->driver_list);
        INIT_LIST_HEAD(&dev->bus_list);
}

int device_add(struct device *dev)
{
        struct device * parent;
        int error;

        dev = get_device(dev);
        if (!dev || !strlen(dev->bus_id))
                return -EINVAL;

        parent = get_device(dev->parent);

        pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);

        /* first, register with generic layer. */
        kobject_set_name(&dev->kobj,dev->bus_id);
        if (parent)
                dev->kobj.parent = &parent->kobj;

        if ((error = kobject_add(&dev->kobj)))
                goto Error;
        if (parent)
                list_add_tail(&dev->node,&parent->children);

 Done:
        put_device(dev);
        return error;
 Error:
        if (parent)
                put_device(parent);
        goto Done;
}

void device_del(struct device * dev)
{
        struct device * parent = dev->parent;

        if (parent)
                list_del_init(&dev->node);

        kobject_del(&dev->kobj);
        if (parent)
                put_device(parent);
}

#define to_drv(obj) container_of(obj,struct device_driver,kobj)

struct device_driver * get_driver(struct device_driver * drv)
{
        return drv ? to_drv(kobject_get(&drv->kobj)) : NULL;
}

void put_driver(struct device_driver * drv)
{
        kobject_put(&drv->kobj);
}

void driver_unregister(struct device_driver * drv)
{
}

int driver_register(struct device_driver * drv)
{
        INIT_LIST_HEAD(&drv->devices);
        return 0;
}

#define to_dev(obj) container_of(obj,struct device,kobj)

struct device * get_device(struct device * dev)
{
        return dev ? to_dev(kobject_get(&dev->kobj)) : NULL;
}

void put_device(struct device * dev)
{
        kobject_put(&dev->kobj);
}

int device_register(struct device *dev)
{
        return device_add(dev);
}

void device_unregister(struct device * dev)
{
        pr_debug("DEV: Unregistering device. ID = '%s'\n", dev->bus_id);
        device_del(dev);
        put_device(dev);
}

int bus_register(struct bus_type * bus)
{
        return 0;
}

int remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot)
{ return 0; }

unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
{
        unsigned long result = 0,value;

        if (!base) {
                base = 10;
                if (*cp == '0') {
                        base = 8;
                        cp++;
                        if ((*cp == 'x') && isxdigit(cp[1])) {
                                cp++;
                                base = 16;
                        }
                }
        }
        while (isxdigit(*cp) &&
               (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
                result = result*base + value;
                cp++;
        }
        if (endp)
                *endp = (char *)cp;
        return result;
}


long simple_strtol(const char *cp,char **endp,unsigned int base)
{
        if(*cp=='-')
                return -simple_strtoul(cp+1,endp,base);
        return simple_strtoul(cp,endp,base);
}

void dump_stack(void) { }

void panic(const char * fmt, ...) {

  cprintf((char *)(fmt));

}

extern void * malloc(size_t size);

void *__kmalloc(size_t size, int flags) {

  return malloc(size);

}

extern void free(void *);

void kfree(const void *ptr) {

  free((void *)(ptr));

}

unsigned long pci_mem_start = 0x10000000;

signed long schedule_timeout(signed long timeout) {

  SYS_FLAGS f;
  struct timespec t;

  f = ll_fsave();
  sti();

  jiffies_to_timespec(timeout, &t);

  nanosleep(&t,NULL);

  ll_frestore(f);

  return 0;

}

void __const_udelay(unsigned long usecs) {

  SYS_FLAGS f;
  struct timespec t;
                                                                                                                             
  f = ll_fsave();
  sti();
 
  t.tv_sec = 0;
  t.tv_nsec = usecs * 1000;
                                                                                                                           
  nanosleep(&t,NULL);
                                                                                                                             
  ll_frestore(f);
                                                                                                                             
}