diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-09-12 00:35:47 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-09-12 00:35:47 -0700 |
| commit | da4c77fcc28bf973867683e8f3dd056f3ff214f0 (patch) | |
| tree | a9cac69265fb9cdf3fbe17826ce72f80ea303575 /include | |
| parent | 8916919b9d826f4ac881c5b938bf07d3fa34388e (diff) | |
| parent | c3b72b7df571cf2c525aaea1298b674691927748 (diff) | |
Merge bk://jfs.bkbits.net/linux-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
Diffstat (limited to 'include')
118 files changed, 3192 insertions, 519 deletions
diff --git a/include/asm-alpha/hdreg.h b/include/asm-alpha/hdreg.h index 2d9454754910..81d8a40802c3 100644 --- a/include/asm-alpha/hdreg.h +++ b/include/asm-alpha/hdreg.h @@ -7,6 +7,6 @@ #ifndef __ASMalpha_HDREG_H #define __ASMalpha_HDREG_H -typedef unsigned short ide_ioreg_t; +typedef unsigned long ide_ioreg_t; #endif /* __ASMalpha_HDREG_H */ diff --git a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h index 8730c4b833fe..07f843f72edc 100644 --- a/include/asm-alpha/signal.h +++ b/include/asm-alpha/signal.h @@ -186,7 +186,6 @@ struct sigstack { #ifdef __KERNEL__ #include <asm/sigcontext.h> -#define HAVE_ARCH_GET_SIGNAL_TO_DELIVER #define HAVE_ARCH_SYS_PAUSE #endif diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index 8e5848df6369..6342ed4efdbd 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -311,6 +311,8 @@ extern int __min_ipl; #define local_irq_save(flags) do { (flags) = swpipl(IPL_MAX); barrier(); } while(0) #define local_irq_restore(flags) do { barrier(); setipl(flags); barrier(); } while(0) +#define irqs_disabled() (getipl() == IPL_MAX) + /* * TB routines.. */ diff --git a/include/asm-arm/hdreg.h b/include/asm-arm/hdreg.h index a2d301dd5361..81bc05e16260 100644 --- a/include/asm-arm/hdreg.h +++ b/include/asm-arm/hdreg.h @@ -7,7 +7,7 @@ #ifndef __ASMARM_HDREG_H #define __ASMARM_HDREG_H -typedef unsigned int ide_ioreg_t; +typedef unsigned long ide_ioreg_t; #endif /* __ASMARM_HDREG_H */ diff --git a/include/asm-i386/hdreg.h b/include/asm-i386/hdreg.h index 1ad5c073941c..4760b0453b8e 100644 --- a/include/asm-i386/hdreg.h +++ b/include/asm-i386/hdreg.h @@ -7,6 +7,6 @@ #ifndef __ASMi386_HDREG_H #define __ASMi386_HDREG_H -typedef unsigned short ide_ioreg_t; +typedef unsigned long ide_ioreg_t; #endif /* __ASMi386_HDREG_H */ diff --git a/include/asm-i386/ide.h b/include/asm-i386/ide.h index 6e78191eaa81..3f307acc50bd 100644 --- a/include/asm-i386/ide.h +++ b/include/asm-i386/ide.h @@ -77,20 +77,6 @@ static __inline__ void ide_init_default_hwifs(void) #endif } -#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) -#define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id)) -#define ide_check_region(from,extent) check_region((from), (extent)) -#define ide_request_region(from,extent,name) request_region((from), (extent), (name)) -#define ide_release_region(from,extent) release_region((from), (extent)) - -/* - * The following are not needed for the non-m68k ports - */ -#define ide_ack_intr(hwif) (1) -#define ide_fix_driveid(id) do {} while (0) -#define ide_release_lock(lock) do {} while (0) -#define ide_get_lock(lock, hdlr, data) do {} while (0) - #endif /* __KERNEL__ */ #endif /* __ASMi386_IDE_H */ diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index 4b702bd8e683..1a095484bd32 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -254,6 +254,9 @@ #define __NR_io_getevents 247 #define __NR_io_submit 248 #define __NR_io_cancel 249 +#define __NR_alloc_hugepages 250 +#define __NR_free_hugepages 251 +#define __NR_exit_group 252 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */ diff --git a/include/asm-parisc/hdreg.h b/include/asm-parisc/hdreg.h index 629b220f2df0..f934c760bf0e 100644 --- a/include/asm-parisc/hdreg.h +++ b/include/asm-parisc/hdreg.h @@ -1,6 +1,6 @@ #ifndef _ASM_HDREG_H #define _ASM_HDREG_H -typedef unsigned short ide_ioreg_t; +typedef unsigned long ide_ioreg_t; #endif diff --git a/include/asm-ppc/hdreg.h b/include/asm-ppc/hdreg.h index 9506c8293a4a..db83c662f3f0 100644 --- a/include/asm-ppc/hdreg.h +++ b/include/asm-ppc/hdreg.h @@ -14,7 +14,7 @@ #ifndef __ASMPPC_HDREG_H #define __ASMPPC_HDREG_H -typedef unsigned int ide_ioreg_t; +typedef unsigned long ide_ioreg_t; #endif /* __ASMPPC_HDREG_H */ diff --git a/include/asm-sh/hdreg.h b/include/asm-sh/hdreg.h index 1d417a15c17c..9112275e05f8 100644 --- a/include/asm-sh/hdreg.h +++ b/include/asm-sh/hdreg.h @@ -7,6 +7,6 @@ #ifndef __ASM_SH_HDREG_H #define __ASM_SH_HDREG_H -typedef unsigned int ide_ioreg_t; +typedef unsigned long ide_ioreg_t; #endif /* __ASM_SH_HDREG_H */ diff --git a/include/asm-um/a.out.h b/include/asm-um/a.out.h new file mode 100644 index 000000000000..2e208223f860 --- /dev/null +++ b/include/asm-um/a.out.h @@ -0,0 +1,18 @@ +#ifndef __UM_A_OUT_H +#define __UM_A_OUT_H + +#include "asm/arch/a.out.h" + +#undef STACK_TOP + +extern unsigned long stacksizelim; + +extern unsigned long host_task_size; + +extern int honeypot; + +#define STACK_ROOM (stacksizelim) + +#define STACK_TOP (honeypot ? host_task_size : task_size) + +#endif diff --git a/include/asm-um/arch-signal-i386.h b/include/asm-um/arch-signal-i386.h new file mode 100644 index 000000000000..99a9de4728da --- /dev/null +++ b/include/asm-um/arch-signal-i386.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_ARCH_SIGNAL_I386_H +#define __UM_ARCH_SIGNAL_I386_H + +struct arch_signal_context { + unsigned long extrasigs[_NSIG_WORDS]; +}; + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h new file mode 100644 index 000000000000..e236cda82b7d --- /dev/null +++ b/include/asm-um/archparam-i386.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_ARCHPARAM_I386_H +#define __UM_ARCHPARAM_I386_H + +/********* Bits for asm-um/elf.h ************/ + +#include "user.h" + +#define ELF_PLATFORM "i586" + +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) + +typedef struct user_i387_struct elf_fpregset_t; +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_386 + +#define ELF_PLAT_INIT(regs) do { \ + PT_REGS_EBX(regs) = 0; \ + PT_REGS_ECX(regs) = 0; \ + PT_REGS_EDX(regs) = 0; \ + PT_REGS_ESI(regs) = 0; \ + PT_REGS_EDI(regs) = 0; \ + PT_REGS_EBP(regs) = 0; \ + PT_REGS_EAX(regs) = 0; \ +} while(0) + +/* Shamelessly stolen from include/asm-i386/elf.h */ + +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ + pr_reg[0] = PT_REGS_EBX(regs); \ + pr_reg[1] = PT_REGS_ECX(regs); \ + pr_reg[2] = PT_REGS_EDX(regs); \ + pr_reg[3] = PT_REGS_ESI(regs); \ + pr_reg[4] = PT_REGS_EDI(regs); \ + pr_reg[5] = PT_REGS_EBP(regs); \ + pr_reg[6] = PT_REGS_EAX(regs); \ + pr_reg[7] = PT_REGS_DS(regs); \ + pr_reg[8] = PT_REGS_ES(regs); \ + /* fake once used fs and gs selectors? */ \ + pr_reg[9] = PT_REGS_DS(regs); \ + pr_reg[10] = PT_REGS_DS(regs); \ + pr_reg[11] = regs->regs.syscall; \ + pr_reg[12] = PT_REGS_IP(regs); \ + pr_reg[13] = PT_REGS_CS(regs); \ + pr_reg[14] = PT_REGS_EFLAGS(regs); \ + pr_reg[15] = PT_REGS_SP(regs); \ + pr_reg[16] = PT_REGS_SS(regs); \ +} while(0); + +/********* Bits for asm-um/delay.h **********/ + +typedef unsigned long um_udelay_t; + +/********* Nothing for asm-um/hardirq.h **********/ + +/********* Nothing for asm-um/hw_irq.h **********/ + +/********* Nothing for asm-um/string.h **********/ + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/archparam-ppc.h b/include/asm-um/archparam-ppc.h new file mode 100644 index 000000000000..9b8b27e29551 --- /dev/null +++ b/include/asm-um/archparam-ppc.h @@ -0,0 +1,41 @@ +#ifndef __UM_ARCHPARAM_PPC_H +#define __UM_ARCHPARAM_PPC_H + +/********* Bits for asm-um/elf.h ************/ + +#define ELF_PLATFORM (0) + +#define ELF_ET_DYN_BASE (0x08000000) + +/* the following stolen from asm-ppc/elf.h */ +#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */ +#define ELF_NFPREG 33 /* includes fpscr */ +/* General registers */ +typedef unsigned long elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +/* Floating point registers */ +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +#define ELF_DATA ELFDATA2MSB +#define ELF_ARCH EM_PPC + +/********* Bits for asm-um/delay.h **********/ + +typedef unsigned int um_udelay_t; + +/********* Bits for asm-um/hw_irq.h **********/ + +struct hw_interrupt_type; + +/********* Bits for asm-um/hardirq.h **********/ + +#define irq_enter(cpu, irq) hardirq_enter(cpu) +#define irq_exit(cpu, irq) hardirq_exit(cpu) + +/********* Bits for asm-um/string.h **********/ + +#define __HAVE_ARCH_STRRCHR + +#endif diff --git a/include/asm-um/atomic.h b/include/asm-um/atomic.h new file mode 100644 index 000000000000..5e297acc8da5 --- /dev/null +++ b/include/asm-um/atomic.h @@ -0,0 +1,6 @@ +#ifndef __UM_ATOMIC_H +#define __UM_ATOMIC_H + +#include "asm/arch/atomic.h" + +#endif diff --git a/include/asm-um/bitops.h b/include/asm-um/bitops.h new file mode 100644 index 000000000000..46d781953d3a --- /dev/null +++ b/include/asm-um/bitops.h @@ -0,0 +1,6 @@ +#ifndef __UM_BITOPS_H +#define __UM_BITOPS_H + +#include "asm/arch/bitops.h" + +#endif diff --git a/include/asm-um/boot.h b/include/asm-um/boot.h new file mode 100644 index 000000000000..09548c3e784e --- /dev/null +++ b/include/asm-um/boot.h @@ -0,0 +1,6 @@ +#ifndef __UM_BOOT_H +#define __UM_BOOT_H + +#include "asm/arch/boot.h" + +#endif diff --git a/include/asm-um/bugs.h b/include/asm-um/bugs.h new file mode 100644 index 000000000000..6a72e240d5fc --- /dev/null +++ b/include/asm-um/bugs.h @@ -0,0 +1,6 @@ +#ifndef __UM_BUGS_H +#define __UM_BUGS_H + +void check_bugs(void); + +#endif diff --git a/include/asm-um/byteorder.h b/include/asm-um/byteorder.h new file mode 100644 index 000000000000..eee0a834f447 --- /dev/null +++ b/include/asm-um/byteorder.h @@ -0,0 +1,6 @@ +#ifndef __UM_BYTEORDER_H +#define __UM_BYTEORDER_H + +#include "asm/arch/byteorder.h" + +#endif diff --git a/include/asm-um/cache.h b/include/asm-um/cache.h new file mode 100644 index 000000000000..a4962992cf86 --- /dev/null +++ b/include/asm-um/cache.h @@ -0,0 +1,7 @@ +#ifndef __UM_CACHE_H +#define __UM_CACHE_H + +#define L1_CACHE_SHIFT 5 +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + +#endif diff --git a/include/asm-um/cacheflush.h b/include/asm-um/cacheflush.h new file mode 100644 index 000000000000..12e9d4b74c8f --- /dev/null +++ b/include/asm-um/cacheflush.h @@ -0,0 +1,6 @@ +#ifndef __UM_CACHEFLUSH_H +#define __UM_CACHEFLUSH_H + +#include "asm/arch/cacheflush.h" + +#endif diff --git a/include/asm-um/checksum.h b/include/asm-um/checksum.h new file mode 100644 index 000000000000..4b38f37c822e --- /dev/null +++ b/include/asm-um/checksum.h @@ -0,0 +1,6 @@ +#ifndef __UM_CHECKSUM_H +#define __UM_CHECKSUM_H + +#include "asm/arch/checksum.h" + +#endif diff --git a/include/asm-um/cobalt.h b/include/asm-um/cobalt.h new file mode 100644 index 000000000000..f813a684be98 --- /dev/null +++ b/include/asm-um/cobalt.h @@ -0,0 +1,6 @@ +#ifndef __UM_COBALT_H +#define __UM_COBALT_H + +#include "asm/arch/cobalt.h" + +#endif diff --git a/include/asm-um/current.h b/include/asm-um/current.h new file mode 100644 index 000000000000..d62d55df3129 --- /dev/null +++ b/include/asm-um/current.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_CURRENT_H +#define __UM_CURRENT_H + +#ifndef __ASSEMBLY__ + +struct thread_info; + +#include "linux/config.h" +#include "asm/page.h" + +#define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & (PAGE_MASK << 2)) + +#define current ({ int dummy; \ + ((struct thread_info *) CURRENT_THREAD(dummy))->task; }) + +#endif /* __ASSEMBLY__ */ + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/delay.h b/include/asm-um/delay.h new file mode 100644 index 000000000000..40695576ca60 --- /dev/null +++ b/include/asm-um/delay.h @@ -0,0 +1,7 @@ +#ifndef __UM_DELAY_H +#define __UM_DELAY_H + +#include "asm/arch/delay.h" +#include "asm/archparam.h" + +#endif diff --git a/include/asm-um/desc.h b/include/asm-um/desc.h new file mode 100644 index 000000000000..ac1d2a20d178 --- /dev/null +++ b/include/asm-um/desc.h @@ -0,0 +1,6 @@ +#ifndef __UM_DESC_H +#define __UM_DESC_H + +#include "asm/arch/desc.h" + +#endif diff --git a/include/asm-um/div64.h b/include/asm-um/div64.h new file mode 100644 index 000000000000..1e17f7409cab --- /dev/null +++ b/include/asm-um/div64.h @@ -0,0 +1,6 @@ +#ifndef _UM_DIV64_H +#define _UM_DIV64_H + +#include "asm/arch/div64.h" + +#endif diff --git a/include/asm-um/dma.h b/include/asm-um/dma.h new file mode 100644 index 000000000000..9f6139a8a525 --- /dev/null +++ b/include/asm-um/dma.h @@ -0,0 +1,10 @@ +#ifndef __UM_DMA_H +#define __UM_DMA_H + +#include "asm/io.h" + +extern unsigned long uml_physmem; + +#define MAX_DMA_ADDRESS (uml_physmem) + +#endif diff --git a/include/asm-um/elf.h b/include/asm-um/elf.h new file mode 100644 index 000000000000..f33a3533fef7 --- /dev/null +++ b/include/asm-um/elf.h @@ -0,0 +1,18 @@ +#ifndef __UM_ELF_H +#define __UM_ELF_H + +#include "asm/archparam.h" + +#define ELF_HWCAP (0) + +#define SET_PERSONALITY(ex, ibcs2) do ; while(0) + +#define ELF_EXEC_PAGESIZE 4096 + +#define elf_check_arch(x) (1) + +#define ELF_CLASS ELFCLASS32 + +#define USE_ELF_CORE_DUMP + +#endif diff --git a/include/asm-um/errno.h b/include/asm-um/errno.h new file mode 100644 index 000000000000..b7a9e37fd8d8 --- /dev/null +++ b/include/asm-um/errno.h @@ -0,0 +1,6 @@ +#ifndef __UM_ERRNO_H +#define __UM_ERRNO_H + +#include "asm/arch/errno.h" + +#endif diff --git a/include/asm-um/fcntl.h b/include/asm-um/fcntl.h new file mode 100644 index 000000000000..812a65446d92 --- /dev/null +++ b/include/asm-um/fcntl.h @@ -0,0 +1,6 @@ +#ifndef __UM_FCNTL_H +#define __UM_FCNTL_H + +#include "asm/arch/fcntl.h" + +#endif diff --git a/include/asm-um/floppy.h b/include/asm-um/floppy.h new file mode 100644 index 000000000000..453e7415fb6f --- /dev/null +++ b/include/asm-um/floppy.h @@ -0,0 +1,6 @@ +#ifndef __UM_FLOPPY_H +#define __UM_FLOPPY_H + +#include "asm/arch/floppy.h" + +#endif diff --git a/include/asm-um/hardirq.h b/include/asm-um/hardirq.h new file mode 100644 index 000000000000..da49d29a5c5a --- /dev/null +++ b/include/asm-um/hardirq.h @@ -0,0 +1,6 @@ +#ifndef __UM_HARDIRQ_H +#define __UM_HARDIRQ_H + +#include "asm/arch/hardirq.h" + +#endif diff --git a/include/asm-um/hdreg.h b/include/asm-um/hdreg.h new file mode 100644 index 000000000000..cf6363abcab9 --- /dev/null +++ b/include/asm-um/hdreg.h @@ -0,0 +1,6 @@ +#ifndef __UM_HDREG_H +#define __UM_HDREG_H + +#include "asm/arch/hdreg.h" + +#endif diff --git a/include/asm-um/highmem.h b/include/asm-um/highmem.h new file mode 100644 index 000000000000..6713fb2a4896 --- /dev/null +++ b/include/asm-um/highmem.h @@ -0,0 +1,6 @@ +#ifndef __UM_HIGHMEM_H +#define __UM_HIGHMEM_H + +#include "asm/arch/highmem.h" + +#endif diff --git a/include/asm-um/hw_irq.h b/include/asm-um/hw_irq.h new file mode 100644 index 000000000000..4ee38c0b6a64 --- /dev/null +++ b/include/asm-um/hw_irq.h @@ -0,0 +1,10 @@ +#ifndef _ASM_UM_HW_IRQ_H +#define _ASM_UM_HW_IRQ_H + +#include "asm/irq.h" +#include "asm/archparam.h" + +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) +{} + +#endif diff --git a/include/asm-um/ide.h b/include/asm-um/ide.h new file mode 100644 index 000000000000..3d1ccebcfbaf --- /dev/null +++ b/include/asm-um/ide.h @@ -0,0 +1,6 @@ +#ifndef __UM_IDE_H +#define __UM_IDE_H + +#include "asm/arch/ide.h" + +#endif diff --git a/include/asm-um/init.h b/include/asm-um/init.h new file mode 100644 index 000000000000..1e271ca7cec8 --- /dev/null +++ b/include/asm-um/init.h @@ -0,0 +1,11 @@ +#ifndef _UM_INIT_H +#define _UM_INIT_H + +#ifdef notdef +#define __init +#define __initdata +#define __initfunc(__arginit) __arginit +#define __cacheline_aligned +#endif + +#endif diff --git a/include/asm-um/io.h b/include/asm-um/io.h new file mode 100644 index 000000000000..62d6f2423ea6 --- /dev/null +++ b/include/asm-um/io.h @@ -0,0 +1,25 @@ +#ifndef __UM_IO_H +#define __UM_IO_H + +#include "asm/page.h" + +#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */ + +static inline int inb(unsigned long i) { return(0); } +static inline void outb(char c, unsigned long i) { } + +/* + * Change virtual addresses to physical addresses and vv. + * These are pretty trivial + */ +static inline unsigned long virt_to_phys(volatile void * address) +{ + return __pa((void *) address); +} + +static inline void * phys_to_virt(unsigned long address) +{ + return __va(address); +} + +#endif diff --git a/include/asm-um/ioctl.h b/include/asm-um/ioctl.h new file mode 100644 index 000000000000..cc22157346db --- /dev/null +++ b/include/asm-um/ioctl.h @@ -0,0 +1,6 @@ +#ifndef __UM_IOCTL_H +#define __UM_IOCTL_H + +#include "asm/arch/ioctl.h" + +#endif diff --git a/include/asm-um/ioctls.h b/include/asm-um/ioctls.h new file mode 100644 index 000000000000..9a1a017de6a7 --- /dev/null +++ b/include/asm-um/ioctls.h @@ -0,0 +1,6 @@ +#ifndef __UM_IOCTLS_H +#define __UM_IOCTLS_H + +#include "asm/arch/ioctls.h" + +#endif diff --git a/include/asm-um/ipc.h b/include/asm-um/ipc.h new file mode 100644 index 000000000000..e2ddc47f3e52 --- /dev/null +++ b/include/asm-um/ipc.h @@ -0,0 +1,6 @@ +#ifndef __UM_IPC_H +#define __UM_IPC_H + +#include "asm/arch/ipc.h" + +#endif diff --git a/include/asm-um/ipcbuf.h b/include/asm-um/ipcbuf.h new file mode 100644 index 000000000000..bb2ad31dc434 --- /dev/null +++ b/include/asm-um/ipcbuf.h @@ -0,0 +1,6 @@ +#ifndef __UM_IPCBUF_H +#define __UM_IPCBUF_H + +#include "asm/arch/ipcbuf.h" + +#endif diff --git a/include/asm-um/irq.h b/include/asm-um/irq.h new file mode 100644 index 000000000000..11d3761dd824 --- /dev/null +++ b/include/asm-um/irq.h @@ -0,0 +1,35 @@ +#ifndef __UM_IRQ_H +#define __UM_IRQ_H + +/* The i386 irq.h has a struct task_struct in a prototype without including + * sched.h. This forward declaration kills the resulting warning. + */ +struct task_struct; + +#include "asm/arch/irq.h" +#include "asm/ptrace.h" + +#undef NR_IRQS + +#define TIMER_IRQ 0 +#define UMN_IRQ 1 +#define CONSOLE_IRQ 2 +#define CONSOLE_WRITE_IRQ 3 +#define UBD_IRQ 4 +#define UM_ETH_IRQ 5 +#define SSL_IRQ 6 +#define SSL_WRITE_IRQ 7 +#define ACCEPT_IRQ 8 +#define MCONSOLE_IRQ 9 +#define WINCH_IRQ 10 +#define SIGIO_WRITE_IRQ 11 +#define TELNETD_IRQ 12 + +#define LAST_IRQ TELNETD_IRQ +#define NR_IRQS (LAST_IRQ + 1) + +extern int um_request_irq(unsigned int irq, int fd, int type, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, const char * devname, + void *dev_id); +#endif diff --git a/include/asm-um/irq_vectors.h b/include/asm-um/irq_vectors.h new file mode 100644 index 000000000000..62ddba6fc733 --- /dev/null +++ b/include/asm-um/irq_vectors.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_IRQ_VECTORS_H +#define __UM_IRQ_VECTORS_H + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/keyboard.h b/include/asm-um/keyboard.h new file mode 100644 index 000000000000..ee2e2303d0e4 --- /dev/null +++ b/include/asm-um/keyboard.h @@ -0,0 +1,6 @@ +#ifndef __UM_KEYBOARD_H +#define __UM_KEYBOARD_H + +#include "asm/arch/keyboard.h" + +#endif diff --git a/include/asm-um/kmap_types.h b/include/asm-um/kmap_types.h new file mode 100644 index 000000000000..0b22ad776e76 --- /dev/null +++ b/include/asm-um/kmap_types.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_KMAP_TYPES_H +#define __UM_KMAP_TYPES_H + +#include "asm/arch/kmap_types.h" + +#endif diff --git a/include/asm-um/linkage.h b/include/asm-um/linkage.h new file mode 100644 index 000000000000..1504efe84e24 --- /dev/null +++ b/include/asm-um/linkage.h @@ -0,0 +1,6 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +#define FASTCALL(x) x __attribute__((regparm(3))) + +#endif diff --git a/include/asm-um/linux_logo.h b/include/asm-um/linux_logo.h new file mode 100644 index 000000000000..ae3b9289c1d7 --- /dev/null +++ b/include/asm-um/linux_logo.h @@ -0,0 +1,6 @@ +#ifndef __UM_LINUX_LOGO_H +#define __UM_LINUX_LOGO_H + +#include "asm/arch/linux_logo.h" + +#endif diff --git a/include/asm-um/locks.h b/include/asm-um/locks.h new file mode 100644 index 000000000000..f80030a3ef5a --- /dev/null +++ b/include/asm-um/locks.h @@ -0,0 +1,6 @@ +#ifndef __UM_LOCKS_H +#define __UM_LOCKS_H + +#include "asm/arch/locks.h" + +#endif diff --git a/include/asm-um/mca_dma.h b/include/asm-um/mca_dma.h new file mode 100644 index 000000000000..e492e4ec1392 --- /dev/null +++ b/include/asm-um/mca_dma.h @@ -0,0 +1,6 @@ +#ifndef mca___UM_DMA_H +#define mca___UM_DMA_H + +#include "asm/arch/mca_dma.h" + +#endif diff --git a/include/asm-um/mman.h b/include/asm-um/mman.h new file mode 100644 index 000000000000..b09ed523019b --- /dev/null +++ b/include/asm-um/mman.h @@ -0,0 +1,6 @@ +#ifndef __UM_MMAN_H +#define __UM_MMAN_H + +#include "asm/arch/mman.h" + +#endif diff --git a/include/asm-um/mmu.h b/include/asm-um/mmu.h new file mode 100644 index 000000000000..d276d24f07df --- /dev/null +++ b/include/asm-um/mmu.h @@ -0,0 +1,6 @@ +#ifndef __MMU_H +#define __MMU_H + +#include "asm/arch/mmu.h" + +#endif diff --git a/include/asm-um/mmu_context.h b/include/asm-um/mmu_context.h new file mode 100644 index 000000000000..56ef77e1c1c8 --- /dev/null +++ b/include/asm-um/mmu_context.h @@ -0,0 +1,25 @@ +#ifndef __UM_MMU_CONTEXT_H +#define __UM_MMU_CONTEXT_H + +#include "linux/sched.h" + +#define init_new_context(task, mm) (0) +#define get_mmu_context(task) do ; while(0) +#define activate_context(tsk) do ; while(0) +#define destroy_context(mm) do ; while(0) + +static inline void activate_mm(struct mm_struct *old, struct mm_struct *new) +{ +} + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk, unsigned cpu) +{ +} + +static inline void enter_lazy_tlb(struct mm_struct *mm, + struct task_struct *tsk, unsigned cpu) +{ +} + +#endif diff --git a/include/asm-um/module.h b/include/asm-um/module.h new file mode 100644 index 000000000000..94374aa9c691 --- /dev/null +++ b/include/asm-um/module.h @@ -0,0 +1,6 @@ +#ifndef __UM_MODULE_H +#define __UM_MODULE_H + +#include "asm/arch/module.h" + +#endif diff --git a/include/asm-um/msgbuf.h b/include/asm-um/msgbuf.h new file mode 100644 index 000000000000..8ce8c30d5377 --- /dev/null +++ b/include/asm-um/msgbuf.h @@ -0,0 +1,6 @@ +#ifndef __UM_MSGBUF_H +#define __UM_MSGBUF_H + +#include "asm/arch/msgbuf.h" + +#endif diff --git a/include/asm-um/mtrr.h b/include/asm-um/mtrr.h new file mode 100644 index 000000000000..5e9cd12c578d --- /dev/null +++ b/include/asm-um/mtrr.h @@ -0,0 +1,6 @@ +#ifndef __UM_MTRR_H +#define __UM_MTRR_H + +#include "asm/arch/mtrr.h" + +#endif diff --git a/include/asm-um/namei.h b/include/asm-um/namei.h new file mode 100644 index 000000000000..002984d5bc85 --- /dev/null +++ b/include/asm-um/namei.h @@ -0,0 +1,6 @@ +#ifndef __UM_NAMEI_H +#define __UM_NAMEI_H + +#include "asm/arch/namei.h" + +#endif diff --git a/include/asm-um/page.h b/include/asm-um/page.h new file mode 100644 index 000000000000..0f7e84c3196a --- /dev/null +++ b/include/asm-um/page.h @@ -0,0 +1,60 @@ +#ifndef __UM_PAGE_H +#define __UM_PAGE_H + +struct page; + +#include "asm/arch/page.h" + +#undef BUG +#undef PAGE_BUG +#undef __pa +#undef __va +#undef pfn_to_page +#undef page_to_pfn +#undef virt_to_page +#undef pfn_valid +#undef virt_addr_valid +#undef VALID_PAGE +#undef PAGE_OFFSET +#undef KERNELBASE + +#define PAGE_OFFSET (uml_physmem) +#define KERNELBASE PAGE_OFFSET + +#ifndef __ASSEMBLY__ + +extern void stop(void); + +#define BUG() do { \ + panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ +} while (0) + +#define PAGE_BUG(page) do { \ + BUG(); \ +} while (0) + +#endif /* __ASSEMBLY__ */ + +#define __va_space (8*1024*1024) + +extern unsigned long region_pa(void *virt); +extern void *region_va(unsigned long phys); + +#define __pa(virt) region_pa((void *) (virt)) +#define __va(phys) region_va((unsigned long) (phys)) + +extern struct page *phys_to_page(unsigned long phys); + +#define pfn_to_page(pfn) (phys_to_page(pfn << PAGE_SHIFT)) +#define page_to_pfn(page) (page_to_phys(page) >> PAGE_SHIFT) +#define virt_to_page(v) (phys_to_page(__pa(v))) + +extern struct page *page_mem_map(struct page *page); + +#define pfn_valid(pfn) (page_mem_map(pfn_to_page(pfn)) != NULL) +#define virt_addr_valid(v) pfn_valid(__pa(v) >> PAGE_SHIFT) + +extern struct page *arch_validate(struct page *page, int mask, int order); +#define HAVE_ARCH_VALIDATE + +#endif diff --git a/include/asm-um/page_offset.h b/include/asm-um/page_offset.h new file mode 100644 index 000000000000..1c168dfbf359 --- /dev/null +++ b/include/asm-um/page_offset.h @@ -0,0 +1 @@ +#define PAGE_OFFSET_RAW (uml_physmem) diff --git a/include/asm-um/param.h b/include/asm-um/param.h new file mode 100644 index 000000000000..513c23596bd6 --- /dev/null +++ b/include/asm-um/param.h @@ -0,0 +1,22 @@ +#ifndef _UM_PARAM_H +#define _UM_PARAM_H + +#define EXEC_PAGESIZE 4096 + +#ifndef NGROUPS +#define NGROUPS 32 +#endif + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#ifdef __KERNEL__ +#define HZ 100 +#define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */ +#endif + +#endif diff --git a/include/asm-um/pci.h b/include/asm-um/pci.h new file mode 100644 index 000000000000..b44cf59ede1e --- /dev/null +++ b/include/asm-um/pci.h @@ -0,0 +1,6 @@ +#ifndef __UM_PCI_H +#define __UM_PCI_H + +#define PCI_DMA_BUS_IS_PHYS (1) + +#endif diff --git a/include/asm-um/percpu.h b/include/asm-um/percpu.h new file mode 100644 index 000000000000..5b6d9f51b48c --- /dev/null +++ b/include/asm-um/percpu.h @@ -0,0 +1,6 @@ +#ifndef __UM_CACHEFLUSH_H +#define __UM_CACHEFLUSH_H + +#include "asm/arch/percpu.h" + +#endif diff --git a/include/asm-um/pgalloc.h b/include/asm-um/pgalloc.h new file mode 100644 index 000000000000..4620297e2cc7 --- /dev/null +++ b/include/asm-um/pgalloc.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h + * Licensed under the GPL + */ + +#ifndef __UM_PGALLOC_H +#define __UM_PGALLOC_H + +#include "linux/mm.h" + +#define pmd_populate_kernel(mm, pmd, pte) \ + set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) __pa(pte))) + +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, + struct page *pte) +{ + set_pmd(pmd, __pmd(_PAGE_TABLE + phys_addr(page_to_phys(pte)))); +} + +extern pgd_t *pgd_alloc(struct mm_struct *); +extern void pgd_free(pgd_t *pgd); + +extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); +extern struct page *pte_alloc_one(struct mm_struct *, unsigned long); + +static inline void pte_free_kernel(pte_t *pte) +{ + free_page((unsigned long) pte); +} + +static inline void pte_free(struct page *pte) +{ + __free_page(pte); +} + +#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ + +#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_free(x) do { } while (0) +#define __pmd_free_tlb(tlb,x) do { } while (0) +#define pgd_populate(mm, pmd, pte) BUG() + +#define check_pgt_cache() do { } while (0) + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h new file mode 100644 index 000000000000..85b366b643a3 --- /dev/null +++ b/include/asm-um/pgtable.h @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Derived from include/asm-i386/pgtable.h + * Licensed under the GPL + */ + +#ifndef __UM_PGTABLE_H +#define __UM_PGTABLE_H + +#include "linux/sched.h" +#include "asm/processor.h" +#include "asm/page.h" + +extern pgd_t swapper_pg_dir[1024]; + +/* zero page used for uninitialized stuff */ +extern unsigned long *empty_zero_page; + +#define pgtable_cache_init() do ; while (0) + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#define PMD_SHIFT 22 +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define PGDIR_SHIFT 22 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * entries per page directory level: the i386 is two-level, so + * we don't really have any PMD directory physically. + */ +#define PTRS_PER_PTE 1024 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 1024 +#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) +#define FIRST_USER_PGD_NR 0 + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + +/* + * pgd entries used up by user/kernel: + */ + +#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT) +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) + +#ifndef __ASSEMBLY__ +/* Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ + +extern unsigned long high_physmem; +extern unsigned long end_vm; + +#define VMALLOC_OFFSET (__va_space) +#define VMALLOC_START (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_END (end_vm) + +#define _PAGE_PRESENT 0x001 +#define _PAGE_NEWPAGE 0x002 +#define _PAGE_PROTNONE 0x004 /* If not present */ +#define _PAGE_RW 0x008 +#define _PAGE_USER 0x010 +#define _PAGE_ACCESSED 0x020 +#define _PAGE_DIRTY 0x040 +#define _PAGE_NEWPROT 0x080 + +#define REGION_MASK 0xf0000000 +#define REGION_SHIFT 28 + +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED) + +/* + * The i386 can't do page protection for execute, and considers that the same are read. + * Also, write permissions imply read permissions. This is the closest we can get.. + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +/* + * Define this if things work differently on an i386 and an i486: + * it will (on an i486) warn about kernel memory accesses that are + * done without a 'verify_area(VERIFY_WRITE,..)' + */ +#undef TEST_VERIFY_AREA + +/* page table for 0-4MB for everybody */ +extern unsigned long pg0[1024]; + +/* + * BAD_PAGETABLE is used when we need a bogus page-table, while + * BAD_PAGE is used for a bogus page. + * + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern pte_t __bad_page(void); +extern pte_t * __bad_pagetable(void); + +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) + +/* number of bits that fit into a memory pointer */ +#define BITS_PER_PTR (8*sizeof(unsigned long)) + +/* to align the pointer to a pointer address */ +#define PTR_MASK (~(sizeof(void*)-1)) + +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ +/* 64-bit machines, beware! SRB. */ +#define SIZEOF_PTR_LOG2 2 + +/* to find an entry in a page-table */ +#define PAGE_PTR(address) \ +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) + +#define pte_none(x) !(pte_val(x) & ~_PAGE_NEWPAGE) +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) + +#define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0) + +#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT) +#define pte_region_index(x) phys_region_index(pte_val(x)) + +#define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE)) +#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) +#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0) + +#define pmd_newpage(x) (pmd_val(x) & _PAGE_NEWPAGE) +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +static inline int pgd_none(pgd_t pgd) { return 0; } +static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) { return 1; } +static inline void pgd_clear(pgd_t * pgdp) { } + + +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) + +extern struct page *pte_mem_map(pte_t pte); +extern struct page *phys_mem_map(unsigned long phys); + +#define pte_page(x) pfn_to_page(pte_pfn(x)) +#define pte_address(x) (__va(pte_val(x) & PAGE_MASK)) +#define mk_phys(a, r) ((a) + (r << REGION_SHIFT)) +#define phys_addr(p) ((p) & ~REGION_MASK) +#define phys_page(p) (phys_mem_map(p) + ((phys_addr(p)) >> PAGE_SHIFT)) +#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +static inline pte_t pte_mknewprot(pte_t pte) +{ + pte_val(pte) |= _PAGE_NEWPROT; + return(pte); +} + +static inline pte_t pte_mknewpage(pte_t pte) +{ + pte_val(pte) |= _PAGE_NEWPAGE; + return(pte); +} + +static inline void set_pte(pte_t *pteptr, pte_t pteval) +{ + /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so + * fix_range knows to unmap it. _PAGE_NEWPROT is specific to + * mapped pages. + */ + *pteptr = pte_mknewpage(pteval); + if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr); +} + +/* + * (pmds are folded into pgds so this doesnt get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } +static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; } +static inline int pte_newprot(pte_t pte) +{ + return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT)); +} + +static inline pte_t pte_rdprotect(pte_t pte) +{ + pte_val(pte) &= ~_PAGE_USER; + return(pte_mknewprot(pte)); +} + +static inline pte_t pte_exprotect(pte_t pte) +{ + pte_val(pte) &= ~_PAGE_USER; + return(pte_mknewprot(pte)); +} + +static inline pte_t pte_mkclean(pte_t pte) +{ + pte_val(pte) &= ~_PAGE_DIRTY; + return(pte); +} + +static inline pte_t pte_mkold(pte_t pte) +{ + pte_val(pte) &= ~_PAGE_ACCESSED; + return(pte); +} + +static inline pte_t pte_wrprotect(pte_t pte) +{ + pte_val(pte) &= ~_PAGE_RW; + return(pte_mknewprot(pte)); +} + +static inline pte_t pte_mkread(pte_t pte) +{ + pte_val(pte) |= _PAGE_USER; + return(pte_mknewprot(pte)); +} + +static inline pte_t pte_mkexec(pte_t pte) +{ + pte_val(pte) |= _PAGE_USER; + return(pte_mknewprot(pte)); +} + +static inline pte_t pte_mkdirty(pte_t pte) +{ + pte_val(pte) |= _PAGE_DIRTY; + return(pte); +} + +static inline pte_t pte_mkyoung(pte_t pte) +{ + pte_val(pte) |= _PAGE_ACCESSED; + return(pte); +} + +static inline pte_t pte_mkwrite(pte_t pte) +{ + pte_val(pte) |= _PAGE_RW; + return(pte_mknewprot(pte)); +} + +static inline pte_t pte_mkuptodate(pte_t pte) +{ + pte_val(pte) &= ~_PAGE_NEWPAGE; + if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT; + return(pte); +} + +extern unsigned long page_to_phys(struct page *page); + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ + +#define mk_pte(page, pgprot) \ +({ \ + pte_t __pte; \ + \ + pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\ + if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \ + __pte; \ +}) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); + if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte)); + return pte; +} + +#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) +#define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \ + ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT))) + +/* to find an entry in a page-table-directory. */ +#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) + +/* to find an entry in a page-table-directory */ +#define pgd_offset(mm, address) \ +((mm)->pgd + ((address) >> PGDIR_SHIFT)) + +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* Find an entry in the second-level page table.. */ +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) dir; +} + +/* Find an entry in the third-level page table.. */ +#define __pte_offset(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_kernel(*(dir)) + __pte_offset(address)) +#define pte_offset_map(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + __pte_offset(address)) +#define pte_offset_map_nested(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + __pte_offset(address)) +#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) +#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) + +#define update_mmu_cache(vma,address,pte) do ; while (0) + +/* Encode and de-code a swap entry */ +#define __swp_type(x) (((x).val >> 3) & 0x7f) +#define __swp_offset(x) ((x).val >> 10) + +#define __swp_entry(type, offset) \ + ((swp_entry_t) { ((type) << 3) | ((offset) << 10) }) +#define __pte_to_swp_entry(pte) \ + ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +#define kern_addr_valid(addr) (1) + +#include <asm-generic/pgtable.h> + +#endif + +#endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/poll.h b/include/asm-um/poll.h new file mode 100644 index 000000000000..1eb4e1bc6383 --- /dev/null +++ b/include/asm-um/poll.h @@ -0,0 +1,6 @@ +#ifndef __UM_POLL_H +#define __UM_POLL_H + +#include "asm/arch/poll.h" + +#endif diff --git a/include/asm-um/posix_types.h b/include/asm-um/posix_types.h new file mode 100644 index 000000000000..32fb4198f644 --- /dev/null +++ b/include/asm-um/posix_types.h @@ -0,0 +1,6 @@ +#ifndef __UM_POSIX_TYPES_H +#define __UM_POSIX_TYPES_H + +#include "asm/arch/posix_types.h" + +#endif diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h new file mode 100644 index 000000000000..103efbbe56e6 --- /dev/null +++ b/include/asm-um/processor-generic.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_PROCESSOR_GENERIC_H +#define __UM_PROCESSOR_GENERIC_H + +struct pt_regs; + +struct task_struct; + +#include "linux/config.h" +#include "linux/signal.h" +#include "asm/segment.h" +#include "asm/ptrace.h" +#include "asm/siginfo.h" + +struct mm_struct; + +#define current_text_addr() ((void *) 0) + +#define cpu_relax() do ; while (0) + +struct thread_struct { + int extern_pid; + int tracing; + int forking; + unsigned long kernel_stack; + int nsyscalls; + struct pt_regs regs; + unsigned long cr2; + int err; + void *fault_addr; + void *fault_catcher; + int vm_seq; + struct task_struct *prev_sched; + unsigned long temp_stack; + int switch_pipe[2]; + void *jmp; + struct arch_thread arch; + int singlestep_syscall; + struct { + int op; + union { + struct { + int pid; + } fork, exec; + struct { + int (*proc)(void *); + void *arg; + } thread; + struct { + void (*proc)(void *); + void *arg; + } cb; + } u; + } request; +}; + +#define INIT_THREAD \ +{ \ + extern_pid: -1, \ + tracing: 0, \ + forking: 0, \ + kernel_stack: 0, \ + nsyscalls: 0, \ + regs: EMPTY_REGS, \ + cr2: 0, \ + err: 0, \ + fault_addr: NULL, \ + vm_seq: 0, \ + prev_sched: NULL, \ + temp_stack: 0, \ + switch_pipe: { -1, -1 }, \ + jmp: NULL, \ + arch: INIT_ARCH_THREAD, \ + singlestep_syscall: 0, \ + request: { 0 } \ +} + +#define INIT_THREAD_SIZE (4 * PAGE_SIZE) + +typedef struct { + unsigned long seg; +} mm_segment_t; + +extern struct task_struct *alloc_task_struct(void); +extern void free_task_struct(struct task_struct *task); + +extern void release_thread(struct task_struct *); +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); +extern void dump_thread(struct pt_regs *regs, struct user *u); + +static inline void release_segments(struct mm_struct *mm) +{ +} + +static inline void copy_segments(struct task_struct *p, + struct mm_struct *new_mm) +{ +} + +#define forget_segments() do ; while(0) + +extern unsigned long thread_saved_pc(struct task_struct *t); + +#define init_stack (init_thread_union.stack) + +/* + * User space process size: 3GB (default). + */ +extern unsigned long task_size; + +#define TASK_SIZE (task_size) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (0x40000000) + +extern void start_thread(struct pt_regs *regs, unsigned long entry, + unsigned long stack); + +struct cpuinfo_um { + unsigned long loops_per_jiffy; + int ipi_pipe[2]; +}; + +extern struct cpuinfo_um boot_cpu_data; + +#define my_cpu_data cpu_data[smp_processor_id()] + +#ifdef CONFIG_SMP +extern struct cpuinfo_um cpu_data[]; +#define current_cpu_data cpu_data[smp_processor_id()] +#else +#define cpu_data (&boot_cpu_data) +#define current_cpu_data boot_cpu_data +#endif + +#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs)) +#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs)) +#define get_wchan(p) (0) + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h new file mode 100644 index 000000000000..7af2488b41fe --- /dev/null +++ b/include/asm-um/processor-i386.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_PROCESSOR_I386_H +#define __UM_PROCESSOR_I386_H + +extern int cpu_has_xmm; +extern int cpu_has_cmov; + +struct arch_thread { + unsigned long debugregs[8]; + int debugregs_seq; +}; + +#define INIT_ARCH_THREAD { debugregs : { [ 0 ... 7 ] = 0 }, \ + debugregs_seq : 0 } + +#include "asm/arch/user.h" + +#include "asm/processor-generic.h" + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/processor-ppc.h b/include/asm-um/processor-ppc.h new file mode 100644 index 000000000000..a0441e9b40eb --- /dev/null +++ b/include/asm-um/processor-ppc.h @@ -0,0 +1,15 @@ +#ifndef __UM_PROCESSOR_PPC_H +#define __UM_PROCESSOR_PPC_H + +#if defined(__ASSEMBLY__) + +#define CONFIG_ALL_PPC +#include "arch/processor.h" + +#else + +#include "asm/processor-generic.h" + +#endif + +#endif diff --git a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h new file mode 100644 index 000000000000..18f6b5991856 --- /dev/null +++ b/include/asm-um/ptrace-generic.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_PTRACE_GENERIC_H +#define __UM_PTRACE_GENERIC_H + +#ifndef __ASSEMBLY__ + +#include "asm/current.h" + +#define pt_regs pt_regs_subarch +#define show_regs show_regs_subarch + +#include "asm/arch/ptrace.h" + +#undef pt_regs +#undef show_regs +#undef user_mode +#undef instruction_pointer + +#include "sysdep/ptrace.h" + +struct pt_regs { + struct uml_pt_regs regs; +}; + +#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS } + +#define PT_REGS_IP(r) UPT_IP(&(r)->regs) +#define PT_REGS_SP(r) UPT_SP(&(r)->regs) + +#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg) +#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val) + +#define PT_REGS_SET_SYSCALL_RETURN(r, res) \ + UPT_SET_SYSCALL_RETURN(&(r)->regs, res) +#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs) + +#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs) + +#define PT_REGS_SC(r) UPT_SC(&(r)->regs) + +struct task_struct; + +extern unsigned long getreg(struct task_struct *child, int regno); +extern int putreg(struct task_struct *child, int regno, unsigned long value); +extern int get_fpregs(unsigned long buf, struct task_struct *child); +extern int set_fpregs(unsigned long buf, struct task_struct *child); +extern int get_fpxregs(unsigned long buf, struct task_struct *child); +extern int set_fpxregs(unsigned long buf, struct task_struct *tsk); + +extern void show_regs(struct pt_regs *regs); + +#endif + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h new file mode 100644 index 000000000000..3c69e3e7b0e3 --- /dev/null +++ b/include/asm-um/ptrace-i386.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_PTRACE_I386_H +#define __UM_PTRACE_I386_H + +#include "asm/ptrace-generic.h" + +#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) +#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) +#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs) +#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs) +#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs) +#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs) +#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs) + +#define PT_REGS_CS(r) UPT_CS(&(r)->regs) +#define PT_REGS_SS(r) UPT_SS(&(r)->regs) +#define PT_REGS_DS(r) UPT_DS(&(r)->regs) +#define PT_REGS_ES(r) UPT_ES(&(r)->regs) +#define PT_REGS_FS(r) UPT_FS(&(r)->regs) +#define PT_REGS_GS(r) UPT_GS(&(r)->regs) + +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) + +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r) +#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) +#define PT_FIX_EXEC_STACK(sp) do ; while(0) + +#define user_mode(r) ((r)->regs.is_user) + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/resource.h b/include/asm-um/resource.h new file mode 100644 index 000000000000..c9b074001252 --- /dev/null +++ b/include/asm-um/resource.h @@ -0,0 +1,6 @@ +#ifndef __UM_RESOURCE_H +#define __UM_RESOURCE_H + +#include "asm/arch/resource.h" + +#endif diff --git a/include/asm-um/rmap.h b/include/asm-um/rmap.h new file mode 100644 index 000000000000..a244d486b66f --- /dev/null +++ b/include/asm-um/rmap.h @@ -0,0 +1,6 @@ +#ifndef __UM_RMAP_H +#define __UM_RMAP_H + +#include "asm/arch/rmap.h" + +#endif diff --git a/include/asm-um/rwlock.h b/include/asm-um/rwlock.h new file mode 100644 index 000000000000..ff383aafc9fe --- /dev/null +++ b/include/asm-um/rwlock.h @@ -0,0 +1,6 @@ +#ifndef __UM_RWLOCK_H +#define __UM_RWLOCK_H + +#include "asm/arch/rwlock.h" + +#endif diff --git a/include/asm-um/rwsem.h b/include/asm-um/rwsem.h new file mode 100644 index 000000000000..661c0e54702b --- /dev/null +++ b/include/asm-um/rwsem.h @@ -0,0 +1,10 @@ +#ifndef __UM_RWSEM_H__ +#define __UM_RWSEM_H__ + +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) +#define __builtin_expect(exp,c) (exp) +#endif + +#include "asm/arch/rwsem.h" + +#endif diff --git a/include/asm-um/scatterlist.h b/include/asm-um/scatterlist.h new file mode 100644 index 000000000000..e92016aa2079 --- /dev/null +++ b/include/asm-um/scatterlist.h @@ -0,0 +1,6 @@ +#ifndef __UM_SCATTERLIST_H +#define __UM_SCATTERLIST_H + +#include "asm/arch/scatterlist.h" + +#endif diff --git a/include/asm-um/segment.h b/include/asm-um/segment.h new file mode 100644 index 000000000000..55e40301f625 --- /dev/null +++ b/include/asm-um/segment.h @@ -0,0 +1,4 @@ +#ifndef __UM_SEGMENT_H +#define __UM_SEGMENT_H + +#endif diff --git a/include/asm-um/semaphore.h b/include/asm-um/semaphore.h new file mode 100644 index 000000000000..ff13c34de421 --- /dev/null +++ b/include/asm-um/semaphore.h @@ -0,0 +1,6 @@ +#ifndef __UM_SEMAPHORE_H +#define __UM_SEMAPHORE_H + +#include "asm/arch/semaphore.h" + +#endif diff --git a/include/asm-um/sembuf.h b/include/asm-um/sembuf.h new file mode 100644 index 000000000000..1ae82c14ff86 --- /dev/null +++ b/include/asm-um/sembuf.h @@ -0,0 +1,6 @@ +#ifndef __UM_SEMBUF_H +#define __UM_SEMBUF_H + +#include "asm/arch/sembuf.h" + +#endif diff --git a/include/asm-um/serial.h b/include/asm-um/serial.h new file mode 100644 index 000000000000..61ad07cfd2d5 --- /dev/null +++ b/include/asm-um/serial.h @@ -0,0 +1,6 @@ +#ifndef __UM_SERIAL_H +#define __UM_SERIAL_H + +#include "asm/arch/serial.h" + +#endif diff --git a/include/asm-um/shmbuf.h b/include/asm-um/shmbuf.h new file mode 100644 index 000000000000..9684d4a284a6 --- /dev/null +++ b/include/asm-um/shmbuf.h @@ -0,0 +1,6 @@ +#ifndef __UM_SHMBUF_H +#define __UM_SHMBUF_H + +#include "asm/arch/shmbuf.h" + +#endif diff --git a/include/asm-um/shmparam.h b/include/asm-um/shmparam.h new file mode 100644 index 000000000000..124c00174f6a --- /dev/null +++ b/include/asm-um/shmparam.h @@ -0,0 +1,6 @@ +#ifndef __UM_SHMPARAM_H +#define __UM_SHMPARAM_H + +#include "asm/arch/shmparam.h" + +#endif diff --git a/include/asm-um/sigcontext-generic.h b/include/asm-um/sigcontext-generic.h new file mode 100644 index 000000000000..164587014c61 --- /dev/null +++ b/include/asm-um/sigcontext-generic.h @@ -0,0 +1,6 @@ +#ifndef __UM_SIGCONTEXT_GENERIC_H +#define __UM_SIGCONTEXT_GENERIC_H + +#include "asm/arch/sigcontext.h" + +#endif diff --git a/include/asm-um/sigcontext-i386.h b/include/asm-um/sigcontext-i386.h new file mode 100644 index 000000000000..b88333f488bb --- /dev/null +++ b/include/asm-um/sigcontext-i386.h @@ -0,0 +1,6 @@ +#ifndef __UM_SIGCONTEXT_I386_H +#define __UM_SIGCONTEXT_I386_H + +#include "asm/sigcontext-generic.h" + +#endif diff --git a/include/asm-um/sigcontext-ppc.h b/include/asm-um/sigcontext-ppc.h new file mode 100644 index 000000000000..2467f20eda99 --- /dev/null +++ b/include/asm-um/sigcontext-ppc.h @@ -0,0 +1,10 @@ +#ifndef __UM_SIGCONTEXT_PPC_H +#define __UM_SIGCONTEXT_PPC_H + +#define pt_regs sys_pt_regs + +#include "asm/sigcontext-generic.h" + +#undef pt_regs + +#endif diff --git a/include/asm-um/siginfo.h b/include/asm-um/siginfo.h new file mode 100644 index 000000000000..bec6124c36d0 --- /dev/null +++ b/include/asm-um/siginfo.h @@ -0,0 +1,6 @@ +#ifndef __UM_SIGINFO_H +#define __UM_SIGINFO_H + +#include "asm/arch/siginfo.h" + +#endif diff --git a/include/asm-um/signal.h b/include/asm-um/signal.h new file mode 100644 index 000000000000..211d1e8a8179 --- /dev/null +++ b/include/asm-um/signal.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_SIGNAL_H +#define __UM_SIGNAL_H + +/* Need to kill the do_signal() declaration in the i386 signal.h */ + +#define do_signal do_signal_renamed +#include "asm/arch/signal.h" +#undef do_signal + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/smp.h b/include/asm-um/smp.h new file mode 100644 index 000000000000..931b1f956f17 --- /dev/null +++ b/include/asm-um/smp.h @@ -0,0 +1,20 @@ +#ifndef __UM_SMP_H +#define __UM_SMP_H + +extern unsigned long cpu_online_map; + +#ifdef CONFIG_SMP + +#include "linux/config.h" +#include "asm/current.h" + +#define smp_processor_id() (current->processor) +#define cpu_logical_map(n) (n) +#define cpu_number_map(n) (n) +#define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */ +extern int hard_smp_processor_id(void); +#define NO_PROC_ID -1 + +#endif + +#endif diff --git a/include/asm-um/smplock.h b/include/asm-um/smplock.h new file mode 100644 index 000000000000..aacda39c5191 --- /dev/null +++ b/include/asm-um/smplock.h @@ -0,0 +1,6 @@ +#ifndef __UM_SMPLOCK_H +#define __UM_SMPLOCK_H + +#include "asm/arch/smplock.h" + +#endif diff --git a/include/asm-um/socket.h b/include/asm-um/socket.h new file mode 100644 index 000000000000..67886e42ef04 --- /dev/null +++ b/include/asm-um/socket.h @@ -0,0 +1,6 @@ +#ifndef __UM_SOCKET_H +#define __UM_SOCKET_H + +#include "asm/arch/socket.h" + +#endif diff --git a/include/asm-um/sockios.h b/include/asm-um/sockios.h new file mode 100644 index 000000000000..93ee1c55c4d6 --- /dev/null +++ b/include/asm-um/sockios.h @@ -0,0 +1,6 @@ +#ifndef __UM_SOCKIOS_H +#define __UM_SOCKIOS_H + +#include "asm/arch/sockios.h" + +#endif diff --git a/include/asm-um/softirq.h b/include/asm-um/softirq.h new file mode 100644 index 000000000000..41734a0a9602 --- /dev/null +++ b/include/asm-um/softirq.h @@ -0,0 +1,13 @@ +#ifndef __UM_SOFTIRQ_H +#define __UM_SOFTIRQ_H + +#include "linux/smp.h" +#include "asm/system.h" +#include "asm/processor.h" + +/* A gratuitous name change */ +#define i386_bh_lock um_bh_lock +#include "asm/arch/softirq.h" +#undef i386_bh_lock + +#endif diff --git a/include/asm-um/spinlock.h b/include/asm-um/spinlock.h new file mode 100644 index 000000000000..bd6c35d4874c --- /dev/null +++ b/include/asm-um/spinlock.h @@ -0,0 +1,10 @@ +#ifndef __UM_SPINLOCK_H +#define __UM_SPINLOCK_H + +#include "linux/config.h" + +#ifdef CONFIG_SMP +#include "asm/arch/spinlock.h" +#endif + +#endif diff --git a/include/asm-um/stat.h b/include/asm-um/stat.h new file mode 100644 index 000000000000..83ed85ad2539 --- /dev/null +++ b/include/asm-um/stat.h @@ -0,0 +1,6 @@ +#ifndef __UM_STAT_H +#define __UM_STAT_H + +#include "asm/arch/stat.h" + +#endif diff --git a/include/asm-um/statfs.h b/include/asm-um/statfs.h new file mode 100644 index 000000000000..ba6fb53e7f87 --- /dev/null +++ b/include/asm-um/statfs.h @@ -0,0 +1,6 @@ +#ifndef _UM_STATFS_H +#define _UM_STATFS_H + +#include "asm/arch/statfs.h" + +#endif diff --git a/include/asm-um/string.h b/include/asm-um/string.h new file mode 100644 index 000000000000..9a0571f6dd61 --- /dev/null +++ b/include/asm-um/string.h @@ -0,0 +1,7 @@ +#ifndef __UM_STRING_H +#define __UM_STRING_H + +#include "asm/arch/string.h" +#include "asm/archparam.h" + +#endif diff --git a/include/asm-um/suspend.h b/include/asm-um/suspend.h new file mode 100644 index 000000000000..f4e8e007f468 --- /dev/null +++ b/include/asm-um/suspend.h @@ -0,0 +1,4 @@ +#ifndef __UM_SUSPEND_H +#define __UM_SUSPEND_H + +#endif diff --git a/include/asm-um/system-generic.h b/include/asm-um/system-generic.h new file mode 100644 index 000000000000..98915529c549 --- /dev/null +++ b/include/asm-um/system-generic.h @@ -0,0 +1,41 @@ +#ifndef __UM_SYSTEM_GENERIC_H +#define __UM_SYSTEM_GENERIC_H + +#include "asm/arch/system.h" + +#undef switch_to +#undef local_irq_save +#undef local_irq_restore +#undef local_irq_disable +#undef local_irq_enable +#undef local_save_flags +#undef local_irq_restore +#undef local_irq_enable +#undef local_irq_disable +#undef local_irq_save +#undef irqs_disabled + +extern void *switch_to(void *prev, void *next, void *last); + +extern int set_signals(int enable); +extern void block_signals(void); +extern void unblock_signals(void); +extern int get_signals(void); + +#define local_save_flags(flags) do { (flags) = get_signals(); } while(0) +#define local_irq_restore(flags) do { set_signals(flags); } while(0) + +#define local_irq_save(flags) do { local_save_flags(flags); \ + local_irq_disable(); } while(0) + +#define local_irq_enable() unblock_signals() +#define local_irq_disable() block_signals() + +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + local_save_flags(flags); \ + (flags != 0); \ +}) + +#endif diff --git a/include/asm-um/system-i386.h b/include/asm-um/system-i386.h new file mode 100644 index 000000000000..bb77d416f251 --- /dev/null +++ b/include/asm-um/system-i386.h @@ -0,0 +1,6 @@ +#ifndef __UM_SYSTEM_I386_H +#define __UM_SYSTEM_I386_H + +#include "asm/system-generic.h" + +#endif diff --git a/include/asm-um/system-ppc.h b/include/asm-um/system-ppc.h new file mode 100644 index 000000000000..17cde6640bf5 --- /dev/null +++ b/include/asm-um/system-ppc.h @@ -0,0 +1,12 @@ +#ifndef __UM_SYSTEM_PPC_H +#define __UM_SYSTEM_PPC_H + +#define _switch_to _ppc_switch_to + +#include "asm/arch/system.h" + +#undef _switch_to + +#include "asm/system-generic.h" + +#endif diff --git a/include/asm-um/termbits.h b/include/asm-um/termbits.h new file mode 100644 index 000000000000..5739c608a2cb --- /dev/null +++ b/include/asm-um/termbits.h @@ -0,0 +1,6 @@ +#ifndef __UM_TERMBITS_H +#define __UM_TERMBITS_H + +#include "asm/arch/termbits.h" + +#endif diff --git a/include/asm-um/termios.h b/include/asm-um/termios.h new file mode 100644 index 000000000000..d9f97b303311 --- /dev/null +++ b/include/asm-um/termios.h @@ -0,0 +1,6 @@ +#ifndef __UM_TERMIOS_H +#define __UM_TERMIOS_H + +#include "asm/arch/termios.h" + +#endif diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h new file mode 100644 index 000000000000..494e367f4ff9 --- /dev/null +++ b/include/asm-um/thread_info.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_THREAD_INFO_H +#define __UM_THREAD_INFO_H + +#ifndef __ASSEMBLY__ + +#include <asm/processor.h> + +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + __u32 cpu; /* current CPU */ + __s32 preempt_count; /* 0 => preemptable, + <0 => BUG */ + mm_segment_t addr_limit; /* thread address space: + 0-0xBFFFFFFF for user + 0-0xFFFFFFFF for kernel */ +}; + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ + +#define INIT_THREAD_INFO(tsk) \ +{ \ + task: &tsk, \ + exec_domain: &default_exec_domain, \ + flags: 0, \ + cpu: 0, \ + preempt_count: 1, \ + addr_limit: KERNEL_DS, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* how to get the thread information struct from C */ +static inline struct thread_info *current_thread_info(void) +{ + struct thread_info *ti; + __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL)); + return ti; +} + +/* thread information allocation */ +#define THREAD_SIZE (4*PAGE_SIZE) +#define alloc_thread_info() ((struct thread_info *) \ + __get_free_pages(GFP_KERNEL,2)) +#define free_thread_info(ti) free_pages((unsigned long) (ti), 2) +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) + +#endif + +#define PREEMPT_ACTIVE 0x4000000 + +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_SIGPENDING 1 /* signal pending */ +#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ + +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) +#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/timex.h b/include/asm-um/timex.h new file mode 100644 index 000000000000..564eb790ae07 --- /dev/null +++ b/include/asm-um/timex.h @@ -0,0 +1,15 @@ +#ifndef __UM_TIMEX_H +#define __UM_TIMEX_H + +#include "linux/time.h" + +typedef unsigned long cycles_t; + +#define cacheflush_time (0) + +static inline cycles_t get_cycles (void) +{ + return 0; +} + +#endif diff --git a/include/asm-um/tlb.h b/include/asm-um/tlb.h new file mode 100644 index 000000000000..c640033bc1fd --- /dev/null +++ b/include/asm-um/tlb.h @@ -0,0 +1,6 @@ +#ifndef __UM_TLB_H +#define __UM_TLB_H + +#include <asm/arch/tlb.h> + +#endif diff --git a/include/asm-um/tlbflush.h b/include/asm-um/tlbflush.h new file mode 100644 index 000000000000..fd55c6efb4d3 --- /dev/null +++ b/include/asm-um/tlbflush.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_TLBFLUSH_H +#define __UM_TLBFLUSH_H + +#include <linux/mm.h> + +/* + * TLB flushing: + * + * - flush_tlb() flushes the current mm struct TLBs + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_kernel_vm() flushes the kernel vm area + * - flush_tlb_range(vma, start, end) flushes a range of pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables + */ + +extern void flush_tlb_all(void); +extern void flush_tlb_mm(struct mm_struct *mm); +extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end); +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); +extern void flush_tlb_kernel_vm(void); +extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/types.h b/include/asm-um/types.h new file mode 100644 index 000000000000..816e9590fc73 --- /dev/null +++ b/include/asm-um/types.h @@ -0,0 +1,6 @@ +#ifndef __UM_TYPES_H +#define __UM_TYPES_H + +#include "asm/arch/types.h" + +#endif diff --git a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h new file mode 100644 index 000000000000..a8a7dfb7e4c8 --- /dev/null +++ b/include/asm-um/uaccess.h @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_UACCESS_H +#define __UM_UACCESS_H + +#include "linux/string.h" +#include "linux/sched.h" +#include "asm/processor.h" +#include "asm/errno.h" +#include "asm/current.h" +#include "asm/a.out.h" + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. + * + * For historical reasons, these macros are grossly misnamed. + */ + +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) + +#define ABOVE_KMEM (16 * 1024 * 1024) + +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) +#define USER_DS MAKE_MM_SEG(TASK_SIZE) + +#define get_ds() (KERNEL_DS) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) + +extern unsigned long end_vm; +extern unsigned long uml_physmem; + +#define under_task_size(addr, size) \ + (((unsigned long) (addr) < TASK_SIZE) && \ + (((unsigned long) (addr) + (size)) < TASK_SIZE)) + +#define is_stack(addr, size) \ + (((unsigned long) (addr) < STACK_TOP) && \ + ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \ + (((unsigned long) (addr) + (size)) <= STACK_TOP)) + +#define segment_eq(a, b) ((a).seg == (b).seg) + +#define access_ok(type, addr, size) \ + ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \ + (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ + (under_task_size(addr, size) || is_stack(addr, size)))) + +static inline int verify_area(int type, const void * addr, unsigned long size) +{ + return(access_ok(type, addr, size) ? 0 : -EFAULT); +} + +extern unsigned long get_fault_addr(void); + +extern int __do_copy_from_user(void *to, const void *from, int n, + void **fault_addr, void **fault_catcher); + +static inline int copy_from_user(void *to, const void *from, int n) +{ + return(access_ok(VERIFY_READ, from, n) ? + __do_copy_from_user(to, from, n, + ¤t->thread.fault_addr, + ¤t->thread.fault_catcher) : n); +} + +#define __copy_from_user(to, from, n) copy_from_user(to, from, n) + +extern int __do_copy_to_user(void *to, const void *from, int n, + void **fault_addr, void **fault_catcher); + +static inline int copy_to_user(void *to, const void *from, int n) +{ + return(access_ok(VERIFY_WRITE, to, n) ? + __do_copy_to_user(to, from, n, + ¤t->thread.fault_addr, + ¤t->thread.fault_catcher) : n); +} + +#define __copy_to_user(to, from, n) copy_to_user(to, from, n) + +#define __get_user(x, ptr) \ +({ \ + const __typeof__(ptr) __private_ptr = ptr; \ + __typeof__(*(__private_ptr)) __private_val; \ + int __private_ret = -EFAULT; \ + (x) = 0; \ + if (__copy_from_user(&__private_val, (__private_ptr), \ + sizeof(*(__private_ptr))) == 0) {\ + (x) = (__typeof__(*(__private_ptr))) __private_val; \ + __private_ret = 0; \ + } \ + __private_ret; \ +}) + +#define get_user(x, ptr) \ +({ \ + const __typeof__((*ptr)) *private_ptr = (ptr); \ + (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \ + __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \ +}) + +#define __put_user(x, ptr) \ +({ \ + __typeof__(ptr) __private_ptr = ptr; \ + __typeof__(*(__private_ptr)) __private_val; \ + int __private_ret = -EFAULT; \ + __private_val = (__typeof__(*(__private_ptr))) (x); \ + if (__copy_to_user((__private_ptr), &__private_val, \ + sizeof(*(__private_ptr))) == 0) { \ + __private_ret = 0; \ + } \ + __private_ret; \ +}) + +#define put_user(x, ptr) \ +({ \ + __typeof__(*(ptr)) *private_ptr = (ptr); \ + (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \ + __put_user(x, private_ptr) : -EFAULT); \ +}) + +extern int __do_strncpy_from_user(char *dst, const char *src, size_t n, + void **fault_addr, void **fault_catcher); + +static inline int strncpy_from_user(char *dst, const char *src, int count) +{ + int n; + + if(!access_ok(VERIFY_READ, src, 1)) return(-EFAULT); + n = __do_strncpy_from_user(dst, src, count, + ¤t->thread.fault_addr, + ¤t->thread.fault_catcher); + if(n < 0) return(-EFAULT); + return(n); +} + +extern int __do_clear_user(void *mem, size_t len, void **fault_addr, + void **fault_catcher); + +static inline int __clear_user(void *mem, int len) +{ + return(__do_clear_user(mem, len, + ¤t->thread.fault_addr, + ¤t->thread.fault_catcher)); +} + +static inline int clear_user(void *mem, int len) +{ + return(access_ok(VERIFY_WRITE, mem, len) ? + __do_clear_user(mem, len, + ¤t->thread.fault_addr, + ¤t->thread.fault_catcher) : len); +} + +extern int __do_strnlen_user(const char *str, unsigned long n, + void **fault_addr, void **fault_catcher); + +static inline int strnlen_user(void *str, int len) +{ + return(__do_strnlen_user(str, len, + ¤t->thread.fault_addr, + ¤t->thread.fault_catcher)); +} + +#define strlen_user(str) strnlen_user(str, ~0UL >> 1) + +struct exception_table_entry +{ + unsigned long insn; + unsigned long fixup; +}; + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/unaligned.h b/include/asm-um/unaligned.h new file mode 100644 index 000000000000..1d2497c57274 --- /dev/null +++ b/include/asm-um/unaligned.h @@ -0,0 +1,6 @@ +#ifndef __UM_UNALIGNED_H +#define __UM_UNALIGNED_H + +#include "asm/arch/unaligned.h" + +#endif diff --git a/include/asm-um/unistd.h b/include/asm-um/unistd.h new file mode 100644 index 000000000000..6c5e913cbf9c --- /dev/null +++ b/include/asm-um/unistd.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef _UM_UNISTD_H_ +#define _UM_UNISTD_H_ + +#include "linux/resource.h" +#include "asm/uaccess.h" + +extern long sys_open(const char *filename, int flags, int mode); +extern long sys_dup(unsigned int fildes); +extern long sys_close(unsigned int fd); +extern int um_execve(const char *file, char *const argv[], char *const env[]); +extern long sys_setsid(void); +extern long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options); +extern long sys_wait4(pid_t pid,unsigned int *stat_addr, int options, + struct rusage *ru); +extern long sys_mount(char *dev_name, char *dir_name, char *type, + unsigned long flags, void *data); +extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, + struct timeval *tvp); +extern long sys_lseek(unsigned int fildes, unsigned long offset, int whence); +extern long sys_read(unsigned int fildes, char *buf, int len); +extern long sys_write(unsigned int fildes, char *buf, int len); + +#ifdef __KERNEL_SYSCALLS__ + +#define KERNEL_CALL(ret_t, sys, args...) \ + mm_segment_t fs = get_fs(); \ + ret_t ret; \ + set_fs(KERNEL_DS); \ + ret = sys(args); \ + set_fs(fs); \ + return ret; + +static inline long open(const char *pathname, int flags, int mode) +{ + KERNEL_CALL(int, sys_open, pathname, flags, mode) +} + +static inline long dup(unsigned int fd) +{ + KERNEL_CALL(int, sys_dup, fd); +} + +static inline long close(unsigned int fd) +{ + KERNEL_CALL(int, sys_close, fd); +} + +static inline int execve(const char *filename, char *const argv[], + char *const envp[]) +{ + KERNEL_CALL(int, um_execve, filename, argv, envp); +} + +static inline long waitpid(pid_t pid, unsigned int *status, int options) +{ + KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL) +} + +static inline pid_t wait(int *status) +{ + KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL) +} + +static inline pid_t setsid(void) +{ + KERNEL_CALL(pid_t, sys_setsid) +} + +static inline long lseek(unsigned int fd, off_t offset, unsigned int whence) +{ + KERNEL_CALL(long, sys_lseek, fd, offset, whence) +} + +static inline int read(unsigned int fd, char * buf, int len) +{ + KERNEL_CALL(int, sys_read, fd, buf, len) +} + +static inline int write(unsigned int fd, char * buf, int len) +{ + KERNEL_CALL(int, sys_write, fd, buf, len) +} + +#endif + +/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying + * arch's unistd.h for the system call numbers, and restore the old + * __KERNEL_SYSCALLS__. + */ + +#ifdef __KERNEL_SYSCALLS__ +#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__ +#endif + +#undef __KERNEL_SYSCALLS__ +#include "asm/arch/unistd.h" + +#ifdef __KERNEL_SYSCALLS__ +#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__ +#endif + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/include/asm-um/user.h b/include/asm-um/user.h new file mode 100644 index 000000000000..aae414ee1f5e --- /dev/null +++ b/include/asm-um/user.h @@ -0,0 +1,6 @@ +#ifndef __UM_USER_H +#define __UM_USER_H + +#include "asm/arch/user.h" + +#endif diff --git a/include/asm-um/vga.h b/include/asm-um/vga.h new file mode 100644 index 000000000000..903a592b00d0 --- /dev/null +++ b/include/asm-um/vga.h @@ -0,0 +1,6 @@ +#ifndef __UM_VGA_H +#define __UM_VGA_H + +#include "asm/arch/vga.h" + +#endif diff --git a/include/asm-x86_64/hdreg.h b/include/asm-x86_64/hdreg.h index 7de6fcf98f85..6ca37a9778de 100644 --- a/include/asm-x86_64/hdreg.h +++ b/include/asm-x86_64/hdreg.h @@ -7,6 +7,6 @@ #ifndef __ASMx86_64_HDREG_H #define __ASMx86_64_HDREG_H -typedef unsigned short ide_ioreg_t; +typedef unsigned long ide_ioreg_t; #endif /* __ASMx86_64_HDREG_H */ diff --git a/include/asm-x86_64/ide.h b/include/asm-x86_64/ide.h index b2ad635bdf94..f6620abade97 100644 --- a/include/asm-x86_64/ide.h +++ b/include/asm-x86_64/ide.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-i386/ide.h + * linux/include/asm-x86_64/ide.h * * Copyright (C) 1994-1996 Linus Torvalds & authors */ @@ -8,8 +8,8 @@ * This file contains the i386 architecture specific IDE code. */ -#ifndef __ASMi386_IDE_H -#define __ASMi386_IDE_H +#ifndef __ASMx86_64_IDE_H +#define __ASMx86_64_IDE_H #ifdef __KERNEL__ @@ -79,4 +79,4 @@ static __inline__ void ide_init_default_hwifs(void) #endif /* __KERNEL__ */ -#endif /* __ASMi386_IDE_H */ +#endif /* __ASMx86_64_IDE_H */ diff --git a/include/linux/bio.h b/include/linux/bio.h index fee72762ad8d..5fdfd8e8936c 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -215,17 +215,11 @@ extern inline char *bio_kmap_irq(struct bio *bio, unsigned long *flags) { unsigned long addr; - local_save_flags(*flags); - - /* - * could be low - */ - if (!PageHighMem(bio_page(bio))) - return bio_data(bio); - /* - * it's a highmem page + * might not be a highmem page, but the preempt/irq count + * balancing is a lot nicer this way */ + local_save_flags(*flags); local_irq_disable(); addr = (unsigned long) kmap_atomic(bio_page(bio), KM_BIO_SRC_IRQ); diff --git a/include/linux/ide.h b/include/linux/ide.h index 1843237adf4a..c9064eff5996 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -3,7 +3,7 @@ /* * linux/include/linux/ide.h * - * Copyright (C) 1994-1998 Linus Torvalds & authors + * Copyright (C) 1994-2002 Linus Torvalds & authors */ #include <linux/config.h> @@ -14,18 +14,14 @@ #include <linux/blkdev.h> #include <linux/proc_fs.h> #include <linux/devfs_fs_kernel.h> +#include <linux/interrupt.h> +#include <linux/bitops.h> #include <linux/bio.h> #include <asm/byteorder.h> #include <asm/system.h> #include <asm/hdreg.h> #include <asm/io.h> -#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT -# define __IDEDMA_TIMEOUT -#else /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ -# undef __IDEDMA_TIMEOUT -#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ - /* * This is the multiple IDE interface driver, as evolved from hd.c. * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15). @@ -42,7 +38,7 @@ * * REALLY_SLOW_IO can be defined in ide.c and ide-cd.c, if necessary */ -#undef REALLY_FAST_IO /* define if ide ports are perfect */ +#define REALLY_FAST_IO /* define if ide ports are perfect */ #define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */ #ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */ @@ -170,9 +166,6 @@ typedef unsigned char byte; /* used everywhere */ #define IDE_BCOUNTL_REG IDE_LCYL_REG #define IDE_BCOUNTH_REG IDE_HCYL_REG -#define GET_ERR() IN_BYTE(IDE_ERROR_REG) -#define GET_STAT() IN_BYTE(IDE_STATUS_REG) -#define GET_ALTSTAT() IN_BYTE(IDE_CONTROL_REG) #define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good)) #define BAD_R_STAT (BUSY_STAT | ERR_STAT) #define BAD_W_STAT (BAD_R_STAT | WRERR_STAT) @@ -180,6 +173,43 @@ typedef unsigned char byte; /* used everywhere */ #define DRIVE_READY (READY_STAT | SEEK_STAT) #define DATA_READY (DRQ_STAT) +#define BAD_CRC (ABRT_ERR | ICRC_ERR) + +#define SATA_NR_PORTS (3) /* 16 possible ?? */ + +#define SATA_STATUS_OFFSET (0) +#define SATA_STATUS_REG (HWIF(drive)->sata_scr[SATA_STATUS_OFFSET]) +#define SATA_ERROR_OFFSET (1) +#define SATA_ERROR_REG (HWIF(drive)->sata_scr[SATA_ERROR_OFFSET]) +#define SATA_CONTROL_OFFSET (2) +#define SATA_CONTROL_REG (HWIF(drive)->sata_scr[SATA_CONTROL_OFFSET]) + +#define SATA_MISC_OFFSET (0) +#define SATA_MISC_REG (HWIF(drive)->sata_misc[SATA_MISC_OFFSET]) +#define SATA_PHY_OFFSET (1) +#define SATA_PHY_REG (HWIF(drive)->sata_misc[SATA_PHY_OFFSET]) +#define SATA_IEN_OFFSET (2) +#define SATA_IEN_REG (HWIF(drive)->sata_misc[SATA_IEN_OFFSET]) + +/* + * Our Physical Region Descriptor (PRD) table should be large enough + * to handle the biggest I/O request we are likely to see. Since requests + * can have no more than 256 sectors, and since the typical blocksize is + * two or more sectors, we could get by with a limit of 128 entries here for + * the usual worst case. Most requests seem to include some contiguous blocks, + * further reducing the number of table entries required. + * + * The driver reverts to PIO mode for individual requests that exceed + * this limit (possible with 512 byte blocksizes, eg. MSDOS f/s), so handling + * 100% of all crazy scenarios here is not necessary. + * + * As it turns out though, we must allocate a full 4KB page for this, + * so the two PRD tables (ide0 & ide1) will each get half of that, + * allowing each to have about 256 entries (8 bytes each) from this. + */ +#define PRD_BYTES 8 +#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES)) + /* * sector count bits */ @@ -215,21 +245,12 @@ typedef unsigned char byte; /* used everywhere */ #define PARTN_BITS 6 /* number of minor dev bits for partitions */ #define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */ #define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */ -#define CASCADE_DRIVES 8 /* per interface; 8|2 assumed by lots of code */ #define SECTOR_SIZE 512 #define SECTOR_WORDS (SECTOR_SIZE / 4) /* number of 32bit words per sector */ #define IDE_LARGE_SEEK(b1,b2,t) (((b1) > (b2) + (t)) || ((b2) > (b1) + (t))) #define IDE_MIN(a,b) ((a)<(b) ? (a):(b)) #define IDE_MAX(a,b) ((a)>(b) ? (a):(b)) -#ifndef SPLIT_WORD -# define SPLIT_WORD(W,HB,LB) ((HB)=(W>>8), (LB)=(W-((W>>8)<<8))) -#endif -#ifndef MAKE_WORD -# define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB)) -#endif - - /* * Timeouts for various operations: */ @@ -244,39 +265,6 @@ typedef unsigned char byte; /* used everywhere */ #define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */ #define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */ -#define SELECT_DRIVE(hwif,drive) \ -{ \ - if (hwif->selectproc) \ - hwif->selectproc(drive); \ - OUT_BYTE((drive)->select.all, hwif->io_ports[IDE_SELECT_OFFSET]); \ -} - -#define SELECT_INTERRUPT(hwif,drive) \ -{ \ - if (hwif->intrproc) \ - hwif->intrproc(drive); \ - else \ - OUT_BYTE((drive)->ctl|2, hwif->io_ports[IDE_CONTROL_OFFSET]); \ -} - -#define SELECT_MASK(hwif,drive,mask) \ -{ \ - if (hwif->maskproc) \ - hwif->maskproc(drive,mask); \ -} - -#define SELECT_READ_WRITE(hwif,drive,func) \ -{ \ - if (hwif->rwproc) \ - hwif->rwproc(drive,func); \ -} - -#define QUIRK_LIST(hwif,drive) \ -{ \ - if (hwif->quirkproc) \ - (drive)->quirk_list = hwif->quirkproc(drive); \ -} - #define HOST(hwif,chipset) \ { \ return ((hwif)->chipset == chipset) ? 1 : 0; \ @@ -304,9 +292,34 @@ typedef enum { ide_unknown, ide_generic, ide_pci, ide_qd65xx, ide_umc8672, ide_ht6560b, ide_pdc4030, ide_rz1000, ide_trm290, ide_cmd646, ide_cy82c693, ide_4drives, - ide_pmac, ide_etrax100 + ide_pmac, ide_etrax100, ide_acorn } hwif_chipset_t; +typedef struct ide_io_ops_s { + /* insert io operations here! */ + void (*OUTB)(u8 addr, u32 port); + void (*OUTW)(u16 addr, u32 port); + void (*OUTL)(u32 addr, u32 port); + void (*OUTBP)(u8 addr, u32 port); + void (*OUTWP)(u16 addr, u32 port); + void (*OUTLP)(u32 addr, u32 port); + void (*OUTSW)(u32 port, void *addr, u32 count); + void (*OUTSWP)(u32 port, void *addr, u32 count); + void (*OUTSL)(u32 port, void *addr, u32 count); + void (*OUTSLP)(u32 port, void *addr, u32 count); + + u8 (*INB)(u32 port); + u16 (*INW)(u32 port); + u32 (*INL)(u32 port); + u8 (*INBP)(u32 port); + u16 (*INWP)(u32 port); + u32 (*INLP)(u32 port); + void (*INSW)(u32 port, void *addr, u32 count); + void (*INSWP)(u32 port, void *addr, u32 count); + void (*INSL)(u32 port, void *addr, u32 count); + void (*INSLP)(u32 port, void *addr, u32 count); +} ide_io_ops_t; + /* * Structure to hold all information about the location of this port */ @@ -317,6 +330,11 @@ typedef struct hw_regs_s { ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ void *priv; /* interface specific data */ hwif_chipset_t chipset; +#if 0 + ide_io_ops_t *iops; /* */ +#endif + sata_ioreg_t sata_scr[SATA_NR_PORTS]; + sata_ioreg_t sata_misc[SATA_NR_PORTS]; } hw_regs_t; /* @@ -333,10 +351,27 @@ void ide_setup_ports( hw_regs_t *hw, ide_ioreg_t ctrl, ide_ioreg_t intr, ide_ack_intr_t *ack_intr, +#if 0 + ide_io_ops_t *iops, +#endif int irq); #include <asm/ide.h> +/* Currently only m68k, apus and m8xx need it */ +#ifdef IDE_ARCH_ACK_INTR +extern int ide_irq_lock; +# define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1) +#else +# define ide_ack_intr(hwif) (1) +#endif + +/* Currently only Atari needs it */ +#ifndef IDE_ARCH_LOCK +# define ide_release_lock(lock) do {} while (0) +# define ide_get_lock(lock, hdlr, data) do {} while (0) +#endif /* IDE_ARCH_LOCK */ + /* * If the arch-dependant ide.h did not declare/define any OUT_BYTE * or IN_BYTE functions, we make some defaults here. @@ -346,20 +381,30 @@ void ide_setup_ports( hw_regs_t *hw, # ifdef REALLY_FAST_IO # define OUT_BYTE(b,p) outb((b),(p)) # define OUT_WORD(w,p) outw((w),(p)) +# define OUT_LONG(l,p) outl((l),(p)) # else # define OUT_BYTE(b,p) outb_p((b),(p)) # define OUT_WORD(w,p) outw_p((w),(p)) +# define OUT_LONG(l,p) outl_p((l),(p)) # endif +# define OUT_BYTE_P(b,p) outb_p((b),(p)) +# define OUT_WORD_P(w,p) outw_p((w),(p)) +# define OUT_LONG_P(l,p) outl_p((l),(p)) #endif #ifndef HAVE_ARCH_IN_BYTE # ifdef REALLY_FAST_IO -# define IN_BYTE(p) (byte)inb(p) -# define IN_WORD(p) (short)inw(p) +# define IN_BYTE(p) (u8) inb(p) +# define IN_WORD(p) (u16) inw(p) +# define IN_LONG(p) (u32) inl(p) # else -# define IN_BYTE(p) (byte)inb_p(p) -# define IN_WORD(p) (short)inw_p(p) +# define IN_BYTE(p) (u8) inb_p(p) +# define IN_WORD(p) (u16) inw_p(p) +# define IN_LONG(p) (u32) inl_p(p) # endif +# define IN_BYTE_P(p) (u8) inb_p(p) +# define IN_WORD_P(p) (u16) inw_p(p) +# define IN_LONG_P(p) (u32) inl_p(p) #endif /* @@ -373,201 +418,453 @@ void ide_setup_ports( hw_regs_t *hw, #define ide_tape 0x1 #define ide_floppy 0x0 +/* + * Special Driver Flags + * + * set_geometry : respecify drive geometry + * recalibrate : seek to cyl 0 + * set_multmode : set multmode count + * set_tune : tune interface for drive + * serviced : service command + * reserved : unused + */ typedef union { - unsigned all : 8; /* all of the bits together */ + unsigned all : 8; struct { #if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned set_geometry : 1; /* respecify drive geometry */ - unsigned recalibrate : 1; /* seek to cyl 0 */ - unsigned set_multmode : 1; /* set multmode count */ - unsigned set_tune : 1; /* tune interface for drive */ - unsigned serviced : 1; /* service command */ - unsigned reserved : 3; /* unused */ + unsigned set_geometry : 1; + unsigned recalibrate : 1; + unsigned set_multmode : 1; + unsigned set_tune : 1; + unsigned serviced : 1; + unsigned reserved : 3; #elif defined(__BIG_ENDIAN_BITFIELD) - unsigned reserved : 3; /* unused */ - unsigned serviced : 1; /* service command */ - unsigned set_tune : 1; /* tune interface for drive */ - unsigned set_multmode : 1; /* set multmode count */ - unsigned recalibrate : 1; /* seek to cyl 0 */ - unsigned set_geometry : 1; /* respecify drive geometry */ + unsigned reserved : 3; + unsigned serviced : 1; + unsigned set_tune : 1; + unsigned set_multmode : 1; + unsigned recalibrate : 1; + unsigned set_geometry : 1; #else #error "Please fix <asm/byteorder.h>" #endif } b; } special_t; +/* + * ATA DATA Register Special. + * ATA NSECTOR Count Register(). + * ATAPI Byte Count Register. + * Channel index ordering pairs. + */ +typedef union { + unsigned all :16; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned low :8; /* LSB */ + unsigned high :8; /* MSB */ +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned high :8; /* MSB */ + unsigned low :8; /* LSB */ +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} ata_nsector_t, ata_data_t, atapi_bcount_t, ata_index_t; + +/* + * ATA-IDE Error Register + * + * mark : Bad address mark + * tzero : Couldn't find track 0 + * abrt : Aborted Command + * mcr : Media Change Request + * id : ID field not found + * mce : Media Change Event + * ecc : Uncorrectable ECC error + * bdd : dual meaing + */ typedef union { - unsigned all : 8; /* all of the bits together */ + unsigned all :8; struct { #if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned head : 4; /* always zeros here */ - unsigned unit : 1; /* drive select number: 0/1 */ - unsigned bit5 : 1; /* always 1 */ - unsigned lba : 1; /* using LBA instead of CHS */ - unsigned bit7 : 1; /* always 1 */ + unsigned mark :1; + unsigned tzero :1; + unsigned abrt :1; + unsigned mcr :1; + unsigned id :1; + unsigned mce :1; + unsigned ecc :1; + unsigned bdd :1; #elif defined(__BIG_ENDIAN_BITFIELD) - unsigned bit7 : 1; /* always 1 */ - unsigned lba : 1; /* using LBA instead of CHS */ - unsigned bit5 : 1; /* always 1 */ - unsigned unit : 1; /* drive select number: 0/1 */ - unsigned head : 4; /* always zeros here */ + unsigned bdd :1; + unsigned ecc :1; + unsigned mce :1; + unsigned id :1; + unsigned mcr :1; + unsigned abrt :1; + unsigned tzero :1; + unsigned mark :1; #else #error "Please fix <asm/byteorder.h>" #endif } b; -} select_t; +} ata_error_t; +/* + * ATA-IDE Select Register, aka Device-Head + * + * head : always zeros here + * unit : drive select number: 0/1 + * bit5 : always 1 + * lba : using LBA instead of CHS + * bit7 : always 1 + */ typedef union { - unsigned all : 8; /* all of the bits together */ + unsigned all : 8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned head : 4; + unsigned unit : 1; + unsigned bit5 : 1; + unsigned lba : 1; + unsigned bit7 : 1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned bit7 : 1; + unsigned lba : 1; + unsigned bit5 : 1; + unsigned unit : 1; + unsigned head : 4; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} select_t, ata_select_t; + +/* + * The ATA-IDE Status Register. + * The ATAPI Status Register. + * + * check : Error occurred + * idx : Index Error + * corr : Correctable error occurred + * drq : Data is request by the device + * dsc : Disk Seek Complete : ata + * : Media access command finished : atapi + * df : Device Fault : ata + * : Reserved : atapi + * drdy : Ready, Command Mode Capable : ata + * : Ignored for ATAPI commands : atapi + * bsy : Disk is Busy + * : The device has access to the command block + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned check :1; + unsigned idx :1; + unsigned corr :1; + unsigned drq :1; + unsigned dsc :1; + unsigned df :1; + unsigned drdy :1; + unsigned bsy :1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned bsy :1; + unsigned drdy :1; + unsigned df :1; + unsigned dsc :1; + unsigned drq :1; + unsigned corr :1; + unsigned idx :1; + unsigned check :1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} ata_status_t, atapi_status_t; + +/* + * ATA-IDE Control Register + * + * bit0 : Should be set to zero + * nIEN : device INTRQ to host + * SRST : host soft reset bit + * bit3 : ATA-2 thingy, Should be set to 1 + * reserved456 : Reserved + * HOB : 48-bit address ordering, High Ordered Bit + */ +typedef union { + unsigned all : 8; struct { #if defined(__LITTLE_ENDIAN_BITFIELD) unsigned bit0 : 1; - unsigned nIEN : 1; /* device INTRQ to host */ - unsigned SRST : 1; /* host soft reset bit */ - unsigned bit3 : 1; /* ATA-2 thingy */ - unsigned reserved456 : 3; - unsigned HOB : 1; /* 48-bit address ordering */ + unsigned nIEN : 1; + unsigned SRST : 1; + unsigned bit3 : 1; + unsigned reserved456 : 3; + unsigned HOB : 1; #elif defined(__BIG_ENDIAN_BITFIELD) - unsigned HOB : 1; /* 48-bit address ordering */ + unsigned HOB : 1; unsigned reserved456 : 3; - unsigned bit3 : 1; /* ATA-2 thingy */ - unsigned SRST : 1; /* host soft reset bit */ - unsigned nIEN : 1; /* device INTRQ to host */ + unsigned bit3 : 1; + unsigned SRST : 1; + unsigned nIEN : 1; unsigned bit0 : 1; #else #error "Please fix <asm/byteorder.h>" #endif } b; -} control_t; +} ata_control_t; +/* + * ATAPI Feature Register + * + * dma : Using DMA or PIO + * reserved321 : Reserved + * reserved654 : Reserved (Tag Type) + * reserved7 : Reserved + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned dma :1; + unsigned reserved321 :3; + unsigned reserved654 :3; + unsigned reserved7 :1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned reserved7 :1; + unsigned reserved654 :3; + unsigned reserved321 :3; + unsigned dma :1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_feature_t; + +/* + * ATAPI Interrupt Reason Register. + * + * cod : Information transferred is command (1) or data (0) + * io : The device requests us to read (1) or write (0) + * reserved : Reserved + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned cod :1; + unsigned io :1; + unsigned reserved :6; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned reserved :6; + unsigned io :1; + unsigned cod :1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_ireason_t; + +/* + * The ATAPI error register. + * + * ili : Illegal Length Indication + * eom : End Of Media Detected + * abrt : Aborted command - As defined by ATA + * mcr : Media Change Requested - As defined by ATA + * sense_key : Sense key of the last failed packet command + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned ili :1; + unsigned eom :1; + unsigned abrt :1; + unsigned mcr :1; + unsigned sense_key :4; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned sense_key :4; + unsigned mcr :1; + unsigned abrt :1; + unsigned eom :1; + unsigned ili :1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_error_t; + +/* + * ATAPI floppy Drive Select Register + * + * sam_lun : Logical unit number + * reserved3 : Reserved + * drv : The responding drive will be drive 0 (0) or drive 1 (1) + * one5 : Should be set to 1 + * reserved6 : Reserved + * one7 : Should be set to 1 + */ +typedef union { + unsigned all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned sam_lun :3; + unsigned reserved3 :1; + unsigned drv :1; + unsigned one5 :1; + unsigned reserved6 :1; + unsigned one7 :1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned one7 :1; + unsigned reserved6 :1; + unsigned one5 :1; + unsigned drv :1; + unsigned reserved3 :1; + unsigned sam_lun :3; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_select_t; struct ide_driver_s; struct ide_settings_s; typedef struct ide_drive_s { - request_queue_t queue; /* request queue */ + char name[4]; /* drive name, such as "hda" */ + char driver_req[10]; /* requests specific driver */ + + request_queue_t queue; /* request queue */ + + struct request *rq; /* current request */ struct ide_drive_s *next; /* circular list of hwgroup drives */ + struct ide_driver_s *driver;/* (ide_driver_t *) */ + void *driver_data; /* extra driver data */ + struct hd_driveid *id; /* drive model identification info */ + struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ + struct ide_settings_s *settings;/* /proc/ide/ drive settings */ + devfs_handle_t de; /* directory for device */ + + struct hwif_s *hwif; /* actually (ide_hwif_t *) */ + unsigned long sleep; /* sleep until this time */ unsigned long service_start; /* time we started last request */ unsigned long service_time; /* service time of last request */ unsigned long timeout; /* max time to wait for irq */ + special_t special; /* special action flags */ - byte keep_settings; /* restore settings after drive reset */ - byte using_dma; /* disk is using dma for read/write */ - byte retry_pio; /* retrying dma capable host in pio */ - byte state; /* retry state */ - byte waiting_for_dma; /* dma currently in progress */ - byte unmask; /* flag: okay to unmask other irqs */ - byte slow; /* flag: slow data port */ - byte bswap; /* flag: byte swap data */ - byte dsc_overlap; /* flag: DSC overlap */ - byte nice1; /* flag: give potential excess bandwidth */ + select_t select; /* basic drive/head select reg value */ + + u8 keep_settings; /* restore settings after drive reset */ + u8 autodma; /* device can safely use dma on host */ + u8 using_dma; /* disk is using dma for read/write */ + u8 using_tcq; /* disk is using queueing */ + u8 retry_pio; /* retrying dma capable host in pio */ + u8 state; /* retry state */ + u8 waiting_for_dma; /* dma currently in progress */ + u8 unmask; /* okay to unmask other irqs */ + u8 slow; /* slow data port */ + u8 bswap; /* byte swap data */ + u8 dsc_overlap; /* DSC overlap */ + u8 nice1; /* give potential excess bandwidth */ + unsigned present : 1; /* drive is physically present */ unsigned noprobe : 1; /* from: hdx=noprobe */ unsigned removable : 1; /* 1 if need to do check_media_change */ + unsigned is_flash : 1; /* 1 if probed as flash */ unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ unsigned no_unmask : 1; /* disallow setting unmask bit */ unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ - unsigned nobios : 1; /* flag: do not probe bios for drive */ - unsigned atapi_overlap : 1; /* flag: ATAPI overlap (not supported) */ - unsigned nice0 : 1; /* flag: give obvious excess bandwidth */ - unsigned nice2 : 1; /* flag: give a share in our own bandwidth */ - unsigned doorlocking : 1; /* flag: for removable only: door lock/unlock works */ + unsigned nobios : 1; /* do not probe bios for drive */ + unsigned atapi_overlap : 1; /* ATAPI overlap (not supported) */ + unsigned nice0 : 1; /* give obvious excess bandwidth */ + unsigned nice2 : 1; /* give a share in our own bandwidth */ + unsigned doorlocking : 1; /* for removable only: door lock/unlock works */ unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */ unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */ unsigned ata_flash : 1; /* 1=present, 0=default */ - unsigned addressing; /* : 3; + unsigned addressing; /* : 3; * 0=28-bit * 1=48-bit * 2=48-bit doing 28-bit * 3=64-bit */ - byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ - byte media; /* disk, cdrom, tape, floppy, ... */ - select_t select; /* basic drive/head select reg value */ - byte ctl; /* "normal" value for IDE_CONTROL_REG */ - byte ready_stat; /* min status value for drive ready */ - byte mult_count; /* current multiple sector setting */ - byte mult_req; /* requested multiple sector setting */ - byte tune_req; /* requested drive tuning setting */ - byte io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ - byte bad_wstat; /* used for ignoring WRERR_STAT */ - byte nowerr; /* used for ignoring WRERR_STAT */ - byte sect0; /* offset of first sector for DM6:DDO */ - unsigned int usage; /* current "open()" count for drive */ - byte head; /* "real" number of heads */ - byte sect; /* "real" sectors per track */ - byte bios_head; /* BIOS/fdisk/LILO number of heads */ - byte bios_sect; /* BIOS/fdisk/LILO sectors per track */ + + u8 scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ + u8 quirk_list; /* considered quirky, set for a specific host */ + u8 suspend_reset; /* drive suspend mode flag, soft-reset recovers */ + u8 init_speed; /* transfer rate set at boot */ + u8 current_speed; /* current transfer rate set */ + u8 dn; /* now wide spread use */ + u8 wcache; /* status of write cache */ + u8 acoustic; /* acoustic management */ + u8 media; /* disk, cdrom, tape, floppy, ... */ + u8 ctl; /* "normal" value for IDE_CONTROL_REG */ + u8 ready_stat; /* min status value for drive ready */ + u8 mult_count; /* current multiple sector setting */ + u8 mult_req; /* requested multiple sector setting */ + u8 tune_req; /* requested drive tuning setting */ + u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ + u8 bad_wstat; /* used for ignoring WRERR_STAT */ + u8 nowerr; /* used for ignoring WRERR_STAT */ + u8 sect0; /* offset of first sector for DM6:DDO */ + u8 head; /* "real" number of heads */ + u8 sect; /* "real" sectors per track */ + u8 bios_head; /* BIOS/fdisk/LILO number of heads */ + u8 bios_sect; /* BIOS/fdisk/LILO sectors per track */ + unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ unsigned int cyl; /* "real" number of cyls */ - unsigned long capacity; /* total number of sectors */ - unsigned long long capacity48; /* total number of sectors */ - unsigned int drive_data; /* for use by tuneproc/selectproc as needed */ - struct hwif_s *hwif; /* actually (ide_hwif_t *) */ - struct hd_driveid *id; /* drive model identification info */ - char name[4]; /* drive name, such as "hda" */ - struct ide_driver_s *driver; /* (ide_driver_t *) */ - void *driver_data; /* extra driver data */ - devfs_handle_t de; /* directory for device */ - struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ - struct ide_settings_s *settings; /* /proc/ide/ drive settings */ - char driver_req[10]; /* requests specific driver */ + unsigned int drive_data; /* use by tuneproc/selectproc */ + unsigned int usage; /* current "open()" count for drive */ + unsigned int failures; /* current failure count */ + unsigned int max_failures; /* maximum allowed failure count */ + + u32 capacity; /* total number of sectors */ + u64 capacity48; /* total number of sectors */ + int last_lun; /* last logical unit */ int forced_lun; /* if hdxlun was given at boot */ int lun; /* logical unit */ int crc_count; /* crc counter to reduce drive speed */ - byte quirk_list; /* drive is considered quirky if set for a specific host */ - byte suspend_reset; /* drive suspend mode flag, soft-reset recovers */ - byte init_speed; /* transfer rate set at boot */ - byte current_speed; /* current transfer rate set */ - byte dn; /* now wide spread use */ - byte wcache; /* status of write cache */ - byte acoustic; /* acoustic management */ - unsigned int failures; /* current failure count */ - unsigned int max_failures; /* maximum allowed failure count */ struct list_head list; struct gendisk *disk; } ide_drive_t; -/* - * An ide_dmaproc_t() initiates/aborts DMA read/write operations on a drive. - * - * The caller is assumed to have selected the drive and programmed the drive's - * sector address using CHS or LBA. All that remains is to prepare for DMA - * and then issue the actual read/write DMA/PIO command to the drive. - * - * Returns 0 if all went well. - * Returns 1 if DMA read/write could not be started, in which case the caller - * should either try again later, or revert to PIO for the current request. - */ -typedef enum { ide_dma_read, ide_dma_write, ide_dma_begin, - ide_dma_end, ide_dma_check, ide_dma_on, - ide_dma_off, ide_dma_off_quietly, ide_dma_test_irq, - ide_dma_host_on, ide_dma_host_off, - ide_dma_bad_drive, ide_dma_good_drive, - ide_dma_verbose, ide_dma_retune, - ide_dma_lostirq, ide_dma_timeout -} ide_dma_action_t; - -typedef int (ide_dmaproc_t)(ide_dma_action_t, ide_drive_t *); - -/* - * An ide_ideproc_t() performs CPU-polled transfers to/from a drive. - * Arguments are: the drive, the buffer pointer, and the length (in bytes or - * words depending on if it's an IDE or ATAPI call). - * - * If it is not defined for a controller, standard-code is used from ide.c. - * - * Controllers which are not memory-mapped in the standard way need to - * override that mechanism using this function to work. - * - */ -typedef enum { ideproc_ide_input_data, ideproc_ide_output_data, - ideproc_atapi_input_bytes, ideproc_atapi_output_bytes -} ide_ide_action_t; - -typedef void (ide_ideproc_t)(ide_ide_action_t, ide_drive_t *, void *, unsigned int); +typedef struct ide_pio_ops_s { + void (*ata_input_data)(ide_drive_t *, void *, u32); + void (*ata_output_data)(ide_drive_t *, void *, u32); + + void (*atapi_input_bytes)(ide_drive_t *, void *, u32); + void (*atapi_output_bytes)(ide_drive_t *, void *, u32); +} ide_pio_ops_t; + +typedef struct ide_dma_ops_s { + /* insert dma operations here! */ + int (*ide_dma_read)(ide_drive_t *drive); + int (*ide_dma_write)(ide_drive_t *drive); + int (*ide_dma_begin)(ide_drive_t *drive); + int (*ide_dma_end)(ide_drive_t *drive); + int (*ide_dma_check)(ide_drive_t *drive); + int (*ide_dma_on)(ide_drive_t *drive); + int (*ide_dma_off)(ide_drive_t *drive); + int (*ide_dma_off_quietly)(ide_drive_t *drive); + int (*ide_dma_test_irq)(ide_drive_t *drive); + int (*ide_dma_host_on)(ide_drive_t *drive); + int (*ide_dma_host_off)(ide_drive_t *drive); + int (*ide_dma_bad_drive)(ide_drive_t *drive); + int (*ide_dma_good_drive)(ide_drive_t *drive); + int (*ide_dma_count)(ide_drive_t *drive); + int (*ide_dma_verbose)(ide_drive_t *drive); + int (*ide_dma_retune)(ide_drive_t *drive); + int (*ide_dma_lostirq)(ide_drive_t *drive); + int (*ide_dma_timeout)(ide_drive_t *drive); +} ide_dma_ops_t; /* * mapping stuff, prepare for highmem... @@ -597,171 +894,188 @@ extern inline void *ide_map_buffer(struct request *rq, unsigned long *flags) return rq->buffer + task_rq_offset(rq); } -extern inline void ide_unmap_buffer(char *buffer, unsigned long *flags) +extern inline void ide_unmap_buffer(struct request *rq, char *buffer, unsigned long *flags) { - bio_kunmap_irq(buffer, flags); -} - -/* - * A Verbose noise maker for debugging on the attempted transfer rates. - */ -extern inline char *ide_xfer_verbose (byte xfer_rate) -{ - switch(xfer_rate) { - case XFER_UDMA_7: return("UDMA 7"); - case XFER_UDMA_6: return("UDMA 6"); - case XFER_UDMA_5: return("UDMA 5"); - case XFER_UDMA_4: return("UDMA 4"); - case XFER_UDMA_3: return("UDMA 3"); - case XFER_UDMA_2: return("UDMA 2"); - case XFER_UDMA_1: return("UDMA 1"); - case XFER_UDMA_0: return("UDMA 0"); - case XFER_MW_DMA_2: return("MW DMA 2"); - case XFER_MW_DMA_1: return("MW DMA 1"); - case XFER_MW_DMA_0: return("MW DMA 0"); - case XFER_SW_DMA_2: return("SW DMA 2"); - case XFER_SW_DMA_1: return("SW DMA 1"); - case XFER_SW_DMA_0: return("SW DMA 0"); - case XFER_PIO_4: return("PIO 4"); - case XFER_PIO_3: return("PIO 3"); - case XFER_PIO_2: return("PIO 2"); - case XFER_PIO_1: return("PIO 1"); - case XFER_PIO_0: return("PIO 0"); - case XFER_PIO_SLOW: return("PIO SLOW"); - default: return("XFER ERROR"); - } -} - -/* - * A Verbose noise maker for debugging on the attempted dmaing calls. - */ -extern inline char *ide_dmafunc_verbose (ide_dma_action_t dmafunc) -{ - switch (dmafunc) { - case ide_dma_read: return("ide_dma_read"); - case ide_dma_write: return("ide_dma_write"); - case ide_dma_begin: return("ide_dma_begin"); - case ide_dma_end: return("ide_dma_end:"); - case ide_dma_check: return("ide_dma_check"); - case ide_dma_on: return("ide_dma_on"); - case ide_dma_off: return("ide_dma_off"); - case ide_dma_off_quietly: return("ide_dma_off_quietly"); - case ide_dma_test_irq: return("ide_dma_test_irq"); - case ide_dma_host_on: return("ide_dma_host_on"); - case ide_dma_host_off: return("ide_dma_host_off"); - case ide_dma_bad_drive: return("ide_dma_bad_drive"); - case ide_dma_good_drive: return("ide_dma_good_drive"); - case ide_dma_verbose: return("ide_dma_verbose"); - case ide_dma_retune: return("ide_dma_retune"); - case ide_dma_lostirq: return("ide_dma_lostirq"); - case ide_dma_timeout: return("ide_dma_timeout"); - default: return("unknown"); - } + if (rq->bio) + bio_kunmap_irq(buffer, flags); } -/* - * An ide_tuneproc_t() is used to set the speed of an IDE interface - * to a particular PIO mode. The "byte" parameter is used - * to select the PIO mode by number (0,1,2,3,4,5), and a value of 255 - * indicates that the interface driver should "auto-tune" the PIO mode - * according to the drive capabilities in drive->id; - * - * Not all interface types support tuning, and not all of those - * support all possible PIO settings. They may silently ignore - * or round values as they see fit. - */ -typedef void (ide_tuneproc_t) (ide_drive_t *, byte); -typedef int (ide_speedproc_t) (ide_drive_t *, byte); - -/* - * This is used to provide support for strange interfaces - */ -typedef void (ide_selectproc_t) (ide_drive_t *); -typedef void (ide_resetproc_t) (ide_drive_t *); -typedef int (ide_quirkproc_t) (ide_drive_t *); -typedef void (ide_intrproc_t) (ide_drive_t *); -typedef void (ide_maskproc_t) (ide_drive_t *, int); -typedef void (ide_rw_proc_t) (ide_drive_t *, ide_dma_action_t); - -/* - * ide soft-power support - */ -typedef int (ide_busproc_t) (ide_drive_t *, int); - #define IDE_CHIPSET_PCI_MASK \ ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx)) #define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1) #ifdef CONFIG_BLK_DEV_IDEPCI -typedef struct ide_pci_devid_s { - unsigned short vid; - unsigned short did; -} ide_pci_devid_t; - -#define IDE_PCI_DEVID_NULL ((ide_pci_devid_t){0,0}) -#define IDE_PCI_DEVID_EQ(a,b) (a.vid == b.vid && a.did == b.did) +struct ide_pci_device_s; #endif /* CONFIG_BLK_DEV_IDEPCI */ typedef struct hwif_s { - struct hwif_s *next; /* for linked-list in ide_hwgroup_t */ + struct hwif_s *next; /* for linked-list in ide_hwgroup_t */ + struct hwif_s *mate; /* other hwif from same PCI chip */ struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */ - ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */ -/* - * FIXME!! need a generic register set :-/ PPC guys ideas?? - * - * ide_mmioreg_t mm_ports[IDE_NR_PORTS]; "task file registers" - * - */ + struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ + + char name[6]; /* name of interface, eg. "ide0" */ + + /* task file registers for pata and sata */ + ide_ioreg_t io_ports[IDE_NR_PORTS]; + sata_ioreg_t sata_scr[SATA_NR_PORTS]; + sata_ioreg_t sata_misc[SATA_NR_PORTS]; + hw_regs_t hw; /* Hardware info */ ide_drive_t drives[MAX_DRIVES]; /* drive info */ - int addressing; /* hosts addressing */ - void (*tuneproc)(ide_drive_t *, byte); /* routine to tune PIO mode for drives */ - int (*speedproc)(ide_drive_t *, byte); /* routine to retune DMA modes for drives */ - void (*selectproc)(ide_drive_t *); /* tweaks hardware to select drive */ - void (*resetproc)(ide_drive_t *); /* routine to reset controller after a disk reset */ - void (*intrproc)(ide_drive_t *); /* special interrupt handling for shared pci interrupts */ - void (*maskproc)(ide_drive_t *, int); /* special host masking for drive selection */ - int (*quirkproc)(ide_drive_t *); /* check host's drive quirk list */ - void (*rwproc)(ide_drive_t *, ide_dma_action_t); /* adjust timing based upon rq->cmd direction */ - void (*ideproc)(ide_ide_action_t, ide_drive_t *, void *, unsigned int); /* CPU-polled transfer routine */ - int (*dmaproc)(ide_dma_action_t, ide_drive_t *); /* dma read/write/abort routine */ - int (*busproc)(ide_drive_t *, int); /* driver soft-power interface */ - unsigned int *dmatable_cpu; /* dma physical region descriptor table (cpu view) */ - dma_addr_t dmatable_dma; /* dma physical region descriptor table (dma view) */ - struct scatterlist *sg_table; /* Scatter-gather list used to build the above */ + + u8 major; /* our major number */ + u8 index; /* 0 for ide0; 1 for ide1; ... */ + u8 channel; /* for dual-port chips: 0=primary, 1=secondary */ + u8 straight8; /* Alan's straight 8 check */ + u8 bus_state; /* power state of the IDE bus */ + + u8 atapi_dma; /* host supports atapi_dma */ + u8 ultra_mask; + u8 mwdma_mask; + u8 swdma_mask; + + hwif_chipset_t chipset; /* sub-module for tuning.. */ + +#ifdef CONFIG_BLK_DEV_IDEPCI + struct pci_dev *pci_dev; /* for pci chipsets */ + struct ide_pci_device_s *cds; /* chipset device struct */ +#endif /* CONFIG_BLK_DEV_IDEPCI */ + +#if 0 + ide_hwif_ops_t *hwifops; +#else + /* routine is for HBA specific IDENTITY operations */ + int (*identify)(ide_drive_t *); + /* routine to tune PIO mode for drives */ + void (*tuneproc)(ide_drive_t *, u8); + /* routine to retune DMA modes for drives */ + int (*speedproc)(ide_drive_t *, u8); + /* tweaks hardware to select drive */ + void (*selectproc)(ide_drive_t *); + /* chipset polling based on hba specifics */ + int (*reset_poll)(ide_drive_t *); + /* chipset specific changes to default for device-hba resets */ + void (*pre_reset)(ide_drive_t *); + /* routine to reset controller after a disk reset */ + void (*resetproc)(ide_drive_t *); + /* special interrupt handling for shared pci interrupts */ + void (*intrproc)(ide_drive_t *); + /* special host masking for drive selection */ + void (*maskproc)(ide_drive_t *, int); + /* check host's drive quirk list */ + int (*quirkproc)(ide_drive_t *); + /* driver soft-power interface */ + int (*busproc)(ide_drive_t *, int); +// /* host rate limiter */ +// u8 (*ratemask)(ide_drive_t *); +// /* device rate limiter */ +// u8 (*ratefilter)(ide_drive_t *, u8); +#endif + +#if 0 + ide_pio_ops_t *pioops; +#else + void (*ata_input_data)(ide_drive_t *, void *, u32); + void (*ata_output_data)(ide_drive_t *, void *, u32); + + void (*atapi_input_bytes)(ide_drive_t *, void *, u32); + void (*atapi_output_bytes)(ide_drive_t *, void *, u32); +#endif + +#if 0 + ide_dma_ops_t *dmaops; +#else + int (*ide_dma_read)(ide_drive_t *drive); + int (*ide_dma_write)(ide_drive_t *drive); + int (*ide_dma_begin)(ide_drive_t *drive); + int (*ide_dma_end)(ide_drive_t *drive); + int (*ide_dma_check)(ide_drive_t *drive); + int (*ide_dma_on)(ide_drive_t *drive); + int (*ide_dma_off)(ide_drive_t *drive); + int (*ide_dma_off_quietly)(ide_drive_t *drive); + int (*ide_dma_test_irq)(ide_drive_t *drive); + int (*ide_dma_host_on)(ide_drive_t *drive); + int (*ide_dma_host_off)(ide_drive_t *drive); + int (*ide_dma_bad_drive)(ide_drive_t *drive); + int (*ide_dma_good_drive)(ide_drive_t *drive); + int (*ide_dma_count)(ide_drive_t *drive); + int (*ide_dma_verbose)(ide_drive_t *drive); + int (*ide_dma_retune)(ide_drive_t *drive); + int (*ide_dma_lostirq)(ide_drive_t *drive); + int (*ide_dma_timeout)(ide_drive_t *drive); +#endif + +#if 0 + ide_io_ops_t *iops; +#else + void (*OUTB)(u8 addr, u32 port); + void (*OUTW)(u16 addr, u32 port); + void (*OUTL)(u32 addr, u32 port); + void (*OUTBP)(u8 addr, u32 port); + void (*OUTWP)(u16 addr, u32 port); + void (*OUTLP)(u32 addr, u32 port); + void (*OUTSW)(u32 port, void *addr, u32 count); + void (*OUTSWP)(u32 port, void *addr, u32 count); + void (*OUTSL)(u32 port, void *addr, u32 count); + void (*OUTSLP)(u32 port, void *addr, u32 count); + + u8 (*INB)(u32 port); + u16 (*INW)(u32 port); + u32 (*INL)(u32 port); + u8 (*INBP)(u32 port); + u16 (*INWP)(u32 port); + u32 (*INLP)(u32 port); + void (*INSW)(u32 port, void *addr, u32 count); + void (*INSWP)(u32 port, void *addr, u32 count); + void (*INSL)(u32 port, void *addr, u32 count); + void (*INSLP)(u32 port, void *addr, u32 count); +#endif + + /* dma physical region descriptor table (cpu view) */ + unsigned int *dmatable_cpu; + /* dma physical region descriptor table (dma view) */ + dma_addr_t dmatable_dma; + /* Scatter-gather list used to build the above */ + struct scatterlist *sg_table; int sg_nents; /* Current number of entries in it */ int sg_dma_direction; /* dma transfer direction */ int sg_dma_active; /* is it in use */ - struct hwif_s *mate; /* other hwif from same PCI chip */ + + int mmio; /* hosts iomio (0), mmio (1) or custom (2) select */ + int rqsize; /* max sectors per request */ + int addressing; /* hosts addressing */ + int irq; /* our irq number */ + int initializing; /* set while initializing self */ + + unsigned long dma_master; /* reference base addr dmabase */ unsigned long dma_base; /* base addr for dma ports */ + unsigned long dma_command; /* dma command register */ + unsigned long dma_vendor1; /* dma vendor 1 register */ + unsigned long dma_status; /* dma status register */ + unsigned long dma_vendor3; /* dma vendor 3 register */ + unsigned long dma_prdtable; /* actual prd table address */ + unsigned long dma_base2; /* extended base addr for dma ports */ + unsigned dma_extra; /* extra addr for dma ports */ unsigned long config_data; /* for use by chipset-specific code */ unsigned long select_data; /* for use by chipset-specific code */ - struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ - int irq; /* our irq number */ - byte major; /* our major number */ - char name[6]; /* name of interface, eg. "ide0" */ - byte index; /* 0 for ide0; 1 for ide1; ... */ - hwif_chipset_t chipset; /* sub-module for tuning.. */ +#if (DISK_RECOVERY_TIME > 0) + unsigned long last_time; /* time when previous rq was done */ +#endif + + unsigned noprobe : 1; /* don't probe for this interface */ unsigned present : 1; /* this interface exists */ - unsigned serialized : 1; /* serialized operation with mate hwif */ + unsigned serialized : 1; /* serialized all channel operation */ unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned reset : 1; /* reset after probe */ - unsigned autodma : 1; /* automatically try to enable DMA at boot */ + unsigned autodma : 1; /* auto-attempt using DMA at boot */ unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ - unsigned no_highmem : 1; /* always use high i/o bounce */ - byte channel; /* for dual-port chips: 0=primary, 1=secondary */ -#ifdef CONFIG_BLK_DEV_IDEPCI - struct pci_dev *pci_dev; /* for pci chipsets */ - ide_pci_devid_t pci_devid; /* for pci chipsets: {VID,DID} */ -#endif /* CONFIG_BLK_DEV_IDEPCI */ -#if (DISK_RECOVERY_TIME > 0) - unsigned long last_time; /* time when previous rq was done */ -#endif - byte straight8; /* Alan's straight 8 check */ + unsigned highmem : 1; /* can do full 32-bit dma */ + unsigned no_dsc : 1; /* 0 default, 1 dsc_overlap disabled */ + void *hwif_data; /* extra hwif data */ - byte bus_state; /* power state of the IDE bus */ } ide_hwif_t; /* @@ -769,7 +1083,7 @@ typedef struct hwif_s { */ typedef enum { ide_stopped, /* no drive operation was started */ - ide_started /* a drive operation was started, and a handler was set */ + ide_started /* a drive operation was started, handler was set */ } ide_startstop_t; /* @@ -778,26 +1092,41 @@ typedef enum { typedef ide_startstop_t (ide_pre_handler_t)(ide_drive_t *, struct request *); typedef ide_startstop_t (ide_handler_t)(ide_drive_t *); typedef ide_startstop_t (ide_post_handler_t)(ide_drive_t *); - -/* - * when ide_timer_expiry fires, invoke a handler of this type - * to decide what to do. - */ typedef int (ide_expiry_t)(ide_drive_t *); typedef struct hwgroup_s { - ide_handler_t *handler;/* irq handler, if active */ - ide_handler_t *handler_save;/* irq handler, if active */ - volatile int busy; /* BOOL: protects all fields below */ - int sleeping; /* BOOL: wake us up on timer expiry */ - ide_drive_t *drive; /* current drive */ - ide_hwif_t *hwif; /* ptr to current hwif in linked-list */ - struct request *rq; /* current request */ - struct timer_list timer; /* failsafe timer */ - struct request wrq; /* local copy of current write rq */ - unsigned long poll_timeout; /* timeout value during long polls */ - ide_expiry_t *expiry; /* queried upon timeouts */ - int pio_clock; /* ide_system_bus_speed */ + /* irq handler, if active */ + ide_startstop_t (*handler)(ide_drive_t *); + /* irq handler, suspended if active */ + ide_startstop_t (*handler_save)(ide_drive_t *); + /* BOOL: protects all fields below */ + volatile int busy; + /* BOOL: wake us up on timer expiry */ + int sleeping; + /* current drive */ + ide_drive_t *drive; + /* ptr to current hwif in linked-list */ + ide_hwif_t *hwif; + +#ifdef CONFIG_BLK_DEV_IDEPCI + /* for pci chipsets */ + struct pci_dev *pci_dev; + /* chipset device struct */ + struct ide_pci_device_s *cds; +#endif /* CONFIG_BLK_DEV_IDEPCI */ + + /* current request */ + struct request *rq; + /* failsafe timer */ + struct timer_list timer; + /* local copy of current write rq */ + struct request wrq; + /* timeout value during long polls */ + unsigned long poll_timeout; + /* queried upon timeouts */ + int (*expiry)(ide_drive_t *); + /* ide_system_bus_speed */ + int pio_clock; } ide_hwgroup_t; /* structure attached to the request for IDE_TASK_CMDS */ @@ -850,14 +1179,14 @@ typedef struct { } ide_proc_entry_t; #ifdef CONFIG_PROC_FS -void proc_ide_create(void); -void proc_ide_destroy(void); -void recreate_proc_ide_device(ide_hwif_t *, ide_drive_t *); -void destroy_proc_ide_device(ide_hwif_t *, ide_drive_t *); -void destroy_proc_ide_drives(ide_hwif_t *); -void create_proc_ide_interfaces(void); -void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data); -void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p); +extern void proc_ide_create(void); +extern void proc_ide_destroy(void); +extern void recreate_proc_ide_device(ide_hwif_t *, ide_drive_t *); +extern void destroy_proc_ide_device(ide_hwif_t *, ide_drive_t *); +extern void destroy_proc_ide_drives(ide_hwif_t *); +extern void create_proc_ide_interfaces(void); +extern void ide_add_proc_entries(struct proc_dir_entry *, ide_proc_entry_t *, void *); +extern void ide_remove_proc_entries(struct proc_dir_entry *, ide_proc_entry_t *); read_proc_t proc_ide_read_capacity; read_proc_t proc_ide_read_geometry; @@ -889,7 +1218,7 @@ typedef struct ide_driver_s { struct module *owner; const char *name; const char *version; - byte media; + u8 media; unsigned busy : 1; unsigned supports_dma : 1; unsigned supports_dsc_overlap : 1; @@ -899,9 +1228,9 @@ typedef struct ide_driver_s { int (*resume)(ide_drive_t *); int (*flushcache)(ide_drive_t *); ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long); - int (*end_request)(ide_drive_t *, int); - byte (*sense)(ide_drive_t *, const char *, byte); - ide_startstop_t (*error)(ide_drive_t *, const char *, byte); + int (*end_request)(ide_drive_t *, int, int); + u8 (*sense)(ide_drive_t *, const char *, u8); + ide_startstop_t (*error)(ide_drive_t *, const char *, u8); int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); int (*open)(struct inode *, struct file *, ide_drive_t *); void (*release)(struct inode *, struct file *, ide_drive_t *); @@ -910,8 +1239,8 @@ typedef struct ide_driver_s { void (*pre_reset)(ide_drive_t *); unsigned long (*capacity)(ide_drive_t *); ide_startstop_t (*special)(ide_drive_t *); - ide_proc_entry_t *proc; - int (*reinit)(ide_drive_t *); + ide_proc_entry_t *proc; + int (*attach)(ide_drive_t *); void (*ata_prebuilder)(ide_drive_t *); void (*atapi_prebuilder)(ide_drive_t *); struct list_head drives; @@ -935,6 +1264,13 @@ typedef struct ide_module_s { struct ide_module_s *next; } ide_module_t; +typedef struct ide_devices_s { + char name[4]; /* hdX */ + unsigned attached : 1; /* native */ + unsigned alttached : 1; /* alternate */ + struct ide_devices_s *next; +} ide_devices_t; + /* * ide_hwifs[] is the master data structure used to keep track * of just about everything in ide.c. Whenever possible, routines @@ -945,7 +1281,15 @@ typedef struct ide_module_s { */ #ifndef _IDE_C extern ide_hwif_t ide_hwifs[]; /* master data repository */ +extern ide_module_t *ide_chipsets; extern ide_module_t *ide_probe; + +extern ide_devices_t *idedisk; +extern ide_devices_t *idecd; +extern ide_devices_t *idefloppy; +extern ide_devices_t *idetape; +extern ide_devices_t *idescsi; + #endif extern int noautodma; @@ -957,38 +1301,47 @@ extern int noautodma; #define DEVICE_NR(device) (minor(device) >> PARTN_BITS) #include <linux/blk.h> -int ide_end_request (ide_drive_t *drive, int uptodate); +extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); /* * This is used on exit from the driver, to designate the next irq handler * and also to start the safety timer. */ -void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry); +extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry); /* * Error reporting, in human readable form (luxurious, but a memory hog). + * + * (drive, msg, status) */ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat); /* * ide_error() takes action based on the error returned by the controller. * The caller should return immediately after invoking this. + * + * (drive, msg, status) */ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat); /* * Issue a simple drive command * The drive must be selected beforehand. + * + * (drive, command, nsector, handler) */ -void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler); +extern void ide_cmd(ide_drive_t *, u8, u8, ide_handler_t *); +extern void ide_fix_driveid(struct hd_driveid *); /* * ide_fixstring() cleans up and (optionally) byte-swaps a text string, * removing leading/trailing blanks and compressing internal blanks. * It is primarily used to tidy up the model name/number fields as * returned by the WIN_[P]IDENTIFY commands. + * + * (s, bytecount, byteswap) */ -void ide_fixstring (byte *s, const int bytecount, const int byteswap); +extern void ide_fixstring(u8 *, const int, const int); /* * This routine busy-waits for the drive status to be not "busy". @@ -997,43 +1350,44 @@ void ide_fixstring (byte *s, const int bytecount, const int byteswap); * cases return 1 after doing "*startstop = ide_error()", and the * caller should return the updated value of "startstop" in this case. * "startstop" is unchanged when the function returns 0; + * (startstop, drive, good, bad, timeout) */ -int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout); +extern int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); /* * This routine is called from the partition-table code in genhd.c * to "convert" a drive to a logical geometry with fewer than 1024 cyls. */ -int ide_xlate_1024 (kdev_t, int, int, const char *); +extern int ide_xlate_1024 (kdev_t, int, int, const char *); /* * Convert kdev_t structure into ide_drive_t * one. */ -ide_drive_t *get_info_ptr (kdev_t i_rdev); +extern ide_drive_t *get_info_ptr (kdev_t i_rdev); /* * Return the current idea about the total capacity of this drive. */ -unsigned long current_capacity (ide_drive_t *drive); +extern unsigned long current_capacity (ide_drive_t *drive); -void ide_revalidate_drive (ide_drive_t *drive); +extern void ide_revalidate_drive (ide_drive_t *drive); /* * Start a reset operation for an IDE interface. * The caller should return immediately after invoking this. */ -ide_startstop_t ide_do_reset (ide_drive_t *); +extern ide_startstop_t ide_do_reset (ide_drive_t *); /* * Re-Start an operation for an IDE interface. * The caller should return immediately after invoking this. */ -int restart_request (ide_drive_t *, struct request *); +extern int restart_request (ide_drive_t *, struct request *); /* * This function is intended to be used prior to invoking ide_do_drive_cmd(). */ -void ide_init_drive_cmd (struct request *rq); +extern void ide_init_drive_cmd (struct request *rq); /* * "action" parameter type for ide_do_drive_cmd() below. @@ -1070,23 +1424,35 @@ typedef enum { * for the new rq to be completed. This is again intended for careful * use by the ATAPI tape/cdrom driver code. */ -int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action); +extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t); /* * Clean up after success/failure of an explicit drive cmd. * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_CMD). * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASK_MASK). + * + * (ide_drive_t *drive, u8 stat, u8 err) */ -void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err); +extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); /* - * Issue ATA command and wait for completion. use for implementing commands in kernel + * Issue ATA command and wait for completion. + * Use for implementing commands in kernel + * + * (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf) */ -int ide_wait_cmd (ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *buf); +extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *); + +/* (ide_drive_t *drive, u8 *buf) */ +extern int ide_wait_cmd_task(ide_drive_t *, u8 *); -int ide_wait_cmd_task (ide_drive_t *drive, byte *buf); - typedef struct ide_task_s { +/* + * struct hd_drive_task_hdr tf; + * task_struct_t tf; + * struct hd_drive_hob_hdr hobf; + * hob_struct_t hobf; + */ task_ioreg_t tfRegister[8]; task_ioreg_t hobRegister[8]; ide_reg_valid_t tf_out_flags; @@ -1101,6 +1467,11 @@ typedef struct ide_task_s { } ide_task_t; typedef struct pkt_task_s { +/* + * struct hd_drive_task_hdr pktf; + * task_struct_t pktf; + * u8 pkcdb[12]; + */ task_ioreg_t tfRegister[8]; int data_phase; int command_type; @@ -1109,66 +1480,129 @@ typedef struct pkt_task_s { void *special; } pkt_task_t; -void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); -void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); -void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); -void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); -void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); -void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); +extern inline void SELECT_DRIVE(ide_drive_t *); +extern inline void SELECT_INTERRUPT(ide_drive_t *); +extern inline void SELECT_MASK(ide_drive_t *, int); +extern inline void QUIRK_LIST(ide_drive_t *); -int drive_is_ready (ide_drive_t *drive); -int wait_for_ready (ide_drive_t *drive, int timeout); +extern void ata_input_data(ide_drive_t *, void *, u32); +extern void ata_output_data(ide_drive_t *, void *, u32); +extern void atapi_input_bytes(ide_drive_t *, void *, u32); +extern void atapi_output_bytes(ide_drive_t *, void *, u32); +extern void taskfile_input_data(ide_drive_t *, void *, u32); +extern void taskfile_output_data(ide_drive_t *, void *, u32); + +extern int drive_is_ready(ide_drive_t *); +extern int wait_for_ready(ide_drive_t *, int /* timeout */); /* * taskfile io for disks for now...and builds request from ide_ioctl */ -ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task); +extern ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); -void ide_end_taskfile (ide_drive_t *drive, byte stat, byte err); +/* (ide_drive_t *drive, u8 stat, u8 err) */ +extern void ide_end_taskfile(ide_drive_t *, u8, u8); /* * Special Flagged Register Validation Caller */ -ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task); - -ide_startstop_t set_multmode_intr (ide_drive_t *drive); -ide_startstop_t set_geometry_intr (ide_drive_t *drive); -ide_startstop_t recal_intr (ide_drive_t *drive); -ide_startstop_t task_no_data_intr (ide_drive_t *drive); -ide_startstop_t task_in_intr (ide_drive_t *drive); -ide_startstop_t task_mulin_intr (ide_drive_t *drive); -ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq); -ide_startstop_t task_out_intr (ide_drive_t *drive); -ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq); -ide_startstop_t task_mulout_intr (ide_drive_t *drive); -void ide_init_drive_taskfile (struct request *rq); - -int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *cmd, byte *buf); - -ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); -ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); -ide_post_handler_t * ide_post_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); +extern ide_startstop_t flagged_taskfile(ide_drive_t *, ide_task_t *); + +extern ide_startstop_t set_multmode_intr(ide_drive_t *); +extern ide_startstop_t set_geometry_intr(ide_drive_t *); +extern ide_startstop_t recal_intr(ide_drive_t *); +extern ide_startstop_t task_no_data_intr(ide_drive_t *); +extern ide_startstop_t task_in_intr(ide_drive_t *); +extern ide_startstop_t task_mulin_intr(ide_drive_t *); +extern ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); +extern ide_startstop_t task_out_intr(ide_drive_t *); +extern ide_startstop_t pre_task_mulout_intr(ide_drive_t *, struct request *); +extern ide_startstop_t task_mulout_intr(ide_drive_t *); +extern void ide_init_drive_taskfile(struct request *); + +extern int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *); + +extern ide_pre_handler_t * ide_pre_handler_parser(struct hd_drive_task_hdr *, struct hd_drive_hob_hdr *); + +extern ide_handler_t * ide_handler_parser(struct hd_drive_task_hdr *, struct hd_drive_hob_hdr *); + +extern ide_post_handler_t * ide_post_handler_parser(struct hd_drive_task_hdr *, struct hd_drive_hob_hdr *); + /* Expects args is a full set of TF registers and parses the command type */ -int ide_cmd_type_parser (ide_task_t *args); +extern int ide_cmd_type_parser(ide_task_t *); + +int ide_taskfile_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); +int ide_cmd_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); +int ide_task_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); + +#if 0 + +#define IDEFLOPPY_PC_BUFFER_SIZE 256 +#define IDETAPE_PC_BUFFER_SIZE 256 +#define IDE_PC_BUFFER_SIZE 256 + +typedef struct ide_packet_command_s { + /* Actual packet bytes */ + u8 c[12]; + /* On each retry, we increment retries */ + int retries; + /* Error code */ + int error; + /* Bytes to transfer */ + int request_transfer; + /* Bytes actually transferred */ + int actually_transferred; + /* Size of our data buffer */ + int buffer_size; + + struct buffer_head *bh; + u8 *b_data; + /* The corresponding request */ + struct request *rq; +# if 0 + /* Scatter gather table */ + struct scatterlist *sg; +# endif + int b_count; + /* Data buffer */ + u8 *buffer; + /* Pointer into the above buffer */ + u8 *current_position; + /* Called when this packet command is completed */ + ide_startstop_t (*callback) (ide_drive_t *); + /* Temporary buffer */ + u8 pc_buffer[IDE_PC_BUFFER_SIZE]; + /* Status/Action bit flags: long for set_bit */ + unsigned long flags; +} ide_pc_t; + +ide-cd orthoginal :-/ +struct packet_command { + char *buffer; + int buflen; + int stat; + int quiet; + int timeout; + struct request_sense *sense; + unsigned char c[12]; +}; -int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +#endif #ifdef CONFIG_PKT_TASK_IOCTL -int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +extern int pkt_taskfile_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); #endif /* CONFIG_PKT_TASK_IOCTL */ -void ide_delay_50ms (void); -int system_bus_clock(void); +extern void ide_delay_50ms(void); +extern int system_bus_clock(void); -byte ide_auto_reduce_xfer (ide_drive_t *drive); -int ide_driveid_update (ide_drive_t *drive); -int ide_ata66_check (ide_drive_t *drive, ide_task_t *args); -int ide_config_drive_speed (ide_drive_t *drive, byte speed); -byte eighty_ninty_three (ide_drive_t *drive); -int set_transfer (ide_drive_t *drive, ide_task_t *args); -int taskfile_lib_get_identify (ide_drive_t *drive, byte *buf); +extern u8 ide_auto_reduce_xfer(ide_drive_t *); +extern int ide_driveid_update(ide_drive_t *); +extern int ide_ata66_check(ide_drive_t *, ide_task_t *); +extern int ide_config_drive_speed(ide_drive_t *, u8); +extern u8 eighty_ninty_three (ide_drive_t *); +extern int set_transfer(ide_drive_t *, ide_task_t *); +extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *); /* * ide_system_bus_speed() returns what we think is the system VESA/PCI @@ -1176,45 +1610,55 @@ int taskfile_lib_get_identify (ide_drive_t *drive, byte *buf); * The default is 40 for known PCI systems, 50 otherwise. * The "idebus=xx" parameter can be used to override this value. */ -int ide_system_bus_speed (void); +extern int ide_system_bus_speed(void); /* * ide_stall_queue() can be used by a drive to give excess bandwidth back * to the hwgroup by sleeping for timeout jiffies. */ -void ide_stall_queue (ide_drive_t *drive, unsigned long timeout); +extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); /* * ide_get_queue() returns the queue which corresponds to a given device. */ -request_queue_t *ide_get_queue (kdev_t dev); +extern request_queue_t *ide_get_queue (kdev_t dev); /* * CompactFlash cards and their brethern pretend to be removable hard disks, * but they never have a slave unit, and they don't have doorlock mechanisms. - * This test catches them, and is invoked elsewhere when setting appropriate config bits. + * This test catches them, and is invoked elsewhere when setting appropriate + * config bits. */ -int drive_is_flashcard (ide_drive_t *drive); +extern int drive_is_flashcard (ide_drive_t *drive); -int ide_spin_wait_hwgroup (ide_drive_t *drive); -void ide_timer_expiry (unsigned long data); -void ide_intr (int irq, void *dev_id, struct pt_regs *regs); -void do_ide_request (request_queue_t * q); -void ide_init_subdrivers (void); +extern int ide_spin_wait_hwgroup(ide_drive_t *); +extern void ide_timer_expiry(unsigned long); +extern void ide_intr(int irq, void *dev_id, struct pt_regs *regs); +extern void do_ide_request(request_queue_t *); +extern void ide_init_subdrivers(void); #ifndef _IDE_C extern struct block_device_operations ide_fops[]; extern ide_proc_entry_t generic_subdriver_entries[]; #endif -int ata_attach(ide_drive_t *drive); +extern int ata_attach(ide_drive_t *); #ifdef _IDE_C #ifdef CONFIG_BLK_DEV_IDE -int ideprobe_init (void); +extern int ideprobe_init(void); + +#ifdef CONFIG_BLK_DEV_IDEPCI +extern void ide_scan_pcibus(int scan_direction) __init; +#endif /* CONFIG_BLK_DEV_IDEPCI */ + #endif /* CONFIG_BLK_DEV_IDE */ #endif /* _IDE_C */ +extern void default_hwif_iops(ide_hwif_t *); +extern void default_hwif_mmiops(ide_hwif_t *); +extern void default_hwif_transport(ide_hwif_t *); + int ide_register_driver(ide_driver_t *driver); void ide_unregister_driver(ide_driver_t *driver); int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int version); @@ -1222,85 +1666,113 @@ int ide_unregister_subdriver (ide_drive_t *drive); int ide_replace_subdriver(ide_drive_t *drive, const char *driver); #ifdef CONFIG_BLK_DEV_IDEPCI + +#ifdef CONFIG_PROC_FS +typedef struct ide_pci_host_proc_s { + char *name; + u8 set; + get_info_t *get_info; + struct proc_dir_entry *parent; + struct ide_pci_host_proc_s *next; +} ide_pci_host_proc_t; + +void ide_pci_register_host_proc(ide_pci_host_proc_t *); +#endif /* CONFIG_PROC_FS */ + #define ON_BOARD 1 #define NEVER_BOARD 0 + #ifdef CONFIG_BLK_DEV_OFFBOARD # define OFF_BOARD ON_BOARD #else /* CONFIG_BLK_DEV_OFFBOARD */ # define OFF_BOARD NEVER_BOARD #endif /* CONFIG_BLK_DEV_OFFBOARD */ +#define NODMA 0 +#define NOAUTODMA 1 +#define AUTODMA 2 +#define EOL 255 typedef struct ide_pci_enablebit_s { - byte reg; /* byte pci reg holding the enable-bit */ - byte mask; /* mask to isolate the enable-bit */ - byte val; /* value of masked reg when "enabled" */ + u8 reg; /* byte pci reg holding the enable-bit */ + u8 mask; /* mask to isolate the enable-bit */ + u8 val; /* value of masked reg when "enabled" */ } ide_pci_enablebit_t; typedef struct ide_pci_device_s { - ide_pci_devid_t devid; + u16 vendor; + u16 device; char *name; - void (*fixup_device)(struct pci_dev *, struct ide_pci_device_s *); + void (*init_setup)(struct pci_dev *, struct ide_pci_device_s *); unsigned int (*init_chipset)(struct pci_dev *, const char *); - unsigned int (*ata66_check)(ide_hwif_t *); - void (*init_hwif)(ide_hwif_t *); - void (*dma_init)(ide_hwif_t *, unsigned long); + void (*init_iops)(ide_hwif_t *); + void (*init_hwif)(ide_hwif_t *); + void (*init_dma)(ide_hwif_t *, unsigned long); + u8 channels; + u8 autodma; ide_pci_enablebit_t enablebits[2]; - byte bootable; + u8 bootable; unsigned int extra; + struct ide_pci_device_s *next; } ide_pci_device_t; #ifdef LINUX_PCI_H -extern inline void ide_register_xp_fix(struct pci_dev *dev) -{ - int i; - unsigned short cmd; - unsigned long flags; - unsigned long base_address[4] = { 0x1f0, 0x3f4, 0x170, 0x374 }; - - local_irq_save(flags); - pci_read_config_word(dev, PCI_COMMAND, &cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); - for (i=0; i<4; i++) { - dev->resource[i].start = 0; - dev->resource[i].end = 0; - dev->resource[i].flags = 0; - } - for (i=0; i<4; i++) { - dev->resource[i].start = base_address[i]; - dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; - pci_write_config_dword(dev, - (PCI_BASE_ADDRESS_0 + (i * 4)), - dev->resource[i].start); - } - pci_write_config_word(dev, PCI_COMMAND, cmd); - local_irq_restore(flags); -} - -void ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) __init; +extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); +extern void ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *); #endif /* LINUX_PCI_H */ -unsigned long ide_find_free_region (unsigned short size) __init; -void ide_scan_pcibus (int scan_direction) __init; -#endif +#endif /* CONFIG_BLK_DEV_IDEPCI */ + #ifdef CONFIG_BLK_DEV_IDEDMA #define BAD_DMA_DRIVE 0 #define GOOD_DMA_DRIVE 1 -int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func); -void ide_destroy_dmatable (ide_drive_t *drive); -ide_startstop_t ide_dma_intr (ide_drive_t *drive); -int check_drive_lists (ide_drive_t *drive, int good_bad); -int report_drive_dmaing (ide_drive_t *drive); -int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive); -int ide_release_dma (ide_hwif_t *hwif); -void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init; -unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init; -#endif /* CONFIG_BLK_DEV_IDEPCI */ +extern int ide_build_dmatable(ide_drive_t *, struct request *); +extern void ide_destroy_dmatable(ide_drive_t *); +extern ide_startstop_t ide_dma_intr(ide_drive_t *); +extern int ide_release_dma(ide_hwif_t *); +extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int); + +extern int __ide_dma_host_off(ide_drive_t *); +extern int __ide_dma_off_quietly(ide_drive_t *); +extern int __ide_dma_off(ide_drive_t *); +extern int __ide_dma_host_on(ide_drive_t *); +extern int __ide_dma_on(ide_drive_t *); +extern int __ide_dma_check(ide_drive_t *); +extern int __ide_dma_read(ide_drive_t *); +extern int __ide_dma_write(ide_drive_t *); +extern int __ide_dma_begin(ide_drive_t *); +extern int __ide_dma_end(ide_drive_t *); +extern int __ide_dma_test_irq(ide_drive_t *); +extern int __ide_dma_bad_drive(ide_drive_t *); +extern int __ide_dma_good_drive(ide_drive_t *); +extern int __ide_dma_count(ide_drive_t *); +extern int __ide_dma_verbose(ide_drive_t *); +extern int __ide_dma_retune(ide_drive_t *); +extern int __ide_dma_lostirq(ide_drive_t *); +extern int __ide_dma_timeout(ide_drive_t *); +#endif /* CONFIG_BLK_DEV_IDEDMA */ + +extern void hwif_unregister(ide_hwif_t *); + +extern void export_ide_init_queue(ide_drive_t *); +extern u8 export_probe_for_drive(ide_drive_t *); +extern int probe_hwif_init(ide_hwif_t *); + +static inline void *ide_get_hwifdata (ide_hwif_t * hwif) +{ + return hwif->hwif_data; +} -void hwif_unregister (ide_hwif_t *hwif); +static inline void ide_set_hwifdata (ide_hwif_t * hwif, void *data) +{ + hwif->hwif_data = data; +} -void export_ide_init_queue (ide_drive_t *drive); -byte export_probe_for_drive (ide_drive_t *drive); +/* ide-lib.c */ +extern u8 ide_dma_speed(ide_drive_t *drive, u8 mode); +extern u8 ide_rate_filter(u8 mode, u8 speed); +extern int ide_dma_enable(ide_drive_t *drive); +extern char *ide_xfer_verbose(u8 xfer_rate); extern spinlock_t ide_lock; diff --git a/include/linux/sched.h b/include/linux/sched.h index 600035a0b715..bdce46f40af2 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -27,6 +27,7 @@ extern unsigned long event; #include <linux/securebits.h> #include <linux/fs_struct.h> #include <linux/compiler.h> +#include <linux/completion.h> struct exec_domain; @@ -128,8 +129,6 @@ struct sched_param { int sched_priority; }; -struct completion; - #ifdef __KERNEL__ #include <linux/spinlock.h> @@ -216,6 +215,12 @@ struct signal_struct { task_t *curr_target; struct sigpending shared_pending; + + /* thread group exit support */ + int group_exit; + int group_exit_code; + + struct completion group_exit_done; }; /* @@ -555,6 +560,7 @@ extern void notify_parent(struct task_struct *, int); extern void do_notify_parent(struct task_struct *, int); extern void force_sig(int, struct task_struct *); extern int send_sig(int, struct task_struct *, int); +extern int __broadcast_thread_group(struct task_struct *p, int sig); extern int kill_pg(pid_t, int, int); extern int kill_sl(pid_t, int, int); extern int kill_proc(pid_t, int, int); @@ -661,6 +667,7 @@ extern void exit_thread(void); extern void exit_mm(struct task_struct *); extern void exit_files(struct task_struct *); extern void exit_sighand(struct task_struct *); +extern void __exit_sighand(struct task_struct *); extern void remove_thread_group(struct task_struct *tsk, struct signal_struct *sig); extern void reparent_to_init(void); |
