Rev 436 |
Rev 455 |
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
);
}