diff options
Diffstat (limited to 'include')
675 files changed, 61404 insertions, 11392 deletions
diff --git a/include/asm-alpha/,fcntl.h, b/include/asm-alpha/,fcntl.h, deleted file mode 100644 index e69de29bb..000000000 --- a/include/asm-alpha/,fcntl.h, +++ /dev/null diff --git a/include/asm-alpha/a.out.h b/include/asm-alpha/a.out.h new file mode 100644 index 000000000..f1965d5ca --- /dev/null +++ b/include/asm-alpha/a.out.h @@ -0,0 +1,97 @@ +#ifndef __ALPHA_A_OUT_H__ +#define __ALPHA_A_OUT_H__ + +#include <linux/types.h> + +/* + * OSF/1 ECOFF header structs. ECOFF files consist of: + * - a file header (struct filehdr), + * - an a.out header (struct aouthdr), + * - one or more section headers (struct scnhdr). + * The filhdr's "f_nscns" field contains the + * number of section headers. + */ + +struct filehdr +{ + /* OSF/1 "file" header */ + __u16 f_magic, f_nscns; + __u32 f_timdat; + __u64 f_symptr; + __u32 f_nsyms; + __u16 f_opthdr, f_flags; +}; + +struct aouthdr +{ + __u64 info; /* after that it looks quite normal.. */ + __u64 tsize; + __u64 dsize; + __u64 bsize; + __u64 entry; + __u64 text_start; /* with a few additions that actually make sense */ + __u64 data_start; + __u64 bss_start; + __u32 gprmask, fprmask; /* bitmask of general & floating point regs used in binary */ + __u64 gpvalue; +}; + +struct scnhdr +{ + char s_name[8]; + __u64 s_paddr; + __u64 s_vaddr; + __u64 s_size; + __u64 s_scnptr; + __u64 s_relptr; + __u64 s_lnnoptr; + __u16 s_nreloc; + __u16 s_nlnno; + __u32 s_flags; +}; + +struct exec +{ + /* OSF/1 "file" header */ + struct filehdr fh; + struct aouthdr ah; +}; + +/* + * Define's so that the kernel exec code can access the a.out header + * fields... + */ +#define a_info ah.info +#define a_text ah.tsize +#define a_data ah.dsize +#define a_bss ah.bsize +#define a_entry ah.entry +#define a_textstart ah.text_start +#define a_datastart ah.data_start +#define a_bssstart ah.bss_start +#define a_gprmask ah.gprmask +#define a_fprmask ah.fprmask +#define a_gpvalue ah.gpvalue + +#define N_TXTADDR(x) ((x).a_textstart) +#define N_DATADDR(x) ((x).a_datastart) +#define N_BSSADDR(x) ((x).a_bssstart) +#define N_DRSIZE(x) 0 +#define N_TRSIZE(x) 0 +#define N_SYMSIZE(x) 0 + +#define AOUTHSZ sizeof(struct aouthdr) +#define SCNHSZ sizeof(struct scnhdr) +#define SCNROUND 16 + +#define N_TXTOFF(x) \ + ((long) N_MAGIC(x) == ZMAGIC ? 0 : \ + (sizeof(struct exec) + (x).fh.f_nscns*SCNHSZ + SCNROUND - 1) & ~(SCNROUND - 1)) + +#ifdef __KERNEL__ + +#define STACK_TOP (0x00120000000UL) + +#endif + +#endif /* __A_OUT_GNU_H__ */ diff --git a/include/asm-alpha/apecs.h b/include/asm-alpha/apecs.h new file mode 100644 index 000000000..0f38c8aac --- /dev/null +++ b/include/asm-alpha/apecs.h @@ -0,0 +1,561 @@ +#ifndef __ALPHA_APECS__H__ +#define __ALPHA_APECS__H__ + +#include <linux/types.h> + +/* + * APECS is the internal name for the 2107x chipset which provides + * memory controller and PCI access for the 21064 chip based systems. + * + * This file is based on: + * + * DECchip 21071-AA and DECchip 21072-AA Core Logic Chipsets + * Data Sheet + * + * EC-N0648-72 + * + * + * david.rusling@reo.mts.dec.com Initial Version. + * + */ +#include <linux/config.h> + +#ifdef CONFIG_ALPHA_XL +/* + An AVANTI *might* be an XL, and an XL has only 27 bits of ISA address + that get passed through the PCI<->ISA bridge chip. So we've gotta use + both windows to max out the physical memory we can DMA to. Sigh... + + If we try a window at 0 for 1GB as a work-around, we run into conflicts + with ISA/PCI bus memory which can't be relocated, like VGA aperture and + BIOS ROMs. So we must put the windows high enough to avoid these areas. + + We put window 1 at BUS 64Mb for 64Mb, mapping physical 0 to 64Mb-1, + and window 2 at BUS 512Mb for 512Mb, mapping physical 0 to 512Mb-1. + Yes, this does map 0 to 64Mb-1 twice, but only window 1 will actually + be used for that range (via virt_to_bus()). + + Note that we actually fudge the window 1 maximum as 48Mb instead of 64Mb, + to keep virt_to_bus() from returning an address in the first window, for + a data area that goes beyond the 64Mb first DMA window. Sigh... + The fudge factor MUST match with <asm/dma.h> MAX_DMA_ADDRESS, but + we can't just use that here, because of header file looping... :-( + + Window 1 will be used for all DMA from the ISA bus; yes, that does + limit what memory an ISA floppy or soundcard or Ethernet can touch, but + it's also a known limitation on other platforms as well. We use the + same technique that is used on INTEL platforms with similar limitation: + set MAX_DMA_ADDRESS and clear some pages' DMAable flags during mem_init(). + We trust that any ISA bus device drivers will *always* ask for DMAable + memory explicitly via kmalloc()/get_free_pages() flags arguments. + + Note that most PCI bus devices' drivers do *not* explicitly ask for + DMAable memory; they count on being able to DMA to any memory they + get from kmalloc()/get_free_pages(). They will also use window 1 for + any physical memory accesses below 64Mb; the rest will be handled by + window 2, maxing out at 512Mb of memory. I trust this is enough... :-) + + Finally, the reason we make window 2 start at 512Mb for 512Mb, is so that + we can allocate PCI bus devices' memory starting at 1Gb and up, to ensure + that no conflicts occur and bookkeeping is simplified (ie we don't + try to fill the gap between the two windows, we just go above the top). + + Note that the XL is treated differently from the AVANTI, even though + for most other things they are identical. It didn't seem reasonable to + make the AVANTI support pay for the limitations of the XL. It is true, + however, that an XL kernel will run on an AVANTI without problems. + +*/ +#define APECS_XL_DMA_WIN1_BASE (64*1024*1024) +#define APECS_XL_DMA_WIN1_SIZE (64*1024*1024) +#define APECS_XL_DMA_WIN1_SIZE_PARANOID (48*1024*1024) +#define APECS_XL_DMA_WIN2_BASE (512*1024*1024) +#define APECS_XL_DMA_WIN2_SIZE (512*1024*1024) + +#else /* CONFIG_ALPHA_XL */ + +/* these are for normal APECS family machines, AVANTI/MUSTANG/EB64/PC64 */ +#define APECS_DMA_WIN_BASE (1024*1024*1024) +#define APECS_DMA_WIN_SIZE (1024*1024*1024) + +#endif /* CONFIG_ALPHA_XL */ + +/* + * 21071-DA Control and Status registers. + * These are used for PCI memory access. + */ +#define APECS_IOC_DCSR (IDENT_ADDR + 0x1A0000000UL) +#define APECS_IOC_PEAR (IDENT_ADDR + 0x1A0000020UL) +#define APECS_IOC_SEAR (IDENT_ADDR + 0x1A0000040UL) +#define APECS_IOC_DR1 (IDENT_ADDR + 0x1A0000060UL) +#define APECS_IOC_DR2 (IDENT_ADDR + 0x1A0000080UL) +#define APECS_IOC_DR3 (IDENT_ADDR + 0x1A00000A0UL) + +#define APECS_IOC_TB1R (IDENT_ADDR + 0x1A00000C0UL) +#define APECS_IOC_TB2R (IDENT_ADDR + 0x1A00000E0UL) + +#define APECS_IOC_PB1R (IDENT_ADDR + 0x1A0000100UL) +#define APECS_IOC_PB2R (IDENT_ADDR + 0x1A0000120UL) + +#define APECS_IOC_PM1R (IDENT_ADDR + 0x1A0000140UL) +#define APECS_IOC_PM2R (IDENT_ADDR + 0x1A0000160UL) + +#define APECS_IOC_HAXR0 (IDENT_ADDR + 0x1A0000180UL) +#define APECS_IOC_HAXR1 (IDENT_ADDR + 0x1A00001A0UL) +#define APECS_IOC_HAXR2 (IDENT_ADDR + 0x1A00001C0UL) + +#define APECS_IOC_PMLT (IDENT_ADDR + 0x1A00001E0UL) + +#define APECS_IOC_TLBTAG0 (IDENT_ADDR + 0x1A0000200UL) +#define APECS_IOC_TLBTAG1 (IDENT_ADDR + 0x1A0000220UL) +#define APECS_IOC_TLBTAG2 (IDENT_ADDR + 0x1A0000240UL) +#define APECS_IOC_TLBTAG3 (IDENT_ADDR + 0x1A0000260UL) +#define APECS_IOC_TLBTAG4 (IDENT_ADDR + 0x1A0000280UL) +#define APECS_IOC_TLBTAG5 (IDENT_ADDR + 0x1A00002A0UL) +#define APECS_IOC_TLBTAG6 (IDENT_ADDR + 0x1A00002C0UL) +#define APECS_IOC_TLBTAG7 (IDENT_ADDR + 0x1A00002E0UL) + +#define APECS_IOC_TLBDATA0 (IDENT_ADDR + 0x1A0000300UL) +#define APECS_IOC_TLBDATA1 (IDENT_ADDR + 0x1A0000320UL) +#define APECS_IOC_TLBDATA2 (IDENT_ADDR + 0x1A0000340UL) +#define APECS_IOC_TLBDATA3 (IDENT_ADDR + 0x1A0000360UL) +#define APECS_IOC_TLBDATA4 (IDENT_ADDR + 0x1A0000380UL) +#define APECS_IOC_TLBDATA5 (IDENT_ADDR + 0x1A00003A0UL) +#define APECS_IOC_TLBDATA6 (IDENT_ADDR + 0x1A00003C0UL) +#define APECS_IOC_TLBDATA7 (IDENT_ADDR + 0x1A00003E0UL) + +#define APECS_IOC_TBIA (IDENT_ADDR + 0x1A0000400UL) + + +/* + * 21071-CA Control and Status registers. + * These are used to program memory timing, + * configure memory and initialise the B-Cache. + */ +#define APECS_MEM_GCR (IDENT_ADDR + 0x180000000UL) +#define APECS_MEM_EDSR (IDENT_ADDR + 0x180000040UL) +#define APECS_MEM_TAR (IDENT_ADDR + 0x180000060UL) +#define APECS_MEM_ELAR (IDENT_ADDR + 0x180000080UL) +#define APECS_MEM_EHAR (IDENT_ADDR + 0x1800000a0UL) +#define APECS_MEM_SFT_RST (IDENT_ADDR + 0x1800000c0UL) +#define APECS_MEM_LDxLAR (IDENT_ADDR + 0x1800000e0UL) +#define APECS_MEM_LDxHAR (IDENT_ADDR + 0x180000100UL) +#define APECS_MEM_GTR (IDENT_ADDR + 0x180000200UL) +#define APECS_MEM_RTR (IDENT_ADDR + 0x180000220UL) +#define APECS_MEM_VFPR (IDENT_ADDR + 0x180000240UL) +#define APECS_MEM_PDLDR (IDENT_ADDR + 0x180000260UL) +#define APECS_MEM_PDhDR (IDENT_ADDR + 0x180000280UL) + +/* Bank x Base Address Register */ +#define APECS_MEM_B0BAR (IDENT_ADDR + 0x180000800UL) +#define APECS_MEM_B1BAR (IDENT_ADDR + 0x180000820UL) +#define APECS_MEM_B2BAR (IDENT_ADDR + 0x180000840UL) +#define APECS_MEM_B3BAR (IDENT_ADDR + 0x180000860UL) +#define APECS_MEM_B4BAR (IDENT_ADDR + 0x180000880UL) +#define APECS_MEM_B5BAR (IDENT_ADDR + 0x1800008A0UL) +#define APECS_MEM_B6BAR (IDENT_ADDR + 0x1800008C0UL) +#define APECS_MEM_B7BAR (IDENT_ADDR + 0x1800008E0UL) +#define APECS_MEM_B8BAR (IDENT_ADDR + 0x180000900UL) + +/* Bank x Configuration Register */ +#define APECS_MEM_B0BCR (IDENT_ADDR + 0x180000A00UL) +#define APECS_MEM_B1BCR (IDENT_ADDR + 0x180000A20UL) +#define APECS_MEM_B2BCR (IDENT_ADDR + 0x180000A40UL) +#define APECS_MEM_B3BCR (IDENT_ADDR + 0x180000A60UL) +#define APECS_MEM_B4BCR (IDENT_ADDR + 0x180000A80UL) +#define APECS_MEM_B5BCR (IDENT_ADDR + 0x180000AA0UL) +#define APECS_MEM_B6BCR (IDENT_ADDR + 0x180000AC0UL) +#define APECS_MEM_B7BCR (IDENT_ADDR + 0x180000AE0UL) +#define APECS_MEM_B8BCR (IDENT_ADDR + 0x180000B00UL) + +/* Bank x Timing Register A */ +#define APECS_MEM_B0TRA (IDENT_ADDR + 0x180000C00UL) +#define APECS_MEM_B1TRA (IDENT_ADDR + 0x180000C20UL) +#define APECS_MEM_B2TRA (IDENT_ADDR + 0x180000C40UL) +#define APECS_MEM_B3TRA (IDENT_ADDR + 0x180000C60UL) +#define APECS_MEM_B4TRA (IDENT_ADDR + 0x180000C80UL) +#define APECS_MEM_B5TRA (IDENT_ADDR + 0x180000CA0UL) +#define APECS_MEM_B6TRA (IDENT_ADDR + 0x180000CC0UL) +#define APECS_MEM_B7TRA (IDENT_ADDR + 0x180000CE0UL) +#define APECS_MEM_B8TRA (IDENT_ADDR + 0x180000D00UL) + +/* Bank x Timing Register B */ +#define APECS_MEM_B0TRB (IDENT_ADDR + 0x180000E00UL) +#define APECS_MEM_B1TRB (IDENT_ADDR + 0x180000E20UL) +#define APECS_MEM_B2TRB (IDENT_ADDR + 0x180000E40UL) +#define APECS_MEM_B3TRB (IDENT_ADDR + 0x180000E60UL) +#define APECS_MEM_B4TRB (IDENT_ADDR + 0x180000E80UL) +#define APECS_MEM_B5TRB (IDENT_ADDR + 0x180000EA0UL) +#define APECS_MEM_B6TRB (IDENT_ADDR + 0x180000EC0UL) +#define APECS_MEM_B7TRB (IDENT_ADDR + 0x180000EE0UL) +#define APECS_MEM_B8TRB (IDENT_ADDR + 0x180000F00UL) + + +/* + * Memory spaces: + */ +#define APECS_IACK_SC (IDENT_ADDR + 0x1b0000000UL) +#define APECS_CONF (IDENT_ADDR + 0x1e0000000UL) +#define APECS_IO (IDENT_ADDR + 0x1c0000000UL) +#define APECS_SPARSE_MEM (IDENT_ADDR + 0x200000000UL) +#define APECS_DENSE_MEM (IDENT_ADDR + 0x300000000UL) + +/* + * Bit definitions for I/O Controller status register 0: + */ +#define APECS_IOC_STAT0_CMD 0xf +#define APECS_IOC_STAT0_ERR (1<<4) +#define APECS_IOC_STAT0_LOST (1<<5) +#define APECS_IOC_STAT0_THIT (1<<6) +#define APECS_IOC_STAT0_TREF (1<<7) +#define APECS_IOC_STAT0_CODE_SHIFT 8 +#define APECS_IOC_STAT0_CODE_MASK 0x7 +#define APECS_IOC_STAT0_P_NBR_SHIFT 13 +#define APECS_IOC_STAT0_P_NBR_MASK 0x7ffff + +#define HAE_ADDRESS APECS_IOC_HAXR1 + +#ifdef __KERNEL__ + +/* + * Translate physical memory address as seen on (PCI) bus into + * a kernel virtual address and vv. + */ +/* NOTE: we fudge the window 1 maximum as 48Mb instead of 64Mb, to prevent + virt_to_bus() from returning an address in the first window, for a + data area that goes beyond the 64Mb first DMA window. Sigh... + This MUST match with <asm/dma.h> MAX_DMA_ADDRESS for consistency, but + we can't just use that here, because of header file looping... :-( +*/ +extern inline unsigned long virt_to_bus(void * address) +{ + unsigned long paddr = virt_to_phys(address); +#ifdef CONFIG_ALPHA_XL + if (paddr < APECS_XL_DMA_WIN1_SIZE_PARANOID) + return paddr + APECS_XL_DMA_WIN1_BASE; + else + return paddr + APECS_XL_DMA_WIN2_BASE; /* win 2 xlates to 0 also */ +#else /* CONFIG_ALPHA_XL */ + return paddr + APECS_DMA_WIN_BASE; +#endif /* CONFIG_ALPHA_XL */ +} + +extern inline void * bus_to_virt(unsigned long address) +{ + /* + * This check is a sanity check but also ensures that bus + * address 0 maps to virtual address 0 which is useful to + * detect null "pointers" (the NCR driver is much simpler if + * NULL pointers are preserved). + */ +#ifdef CONFIG_ALPHA_XL + if (address < APECS_XL_DMA_WIN1_BASE) + return 0; + else if (address < (APECS_XL_DMA_WIN1_BASE + APECS_XL_DMA_WIN1_SIZE)) + return phys_to_virt(address - APECS_XL_DMA_WIN1_BASE); + else /* should be more checking here, maybe? */ + return phys_to_virt(address - APECS_XL_DMA_WIN2_BASE); +#else /* CONFIG_ALPHA_XL */ + if (address < APECS_DMA_WIN_BASE) + return 0; + return phys_to_virt(address - APECS_DMA_WIN_BASE); +#endif /* CONFIG_ALPHA_XL */ +} + +/* + * I/O functions: + * + * Unlike Jensen, the APECS machines have no concept of local + * I/O---everything goes over the PCI bus. + * + * There is plenty room for optimization here. In particular, + * the Alpha's insb/insw/extb/extw should be useful in moving + * data to/from the right byte-lanes. + */ + +#define vuip volatile unsigned int * + +extern inline unsigned int __inb(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + APECS_IO + 0x00); + result >>= (addr & 3) * 8; + return 0xffUL & result; +} + +extern inline void __outb(unsigned char b, unsigned long addr) +{ + unsigned int w; + + asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + APECS_IO + 0x00) = w; + mb(); +} + +extern inline unsigned int __inw(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + APECS_IO + 0x08); + result >>= (addr & 3) * 8; + return 0xffffUL & result; +} + +extern inline void __outw(unsigned short b, unsigned long addr) +{ + unsigned int w; + + asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + APECS_IO + 0x08) = w; + mb(); +} + +extern inline unsigned int __inl(unsigned long addr) +{ + return *(vuip) ((addr << 5) + APECS_IO + 0x18); +} + +extern inline void __outl(unsigned int b, unsigned long addr) +{ + *(vuip) ((addr << 5) + APECS_IO + 0x18) = b; + mb(); +} + + +/* + * Memory functions. 64-bit and 32-bit accesses are done through + * dense memory space, everything else through sparse space. + */ +extern inline unsigned long __readb(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8; + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + if (msb != hae.cache) { + set_hae(msb); + } + } + result = *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x00); + result >>= shift; + return 0xffUL & result; +} + +extern inline unsigned long __readw(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8; + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + if (msb != hae.cache) { + set_hae(msb); + } + } + result = *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x08); + result >>= shift; + return 0xffffUL & result; +} + +extern inline unsigned long __readl(unsigned long addr) +{ + return *(vuip) (addr + APECS_DENSE_MEM); +} + +extern inline void __writeb(unsigned char b, unsigned long addr) +{ + unsigned long msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + if (msb != hae.cache) { + set_hae(msb); + } + } + *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x00) = b * 0x01010101; +} + +extern inline void __writew(unsigned short b, unsigned long addr) +{ + unsigned long msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + if (msb != hae.cache) { + set_hae(msb); + } + } + *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x08) = b * 0x00010001; +} + +extern inline void __writel(unsigned int b, unsigned long addr) +{ + *(vuip) (addr + APECS_DENSE_MEM) = b; +} + +#define inb(port) \ +(__builtin_constant_p((port))?__inb(port):_inb(port)) + +#define outb(x, port) \ +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) + +#define readl(a) __readl((unsigned long)(a)) +#define writel(v,a) __writel((v),(unsigned long)(a)) + +#undef vuip + +extern unsigned long apecs_init (unsigned long mem_start, + unsigned long mem_end); + +#endif /* __KERNEL__ */ + +/* + * Data structure for handling APECS machine checks: + */ +#ifdef CONFIG_ALPHA_MIKASA +struct el_apecs_sysdata_mcheck { + unsigned long coma_gcr; + unsigned long coma_edsr; + unsigned long coma_ter; + unsigned long coma_elar; + unsigned long coma_ehar; + unsigned long coma_ldlr; + unsigned long coma_ldhr; + unsigned long coma_base0; + unsigned long coma_base1; + unsigned long coma_base2; + unsigned long coma_base3; + unsigned long coma_cnfg0; + unsigned long coma_cnfg1; + unsigned long coma_cnfg2; + unsigned long coma_cnfg3; + unsigned long epic_dcsr; + unsigned long epic_pear; + unsigned long epic_sear; + unsigned long epic_tbr1; + unsigned long epic_tbr2; + unsigned long epic_pbr1; + unsigned long epic_pbr2; + unsigned long epic_pmr1; + unsigned long epic_pmr2; + unsigned long epic_harx1; + unsigned long epic_harx2; + unsigned long epic_pmlt; + unsigned long epic_tag0; + unsigned long epic_tag1; + unsigned long epic_tag2; + unsigned long epic_tag3; + unsigned long epic_tag4; + unsigned long epic_tag5; + unsigned long epic_tag6; + unsigned long epic_tag7; + unsigned long epic_data0; + unsigned long epic_data1; + unsigned long epic_data2; + unsigned long epic_data3; + unsigned long epic_data4; + unsigned long epic_data5; + unsigned long epic_data6; + unsigned long epic_data7; + + unsigned long pceb_vid; + unsigned long pceb_did; + unsigned long pceb_revision; + unsigned long pceb_command; + unsigned long pceb_status; + unsigned long pceb_latency; + unsigned long pceb_control; + unsigned long pceb_arbcon; + unsigned long pceb_arbpri; + + unsigned long esc_id; + unsigned long esc_revision; + unsigned long esc_int0; + unsigned long esc_int1; + unsigned long esc_elcr0; + unsigned long esc_elcr1; + unsigned long esc_last_eisa; + unsigned long esc_nmi_stat; + + unsigned long pci_ir; + unsigned long pci_imr; + unsigned long svr_mgr; +}; +#else /* CONFIG_ALPHA_MIKASA */ +/* this for the normal APECS machines */ +struct el_apecs_sysdata_mcheck { + unsigned long coma_gcr; + unsigned long coma_edsr; + unsigned long coma_ter; + unsigned long coma_elar; + unsigned long coma_ehar; + unsigned long coma_ldlr; + unsigned long coma_ldhr; + unsigned long coma_base0; + unsigned long coma_base1; + unsigned long coma_base2; + unsigned long coma_cnfg0; + unsigned long coma_cnfg1; + unsigned long coma_cnfg2; + unsigned long epic_dcsr; + unsigned long epic_pear; + unsigned long epic_sear; + unsigned long epic_tbr1; + unsigned long epic_tbr2; + unsigned long epic_pbr1; + unsigned long epic_pbr2; + unsigned long epic_pmr1; + unsigned long epic_pmr2; + unsigned long epic_harx1; + unsigned long epic_harx2; + unsigned long epic_pmlt; + unsigned long epic_tag0; + unsigned long epic_tag1; + unsigned long epic_tag2; + unsigned long epic_tag3; + unsigned long epic_tag4; + unsigned long epic_tag5; + unsigned long epic_tag6; + unsigned long epic_tag7; + unsigned long epic_data0; + unsigned long epic_data1; + unsigned long epic_data2; + unsigned long epic_data3; + unsigned long epic_data4; + unsigned long epic_data5; + unsigned long epic_data6; + unsigned long epic_data7; +}; +#endif /* CONFIG_ALPHA_MIKASA */ + +struct el_procdata { + unsigned long paltemp[32]; /* PAL TEMP REGS. */ + /* EV4-specific fields */ + unsigned long exc_addr; /* Address of excepting instruction. */ + unsigned long exc_sum; /* Summary of arithmetic traps. */ + unsigned long exc_mask; /* Exception mask (from exc_sum). */ + unsigned long iccsr; /* IBox hardware enables. */ + unsigned long pal_base; /* Base address for PALcode. */ + unsigned long hier; /* Hardware Interrupt Enable. */ + unsigned long hirr; /* Hardware Interrupt Request. */ + unsigned long csr; /* D-stream fault info. */ + unsigned long dc_stat; /* D-cache status (ECC/Parity Err). */ + unsigned long dc_addr; /* EV3 Phys Addr for ECC/DPERR. */ + unsigned long abox_ctl; /* ABox Control Register. */ + unsigned long biu_stat; /* BIU Status. */ + unsigned long biu_addr; /* BUI Address. */ + unsigned long biu_ctl; /* BIU Control. */ + unsigned long fill_syndrome;/* For correcting ECC errors. */ + unsigned long fill_addr; /* Cache block which was being read */ + unsigned long va; /* Effective VA of fault or miss. */ + unsigned long bc_tag; /* Backup Cache Tag Probe Results.*/ +}; + + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ADDR(x) (0x80 | (x)) +#define RTC_ALWAYS_BCD 0 + +#endif /* __ALPHA_APECS__H__ */ diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h new file mode 100644 index 000000000..621c3a932 --- /dev/null +++ b/include/asm-alpha/atomic.h @@ -0,0 +1,103 @@ +#ifndef __ARCH_ALPHA_ATOMIC__ +#define __ARCH_ALPHA_ATOMIC__ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc... + * + * But use these as seldom as possible since they are much more slower + * than regular operations. + */ + +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) + +typedef int atomic_t; + +extern __inline__ void atomic_add(atomic_t i, atomic_t * v) +{ + unsigned long temp; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "addl %0,%2,%0\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); +} + +extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) +{ + unsigned long temp; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "subl %0,%2,%0\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); +} + +/* + * Same as above, but return the result value + */ +extern __inline__ long atomic_add_return(atomic_t i, atomic_t * v) +{ + long temp, result; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "addl %0,%3,%0\n\t" + "bis %0,%0,%2\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)), + "=&r" (result) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); + return result; +} + +extern __inline__ long atomic_sub_return(atomic_t i, atomic_t * v) +{ + long temp, result; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "subl %0,%3,%0\n\t" + "bis %0,%0,%2\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)), + "=&r" (result) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); + return result; +} + +#define atomic_dec_return(v) atomic_sub_return(1,(v)) +#define atomic_inc_return(v) atomic_add_return(1,(v)) + +#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) + +#define atomic_inc(v) atomic_add(1,(v)) +#define atomic_dec(v) atomic_sub(1,(v)) + +#endif diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h index 420ffa02c..200a905c1 100644 --- a/include/asm-alpha/bitops.h +++ b/include/asm-alpha/bitops.h @@ -17,21 +17,22 @@ extern __inline__ unsigned long set_bit(unsigned long nr, void * addr) { unsigned long oldbit; unsigned long temp; + unsigned int * m = ((unsigned int *) addr) + (nr >> 5); __asm__ __volatile__( "\n1:\t" - "ldq_l %0,%1\n\t" + "ldl_l %0,%1\n\t" "and %0,%3,%2\n\t" "bne %2,2f\n\t" "xor %0,%3,%0\n\t" - "stq_c %0,%1\n\t" + "stl_c %0,%1\n\t" "beq %0,1b\n" "2:" :"=&r" (temp), - "=m" (((unsigned long *) addr)[nr >> 6]), + "=m" (*m), "=&r" (oldbit) - :"r" (1UL << (nr & 63)), - "m" (((unsigned long *) addr)[nr >> 6])); + :"Ir" (1UL << (nr & 31)), + "m" (*m)); return oldbit != 0; } @@ -39,21 +40,22 @@ extern __inline__ unsigned long clear_bit(unsigned long nr, void * addr) { unsigned long oldbit; unsigned long temp; + unsigned int * m = ((unsigned int *) addr) + (nr >> 5); __asm__ __volatile__( "\n1:\t" - "ldq_l %0,%1\n\t" + "ldl_l %0,%1\n\t" "and %0,%3,%2\n\t" "beq %2,2f\n\t" "xor %0,%3,%0\n\t" - "stq_c %0,%1\n\t" + "stl_c %0,%1\n\t" "beq %0,1b\n" "2:" :"=&r" (temp), - "=m" (((unsigned long *) addr)[nr >> 6]), + "=m" (*m), "=&r" (oldbit) - :"r" (1UL << (nr & 63)), - "m" (((unsigned long *) addr)[nr >> 6])); + :"Ir" (1UL << (nr & 31)), + "m" (*m)); return oldbit != 0; } @@ -61,54 +63,57 @@ extern __inline__ unsigned long change_bit(unsigned long nr, void * addr) { unsigned long oldbit; unsigned long temp; + unsigned int * m = ((unsigned int *) addr) + (nr >> 5); __asm__ __volatile__( "\n1:\t" - "ldq_l %0,%1\n\t" + "ldl_l %0,%1\n\t" "and %0,%3,%2\n\t" "xor %0,%3,%0\n\t" - "stq_c %0,%1\n\t" + "stl_c %0,%1\n\t" "beq %0,1b\n" :"=&r" (temp), - "=m" (((unsigned long *) addr)[nr >> 6]), + "=m" (*m), "=&r" (oldbit) - :"r" (1UL << (nr & 63)), - "m" (((unsigned long *) addr)[nr >> 6])); + :"Ir" (1UL << (nr & 31)), + "m" (*m)); return oldbit != 0; } -extern __inline__ unsigned long test_bit(int nr, void * addr) +extern __inline__ unsigned long test_bit(int nr, const void * addr) { - return 1UL & (((unsigned long *) addr)[nr >> 6] >> (nr & 63)); + return 1UL & (((const int *) addr)[nr >> 5] >> (nr & 31)); } /* * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. * - * This uses the cmpbge insn to check which byte contains the zero. - * I don't know if that's actually a good idea, but it's fun and the - * resulting LBS tests should be natural on the alpha.. Besides, I'm - * just teaching myself the asm of the alpha anyway. + * Do a binary search on the bits. Due to the nature of large + * constants on the alpha, it is worthwhile to split the search. */ +extern inline unsigned long ffz_b(unsigned long x) +{ + unsigned long sum = 0; + + x = ~x & -~x; /* set first 0 bit, clear others */ + if (x & 0xF0) sum += 4; + if (x & 0xCC) sum += 2; + if (x & 0xAA) sum += 1; + + return sum; +} + extern inline unsigned long ffz(unsigned long word) { - unsigned long result = 0; - unsigned long tmp; + unsigned long bits, qofs, bofs; - __asm__("cmpbge %1,%0,%0" - :"=r" (tmp) - :"r" (word), "0" (~0UL)); - while (tmp & 1) { - word >>= 8; - tmp >>= 1; - result += 8; - } - while (word & 1) { - result++; - word >>= 1; - } - return result; + __asm__("cmpbge %1,%2,%0" : "=r"(bits) : "r"(word), "r"(~0UL)); + qofs = ffz_b(bits); + __asm__("extbl %1,%2,%0" : "=r"(bits) : "r"(word), "r"(qofs)); + bofs = ffz_b(bits); + + return qofs*8 + bofs; } /* @@ -155,4 +160,14 @@ found_middle: #define find_first_zero_bit(addr, size) \ find_next_zero_bit((addr), (size), 0) +#ifdef __KERNEL__ + +#define ext2_set_bit set_bit +#define ext2_clear_bit clear_bit +#define ext2_test_bit test_bit +#define ext2_find_first_zero_bit find_first_zero_bit +#define ext2_find_next_zero_bit find_next_zero_bit + +#endif /* __KERNEL__ */ + #endif /* _ALPHA_BITOPS_H */ diff --git a/include/asm-alpha/byteorder.h b/include/asm-alpha/byteorder.h index 02902df90..438ecb89c 100644 --- a/include/asm-alpha/byteorder.h +++ b/include/asm-alpha/byteorder.h @@ -6,14 +6,32 @@ #undef htonl #undef htons -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 #endif -#ifndef LITTLE_ENDIAN_BITFIELD -#define LITTLE_ENDIAN_BITFIELD +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD #endif +#ifdef __KERNEL__ + +/* + * In-kernel byte order macros to handle stuff like + * byte-order-dependent filesystems etc. + */ +#define cpu_to_le32(x) (x) +#define le32_to_cpu(x) (x) +#define cpu_to_le16(x) (x) +#define le16_to_cpu(x) (x) + +#define cpu_to_be32(x) htonl((x)) +#define be32_to_cpu(x) ntohl((x)) +#define cpu_to_be16(x) htons((x)) +#define be16_to_cpu(x) ntohs((x)) + +#endif /* __KERNEL__ */ + extern unsigned long int ntohl(unsigned long int); extern unsigned short int ntohs(unsigned short int); extern unsigned long int htonl(unsigned long int); @@ -21,6 +39,9 @@ extern unsigned short int htons(unsigned short int); extern unsigned long int __ntohl(unsigned long int); extern unsigned short int __ntohs(unsigned short int); + +#ifdef __GNUC__ + extern unsigned long int __constant_ntohl(unsigned long int); extern unsigned short int __constant_ntohs(unsigned short int); @@ -34,23 +55,44 @@ extern unsigned short int __constant_ntohs(unsigned short int); extern __inline__ unsigned long int __ntohl(unsigned long int x) { - return (((x & 0x000000ffU) << 24) | - ((x & 0x0000ff00U) << 8) | - ((x & 0x00ff0000U) >> 8) | - ((x & 0xff000000U) >> 24)); + unsigned long int res, t1, t2; + + __asm__( + "# bswap input: %0 (aabbccdd)\n\t" + "# output: %0, used %1 %2\n\t" + "extlh %0,5,%1 # %1 = dd000000\n\t" + "zap %0,0xfd,%2 # %2 = 0000cc00\n\t" + "sll %2,5,%2 # %2 = 00198000\n\t" + "s8addq %2,%1,%1 # %1 = ddcc0000\n\t" + "zap %0,0xfb,%2 # %2 = 00bb0000\n\t" + "srl %2,8,%2 # %2 = 0000bb00\n\t" + "extbl %0,3,%0 # %0 = 000000aa\n\t" + "or %1,%0,%0 # %0 = ddcc00aa\n\t" + "or %2,%0,%0 # %0 = ddccbbaa\n" + : "r="(res), "r="(t1), "r="(t2) + : "0" (x & 0xffffffffUL)); + return res; } #define __constant_ntohl(x) \ -((unsigned int)((((unsigned int)(x) & 0x000000ffU) << 24) | \ - (((unsigned int)(x) & 0x0000ff00U) << 8) | \ - (((unsigned int)(x) & 0x00ff0000U) >> 8) | \ - (((unsigned int)(x) & 0xff000000U) >> 24))) + ((unsigned long int)((((x) & 0x000000ffUL) << 24) | \ + (((x) & 0x0000ff00UL) << 8) | \ + (((x) & 0x00ff0000UL) >> 8) | \ + (((x) & 0xff000000UL) >> 24))) extern __inline__ unsigned short int __ntohs(unsigned short int x) { - return (((x & 0x00ff) << 8) | - ((x & 0xff00) >> 8)); + unsigned long int res, t1; + + __asm__( + "# v0 is result; swap in-place.\n\t" + "bis %2,%2,%0 # v0 = aabb\n\t" + "extwh %0,7,%1 # t1 = bb00\n\t" + "extbl %0,1,%0 # v0 = 00aa\n\t" + "bis %0,%1,%0 # v0 = bbaa\n" + : "r="(res), "r="(t1) : "r"(x)); + return res; } #define __constant_ntohs(x) \ @@ -79,6 +121,8 @@ __ntohs(unsigned short int x) (__builtin_constant_p((short)(x)) ? \ __constant_htons((x)) : \ __htons((x))) -#endif +#endif /* __OPTIMIZE__ */ -#endif +#endif /* __GNUC__ */ + +#endif /* _ALPHA_BYTEORDER_H */ diff --git a/include/asm-alpha/checksum.h b/include/asm-alpha/checksum.h new file mode 100644 index 000000000..26c672521 --- /dev/null +++ b/include/asm-alpha/checksum.h @@ -0,0 +1,76 @@ +#ifndef _ALPHA_CHECKSUM_H +#define _ALPHA_CHECKSUM_H + + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl); + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +extern unsigned short int csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum); + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from user space (but on the alpha + * we have just one address space, so this is identical to the above) + */ +#define csum_partial_copy_fromuser csum_partial_copy + + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +extern unsigned short ip_compute_csum(unsigned char * buff, int len); + +/* + * Fold a partial checksum without adding pseudo headers + */ + +static inline unsigned short csum_fold(unsigned int sum) +{ + sum = (sum & 0xffff) + (sum >> 16); + sum = (sum & 0xffff) + (sum >> 16); + return ~sum; +} + +#define _HAVE_ARCH_IPV6_CSUM +extern unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int sum); + +#endif diff --git a/include/asm-alpha/cia.h b/include/asm-alpha/cia.h new file mode 100644 index 000000000..963cfa8c1 --- /dev/null +++ b/include/asm-alpha/cia.h @@ -0,0 +1,455 @@ +#ifndef __ALPHA_CIA__H__ +#define __ALPHA_CIA__H__ + +#include <linux/config.h> +#include <linux/types.h> + +/* + * CIA is the internal name for the 2117x chipset which provides + * memory controller and PCI access for the 21164 chip based systems. + * + * This file is based on: + * + * DECchip 21171 Core Logic Chipset + * Technical Reference Manual + * + * EC-QE18B-TE + * + * david.rusling@reo.mts.dec.com Initial Version. + * + */ + +/*------------------------------------------------------------------------** +** ** +** EB164 I/O procedures ** +** ** +** inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers ** +** inportbxt: 8 bits only ** +** inport: alias of inportw ** +** outport: alias of outportw ** +** ** +** inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers ** +** inmembxt: 8 bits only ** +** inmem: alias of inmemw ** +** outmem: alias of outmemw ** +** ** +**------------------------------------------------------------------------*/ + + +/* CIA ADDRESS BIT DEFINITIONS + * + * 3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * 9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | \_/ \_/ + * | | | + * +-- IO space, not cached. Byte Enable --+ | + * Transfer Length --+ + * + * + * + * Byte Transfer + * Enable Length Transfer Byte Address + * adr<6:5> adr<4:3> Length Enable Adder + * --------------------------------------------- + * 00 00 Byte 1110 0x000 + * 01 00 Byte 1101 0x020 + * 10 00 Byte 1011 0x040 + * 11 00 Byte 0111 0x060 + * + * 00 01 Word 1100 0x008 + * 01 01 Word 1001 0x028 <= Not supported in this code. + * 10 01 Word 0011 0x048 + * + * 00 10 Tribyte 1000 0x010 + * 01 10 Tribyte 0001 0x030 + * + * 10 11 Longword 0000 0x058 + * + * Note that byte enables are asserted low. + * + */ + +#define BYTE_ENABLE_SHIFT 5 +#define TRANSFER_LENGTH_SHIFT 3 +#define MEM_SP1_MASK 0x1fffffff /* Mem sparse space 1 mask is 29 bits */ + + +#define CIA_DMA_WIN_BASE (1024UL*1024UL*1024UL) +#define CIA_DMA_WIN_SIZE (1024*1024*1024) + +/* + * 21171-CA Control and Status Registers (p4-1) + */ +#define CIA_IOC_CIA_REV (IDENT_ADDR + 0x8740000080UL) +#define CIA_IOC_PCI_LAT (IDENT_ADDR + 0x87400000C0UL) +#define CIA_IOC_CIA_CTRL (IDENT_ADDR + 0x8740000100UL) +#define CIA_IOC_HAE_MEM (IDENT_ADDR + 0x8740000400UL) +#define CIA_IOC_HAE_IO (IDENT_ADDR + 0x8740000440UL) +#define CIA_IOC_CFG (IDENT_ADDR + 0x8740000480UL) +#define CIA_IOC_CACK_EN (IDENT_ADDR + 0x8740000600UL) + +/* + * 21171-CA Diagnostic Registers (p4-2) + */ +#define CIA_IOC_CIA_DIAG (IDENT_ADDR + 0x8740002000UL) +#define CIA_IOC_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL) + +/* + * 21171-CA Performance Monitor registers (p4-3) + */ +#define CIA_IOC_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL) +#define CIA_IOC_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL) + +/* + * 21171-CA Error registers (p4-3) + */ +#define CIA_IOC_CPU_ERR0 (IDENT_ADDR + 0x8740008000UL) +#define CIA_IOC_CPU_ERR1 (IDENT_ADDR + 0x8740008040UL) +#define CIA_IOC_CIA_ERR (IDENT_ADDR + 0x8740008200UL) +#define CIA_IOC_CIA_STAT (IDENT_ADDR + 0x8740008240UL) +#define CIA_IOC_ERR_MASK (IDENT_ADDR + 0x8740008280UL) +#define CIA_IOC_CIA_SYN (IDENT_ADDR + 0x8740008300UL) +#define CIA_IOC_MEM_ERR0 (IDENT_ADDR + 0x8740008400UL) +#define CIA_IOC_MEM_ERR1 (IDENT_ADDR + 0x8740008440UL) +#define CIA_IOC_PCI_ERR0 (IDENT_ADDR + 0x8740008800UL) +#define CIA_IOC_PCI_ERR1 (IDENT_ADDR + 0x8740008840UL) +#define CIA_IOC_PCI_ERR3 (IDENT_ADDR + 0x8740008880UL) + +/* + * 2117A-CA PCI Address Translation Registers. I've only defined + * the first window fully as that's the only one that we're currently using. + * The other window bases are needed to disable the windows. + */ +#define CIA_IOC_PCI_TBIA (IDENT_ADDR + 0x8760000100UL) +#define CIA_IOC_PCI_W0_BASE (IDENT_ADDR + 0x8760000400UL) +#define CIA_IOC_PCI_W0_MASK (IDENT_ADDR + 0x8760000440UL) +#define CIA_IOC_PCI_T0_BASE (IDENT_ADDR + 0x8760000480UL) + +#define CIA_IOC_PCI_W1_BASE (IDENT_ADDR + 0x8760000500UL) +#define CIA_IOC_PCI_W2_BASE (IDENT_ADDR + 0x8760000600UL) +#define CIA_IOC_PCI_W3_BASE (IDENT_ADDR + 0x8760000700UL) + +/* + * 21171-CA System configuration registers (p4-3) + */ +#define CIA_IOC_MCR (IDENT_ADDR + 0x8750000000UL) +#define CIA_IOC_MBA0 (IDENT_ADDR + 0x8750000600UL) +#define CIA_IOC_MBA2 (IDENT_ADDR + 0x8750000680UL) +#define CIA_IOC_MBA4 (IDENT_ADDR + 0x8750000700UL) +#define CIA_IOC_MBA6 (IDENT_ADDR + 0x8750000780UL) +#define CIA_IOC_MBA8 (IDENT_ADDR + 0x8750000800UL) +#define CIA_IOC_MBAA (IDENT_ADDR + 0x8750000880UL) +#define CIA_IOC_MBAC (IDENT_ADDR + 0x8750000900UL) +#define CIA_IOC_MBAE (IDENT_ADDR + 0x8750000980UL) +#define CIA_IOC_TMG0 (IDENT_ADDR + 0x8750000B00UL) +#define CIA_IOC_TMG1 (IDENT_ADDR + 0x8750000B40UL) +#define CIA_IOC_TMG2 (IDENT_ADDR + 0x8750000B80UL) + +/* + * Memory spaces: + */ +#define CIA_IACK_SC (IDENT_ADDR + 0x8720000000UL) +#define CIA_CONF (IDENT_ADDR + 0x8700000000UL) +#define CIA_IO (IDENT_ADDR + 0x8580000000UL) +#define CIA_SPARSE_MEM (IDENT_ADDR + 0x8000000000UL) +#define CIA_DENSE_MEM (IDENT_ADDR + 0x8600000000UL) + +/* + * ALCOR's GRU ASIC registers + */ +#define GRU_INT_REQ (IDENT_ADDR + 0x8780000000UL) +#define GRU_INT_MASK (IDENT_ADDR + 0x8780000040UL) +#define GRU_INT_EDGE (IDENT_ADDR + 0x8780000080UL) +#define GRU_INT_HILO (IDENT_ADDR + 0x87800000C0UL) +#define GRU_INT_CLEAR (IDENT_ADDR + 0x8780000100UL) + +#define GRU_CACHE_CNFG (IDENT_ADDR + 0x8780000200UL) +#define GRU_SCR (IDENT_ADDR + 0x8780000300UL) +#define GRU_LED (IDENT_ADDR + 0x8780000800UL) +#define GRU_RESET (IDENT_ADDR + 0x8780000900UL) + +#if defined(CONFIG_ALPHA_ALCOR) +#define GRU_INT_REQ_BITS 0x800fffffUL +#elif defined(CONFIG_ALPHA_XLT) +#define GRU_INT_REQ_BITS 0x80003fffUL +#else +#define GRU_INT_REQ_BITS 0xffffffffUL +#endif + +/* + * Bit definitions for I/O Controller status register 0: + */ +#define CIA_IOC_STAT0_CMD 0xf +#define CIA_IOC_STAT0_ERR (1<<4) +#define CIA_IOC_STAT0_LOST (1<<5) +#define CIA_IOC_STAT0_THIT (1<<6) +#define CIA_IOC_STAT0_TREF (1<<7) +#define CIA_IOC_STAT0_CODE_SHIFT 8 +#define CIA_IOC_STAT0_CODE_MASK 0x7 +#define CIA_IOC_STAT0_P_NBR_SHIFT 13 +#define CIA_IOC_STAT0_P_NBR_MASK 0x7ffff + +#define HAE_ADDRESS CIA_IOC_HAE_MEM + +#ifdef __KERNEL__ + +/* + * Translate physical memory address as seen on (PCI) bus into + * a kernel virtual address and vv. + */ +extern inline unsigned long virt_to_bus(void * address) +{ + return virt_to_phys(address) + CIA_DMA_WIN_BASE; +} + +extern inline void * bus_to_virt(unsigned long address) +{ + return phys_to_virt(address - CIA_DMA_WIN_BASE); +} + +/* + * I/O functions: + * + * CIA (the 2117x PCI/memory support chipset for the EV5 (21164) + * series of processors uses a sparse address mapping scheme to + * get at PCI memory and I/O. + */ + +#define vuip volatile unsigned int * + +extern inline unsigned int __inb(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + CIA_IO + 0x00); + result >>= (addr & 3) * 8; + return 0xffUL & result; +} + +extern inline void __outb(unsigned char b, unsigned long addr) +{ + unsigned int w; + + asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + CIA_IO + 0x00) = w; + mb(); +} + +extern inline unsigned int __inw(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + CIA_IO + 0x08); + result >>= (addr & 3) * 8; + return 0xffffUL & result; +} + +extern inline void __outw(unsigned short b, unsigned long addr) +{ + unsigned int w; + + asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + CIA_IO + 0x08) = w; + mb(); +} + +extern inline unsigned int __inl(unsigned long addr) +{ + return *(vuip) ((addr << 5) + CIA_IO + 0x18); +} + +extern inline void __outl(unsigned int b, unsigned long addr) +{ + *(vuip) ((addr << 5) + CIA_IO + 0x18) = b; + mb(); +} + + +/* + * Memory functions. 64-bit and 32-bit accesses are done through + * dense memory space, everything else through sparse space. + * + * For reading and writing 8 and 16 bit quantities we need to + * go through one of the three sparse address mapping regions + * and use the HAE_MEM CSR to provide some bits of the address. + * The following few routines use only sparse address region 1 + * which gives 1Gbyte of accessible space which relates exactly + * to the amount of PCI memory mapping *into* system address space. + * See p 6-17 of the specification but it looks something like this: + * + * 21164 Address: + * + * 3 2 1 + * 9876543210987654321098765432109876543210 + * 1ZZZZ0.PCI.QW.Address............BBLL + * + * ZZ = SBZ + * BB = Byte offset + * LL = Transfer length + * + * PCI Address: + * + * 3 2 1 + * 10987654321098765432109876543210 + * HHH....PCI.QW.Address........ 00 + * + * HHH = 31:29 HAE_MEM CSR + * + */ + +extern inline unsigned long __readb(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8 ; + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + result = *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x00) ; + result >>= shift; + return 0xffUL & result; +} + +extern inline unsigned long __readw(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8; + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + result = *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x08); + result >>= shift; + return 0xffffUL & result; +} + +extern inline unsigned long __readl(unsigned long addr) +{ + return *(vuip) (addr + CIA_DENSE_MEM); +} + +extern inline void __writeb(unsigned char b, unsigned long addr) +{ + unsigned long msb ; + + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x00) = b * 0x01010101; +} + +extern inline void __writew(unsigned short b, unsigned long addr) +{ + unsigned long msb ; + + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x08) = b * 0x00010001; +} + +extern inline void __writel(unsigned int b, unsigned long addr) +{ + *(vuip) (addr + CIA_DENSE_MEM) = b; +} + +#define inb(port) \ +(__builtin_constant_p((port))?__inb(port):_inb(port)) + +#define outb(x, port) \ +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) + +#define readl(a) __readl((unsigned long)(a)) +#define writel(v,a) __writel((v),(unsigned long)(a)) + +#undef vuip + +extern unsigned long cia_init (unsigned long mem_start, + unsigned long mem_end); + +#endif /* __KERNEL__ */ + +/* + * Data structure for handling CIA machine checks: + */ +/* ev5-specific info: */ +struct el_procdata { + unsigned long shadow[8]; /* PALmode shadow registers */ + unsigned long paltemp[24]; /* PAL temporary registers */ + /* EV5-specific fields */ + unsigned long exc_addr; /* Address of excepting instruction. */ + unsigned long exc_sum; /* Summary of arithmetic traps. */ + unsigned long exc_mask; /* Exception mask (from exc_sum). */ + unsigned long exc_base; /* PALbase at time of exception. */ + unsigned long isr; /* Interrupt summary register. */ + unsigned long icsr; /* Ibox control register. */ + unsigned long ic_perr_stat; + unsigned long dc_perr_stat; + unsigned long va; /* Effective VA of fault or miss. */ + unsigned long mm_stat; + unsigned long sc_addr; + unsigned long sc_stat; + unsigned long bc_tag_addr; + unsigned long ei_addr; + unsigned long fill_syn; + unsigned long ei_stat; + unsigned long ld_lock; +}; + +/* system-specific info: */ +struct el_CIA_sysdata_mcheck { + unsigned long coma_gcr; + unsigned long coma_edsr; + unsigned long coma_ter; + unsigned long coma_elar; + unsigned long coma_ehar; + unsigned long coma_ldlr; + unsigned long coma_ldhr; + unsigned long coma_base0; + unsigned long coma_base1; + unsigned long coma_base2; + unsigned long coma_cnfg0; + unsigned long coma_cnfg1; + unsigned long coma_cnfg2; + unsigned long epic_dcsr; + unsigned long epic_pear; + unsigned long epic_sear; + unsigned long epic_tbr1; + unsigned long epic_tbr2; + unsigned long epic_pbr1; + unsigned long epic_pbr2; + unsigned long epic_pmr1; + unsigned long epic_pmr2; + unsigned long epic_harx1; + unsigned long epic_harx2; + unsigned long epic_pmlt; + unsigned long epic_tag0; + unsigned long epic_tag1; + unsigned long epic_tag2; + unsigned long epic_tag3; + unsigned long epic_tag4; + unsigned long epic_tag5; + unsigned long epic_tag6; + unsigned long epic_tag7; + unsigned long epic_data0; + unsigned long epic_data1; + unsigned long epic_data2; + unsigned long epic_data3; + unsigned long epic_data4; + unsigned long epic_data5; + unsigned long epic_data6; + unsigned long epic_data7; +}; + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ADDR(x) (0x80 | (x)) +#define RTC_ALWAYS_BCD 0 + +#endif /* __ALPHA_CIA__H__ */ diff --git a/include/asm-alpha/dirent.h b/include/asm-alpha/dirent.h deleted file mode 100644 index 07fe9e9e0..000000000 --- a/include/asm-alpha/dirent.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ALPHA_DIRENT_H -#define _ALPHA_DIRENT_H - -struct dirent { - ino_t d_ino; - unsigned short d_reclen; - unsigned short d_namlen; - char d_name[256]; -}; - -#endif diff --git a/include/asm-alpha/dma.h b/include/asm-alpha/dma.h index 4b327266d..b5c3c1c7c 100644 --- a/include/asm-alpha/dma.h +++ b/include/asm-alpha/dma.h @@ -18,6 +18,8 @@ #ifndef _ASM_DMA_H #define _ASM_DMA_H +#include <linux/config.h> + #include <asm/io.h> /* need byte IO */ #define dma_outb outb @@ -73,8 +75,23 @@ #define MAX_DMA_CHANNELS 8 -/* The maximum address that we can perform a DMA transfer to on this platform */ -#define MAX_DMA_ADDRESS 0x1000000 +#ifdef CONFIG_ALPHA_XL +/* The maximum address that we can perform a DMA transfer to on Alpha XL, + due to a hardware SIO (PCI<->ISA bus bridge) chip limitation, is 64MB. + See <asm/apecs.h> for more info. +*/ +/* NOTE: we must define the maximum as something less than 64Mb, to prevent + virt_to_bus() from returning an address in the first window, for a + data area that goes beyond the 64Mb first DMA window. Sigh... + We MUST coordinate the maximum with <asm/apecs.h> for consistency. + For now, this limit is set to 48Mb... +*/ +#define MAX_DMA_ADDRESS (0xfffffc0003000000UL) +#else /* CONFIG_ALPHA_XL */ +/* The maximum address that we can perform a DMA transfer to on normal + Alpha platforms */ +#define MAX_DMA_ADDRESS (~0UL) +#endif /* CONFIG_ALPHA_XL */ /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ @@ -294,8 +311,7 @@ static __inline__ int get_dma_residue(unsigned int dmanr) /* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, char * device_id); /* reserve a DMA channel */ +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ - #endif /* _ASM_DMA_H */ diff --git a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h new file mode 100644 index 000000000..0cf5ecbec --- /dev/null +++ b/include/asm-alpha/elf.h @@ -0,0 +1,94 @@ +#ifndef __ASMaxp_ELF_H +#define __ASMaxp_ELF_H + +/* + * ELF register definitions.. + */ + +/* + * The OSF/1 version of <sys/procfs.h> makes gregset_t 46 entries long. + * I have no idea why that is so. For now, we just leave it at 33 + * (32 general regs + processor status word). + */ +#define ELF_NGREG 33 +#define ELF_NFPREG 32 + +typedef unsigned long elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x) == EM_ALPHA) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS64 +#define ELF_DATA ELFDATA2LSB; +#define ELF_ARCH EM_ALPHA + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 8192 + +/* $0 is set by ld.so to a pointer to a function which might be + registered using atexit. This provides a mean for the dynamic + linker to call DT_FINI functions for shared libraries that have + been loaded before the code runs. + + So that we can use the same startup file with static executables, + we start programs with a value of 0 to indicate that there is no + such function. */ + +#define ELF_PLAT_INIT(_r) _r->r0 = 0 + +/* Use the same format as the OSF/1 procfs interface. The register + layout is sane. However, since dump_thread() creates the funky + layout that ECOFF coredumps want, we need to undo that layout here. + Eventually, it would be nice if the ECOFF core-dump had to do the + translation, then ELF_CORE_COPY_REGS() would become trivial and + faster. */ +#define ELF_CORE_COPY_REGS(_dest,_regs) \ +{ \ + struct user _dump; \ + \ + dump_thread(_regs, &_dump); \ + _dest[ 0] = _dump.regs[EF_V0]; \ + _dest[ 1] = _dump.regs[EF_T0]; \ + _dest[ 2] = _dump.regs[EF_T1]; \ + _dest[ 3] = _dump.regs[EF_T2]; \ + _dest[ 4] = _dump.regs[EF_T3]; \ + _dest[ 5] = _dump.regs[EF_T4]; \ + _dest[ 6] = _dump.regs[EF_T5]; \ + _dest[ 7] = _dump.regs[EF_T6]; \ + _dest[ 8] = _dump.regs[EF_T7]; \ + _dest[ 9] = _dump.regs[EF_S0]; \ + _dest[10] = _dump.regs[EF_S1]; \ + _dest[11] = _dump.regs[EF_S2]; \ + _dest[12] = _dump.regs[EF_S3]; \ + _dest[13] = _dump.regs[EF_S4]; \ + _dest[14] = _dump.regs[EF_S5]; \ + _dest[15] = _dump.regs[EF_S6]; \ + _dest[16] = _dump.regs[EF_A0]; \ + _dest[17] = _dump.regs[EF_A1]; \ + _dest[18] = _dump.regs[EF_A2]; \ + _dest[19] = _dump.regs[EF_A3]; \ + _dest[20] = _dump.regs[EF_A4]; \ + _dest[21] = _dump.regs[EF_A5]; \ + _dest[22] = _dump.regs[EF_T8]; \ + _dest[23] = _dump.regs[EF_T9]; \ + _dest[24] = _dump.regs[EF_T10]; \ + _dest[25] = _dump.regs[EF_T11]; \ + _dest[26] = _dump.regs[EF_RA]; \ + _dest[27] = _dump.regs[EF_T12]; \ + _dest[28] = _dump.regs[EF_AT]; \ + _dest[29] = _dump.regs[EF_GP]; \ + _dest[30] = _dump.regs[EF_SP]; \ + _dest[31] = _dump.regs[EF_PC]; /* store PC here */ \ + _dest[32] = _dump.regs[EF_PS]; \ +} + +#endif diff --git a/include/asm-alpha/errno.h b/include/asm-alpha/errno.h index 45c1ea0d5..3641c3460 100644 --- a/include/asm-alpha/errno.h +++ b/include/asm-alpha/errno.h @@ -91,44 +91,49 @@ #define EILSEQ 116 /* Illegal byte sequence */ /* The following are just random noise.. */ -#define ECHRNG 44 /* Channel number out of range */ -#define EL2NSYNC 45 /* Level 2 not synchronized */ -#define EL3HLT 46 /* Level 3 halted */ -#define EL3RST 47 /* Level 3 reset */ -#define ELNRNG 48 /* Link number out of range */ -#define EUNATCH 49 /* Protocol driver not attached */ -#define ENOCSI 50 /* No CSI structure available */ -#define EL2HLT 51 /* Level 2 halted */ -#define EBADE 52 /* Invalid exchange */ -#define EBADR 53 /* Invalid request descriptor */ -#define EXFULL 54 /* Exchange full */ -#define ENOANO 55 /* No anode */ -#define EBADRQC 56 /* Invalid request code */ -#define EBADSLT 57 /* Invalid slot */ -#define EDEADLOCK 58 /* File locking deadlock error */ -#define EBFONT 59 /* Bad font file format */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOLINK 67 /* Link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define ENOTUNIQ 76 /* Name not unique on network */ -#define EBADFD 77 /* File descriptor in bad state */ -#define EREMCHG 78 /* Remote address changed */ -#define ELIBACC 79 /* Can not access a needed shared library */ -#define ELIBBAD 80 /* Accessing a corrupted shared library */ -#define ELIBSCN 81 /* .lib section in a.out corrupted */ -#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ -#define ELIBEXEC 83 /* Cannot exec a shared library directly */ -#define ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ +#define ECHRNG 88 /* Channel number out of range */ +#define EL2NSYNC 89 /* Level 2 not synchronized */ +#define EL3HLT 90 /* Level 3 halted */ +#define EL3RST 91 /* Level 3 reset */ + +#define ELNRNG 93 /* Link number out of range */ +#define EUNATCH 94 /* Protocol driver not attached */ +#define ENOCSI 95 /* No CSI structure available */ +#define EL2HLT 96 /* Level 2 halted */ +#define EBADE 97 /* Invalid exchange */ +#define EBADR 98 /* Invalid request descriptor */ +#define EXFULL 99 /* Exchange full */ +#define ENOANO 100 /* No anode */ +#define EBADRQC 101 /* Invalid request code */ +#define EBADSLT 102 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 104 /* Bad font file format */ +#define ENONET 105 /* Machine is not on the network */ +#define ENOLINK 106 /* Link has been severed */ +#define EADV 107 /* Advertise error */ +#define ESRMNT 108 /* Srmount error */ +#define ECOMM 109 /* Communication error on send */ +#define EMULTIHOP 110 /* Multihop attempted */ +#define EDOTDOT 111 /* RFS specific error */ +#define EOVERFLOW 112 /* Value too large for defined data type */ +#define ENOTUNIQ 113 /* Name not unique on network */ +#define EBADFD 114 /* File descriptor in bad state */ +#define EREMCHG 115 /* Remote address changed */ + #define EUCLEAN 117 /* Structure needs cleaning */ #define ENOTNAM 118 /* Not a XENIX named type file */ #define ENAVAIL 119 /* No XENIX semaphores available */ #define EISNAM 120 /* Is a named type file */ #define EREMOTEIO 121 /* Remote I/O error */ +#define ELIBACC 122 /* Can not access a needed shared library */ +#define ELIBBAD 123 /* Accessing a corrupted shared library */ +#define ELIBSCN 124 /* .lib section in a.out corrupted */ +#define ELIBMAX 125 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 126 /* Cannot exec a shared library directly */ +#define ERESTART 127 /* Interrupted system call should be restarted */ +#define ESTRPIPE 128 /* Streams pipe error */ + #endif diff --git a/include/asm-alpha/fcntl.h b/include/asm-alpha/fcntl.h index e4cd88361..3df5edf2b 100644 --- a/include/asm-alpha/fcntl.h +++ b/include/asm-alpha/fcntl.h @@ -33,20 +33,28 @@ /* for F_[GET|SET]FL */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ +/* for posix fcntl() and lockf() */ #define F_RDLCK 1 #define F_WRLCK 2 #define F_UNLCK 8 -/* For bsd flock () */ +/* for old implementation of bsd flock () */ #define F_EXLCK 16 /* or 3 */ #define F_SHLCK 32 /* or 4 */ +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + struct flock { short l_type; short l_whence; - off_t l_start; - off_t l_len; - pid_t l_pid; + __kernel_off_t l_start; + __kernel_off_t l_len; + __kernel_pid_t l_pid; }; #endif diff --git a/include/asm-alpha/floppy.h b/include/asm-alpha/floppy.h new file mode 100644 index 000000000..f5eae6ee2 --- /dev/null +++ b/include/asm-alpha/floppy.h @@ -0,0 +1,61 @@ +/* + * Architecture specific parts of the Floppy driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 + */ +#ifndef __ASM_ALPHA_FLOPPY_H +#define __ASM_ALPHA_FLOPPY_H + +#include <linux/config.h> + +#define fd_inb(port) inb_p(port) +#define fd_outb(value,port) outb_p(value,port) + +#define fd_enable_dma() enable_dma(FLOPPY_DMA) +#define fd_disable_dma() disable_dma(FLOPPY_DMA) +#define fd_request_dma() request_dma(FLOPPY_DMA,"floppy") +#define fd_free_dma() free_dma(FLOPPY_DMA) +#define fd_clear_dma_ff() clear_dma_ff(FLOPPY_DMA) +#define fd_set_dma_mode(mode) set_dma_mode(FLOPPY_DMA,mode) +#define fd_set_dma_addr(addr) set_dma_addr(FLOPPY_DMA,virt_to_bus(addr)) +#define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA,count) +#define fd_enable_irq() enable_irq(FLOPPY_IRQ) +#define fd_disable_irq() disable_irq(FLOPPY_IRQ) +#define fd_cacheflush(addr,size) /* nothing */ +#define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \ + SA_INTERRUPT|SA_SAMPLE_RANDOM, \ + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL); + +__inline__ void virtual_dma_init(void) +{ + /* Nothing to do on an Alpha */ +} + +static int FDC1 = 0x3f0; +static int FDC2 = -1; + +/* + * Again, the CMOS information doesn't work on the alpha.. + */ +#define FLOPPY0_TYPE 6 +#define FLOPPY1_TYPE 0 + +#define N_FDC 2 +#define N_DRIVE 8 + +/* + * Most Alphas have no problems with floppy DMA crossing 64k borders. Sigh... + */ +#ifdef CONFIG_ALPHA_XL +#define CROSS_64KB(a,s) \ + ((unsigned long)(a)/0x10000 != ((unsigned long)(a) + (s) - 1) / 0x10000) +#else /* CONFIG_ALPHA_XL */ +#define CROSS_64KB(a,s) (0) +#endif /* CONFIG_ALPHA_XL */ + +#endif /* __ASM_ALPHA_FLOPPY_H */ diff --git a/include/asm-alpha/fpu.h b/include/asm-alpha/fpu.h new file mode 100644 index 000000000..f32b95f27 --- /dev/null +++ b/include/asm-alpha/fpu.h @@ -0,0 +1,64 @@ +#ifndef __ASM_ALPHA_FPU_H +#define __ASM_ALPHA_FPU_H + +/* + * Alpha floating-point control register defines: + */ +#define FPCR_INVD (1UL<<49) /* invalid op disable (opt.) */ +#define FPCR_DZED (1UL<<50) /* division by zero disable (opt.) */ +#define FPCR_OVFD (1UL<<51) /* overflow disable (optional) */ +#define FPCR_INV (1UL<<52) /* invalid operation */ +#define FPCR_DZE (1UL<<53) /* division by zero */ +#define FPCR_OVF (1UL<<54) /* overflow */ +#define FPCR_UNF (1UL<<55) /* underflow */ +#define FPCR_INE (1UL<<56) /* inexact */ +#define FPCR_IOV (1UL<<57) /* integer overflow */ +#define FPCR_UNDZ (1UL<<60) /* underflow to zero (opt.) */ +#define FPCR_UNFD (1UL<<61) /* underflow disable (opt.) */ +#define FPCR_INED (1UL<<62) /* inexact disable (opt.) */ +#define FPCR_SUM (1UL<<63) /* summary bit */ + +#define FPCR_DYN_SHIFT 58 /* first dynamic rounding mode bit */ +#define FPCR_DYN_CHOPPED (0x0UL << FPCR_DYN_SHIFT) /* towards 0 */ +#define FPCR_DYN_MINUS (0x1UL << FPCR_DYN_SHIFT) /* towards -INF */ +#define FPCR_DYN_NORMAL (0x2UL << FPCR_DYN_SHIFT) /* towards nearest */ +#define FPCR_DYN_PLUS (0x3UL << FPCR_DYN_SHIFT) /* towards +INF */ +#define FPCR_DYN_MASK (0x3UL << FPCR_DYN_SHIFT) + +#define FPCR_MASK 0xfffe000000000000 + +/* + * IEEE trap enables are implemented in software. These per-thread + * bits are stored in the "flags" field of "struct thread_struct". + * Thus, the bits are defined so as not to conflict with the + * floating-point enable bit (which is architected). On top of that, + * we want to make these bits compatible with OSF/1 so + * ieee_set_fp_control() etc. can be implemented easily and + * compatibly. The corresponding definitions are in + * /usr/include/machine/fpu.h under OSF/1. + */ +#define IEEE_TRAP_ENABLE_INV (1<<1) /* invalid op */ +#define IEEE_TRAP_ENABLE_DZE (1<<2) /* division by zero */ +#define IEEE_TRAP_ENABLE_OVF (1<<3) /* overflow */ +#define IEEE_TRAP_ENABLE_UNF (1<<4) /* underflow */ +#define IEEE_TRAP_ENABLE_INE (1<<5) /* inexact */ +#define IEEE_TRAP_ENABLE_MASK (IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE |\ + IEEE_TRAP_ENABLE_OVF | IEEE_TRAP_ENABLE_UNF |\ + IEEE_TRAP_ENABLE_INE) + +/* status bits coming from fpcr: */ +#define IEEE_STATUS_INV (1<<17) +#define IEEE_STATUS_DZE (1<<18) +#define IEEE_STATUS_OVF (1<<19) +#define IEEE_STATUS_UNF (1<<20) +#define IEEE_STATUS_INE (1<<21) + +#define IEEE_STATUS_MASK (IEEE_STATUS_INV | IEEE_STATUS_DZE | \ + IEEE_STATUS_OVF | IEEE_STATUS_UNF | \ + IEEE_STATUS_INE) + +#define IEEE_STATUS_TO_EXCSUM_SHIFT 16 + +#define IEEE_INHERIT (1UL<<63) /* inherit on thread create? */ + +#endif /* __ASM_ALPHA_FPU_H */ diff --git a/include/asm-alpha/gentrap.h b/include/asm-alpha/gentrap.h new file mode 100644 index 000000000..ae50cc319 --- /dev/null +++ b/include/asm-alpha/gentrap.h @@ -0,0 +1,37 @@ +#ifndef _ASMAXP_GENTRAP_H +#define _ASMAXP_GENTRAP_H + +/* + * Definitions for gentrap causes. They are generated by user-level + * programs and therefore should be compatible with the corresponding + * OSF/1 definitions. + */ +#define GEN_INTOVF -1 /* integer overflow */ +#define GEN_INTDIV -2 /* integer division by zero */ +#define GEN_FLTOVF -3 /* fp overflow */ +#define GEN_FLTDIV -4 /* fp division by zero */ +#define GEN_FLTUND -5 /* fp underflow */ +#define GEN_FLTINV -6 /* invalid fp operand */ +#define GEN_FLTINE -7 /* inexact fp operand */ +#define GEN_DECOVF -8 /* decimal overflow (for COBOL??) */ +#define GEN_DECDIV -9 /* decimal division by zero */ +#define GEN_DECINV -10 /* invalid decimal operand */ +#define GEN_ROPRAND -11 /* reserved operand */ +#define GEN_ASSERTERR -12 /* assertion error */ +#define GEN_NULPTRERR -13 /* null pointer error */ +#define GEN_STKOVF -14 /* stack overflow */ +#define GEN_STRLENERR -15 /* string length error */ +#define GEN_SUBSTRERR -16 /* substring error */ +#define GEN_RANGERR -17 /* range error */ +#define GEN_SUBRNG -18 +#define GEN_SUBRNG1 -19 +#define GEN_SUBRNG2 -20 +#define GEN_SUBRNG3 -21 /* these report range errors for */ +#define GEN_SUBRNG4 -22 /* subscripting (indexing) at levels 0..7 */ +#define GEN_SUBRNG5 -23 +#define GEN_SUBRNG6 -24 +#define GEN_SUBRNG7 -25 + +/* the remaining codes (-26..-1023) are reserved. */ + +#endif /* _ASMAXP_GENTRAP_H */ diff --git a/include/asm-alpha/hwrpb.h b/include/asm-alpha/hwrpb.h index 35204d7c2..662aa35f6 100644 --- a/include/asm-alpha/hwrpb.h +++ b/include/asm-alpha/hwrpb.h @@ -13,28 +13,33 @@ #define LCA4_CPU 4 /* LCA4 (21066/21068) */ #define EV5_CPU 5 /* EV5 (21164) */ #define EV45_CPU 6 /* EV4.5 (21064/xxx) */ +#define EV56_CPU 7 /* EV5.6 (21164) */ +#define EV6_CPU 8 /* EV6 (21164) */ /* * DEC system types for Alpha systems. Found in HWRPB. * These values are architected. */ -#define ST_ADU 1 /* Alpha ADU systype */ -#define ST_DEC_4000 2 /* Cobra systype */ -#define ST_DEC_7000 3 /* Ruby systype */ -#define ST_DEC_3000_500 4 /* Flamingo systype */ -#define ST_DEC_2000_300 6 /* Jensen systype */ -#define ST_DEC_3000_300 7 /* Pelican systype */ -#define ST_DEC_2100_A500 9 /* Sable systype */ -#define ST_DEC_AXPVME_64 10 /* AXPvme system type */ -#define ST_DEC_AXPPCI_33 11 /* NoName system type */ -#define ST_DEC_TLASER 12 /* Turbolaser systype */ -#define ST_DEC_2100_A50 13 /* Avanti systype */ -#define ST_DEC_MUSTANG 14 /* Mustang systype */ -#define ST_DEC_ALCOR 15 /* Alcor systype */ -#define ST_DEC_1000 17 /* Mikasa systype */ -#define ST_DEC_EB66 19 /* EB66 systype */ -#define ST_DEC_EB64P 20 /* EB64+ systype */ +#define ST_ADU 1 /* Alpha ADU systype */ +#define ST_DEC_4000 2 /* Cobra systype */ +#define ST_DEC_7000 3 /* Ruby systype */ +#define ST_DEC_3000_500 4 /* Flamingo systype */ +#define ST_DEC_2000_300 6 /* Jensen systype */ +#define ST_DEC_3000_300 7 /* Pelican systype */ +#define ST_DEC_2100_A500 9 /* Sable systype */ +#define ST_DEC_AXPVME_64 10 /* AXPvme system type */ +#define ST_DEC_AXPPCI_33 11 /* NoName system type */ +#define ST_DEC_TLASER 12 /* Turbolaser systype */ +#define ST_DEC_2100_A50 13 /* Avanti systype */ +#define ST_DEC_MUSTANG 14 /* Mustang systype */ +#define ST_DEC_ALCOR 15 /* Alcor (EV5) systype */ +#define ST_DEC_1000 17 /* Mikasa systype */ +#define ST_DEC_EB66 19 /* EB66 systype */ +#define ST_DEC_EB64P 20 /* EB64+ systype */ +#define ST_DEC_EB66P -19 /* EB66 systype */ +#define ST_DEC_EBPC64 -20 /* Cabriolet (AlphaPC64) systype */ +#define ST_DEC_EB164 26 /* EB164 systype */ struct pcb_struct { unsigned long ksp; diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h new file mode 100644 index 000000000..6ad91b1d7 --- /dev/null +++ b/include/asm-alpha/ide.h @@ -0,0 +1,119 @@ +/* + * linux/include/asm-alpha/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* + * This file contains the alpha architecture specific IDE code. + */ + +#ifndef __ASMalpha_IDE_H +#define __ASMalpha_IDE_H + +#ifdef __KERNEL__ + +typedef unsigned short ide_ioreg_t; + +#ifndef MAX_HWIFS +#define MAX_HWIFS 4 +#endif + +#define ide_sti() sti() + +static __inline__ int ide_default_irq(ide_ioreg_t base) +{ + switch (base) { + case 0x1f0: return 14; + case 0x170: return 15; + case 0x1e8: return 11; + case 0x168: return 10; + default: + return 0; + } +} + +static __inline__ ide_ioreg_t ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + case 2: return 0x1e8; + case 3: return 0x168; + default: + return 0; + } +} + +static __inline__ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) +{ + ide_ioreg_t port = base; + int i = 8; + + while (i--) + *p++ = port++; + *p++ = base + 0x206; + if (irq != NULL) + *irq = 0; +} + +typedef union { + unsigned all : 8; /* all of the bits together */ + struct { + unsigned head : 4; /* always zeros here */ + unsigned unit : 1; /* drive select number, 0 or 1 */ + unsigned bit5 : 1; /* always 1 */ + unsigned lba : 1; /* using LBA instead of CHS */ + unsigned bit7 : 1; /* always 1 */ + } b; + } select_t; + +static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *device, void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name) +{ + request_region(from, extent, name); +} + +static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +/* + * The following are not needed for the non-m68k ports + */ +static __inline__ int ide_ack_intr (ide_ioreg_t base_port, ide_ioreg_t irq_port) +{ + return(1); +} + +static __inline__ void ide_fix_driveid(struct hd_driveid *id) +{ +} + +static __inline__ void ide_release_lock (int *ide_lock) +{ +} + +static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data) +{ +} + +#endif /* __KERNEL__ */ + +#endif /* __ASMalpha_IDE_H */ diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h index e567c750b..ed6cffc1f 100644 --- a/include/asm-alpha/io.h +++ b/include/asm-alpha/io.h @@ -5,6 +5,10 @@ #include <asm/system.h> +/* We don't use IO slowdowns on the alpha, but.. */ +#define __SLOW_DOWN_IO do { } while (0) +#define SLOW_DOWN_IO do { } while (0) + /* * The hae (hardware address extension) register is used to * access high IO addresses. To avoid doing an external cycle @@ -19,6 +23,13 @@ extern struct hae { } hae; /* + * Virtual -> physical identity mapping starts at this offset + */ +#define IDENT_ADDR (0xfffffc0000000000UL) + +#ifdef __KERNEL__ + +/* * We try to avoid hae updates (thus the cache), but when we * do need to update the hae, we need to do it atomically, so * that any interrupts wouldn't get confused with the hae @@ -35,14 +46,9 @@ extern inline void set_hae(unsigned long new_hae) } /* - * Virtual -> physical identity mapping starts at this offset - */ -#define IDENT_ADDR (0xfffffc0000000000UL) - -/* * Change virtual addresses to physical addresses and vv. */ -extern inline unsigned long virt_to_phys(void * address) +extern inline unsigned long virt_to_phys(volatile void * address) { return 0xffffffffUL & (unsigned long) address; } @@ -52,15 +58,179 @@ extern inline void * phys_to_virt(unsigned long address) return (void *) (address + IDENT_ADDR); } +#else /* !__KERNEL__ */ + +/* + * Define actual functions in private name-space so it's easier to + * accommodate things like XFree or svgalib that like to define their + * own versions of inb etc. + */ +extern void __sethae (unsigned long addr); /* syscall */ +extern void _sethae (unsigned long addr); /* cached version */ + +#endif /* !__KERNEL__ */ + /* - * There are different version of the alpha motherboards: the - * "interesting" (read: slightly braindead) Jensen type hardware - * and the PCI version + * There are different chipsets to interface the Alpha CPUs to the world. */ -#ifdef CONFIG_PCI -#include <asm/lca.h> /* get chip-specific definitions */ +#if defined(CONFIG_ALPHA_LCA) +# include <asm/lca.h> /* get chip-specific definitions */ +#elif defined(CONFIG_ALPHA_APECS) +# include <asm/apecs.h> /* get chip-specific definitions */ +#elif defined(CONFIG_ALPHA_CIA) +# include <asm/cia.h> /* get chip-specific definitions */ #else -#include <asm/jensen.h> +# include <asm/jensen.h> #endif +/* + * The convention used for inb/outb etc. is that names starting with + * two underscores are the inline versions, names starting with a + * single underscore are proper functions, and names starting with a + * letter are macros that map in some way to inline or proper function + * versions. Not all that pretty, but before you change it, be sure + * to convince yourself that it won't break anything (in particular + * module support). + */ +extern unsigned int _inb (unsigned long port); +extern unsigned int _inw (unsigned long port); +extern unsigned int _inl (unsigned long port); +extern void _outb (unsigned char b,unsigned long port); +extern void _outw (unsigned short w,unsigned long port); +extern void _outl (unsigned int l,unsigned long port); +extern unsigned long _readb(unsigned long addr); +extern unsigned long _readw(unsigned long addr); +extern unsigned long _readl(unsigned long addr); +extern void _writeb(unsigned char b, unsigned long addr); +extern void _writew(unsigned short b, unsigned long addr); +extern void _writel(unsigned int b, unsigned long addr); + +/* + * The platform header files may define some of these macros to use + * the inlined versions where appropriate. These macros may also be + * redefined by userlevel programs. + */ +#ifndef inb +# define inb(p) _inb((p)) +#endif +#ifndef inw +# define inw(p) _inw((p)) +#endif +#ifndef inl +# define inl(p) _inl((p)) +#endif +#ifndef outb +# define outb(b,p) _outb((b),(p)) +#endif +#ifndef outw +# define outw(w,p) _outw((w),(p)) +#endif +#ifndef outl +# define outl(l,p) _outl((l),(p)) +#endif + +#ifndef inb_p +# define inb_p inb +#endif +#ifndef inw_p +# define inw_p inw +#endif +#ifndef inl_p +# define inl_p inl +#endif + +#ifndef outb_p +# define outb_p outb +#endif +#ifndef outw_p +# define outw_p outw +#endif +#ifndef outl_p +# define outl_p outl +#endif + +/* + * The "address" in IO memory space is not clearly either an integer or a + * pointer. We will accept both, thus the casts. + * + * On the alpha, we have the whole physical address space mapped at all + * times, so "ioremap()" and "iounmap()" do not need to do anything. + */ +extern inline void * ioremap(unsigned long offset, unsigned long size) +{ + return (void *) offset; +} + +extern inline void iounmap(void *addr) +{ +} + +#ifndef readb +# define readb(a) _readb((unsigned long)(a)) +#endif +#ifndef readw +# define readw(a) _readw((unsigned long)(a)) +#endif +#ifndef readl +# define readl(a) _readl((unsigned long)(a)) +#endif +#ifndef writeb +# define writeb(v,a) _writeb((v),(unsigned long)(a)) +#endif +#ifndef writew +# define writew(v,a) _writew((v),(unsigned long)(a)) +#endif +#ifndef writel +# define writel(v,a) _writel((v),(unsigned long)(a)) +#endif + +#ifdef __KERNEL__ + +/* + * String version of IO memory access ops: + */ +extern void _memcpy_fromio(void *, unsigned long, unsigned long); +extern void _memcpy_toio(unsigned long, void *, unsigned long); +extern void _memset_io(unsigned long, int, unsigned long); + +#define memcpy_fromio(to,from,len) _memcpy_fromio((to),(unsigned long)(from),(len)) +#define memcpy_toio(to,from,len) _memcpy_toio((unsigned long)(to),(from),(len)) +#define memset_io(addr,c,len) _memset_io((unsigned long)(addr),(c),(len)) + +/* + * String versions of in/out ops: + */ +extern void insb (unsigned long port, void *dst, unsigned long count); +extern void insw (unsigned long port, void *dst, unsigned long count); +extern void insl (unsigned long port, void *dst, unsigned long count); +extern void outsb (unsigned long port, const void *src, unsigned long count); +extern void outsw (unsigned long port, const void *src, unsigned long count); +extern void outsl (unsigned long port, const void *src, unsigned long count); + +/* + * XXX - We don't have csum_partial_copy_fromio() yet, so we cheat here and + * just copy it. The net code will then do the checksum later. Presently + * only used by some shared memory 8390 ethernet cards anyway. + */ + +#define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len)) + +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#endif /* __KERNEL__ */ + #endif diff --git a/include/asm-alpha/ioctl.h b/include/asm-alpha/ioctl.h index a981caadf..fc63727f4 100644 --- a/include/asm-alpha/ioctl.h +++ b/include/asm-alpha/ioctl.h @@ -36,11 +36,12 @@ #define _IOC_READ 2U #define _IOC_WRITE 4U -#define _IOC(dir,type,nr,size) \ - (((dir) << _IOC_DIRSHIFT) | \ - ((type) << _IOC_TYPESHIFT) | \ - ((nr) << _IOC_NRSHIFT) | \ - ((size) << _IOC_SIZESHIFT)) +#define _IOC(dir,type,nr,size) \ + ((unsigned int) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT))) /* used to create numbers */ #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) @@ -54,4 +55,12 @@ #define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) #define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) -#endif +/* ...and for the drivers/sound files... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* _ALPHA_IOCTL_H */ diff --git a/include/asm-alpha/ioctls.h b/include/asm-alpha/ioctls.h new file mode 100644 index 000000000..bb4f71de8 --- /dev/null +++ b/include/asm-alpha/ioctls.h @@ -0,0 +1,102 @@ +#ifndef _ASM_ALPHA_IOCTLS_H +#define _ASM_ALPHA_IOCTLS_H + +#include <asm/ioctl.h> + +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD + +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCSETP _IOW('t', 9, struct sgttyb) +#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ + +#define TIOCSETC _IOW('t', 17, struct tchars) +#define TIOCGETC _IOR('t', 18, struct tchars) +#define TCGETS _IOR('t', 19, struct termios) +#define TCSETS _IOW('t', 20, struct termios) +#define TCSETSW _IOW('t', 21, struct termios) +#define TCSETSF _IOW('t', 22, struct termios) + +#define TCGETA _IOR('t', 23, struct termio) +#define TCSETA _IOW('t', 24, struct termio) +#define TCSETAW _IOW('t', 25, struct termio) +#define TCSETAF _IOW('t', 28, struct termio) + +#define TCSBRK _IO('t', 29) +#define TCXONC _IO('t', 30) +#define TCFLSH _IO('t', 31) + +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ + +#define TIOCGLTC _IOR('t', 116, struct ltchars) +#define TIOCSLTC _IOW('t', 117, struct ltchars) +#define TIOCSPGRP _IOW('t', 118, int) +#define TIOCGPGRP _IOR('t', 119, int) + +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E + +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +# define TIOCM_LE 0x001 +# define TIOCM_DTR 0x002 +# define TIOCM_RTS 0x004 +# define TIOCM_ST 0x008 +# define TIOCM_SR 0x010 +# define TIOCM_CTS 0x020 +# define TIOCM_CAR 0x040 +# define TIOCM_RNG 0x080 +# define TIOCM_DSR 0x100 +# define TIOCM_CD TIOCM_CAR +# define TIOCM_RI TIOCM_RNG + +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +# define TIOCPKT_DATA 0 +# define TIOCPKT_FLUSHREAD 1 +# define TIOCPKT_FLUSHWRITE 2 +# define TIOCPKT_STOP 4 +# define TIOCPKT_START 8 +# define TIOCPKT_NOSTOP 16 +# define TIOCPKT_DOSTOP 32 + + +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ + +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ + /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +#endif /* _ASM_ALPHA_IOCTLS_H */ diff --git a/include/asm-alpha/irq.h b/include/asm-alpha/irq.h index 2a7421aef..bf2a380e9 100644 --- a/include/asm-alpha/irq.h +++ b/include/asm-alpha/irq.h @@ -8,6 +8,18 @@ */ #include <linux/linkage.h> +#include <linux/config.h> + +#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) || defined(CONFIG_ALPHA_EB164) || defined(CONFIG_ALPHA_PC164) +# define NR_IRQS 33 +#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P) || defined(CONFIG_ALPHA_MIKASA) +# define NR_IRQS 32 +#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT) +# define NR_IRQS 48 +#else +# define NR_IRQS 16 +#endif + extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); diff --git a/include/asm-alpha/jensen.h b/include/asm-alpha/jensen.h index 952d56375..7a3b07851 100644 --- a/include/asm-alpha/jensen.h +++ b/include/asm-alpha/jensen.h @@ -95,6 +95,8 @@ extern inline void __set_hae(unsigned long addr) set_hae(addr); } +#ifdef __KERNEL__ + /* * IO functions * @@ -118,8 +120,9 @@ extern inline void __local_outb(unsigned char b, unsigned long addr) mb(); } -extern unsigned int __bus_inb(unsigned long addr); -extern inline unsigned int ___bus_inb(unsigned long addr) +extern unsigned int _bus_inb(unsigned long addr); + +extern inline unsigned int __bus_inb(unsigned long addr) { long result; @@ -129,8 +132,9 @@ extern inline unsigned int ___bus_inb(unsigned long addr) return 0xffUL & result; } -extern void __bus_outb(unsigned char b, unsigned long addr); -extern inline void ___bus_outb(unsigned char b, unsigned long addr) +extern void _bus_outb(unsigned char b, unsigned long addr); + +extern inline void __bus_outb(unsigned char b, unsigned long addr) { __set_hae(0); *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x00) = b * 0x01010101; @@ -153,7 +157,7 @@ extern inline unsigned int __inb(unsigned long addr) { if (__is_local(addr)) return __local_inb(addr); - return __bus_inb(addr); + return _bus_inb(addr); } extern inline void __outb(unsigned char b, unsigned long addr) @@ -161,7 +165,7 @@ extern inline void __outb(unsigned char b, unsigned long addr) if (__is_local(addr)) __local_outb(b, addr); else - __bus_outb(b, addr); + _bus_outb(b, addr); } extern inline unsigned int __inw(unsigned long addr) @@ -251,30 +255,13 @@ extern inline void __writel(unsigned int b, unsigned long addr) * The above have so much overhead that it probably doesn't make * sense to have them inlined (better icache behaviour). */ -extern unsigned int inb(unsigned long addr); -extern unsigned int inw(unsigned long addr); -extern unsigned int inl(unsigned long addr); - -extern void outb(unsigned char b, unsigned long addr); -extern void outw(unsigned short b, unsigned long addr); -extern void outl(unsigned int b, unsigned long addr); - -extern unsigned long readb(unsigned long addr); -extern unsigned long readw(unsigned long addr); -extern unsigned long readl(unsigned long addr); - -extern void writeb(unsigned short b, unsigned long addr); -extern void writew(unsigned short b, unsigned long addr); -extern void writel(unsigned int b, unsigned long addr); - #define inb(port) \ -(__builtin_constant_p((port))?__inb(port):(inb)(port)) +(__builtin_constant_p((port))?__inb(port):_inb(port)) #define outb(x, port) \ -(__builtin_constant_p((port))?__outb((x),(port)):(outb)((x),(port))) +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) -#define inb_p inb -#define outb_p outb +#endif /* __KERNEL__ */ /* * The Alpha Jensen hardware for some rather strange reason puts diff --git a/include/asm-alpha/keyboard.h b/include/asm-alpha/keyboard.h new file mode 100644 index 000000000..6aca53255 --- /dev/null +++ b/include/asm-alpha/keyboard.h @@ -0,0 +1,176 @@ +/* + * CPU specific parts of the keyboard driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef __ASM_ALPHA_KEYBOARD_H +#define __ASM_ALPHA_KEYBOARD_H + +#include <asm/io.h> + +#define KEYBOARD_IRQ 1 + +static int initialize_kbd(void); + +#define kbd_inb_p(port) inb_p(port) +#define kbd_inb(port) inb(port) +#define kbd_outb_p(data,port) outb_p(data,port) +#define kbd_outb(data,port) outb(data,port) + +static int +kbd_wait_for_input(void) +{ + int n; + int status, data; + + n = TIMEOUT_CONST; + do { + status = kbd_inb(KBD_STATUS_REG); + /* + * Wait for input data to become available. This bit will + * then be cleared by the following read of the DATA + * register. + */ + + if (!(status & KBD_OBF)) + continue; + + data = kbd_inb(KBD_DATA_REG); + + /* + * Check to see if a timeout error has occurred. This means + * that transmission was started but did not complete in the + * normal time cycle. PERR is set when a parity error occurred + * in the last transmission. + */ + if (status & (KBD_GTO | KBD_PERR)) { + continue; + } + return (data & 0xff); + } while (--n); + return (-1); /* timed-out if fell through to here... */ +} + +static void +kbd_write(int address, int data) +{ + int status; + + do { + status = kbd_inb(KBD_STATUS_REG); /* spin until input buffer empty*/ + } while (status & KBD_IBF); + kbd_outb(data, address); /* write out the data*/ +} + +static int +initialize_kbd(void) +{ + unsigned long flags; + + save_flags(flags); cli(); + + /* Flush any pending input. */ + while (kbd_wait_for_input() != -1) + continue; + + /* + * Test the keyboard interface. + * This seems to be the only way to get it going. + * If the test is successful a x55 is placed in the input buffer. + */ + kbd_write(KBD_CNTL_REG, KBD_SELF_TEST); + if (kbd_wait_for_input() != 0x55) { + printk(KERN_WARNING "initialize_kbd: " + "keyboard failed self test.\n"); + restore_flags(flags); + return(-1); + } + + /* + * Perform a keyboard interface test. This causes the controller + * to test the keyboard clock and data lines. The results of the + * test are placed in the input buffer. + */ + kbd_write(KBD_CNTL_REG, KBD_SELF_TEST2); + if (kbd_wait_for_input() != 0x00) { + printk(KERN_WARNING "initialize_kbd: " + "keyboard failed self test 2.\n"); + restore_flags(flags); + return(-1); + } + + /* Enable the keyboard by allowing the keyboard clock to run. */ + kbd_write(KBD_CNTL_REG, KBD_CNTL_ENABLE); + + /* + * Reset keyboard. If the read times out + * then the assumption is that no keyboard is + * plugged into the machine. + * This defaults the keyboard to scan-code set 2. + */ + kbd_write(KBD_DATA_REG, KBD_RESET); + if (kbd_wait_for_input() != KBD_ACK) { + printk(KERN_WARNING "initialize_kbd: " + "reset kbd failed, no ACK.\n"); + restore_flags(flags); + return(-1); + } + + /* + * Give the keyboard some time to breathe ... + * ... or it fucks up the floppy controller, too. Wiered. + */ + udelay(20); + + if (kbd_wait_for_input() != KBD_POR) { + printk(KERN_WARNING "initialize_kbd: " + "reset kbd failed, not POR.\n"); + restore_flags(flags); + return(-1); + } + + /* + * now do a DEFAULTS_DISABLE always + */ + kbd_write(KBD_DATA_REG, KBD_DISABLE); + if (kbd_wait_for_input() != KBD_ACK) { + printk(KERN_WARNING "initialize_kbd: " + "disable kbd failed, no ACK.\n"); + restore_flags(flags); + return(-1); + } + + /* + * Enable keyboard interrupt, operate in "sys" mode, + * enable keyboard (by clearing the disable keyboard bit), + * disable mouse, do conversion of keycodes. + */ + kbd_write(KBD_CNTL_REG, KBD_WRITE_MODE); + kbd_write(KBD_DATA_REG, KBD_EKI|KBD_SYS|KBD_DMS|KBD_KCC); + + /* + * now ENABLE the keyboard to set it scanning... + */ + kbd_write(KBD_DATA_REG, KBD_ENABLE); + if (kbd_wait_for_input() != KBD_ACK) { + printk(KERN_WARNING "initialize_kbd: " + "keyboard enable failed.\n"); + restore_flags(flags); + return(-1); + } + + restore_flags(flags); + + return (1); +} + +extern __inline__ void +keyboard_setup() +{ + request_region(0x60,16,"keyboard"); + initialize_kbd(); +} + +#endif /* __ASM_ALPHA_KEYBOARD_H */ diff --git a/include/asm-alpha/lca.h b/include/asm-alpha/lca.h index c3f58650f..43c6e9eca 100644 --- a/include/asm-alpha/lca.h +++ b/include/asm-alpha/lca.h @@ -1,5 +1,5 @@ -#ifndef __ALPHA_LCA__H -#define __ALPHA_LCA__H +#ifndef __ALPHA_LCA__H__ +#define __ALPHA_LCA__H__ /* * Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068, @@ -52,24 +52,12 @@ * ugh). */ +#include <asm/system.h> + #define LCA_DMA_WIN_BASE (1024*1024*1024) #define LCA_DMA_WIN_SIZE (1024*1024*1024) /* - * Translate physical memory address as seen on (PCI) bus into - * a kernel virtual address and vv. - */ -extern inline unsigned long virt_to_bus(void * address) -{ - return virt_to_phys(address) + LCA_DMA_WIN_BASE; -} - -extern inline void * bus_to_virt(unsigned long address) -{ - return phys_to_virt(address - LCA_DMA_WIN_BASE); -} - -/* * Memory Controller registers: */ #define LCA_MEM_BCR0 (IDENT_ADDR + 0x120000000UL) @@ -142,6 +130,30 @@ extern inline void * bus_to_virt(unsigned long address) #define HAE_ADDRESS LCA_IOC_HAE +#ifdef __KERNEL__ + +/* + * Translate physical memory address as seen on (PCI) bus into + * a kernel virtual address and vv. + */ +extern inline unsigned long virt_to_bus(void * address) +{ + return virt_to_phys(address) + LCA_DMA_WIN_BASE; +} + +extern inline void * bus_to_virt(unsigned long address) +{ + /* + * This check is a sanity check but also ensures that bus + * address 0 maps to virtual address 0 which is useful to + * detect null "pointers" (the NCR driver is much simpler if + * NULL pointers are preserved). + */ + if (address < LCA_DMA_WIN_BASE) + return 0; + return phys_to_virt(address - LCA_DMA_WIN_BASE); +} + /* * I/O functions: * @@ -245,6 +257,7 @@ extern inline unsigned long __readl(unsigned long addr) extern inline void __writeb(unsigned char b, unsigned long addr) { unsigned long msb; + unsigned int w; if (addr >= (1UL << 24)) { msb = addr & 0xf8000000; @@ -253,12 +266,14 @@ extern inline void __writeb(unsigned char b, unsigned long addr) set_hae(msb); } } - *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00) = b * 0x01010101; + asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00) = w; } extern inline void __writew(unsigned short b, unsigned long addr) { unsigned long msb; + unsigned int w; if (addr >= (1UL << 24)) { msb = addr & 0xf8000000; @@ -267,7 +282,8 @@ extern inline void __writew(unsigned short b, unsigned long addr) set_hae(msb); } } - *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08) = b * 0x00010001; + asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08) = w; } extern inline void __writel(unsigned int b, unsigned long addr) @@ -279,34 +295,63 @@ extern inline void __writel(unsigned int b, unsigned long addr) * Most of the above have so much overhead that it probably doesn't * make sense to have them inlined (better icache behavior). */ -extern unsigned int inb(unsigned long addr); -extern unsigned int inw(unsigned long addr); -extern unsigned int inl(unsigned long addr); - -extern void outb(unsigned char b, unsigned long addr); -extern void outw(unsigned short b, unsigned long addr); -extern void outl(unsigned int b, unsigned long addr); - -extern unsigned long readb(unsigned long addr); -extern unsigned long readw(unsigned long addr); - -extern void writeb(unsigned short b, unsigned long addr); -extern void writew(unsigned short b, unsigned long addr); #define inb(port) \ -(__builtin_constant_p((port))?__inb(port):(inb)(port)) +(__builtin_constant_p((port))?__inb(port):_inb(port)) #define outb(x, port) \ -(__builtin_constant_p((port))?__outb((x),(port)):(outb)((x),(port))) - -#define inb_p inb -#define outb_p outb +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) -#define readl(addr) __readl(addr) -#define writel(b,addr) __writel(b,addr) +#define readl(a) __readl((unsigned long)(a)) +#define writel(v,a) __writel((v),(unsigned long)(a)) #undef vuip extern unsigned long lca_init (unsigned long mem_start, unsigned long mem_end); -#endif +#endif /* __KERNEL__ */ + +/* + * Data structure for handling LCA machine checks. Correctable errors + * result in a short logout frame, uncorrectable ones in a long one. + */ +struct el_lca_mcheck_short { + struct el_common h; /* common logout header */ + unsigned long esr; /* error-status register */ + unsigned long ear; /* error-address register */ + unsigned long dc_stat; /* dcache status register */ + unsigned long ioc_stat0; /* I/O controller status register 0 */ + unsigned long ioc_stat1; /* I/O controller status register 1 */ +}; + +struct el_lca_mcheck_long { + struct el_common h; /* common logout header */ + unsigned long pt[31]; /* PAL temps */ + unsigned long exc_addr; /* exception address */ + unsigned long pad1[3]; + unsigned long pal_base; /* PALcode base address */ + unsigned long hier; /* hw interrupt enable */ + unsigned long hirr; /* hw interrupt request */ + unsigned long mm_csr; /* MMU control & status */ + unsigned long dc_stat; /* data cache status */ + unsigned long dc_addr; /* data cache addr register */ + unsigned long abox_ctl; /* address box control register */ + unsigned long esr; /* error status register */ + unsigned long ear; /* error address register */ + unsigned long car; /* cache control register */ + unsigned long ioc_stat0; /* I/O controller status register 0 */ + unsigned long ioc_stat1; /* I/O controller status register 1 */ + unsigned long va; /* virtual address register */ +}; + +union el_lca { + struct el_common * c; + struct el_lca_mcheck_long * l; + struct el_lca_mcheck_short * s; +}; + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ADDR(x) (0x80 | (x)) +#define RTC_ALWAYS_BCD 0 + +#endif /* __ALPHA_LCA__H__ */ diff --git a/include/asm-alpha/mc146818rtc.h b/include/asm-alpha/mc146818rtc.h new file mode 100644 index 000000000..40ce6163f --- /dev/null +++ b/include/asm-alpha/mc146818rtc.h @@ -0,0 +1,23 @@ +/* + * Machine dependend access functions for RTC registers. + */ +#ifndef __ASM_ALPHA_MC146818RTC_H +#define __ASM_ALPHA_MC146818RTC_H + +#include <asm/io.h> + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 +#endif + +#define CMOS_READ(addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#endif /* __ASM_ALPHA_MC146818RTC_H */ diff --git a/include/asm-alpha/mman.h b/include/asm-alpha/mman.h new file mode 100644 index 000000000..a08ec81df --- /dev/null +++ b/include/asm-alpha/mman.h @@ -0,0 +1,38 @@ +#ifndef __ALPHA_MMAN_H__ +#define __ALPHA_MMAN_H__ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping (OSF/1 is _wrong_) */ +#define MAP_FIXED 0x100 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x10 /* don't use a file */ + +/* not used by linux, but here to make sure we don't clash with OSF/1 defines */ +#define MAP_HASSEMAPHORE 0x0200 +#define MAP_INHERIT 0x0400 +#define MAP_UNALIGNED 0x0800 + +/* These are linux-specific */ +#define MAP_GROWSDOWN 0x1000 /* stack-like segment */ +#define MAP_DENYWRITE 0x2000 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x4000 /* mark it as an executable */ +#define MAP_LOCKED 0x8000 /* lock the mapping */ +#define MAP_NORESERVE 0x10000 /* don't check for reservations */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_SYNC 2 /* synchronous memory sync */ +#define MS_INVALIDATE 4 /* invalidate the caches */ + +#define MCL_CURRENT 8192 /* lock all currently mapped pages */ +#define MCL_FUTURE 16384 /* lock all additions to address space */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __ALPHA_MMAN_H__ */ diff --git a/include/asm-alpha/mmu_context.h b/include/asm-alpha/mmu_context.h new file mode 100644 index 000000000..a94d1b7ea --- /dev/null +++ b/include/asm-alpha/mmu_context.h @@ -0,0 +1,90 @@ +#ifndef __ALPHA_MMU_CONTEXT_H +#define __ALPHA_MMU_CONTEXT_H + +/* + * get a new mmu context.. + * + * Copyright (C) 1996, Linus Torvalds + */ + +#include <linux/config.h> +#include <asm/system.h> + +/* + * The maximum ASN's the processor supports. On the EV4 this is 63 + * but the PAL-code doesn't actually use this information. On the + * EV5 this is 127. + * + * On the EV4, the ASNs are more-or-less useless anyway, as they are + * only used as an icache tag, not for TB entries. On the EV5 ASN's + * also validate the TB entries, and thus make a lot more sense. + * + * The EV4 ASN's don't even match the architecture manual, ugh. And + * I quote: "If a processor implements address space numbers (ASNs), + * and the old PTE has the Address Space Match (ASM) bit clear (ASNs + * in use) and the Valid bit set, then entries can also effectively be + * made coherent by assigning a new, unused ASN to the currently + * running process and not reusing the previous ASN before calling the + * appropriate PALcode routine to invalidate the translation buffer + * (TB)". + * + * In short, the EV4 has a "kind of" ASN capability, but it doesn't actually + * work correctly and can thus not be used (explaining the lack of PAL-code + * support). + */ +#ifdef CONFIG_ALPHA_EV5 +#define MAX_ASN 127 +#else +#define MAX_ASN 63 +#define BROKEN_ASN 1 +#endif + +extern unsigned long asn_cache; + +#define ASN_VERSION_SHIFT 16 +#define ASN_VERSION_MASK ((~0UL) << ASN_VERSION_SHIFT) +#define ASN_FIRST_VERSION (1UL << ASN_VERSION_SHIFT) + +extern inline void get_new_mmu_context(struct task_struct *p, + struct mm_struct *mm, + unsigned long asn) +{ + /* check if it's legal.. */ + if ((asn & ~ASN_VERSION_MASK) > MAX_ASN) { + /* start a new version, invalidate all old asn's */ + tbiap(); imb(); + asn = (asn & ASN_VERSION_MASK) + ASN_FIRST_VERSION; + if (!asn) + asn = ASN_FIRST_VERSION; + } + asn_cache = asn + 1; + mm->context = asn; /* full version + asn */ + p->tss.asn = asn & ~ASN_VERSION_MASK; /* just asn */ +} + +/* + * NOTE! The way this is set up, the high bits of the "asn_cache" (and + * the "mm->context") are the ASN _version_ code. A version of 0 is + * always considered invalid, so to invalidate another process you only + * need to do "p->mm->context = 0". + * + * If we need more ASN's than the processor has, we invalidate the old + * user TLB's (tbiap()) and start a new ASN version. That will automatically + * force a new asn for any other processes the next time they want to + * run. + */ +extern inline void get_mmu_context(struct task_struct *p) +{ +#ifndef BROKEN_ASN + struct mm_struct * mm = p->mm; + + if (mm) { + unsigned long asn = asn_cache; + /* Check if our ASN is of an older version and thus invalid */ + if ((mm->context ^ asn) & ASN_VERSION_MASK) + get_new_mmu_context(p, mm, asn); + } +#endif +} + +#endif diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h index 316bc9dd1..9e4f2d595 100644 --- a/include/asm-alpha/page.h +++ b/include/asm-alpha/page.h @@ -8,9 +8,68 @@ #ifdef __KERNEL__ -#define CONFIG_STRICT_MM_TYPECHECKS +#define STRICT_MM_TYPECHECKS -#ifdef CONFIG_STRICT_MM_TYPECHECKS +/* + * A _lot_ of the kernel time is spent clearing pages, so + * do this as fast as we possibly can. Also, doing this + * as a separate inline function (rather than memset()) + * results in clearer kernel profiles as we see _who_ is + * doing page clearing or copying. + */ +static inline void clear_page(unsigned long page) +{ + unsigned long count; + __asm__ __volatile__( + ".align 4\n" + "1:\n\t" + "stq $31,0(%1)\n\t" + "stq $31,8(%1)\n\t" + "stq $31,16(%1)\n\t" + "stq $31,24(%1)\n\t" + "subq %0,1,%0\n\t" + "stq $31,32(%1)\n\t" + "stq $31,40(%1)\n\t" + "stq $31,48(%1)\n\t" + "stq $31,56(%1)\n\t" + "addq $1,64,$1\n\t" + "bne %0,1b" + :"=r" (count),"=r" (page) + :"0" (PAGE_SIZE/64), "1" (page)); +} + +static inline void copy_page(unsigned long to, unsigned long from) +{ + unsigned long count; + __asm__ __volatile__( + ".align 4\n" + "1:\n\t" + "ldq $0,0(%1)\n\t" + "ldq $1,8(%1)\n\t" + "ldq $2,16(%1)\n\t" + "ldq $3,24(%1)\n\t" + "ldq $4,32(%1)\n\t" + "ldq $5,40(%1)\n\t" + "ldq $6,48(%1)\n\t" + "ldq $7,56(%1)\n\t" + "subq %0,1,%0\n\t" + "addq %1,64,%1\n\t" + "stq $0,0(%2)\n\t" + "stq $1,8(%2)\n\t" + "stq $2,16(%2)\n\t" + "stq $3,24(%2)\n\t" + "stq $4,32(%2)\n\t" + "stq $5,40(%2)\n\t" + "stq $6,48(%2)\n\t" + "stq $7,56(%2)\n\t" + "addq %2,64,%2\n\t" + "bne %0,1b" + :"=r" (count), "=r" (from), "=r" (to) + :"0" (PAGE_SIZE/64), "1" (from), "2" (to) + :"$0","$1","$2","$3","$4","$5","$6","$7"); +} + +#ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ @@ -48,28 +107,15 @@ typedef unsigned long pgprot_t; #endif -#define invalidate_all() \ -__asm__ __volatile__( \ - "lda $16,-2($31)\n\t" \ - ".long 51" \ - : : :"$1", "$16", "$17", "$22","$23","$24","$25") - -#define invalidate() \ -__asm__ __volatile__( \ - "lda $16,-1($31)\n\t" \ - ".long 51" \ - : : :"$1", "$16", "$17", "$22","$23","$24","$25") - #define copy_page(from,to) memcpy((void *) to, (void *) from, PAGE_SIZE) /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -#define PAGE_OFFSET 0xFFFFFC0000000000 -#define MAP_NR(addr) ((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT) -#define MAP_PAGE_RESERVED (1<<31) - -typedef unsigned int mem_map_t; +#define PAGE_OFFSET 0xFFFFFC0000000000UL +#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) +#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT) #endif /* __KERNEL__ */ diff --git a/include/asm-alpha/pal.h b/include/asm-alpha/pal.h new file mode 100644 index 000000000..a4ef2e38a --- /dev/null +++ b/include/asm-alpha/pal.h @@ -0,0 +1,50 @@ +#ifndef __ALPHA_PAL_H +#define __ALPHA_PAL_H + +/* + * Common PAL-code + */ +#define PAL_halt 0 +#define PAL_cflush 1 +#define PAL_draina 2 +#define PAL_cobratt 9 +#define PAL_bpt 128 +#define PAL_bugchk 129 +#define PAL_chmk 131 +#define PAL_callsys 131 +#define PAL_imb 134 +#define PAL_rduniq 158 +#define PAL_wruniq 159 +#define PAL_gentrap 170 +#define PAL_nphalt 190 + +/* + * VMS specific PAL-code + */ +#define PAL_swppal 10 +#define PAL_mfpr_vptb 41 + +/* + * OSF specific PAL-code + */ +#define PAL_rdmces 16 +#define PAL_wrmces 17 +#define PAL_wrfen 43 +#define PAL_wrvptptr 45 +#define PAL_jtopal 46 +#define PAL_swpctx 48 +#define PAL_wrval 49 +#define PAL_rdval 50 +#define PAL_tbi 51 +#define PAL_wrent 52 +#define PAL_swpipl 53 +#define PAL_rdps 54 +#define PAL_wrkgp 55 +#define PAL_wrusp 56 +#define PAL_wrperfmon 57 +#define PAL_rdusp 58 +#define PAL_whami 60 +#define PAL_rtsys 61 +#define PAL_rti 63 + +#endif /* __ALPHA_PAL_H */ diff --git a/include/asm-alpha/param.h b/include/asm-alpha/param.h index 03f57ecff..07382f5f1 100644 --- a/include/asm-alpha/param.h +++ b/include/asm-alpha/param.h @@ -1,8 +1,8 @@ -#ifndef _ASMAXP_PARAM_H -#define _ASMAXP_PARAM_H +#ifndef _ASM_ALPHA_PARAM_H +#define _ASM_ALPHA_PARAM_H #ifndef HZ -#define HZ 1024 +# define HZ 1024 #endif #define EXEC_PAGESIZE 8192 @@ -17,4 +17,4 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ -#endif +#endif /* _ASM_ALPHA_PARAM_H */ diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h index 51425af46..937700caf 100644 --- a/include/asm-alpha/pgtable.h +++ b/include/asm-alpha/pgtable.h @@ -9,6 +9,131 @@ * in <asm/page.h> (currently 8192). */ +#include <asm/system.h> +#include <asm/mmu_context.h> + +/* Caches aren't brain-dead on the alpha. */ +#define flush_cache_all() do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_range(mm, start, end) do { } while (0) +#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_page_to_ram(page) do { } while (0) + +/* + * Force a context reload. This is needed when we + * change the page table pointer or when we update + * the ASN of the current process. + */ +static inline void reload_context(struct task_struct *task) +{ + __asm__ __volatile__( + "bis %0,%0,$16\n\t" + "call_pal %1" + : /* no outputs */ + : "r" (&task->tss), "i" (PAL_swpctx) + : "$0", "$1", "$16", "$22", "$23", "$24", "$25"); +} + +/* + * Use a few helper functions to hide the ugly broken ASN + * numbers on early alpha's (ev4 and ev45) + */ +#ifdef BROKEN_ASN + +#define flush_tlb_current(x) tbiap() +#define flush_tlb_other(x) do { } while (0) + +#else + +extern void get_new_asn_and_reload(struct task_struct *, struct mm_struct *); + +#define flush_tlb_current(mm) get_new_asn_and_reload(current, mm) +#define flush_tlb_other(mm) do { (mm)->context = 0; } while (0) + +#endif + +/* + * Flush just one page in the current TLB set. + * We need to be very careful about the icache here, there + * is no way to invalidate a specific icache page.. + */ +static inline void flush_tlb_current_page(struct mm_struct * mm, + struct vm_area_struct *vma, + unsigned long addr) +{ +#ifdef BROKEN_ASN + tbi(2 + ((vma->vm_flags & VM_EXEC) != 0), addr); +#else + if (vma->vm_flags & VM_EXEC) + flush_tlb_current(mm); + else + tbi(2, addr); +#endif +} + +/* + * Flush current user mapping. + */ +static inline void flush_tlb(void) +{ + flush_tlb_current(current->mm); +} + +/* + * Flush everything (kernel mapping may also have + * changed due to vmalloc/vfree) + */ +static inline void flush_tlb_all(void) +{ + tbia(); +} + +/* + * Flush a specified user mapping + */ +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm != current->mm) + flush_tlb_other(mm); + else + flush_tlb_current(mm); +} + +/* + * Page-granular tlb flush. + * + * do a tbisd (type = 2) normally, and a tbis (type = 3) + * if it is an executable mapping. We want to avoid the + * itlb flush, because that potentially also does a + * icache flush. + */ +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + struct mm_struct * mm = vma->vm_mm; + + if (mm != current->mm) + flush_tlb_other(mm); + else + flush_tlb_current_page(mm, vma, addr); +} + +/* + * Flush a specified range of user mapping: on the + * alpha we flush the whole user tlb + */ +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + flush_tlb_mm(mm); +} + +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval)) + /* PMD_SHIFT determines the size of the area a second-level page table can map */ #define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3)) #define PMD_SIZE (1UL << PMD_SHIFT) @@ -49,7 +174,6 @@ #define _PAGE_UWE 0x2000 /* used to do the dirty bit in software */ /* .. and these are ours ... */ -#define _PAGE_COW 0x10000 #define _PAGE_DIRTY 0x20000 #define _PAGE_ACCESSED 0x40000 @@ -78,13 +202,13 @@ */ #define PAGE_NONE __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOR | _PAGE_FOW | _PAGE_FOE) #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS) -#define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_COW) +#define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE) #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x)) -#define _PAGE_P(x) _PAGE_NORMAL((x) | (((x) & _PAGE_FOW)?0:(_PAGE_FOW | _PAGE_COW))) +#define _PAGE_P(x) _PAGE_NORMAL((x) | (((x) & _PAGE_FOW)?0:_PAGE_FOW)) #define _PAGE_S(x) _PAGE_NORMAL(x) /* @@ -125,9 +249,9 @@ extern pmd_t * __bad_pagetable(void); extern unsigned long __zero_page(void); -#define BAD_PAGETABLE __bad_pagetable() -#define BAD_PAGE __bad_page() -#define ZERO_PAGE __zero_page() +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE 0xfffffc000030A000 /* number of bits that fit into a memory pointer */ #define BITS_PER_PTR (8*sizeof(unsigned long)) @@ -142,8 +266,6 @@ extern unsigned long __zero_page(void); #define PAGE_PTR(address) \ ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) -extern unsigned long high_memory; - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. @@ -151,6 +273,9 @@ extern unsigned long high_memory; extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) { pte_t pte; pte_val(pte) = ((page-PAGE_OFFSET) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; } +extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) +{ pte_t pte; pte_val(pte) = (physpage << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; } + extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } @@ -171,35 +296,17 @@ extern inline unsigned long pgd_page(pgd_t pgd) extern inline int pte_none(pte_t pte) { return !pte_val(pte); } extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; } -extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; } extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } -extern inline void pte_reuse(pte_t * ptep) -{ - if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(ptep)]++; -} extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); } -extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE || pmd_page(pmd) > high_memory; } +extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE; } extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_VALID; } -extern inline int pmd_inuse(pmd_t *pmdp) { return mem_map[MAP_NR(pmdp)] != 1; } extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; } -extern inline void pmd_reuse(pmd_t * pmdp) -{ - if (!(mem_map[MAP_NR(pmdp)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(pmdp)]++; -} extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); } -extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; } +extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE; } extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_VALID; } -extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)] != 1; } extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; } -extern inline void pgd_reuse(pgd_t * pgdp) -{ - if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(pgdp)]++; -} /* * The following only work if pte_present() is true. @@ -210,20 +317,17 @@ extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_FOW); } extern inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_FOE); } extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -extern inline int pte_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; } extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOW; return pte; } extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOR; return pte; } extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOE; return pte; } extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(__DIRTY_BITS); return pte; } extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(__ACCESS_BITS); return pte; } -extern inline pte_t pte_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; } extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_FOW; return pte; } extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) &= ~_PAGE_FOR; return pte; } extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= ~_PAGE_FOE; return pte; } extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= __DIRTY_BITS; return pte; } extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; } -extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; } /* * To set the page-dir. Note the self-mapping in the last entry @@ -238,21 +342,15 @@ extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir) pgd_val(pgdir[PTRS_PER_PGD]) = pte_val(mk_pte((unsigned long) pgdir, PAGE_KERNEL)); tsk->tss.ptbr = ((unsigned long) pgdir - PAGE_OFFSET) >> PAGE_SHIFT; if (tsk == current) - __asm__ __volatile__( - "bis %0,%0,$16\n\t" - "call_pal %1" - : /* no outputs */ - : "r" (&tsk->tss), "i" (PAL_swpctx) - : "$0", "$1", "$16", "$22", "$23", "$24", "$25"); + reload_context(tsk); } #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) /* to find an entry in a page-table-directory. */ -extern inline pgd_t * pgd_offset(struct task_struct * tsk, unsigned long address) +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) { - return (pgd_t *) ((tsk->tss.ptbr << PAGE_SHIFT) + PAGE_OFFSET) + - ((address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); + return mm->pgd + ((address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); } /* Find an entry in the second-level page table.. */ @@ -270,11 +368,10 @@ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) /* * Allocate and free page tables. The xxx_kernel() versions are * used to allocate a kernel page table - this turns on ASN bits - * if any, and marks the page tables reserved. + * if any. */ extern inline void pte_free_kernel(pte_t * pte) { - mem_map[MAP_NR(pte)] = 1; free_page((unsigned long) pte); } @@ -286,7 +383,6 @@ extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) if (pmd_none(*pmd)) { if (page) { pmd_set(pmd, page); - mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED; return page + address; } pmd_set(pmd, (pte_t *) BAD_PAGETABLE); @@ -304,7 +400,6 @@ extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) extern inline void pmd_free_kernel(pmd_t * pmd) { - mem_map[MAP_NR(pmd)] = 1; free_page((unsigned long) pmd); } @@ -316,7 +411,6 @@ extern inline pmd_t * pmd_alloc_kernel(pgd_t *pgd, unsigned long address) if (pgd_none(*pgd)) { if (page) { pgd_set(pgd, page); - mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED; return page + address; } pgd_set(pgd, BAD_PAGETABLE); diff --git a/include/asm-alpha/posix_types.h b/include/asm-alpha/posix_types.h new file mode 100644 index 000000000..92855e8bc --- /dev/null +++ b/include/asm-alpha/posix_types.h @@ -0,0 +1,111 @@ +#ifndef _ALPHA_POSIX_TYPES_H +#define _ALPHA_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned int __kernel_dev_t; +typedef unsigned int __kernel_ino_t; +typedef unsigned int __kernel_mode_t; +typedef unsigned int __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef int __kernel_ipc_pid_t; +typedef unsigned int __kernel_uid_t; +typedef unsigned int __kernel_gid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#ifndef __GNUC__ + +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#define __FD_ZERO(set) \ + ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set))) + +#else /* __GNUC__ */ + +/* With GNU C, use inline functions instead so args are evaluated only once: */ + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] |= (1UL<<_rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); +} + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long fd, const __kernel_fd_set *p) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set *p) +{ + unsigned long *tmp = p->fds_bits; + int i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 16: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0; + tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0; + return; + + case 8: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + return; + + case 4: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + return; + } + } + i = __FDSET_LONGS; + while (i) { + i--; + *tmp = 0; + tmp++; + } +} + +#endif /* __GNUC__ */ + +#endif /* _ALPHA_POSIX_TYPES_H */ diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h index 2e953e3cd..4ffb38a37 100644 --- a/include/asm-alpha/processor.h +++ b/include/asm-alpha/processor.h @@ -8,7 +8,7 @@ #define __ASM_ALPHA_PROCESSOR_H /* - * We have a 41-bit user address space: 2TB user VM... + * We have a 42-bit user address space: 4TB user VM... */ #define TASK_SIZE (0x40000000000UL) @@ -20,39 +20,51 @@ #define MCA_bus 0 #define MCA_bus__is_a_macro /* for versions in ksyms.c */ -/* - * The alpha has no problems with write protection - */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ - struct thread_struct { + /* the fields below are used by PALcode and must match struct pcb: */ unsigned long ksp; unsigned long usp; unsigned long ptbr; unsigned int pcc; unsigned int asn; unsigned long unique; - unsigned long flags; + /* + * bit 0: floating point enable + * bit 62: performance monitor enable + */ + unsigned long pal_flags; unsigned long res1, res2; + + /* the fields below are Linux-specific: */ + /* bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h) */ + unsigned long flags; + /* perform syscall argument validation (get/set_fs) */ + unsigned long fs; }; -#define INIT_MMAP { &init_task, 0xfffffc0000000000, 0xfffffc0010000000, \ +#define INIT_MMAP { &init_mm, 0xfffffc0000000000, 0xfffffc0010000000, \ PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } #define INIT_TSS { \ 0, 0, 0, \ 0, 0, 0, \ 0, 0, 0, \ + 0, \ + 0 \ } +#define alloc_kernel_stack() __get_free_page(GFP_KERNEL) +#define free_kernel_stack(page) free_page((page)) + #include <asm/ptrace.h> /* - * Return saved PC of a blocked thread. This assumes the frame pointer - * is the 6th saved long on the kernel stack and that the saved return - * address is the first long in the frame. This all holds provided the - * thread blocked through a call to schedule(). + * Return saved PC of a blocked thread. This assumes the frame + * pointer is the 6th saved long on the kernel stack and that the + * saved return address is the first long in the frame. This all + * holds provided the thread blocked through a call to schedule() ($15 + * is the frame pointer in schedule() and $15 is saved at offset 48 by + * entry.S:do_switch_stack). */ extern inline unsigned long thread_saved_pc(struct thread_struct *t) { @@ -65,11 +77,16 @@ extern inline unsigned long thread_saved_pc(struct thread_struct *t) /* * Do necessary setup to start up a newly executed thread. */ -static inline void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) -{ - regs->pc = pc; - regs->ps = 8; - wrusp(sp); -} +extern void start_thread(struct pt_regs *, unsigned long, unsigned long); + +/* + * Return_address is a replacement for __builtin_return_address(count) + * which on certain architectures cannot reasonably be implemented in GCC + * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * Note that __builtin_return_address(x>=1) is forbidden because the GCC + * aborts compilation on some CPUs. It's simply not possible to unwind + * some CPU's stackframes. + */ +#define return_address() __builtin_return_address(0) #endif /* __ASM_ALPHA_PROCESSOR_H */ diff --git a/include/asm-alpha/ptrace.h b/include/asm-alpha/ptrace.h index 7bda114cd..8f7d643fc 100644 --- a/include/asm-alpha/ptrace.h +++ b/include/asm-alpha/ptrace.h @@ -59,11 +59,12 @@ struct switch_stack { unsigned long r14; unsigned long r15; unsigned long r26; - unsigned long fp[32]; + unsigned long fp[32]; /* fp[31] is fpcr */ }; #ifdef __KERNEL__ #define user_mode(regs) ((regs)->ps & 8) +#define instruction_pointer(regs) ((regs)->pc) extern void show_regs(struct pt_regs *); #endif diff --git a/include/asm-alpha/reg.h b/include/asm-alpha/reg.h new file mode 100644 index 000000000..86ff916fb --- /dev/null +++ b/include/asm-alpha/reg.h @@ -0,0 +1,52 @@ +#ifndef __reg_h__ +#define __reg_h__ + +/* + * Exception frame offsets. + */ +#define EF_V0 0 +#define EF_T0 1 +#define EF_T1 2 +#define EF_T2 3 +#define EF_T3 4 +#define EF_T4 5 +#define EF_T5 6 +#define EF_T6 7 +#define EF_T7 8 +#define EF_S0 9 +#define EF_S1 10 +#define EF_S2 11 +#define EF_S3 12 +#define EF_S4 13 +#define EF_S5 14 +#define EF_S6 15 +#define EF_A3 16 +#define EF_A4 17 +#define EF_A5 18 +#define EF_T8 19 +#define EF_T9 20 +#define EF_T10 21 +#define EF_T11 22 +#define EF_RA 23 +#define EF_T12 24 +#define EF_AT 25 +#define EF_SP 26 +#define EF_PS 27 +#define EF_PC 28 +#define EF_GP 29 +#define EF_A0 30 +#define EF_A1 31 +#define EF_A2 32 + +#define EF_SIZE (33*8) +#define HWEF_SIZE (6*8) /* size of PAL frame (PS-A2) */ + +#define EF_SSIZE (EF_SIZE - HWEF_SIZE) + +/* + * Map register number into core file offset. + */ +#define CORE_REG(reg, ubase) \ + (((unsigned long *)((unsigned long)(ubase)))[reg]) + +#endif /* __reg_h__ */ diff --git a/include/asm-alpha/resource.h b/include/asm-alpha/resource.h index daf5c4037..96b338fc4 100644 --- a/include/asm-alpha/resource.h +++ b/include/asm-alpha/resource.h @@ -14,11 +14,26 @@ #define RLIMIT_NOFILE 6 /* max number of open files */ #define RLIMIT_AS 7 /* address space limit(?) */ #define RLIMIT_NPROC 8 /* max number of processes */ +#define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */ -#ifdef notdef -#define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space*/ -#endif +#define RLIM_NLIMITS 10 -#define RLIM_NLIMITS 9 +#ifdef __KERNEL__ -#endif +#define INIT_RLIMITS \ +{ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_CPU */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_FSIZE */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_DATA */ \ + {_STK_LIM, _STK_LIM}, /* RLIMIT_STACK */ \ + { 0, LONG_MAX}, /* RLIMIT_CORE */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_RSS */ \ + { NR_OPEN, NR_OPEN}, /* RLIMIT_NOFILE */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_AS */ \ + {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, /* RLIMIT_NPROC */ \ + {LONG_MAX, LONG_MAX}, /* RLIMIT_MEMLOCK */ \ +} + +#endif /* __KERNEL__ */ + +#endif /* _ALPHA_RESOURCE_H */ diff --git a/include/asm-alpha/segment.h b/include/asm-alpha/segment.h index ed3770607..0453d97da 100644 --- a/include/asm-alpha/segment.h +++ b/include/asm-alpha/segment.h @@ -1,143 +1,6 @@ -#ifndef _ASM_SEGMENT_H -#define _ASM_SEGMENT_H +#ifndef __ALPHA_SEGMENT_H +#define __ALPHA_SEGMENT_H -#include <linux/string.h> +/* Only here because we have some old header files that expect it.. */ -/* - * Uh, these should become the main single-value transfer routines.. - * They automatically use the right size if we just have the right - * pointer type.. - */ -#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))) -#define get_user(ptr) __get_user((ptr),sizeof(*(ptr))) - -/* - * This is a silly but good way to make sure that - * the __put_user function is indeed always optimized, - * and that we use the correct sizes.. - */ -extern int bad_user_access_length(void); - -/* I should make this use unaligned transfers etc.. */ -static inline void __put_user(unsigned long x, void * y, int size) -{ - switch (size) { - case 1: - *(char *) y = x; - break; - case 2: - *(short *) y = x; - break; - case 4: - *(int *) y = x; - break; - case 8: - *(long *) y = x; - break; - default: - bad_user_access_length(); - } -} - -/* I should make this use unaligned transfers etc.. */ -static inline unsigned long __get_user(void * y, int size) -{ - switch (size) { - case 1: - return *(unsigned char *) y; - case 2: - return *(unsigned short *) y; - case 4: - return *(unsigned int *) y; - case 8: - return *(unsigned long *) y; - default: - return bad_user_access_length(); - } -} - -static inline unsigned char get_user_byte(const char * addr) -{ - return *addr; -} - -#define get_fs_byte(addr) get_user_byte((char *)(addr)) - -static inline unsigned short get_user_word(const short *addr) -{ - return *addr; -} - -#define get_fs_word(addr) get_user_word((short *)(addr)) - -static inline unsigned long get_user_long(const int *addr) -{ - return *addr; -} - -#define get_fs_long(addr) get_user_long((int *)(addr)) - -static inline unsigned long get_user_quad(const long *addr) -{ - return *addr; -} - -#define get_fs_quad(addr) get_user_quad((long *)(addr)) - -static inline void put_user_byte(char val,char *addr) -{ - *addr = val; -} - -#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) - -static inline void put_user_word(short val,short * addr) -{ - *addr = val; -} - -#define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) - -static inline void put_user_long(unsigned long val,int * addr) -{ - *addr = val; -} - -#define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) - -static inline void put_user_quad(unsigned long val,long * addr) -{ - *addr = val; -} - -#define put_fs_quad(x,addr) put_user_quad((x),(long *)(addr)) - -#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n)) - -#define memcpy_tofs(to, from, n) memcpy((to),(from),(n)) - -/* - * For segmented architectures, these are used to specify which segment - * to use for the above functions. - * - * The alpha is not segmented, so these are just dummies. - */ - -#define KERNEL_DS 0 -#define USER_DS 1 - -static inline unsigned long get_fs(void) -{ - return 1; -} - -static inline unsigned long get_ds(void) -{ - return 0; -} - -static inline void set_fs(unsigned long val) -{ -} - -#endif /* _ASM_SEGMENT_H */ +#endif diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h new file mode 100644 index 000000000..210c2a5b3 --- /dev/null +++ b/include/asm-alpha/semaphore.h @@ -0,0 +1,43 @@ +#ifndef _ALPHA_SEMAPHORE_H +#define _ALPHA_SEMAPHORE_H + +/* + * SMP- and interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + */ + +#include <asm/atomic.h> + +struct semaphore { + atomic_t count; + atomic_t waiting; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { 1, 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) + +extern void __down(struct semaphore * sem); +extern void __up(struct semaphore * sem); + +/* + * This isn't quite as clever as the x86 side, but the gp register + * makes things a bit more complicated on the alpha.. + */ +extern inline void down(struct semaphore * sem) +{ + for (;;) { + if (atomic_dec_return(&sem->count) >= 0) + break; + __down(sem); + } +} + +extern inline void up(struct semaphore * sem) +{ + if (atomic_inc_return(&sem->count) <= 0) + __up(sem); +} + +#endif diff --git a/include/asm-alpha/shmparam.h b/include/asm-alpha/shmparam.h new file mode 100644 index 000000000..a9ce7164b --- /dev/null +++ b/include/asm-alpha/shmparam.h @@ -0,0 +1,47 @@ +#ifndef _ASMAXP_SHMPARAM_H +#define _ASMAXP_SHMPARAM_H + +/* + * Address range for shared memory attaches if no address passed to shmat(). + */ +#define SHM_RANGE_START 0x14000000000 +#define SHM_RANGE_END 0x15000000000 + + +/* + * Format of a swap-entry for shared memory pages currently out in + * swap space (see also mm/swap.c). + * + * SWP_TYPE = SHM_SWP_TYPE + * SWP_OFFSET is used as follows: + * + * bits 0..6 : id of shared memory segment page belongs to (SHM_ID) + * bits 7..21: index of page within shared memory segment (SHM_IDX) + * (actually fewer bits get used since SHMMAX is so low) + */ + +/* + * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and + * there is a static array of size SHMMNI. + */ +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +/* + * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the Alpha and + * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). + */ + +#define SHMMAX 0x3fa000 /* max shared seg size (bytes) */ +#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ +#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ +#define SHMALL /* max shm system wide (pages) */ \ + (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ +#define SHMSEG SHMMNI /* max shared segs per process */ + +#endif /* _ASMAXP_SHMPARAM_H */ diff --git a/include/asm-alpha/sigcontext.h b/include/asm-alpha/sigcontext.h new file mode 100644 index 000000000..916955f4b --- /dev/null +++ b/include/asm-alpha/sigcontext.h @@ -0,0 +1,34 @@ +#ifndef _ASMAXP_SIGCONTEXT_H +#define _ASMAXP_SIGCONTEXT_H + +struct sigcontext { + /* + * what should we have here? I'd probably better use the same + * stack layout as OSF/1, just in case we ever want to try + * running their binaries.. + * + * This is the basic layout, but I don't know if we'll ever + * actually fill in all the values.. + */ + long sc_onstack; + long sc_mask; + long sc_pc; + long sc_ps; + long sc_regs[32]; + long sc_ownedfp; + long sc_fpregs[32]; + unsigned long sc_fpcr; + unsigned long sc_fp_control; + unsigned long sc_reserved1, sc_reserved2; + unsigned long sc_ssize; + char * sc_sbase; + unsigned long sc_traparg_a0; + unsigned long sc_traparg_a1; + unsigned long sc_traparg_a2; + unsigned long sc_fp_trap_pc; + unsigned long sc_fp_trigger_sum; + unsigned long sc_fp_trigger_inst; + unsigned long sc_retcode[2]; +}; + +#endif diff --git a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h index 83f3d80ee..ecccdd3e8 100644 --- a/include/asm-alpha/signal.h +++ b/include/asm-alpha/signal.h @@ -43,6 +43,8 @@ typedef unsigned long sigset_t; /* at least 32 bits */ #define SIGUSR2 31 #define SIGPOLL SIGIO +#define SIGPWR SIGINFO +#define SIGIOT SIGABRT /* * sa_flags values: SA_STACK is not currently supported, but will allow the @@ -51,6 +53,7 @@ typedef unsigned long sigset_t; /* at least 32 bits */ * the changes in signal handling. LBT 010493. * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. */ #define SA_NOCLDSTOP 0x00000004 @@ -59,6 +62,19 @@ typedef unsigned long sigset_t; /* at least 32 bits */ #define SA_INTERRUPT 0x20000000 #define SA_NOMASK 0x00000008 #define SA_ONESHOT 0x00000010 +#define SA_SHIRQ 0x00000020 + +#ifdef __KERNEL__ +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#endif + #define SIG_BLOCK 1 /* for blocking signals */ #define SIG_UNBLOCK 2 /* for unblocking signals */ @@ -78,37 +94,7 @@ struct sigaction { }; #ifdef __KERNEL__ - -struct sigcontext_struct { - /* - * what should we have here? I'd probably better use the same - * stack layout as OSF/1, just in case we ever want to try - * running their binaries.. - * - * This is the basic layout, but I don't know if we'll ever - * actually fill in all the values.. - */ - long sc_onstack; - long sc_mask; - long sc_pc; - long sc_ps; - long sc_regs[32]; - long sc_ownedfp; - long sc_fpregs[32]; - unsigned long sc_fpcr; - unsigned long sc_fp_control; - unsigned long sc_reserved1, sc_reserved2; - unsigned long sc_ssize; - char * sc_sbase; - unsigned long sc_traparg_a0; - unsigned long sc_traparg_a1; - unsigned long sc_traparg_a2; - unsigned long sc_fp_trap_pc; - unsigned long sc_fp_trigger_sum; - unsigned long sc_fp_trigger_inst; - unsigned long sc_retcode[2]; -}; - +#include <asm/sigcontext.h> #endif #endif diff --git a/include/asm-alpha/socket.h b/include/asm-alpha/socket.h new file mode 100644 index 000000000..031636871 --- /dev/null +++ b/include/asm-alpha/socket.h @@ -0,0 +1,52 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <linux/types.h> +#include <asm/ioctl.h> +#include <asm/sockios.h> + +/* For setsockoptions(2) */ +/* + * Note: we only bother about making the SOL_SOCKET options + * same as OSF/1, as that's all that "normal" programs are + * likely to set. We don't necessarily want to be binary + * compatible with _everything_. + */ +#define SOL_SOCKET 0xffff + +#define SO_DEBUG 0x0001 +#define SO_REUSEADDR 0x0004 +#define SO_KEEPALIVE 0x0008 +#define SO_DONTROUTE 0x0010 +#define SO_BROADCAST 0x0020 +#define SO_LINGER 0x0080 +#define SO_OOBINLINE 0x0100 +/* To add :#define SO_REUSEPORT 0x0200 */ + +#define SO_TYPE 0x1008 +#define SO_ERROR 0x1007 +#define SO_SNDBUF 0x1001 +#define SO_RCVBUF 0x1002 +#define SO_RCVLOWAT 0x1010 +#define SO_SNDLOWAT 0x1011 +#define SO_RCVTIMEO 0x1012 +#define SO_SNDTIMEO 0x1013 + +/* linux-specific, might as well be the same as on i386 */ +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_BSDCOMPAT 14 + +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-alpha/sockios.h b/include/asm-alpha/sockios.h new file mode 100644 index 000000000..e4961a740 --- /dev/null +++ b/include/asm-alpha/sockios.h @@ -0,0 +1,15 @@ +#ifndef _ASM_ALPHA_SOCKIOS_H +#define _ASM_ALPHA_SOCKIOS_H + +/* Socket-level I/O control calls. */ + +#define FIOGETOWN _IOR('f', 123, int) +#define FIOSETOWN _IOW('f', 124, int) + +#define SIOCATMARK _IOR('s', 7, int) +#define SIOCSPGRP _IOW('s', 8, pid_t) +#define SIOCGPGRP _IOR('s', 9, pid_t) + +#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */ + +#endif /* _ASM_ALPHA_SOCKIOS_H */ diff --git a/include/asm-alpha/stat.h b/include/asm-alpha/stat.h index 275383002..66ea898d1 100644 --- a/include/asm-alpha/stat.h +++ b/include/asm-alpha/stat.h @@ -1,7 +1,7 @@ #ifndef _ALPHA_STAT_H #define _ALPHA_STAT_H -struct old_stat { +struct __old_kernel_stat { unsigned int st_dev; unsigned int st_ino; unsigned int st_mode; @@ -10,16 +10,16 @@ struct old_stat { unsigned int st_gid; unsigned int st_rdev; long st_size; - unsigned int st_atime, st_res1; - unsigned int st_mtime, st_res2; - unsigned int st_ctime, st_res3; - unsigned int st_blkize; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; + unsigned int st_blksize; int st_blocks; unsigned int st_flags; unsigned int st_gen; }; -struct new_stat { +struct stat { unsigned int st_dev; unsigned int st_ino; unsigned int st_mode; @@ -28,9 +28,9 @@ struct new_stat { unsigned int st_gid; unsigned int st_rdev; long st_size; - unsigned int st_atime, st_res1; - unsigned int st_mtime, st_res2; - unsigned int st_ctime, st_res3; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; unsigned int st_blksize; int st_blocks; unsigned int st_flags; diff --git a/include/asm-alpha/statfs.h b/include/asm-alpha/statfs.h index b2cd89057..cc4ba1de0 100644 --- a/include/asm-alpha/statfs.h +++ b/include/asm-alpha/statfs.h @@ -1,27 +1,25 @@ #ifndef _ALPHA_STATFS_H #define _ALPHA_STATFS_H -typedef struct { - int val[2]; -} fsid_t; +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif -/* - * The OSF/1 statfs structure is much larger, but this should - * match the beginning, at least. - */ struct statfs { - short f_type; - short f_flags; - int f_fsize; - int f_bsize; - int f_blocks; - int f_bfree; - int f_bavail; - int f_files; - int f_ffree; - fsid_t f_fsid; - /* linux-specific entries start here.. */ - int f_namelen; + int f_type; + int f_bsize; + int f_blocks; + int f_bfree; + int f_bavail; + int f_files; + int f_ffree; + __kernel_fsid_t f_fsid; + int f_namelen; + int f_spare[6]; }; #endif diff --git a/include/asm-alpha/string.h b/include/asm-alpha/string.h index 1c6fe64ec..6ef1f4120 100644 --- a/include/asm-alpha/string.h +++ b/include/asm-alpha/string.h @@ -1,15 +1,40 @@ -#ifndef __ALPHA_STRING_H -#define __ALPHA_STRING_H +#ifndef __ALPHA_STRING_H__ +#define __ALPHA_STRING_H__ + +#ifdef __KERNEL__ extern void * __constant_c_memset(void *, unsigned long, long); extern void * __memset(void *, char, size_t); + +/* + * Ugh. Gcc uses "bcopy()" internally for structure assignments. + */ +#define __HAVE_ARCH_BCOPY + +/* + * Define "memcpy()" to something else, otherwise gcc will + * corrupt that too into a "bcopy". Also, some day we might + * want to do a separate inlined constant-size memcpy (for 8 + * and 16 byte user<->kernel structure copying). + */ +#define __HAVE_ARCH_MEMCPY extern void * __memcpy(void *, const void *, size_t); +#define memcpy __memcpy +#define __HAVE_ARCH_MEMSET #define memset(s, c, count) \ (__builtin_constant_p(c) ? \ - __constant_c_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \ + __constant_c_memset((s),(0x0101010101010101UL*(unsigned char)c),(count)) : \ __memset((s),(c),(count))) -#define memcpy(d,s,count) __memcpy((d),(s),(count)) +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRNCPY +#define __HAVE_ARCH_STRCAT +#define __HAVE_ARCH_STRNCAT +#define __HAVE_ARCH_STRCHR +#define __HAVE_ARCH_STRRCHR +#define __HAVE_ARCH_STRLEN + +#endif /* __KERNEL__ */ -#endif +#endif /* __ALPHA_STRING_H__ */ diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index cbed1ded7..9854413fd 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -1,6 +1,8 @@ #ifndef __ALPHA_SYSTEM_H #define __ALPHA_SYSTEM_H +#include <asm/pal.h> /* for backwards compatibility... */ + /* * System defines.. Note that this is included both from .c and .S * files, so it does only defines, not any C code. @@ -15,6 +17,7 @@ */ #define BOOT_PCB 0x20000000 #define BOOT_ADDR 0x20000000 +/* Remove when official MILO sources have ELF support: */ #define BOOT_SIZE (16*1024) #define KERNEL_START 0xfffffc0000300000 @@ -25,69 +28,41 @@ #define ZERO_PGE 0xfffffc000030A000 #define START_ADDR 0xfffffc0000310000 +/* Remove when official MILO sources have ELF support: */ #define START_SIZE (2*1024*1024) -/* - * Common PAL-code - */ -#define PAL_halt 0 -#define PAL_cflush 1 -#define PAL_draina 2 -#define PAL_cobratt 9 -#define PAL_bpt 128 -#define PAL_bugchk 129 -#define PAL_chmk 131 -#define PAL_callsys 131 -#define PAL_imb 134 -#define PAL_rduniq 158 -#define PAL_wruniq 159 -#define PAL_gentrap 170 -#define PAL_nphalt 190 - -/* - * VMS specific PAL-code - */ -#define PAL_swppal 10 -#define PAL_mfpr_vptb 41 +#ifndef __ASSEMBLY__ /* - * OSF specific PAL-code + * This is the logout header that should be common to all platforms + * (assuming they are running OSF/1 PALcode, I guess). */ -#define PAL_rdmces 16 -#define PAL_wrmces 17 -#define PAL_wrfen 43 -#define PAL_wrvptptr 45 -#define PAL_jtopal 46 -#define PAL_swpctx 48 -#define PAL_wrval 49 -#define PAL_rdval 50 -#define PAL_tbi 51 -#define PAL_wrent 52 -#define PAL_swpipl 53 -#define PAL_rdps 54 -#define PAL_wrkgp 55 -#define PAL_wrusp 56 -#define PAL_wrperfmon 57 -#define PAL_rdusp 58 -#define PAL_whami 60 -#define PAL_rtsys 61 -#define PAL_rti 63 - -#ifndef __ASSEMBLY__ +struct el_common { + unsigned int size; /* size in bytes of logout area */ + int sbz1 : 31; /* should be zero */ + char retry : 1; /* retry flag */ + unsigned int proc_offset; /* processor-specific offset */ + unsigned int sys_offset; /* system-specific offset */ + unsigned long code; /* machine check code */ +}; extern void wrent(void *, unsigned long); extern void wrkgp(unsigned long); extern void wrusp(unsigned long); extern unsigned long rdusp(void); +extern unsigned long rdmces (void); +extern void wrmces (unsigned long); -#define halt() __asm__ __volatile__(".long 0"); +#define halt() __asm__ __volatile__ ("call_pal %0" : : "i" (PAL_halt) : "memory") + +#define switch_to(prev,next) do { \ + current_set[0] = next; \ + alpha_switch_to((unsigned long) &(next)->tss - 0xfffffc0000000000); \ +} while (0) extern void alpha_switch_to(unsigned long pctxp); -#define switch_to(p) do { \ - current = p; \ - alpha_switch_to((unsigned long) &(p)->tss - 0xfffffc0000000000); \ -} while (0) +extern void imb(void); #define mb() \ __asm__ __volatile__("mb": : :"memory") @@ -109,7 +84,7 @@ __asm__ __volatile__( \ "bis %0,%0,$16\n\t" \ "call_pal 53" \ : : "r" (__new_ipl) \ - : "$0", "$1", "$16", "$22", "$23", "$24", "$25") + : "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory") #define swpipl(__new_ipl) \ ({ unsigned long __old_ipl; \ @@ -119,7 +94,7 @@ __asm__ __volatile__( \ "bis $0,$0,%0" \ : "=r" (__old_ipl) \ : "r" (__new_ipl) \ - : "$0", "$1", "$16", "$22", "$23", "$24", "$25"); \ + : "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory"); \ __old_ipl; }) #define cli() setipl(7) @@ -127,41 +102,81 @@ __old_ipl; }) #define save_flags(flags) do { flags = getipl(); } while (0) #define restore_flags(flags) setipl(flags) -extern inline unsigned long xchg_u32(int * m, unsigned long val) -{ - unsigned long dummy, dummy2; +/* + * TB routines.. + */ +extern void tbi(long type, ...); + +#define tbisi(x) tbi(1,(x)) +#define tbisd(x) tbi(2,(x)) +#define tbis(x) tbi(3,(x)) +#define tbiap() tbi(-1) +#define tbia() tbi(-2) +/* + * Give prototypes to shut up gcc. + */ +extern __inline__ unsigned long xchg_u32 (volatile int * m, unsigned long val); +extern __inline__ unsigned long xchg_u64 (volatile long * m, unsigned long val); + +extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) +{ + unsigned long dummy; __asm__ __volatile__( "\n1:\t" - "ldl_l %0,%1\n\t" - "bis %2,%2,%3\n\t" - "stl_c %3,%1\n\t" - "beq %3,1b\n" - : "=r" (val), "=m" (*m), "=r" (dummy), "=r" (dummy2) - : "1" (*m), "2" (val)); + "ldl_l %0,%2\n\t" + "bis %3,%3,%1\n\t" + "stl_c %1,%2\n\t" + "beq %1,1b\n" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "r" (val), "m" (*m)); return val; } -extern inline unsigned long xchg_u64(long * m, unsigned long val) +extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val) { - unsigned long dummy, dummy2; - + unsigned long dummy; __asm__ __volatile__( "\n1:\t" - "ldq_l %0,%1\n\t" - "bis %2,%2,%3\n\t" - "stq_c %3,%1\n\t" - "beq %3,1b\n" - : "=r" (val), "=m" (*m), "=r" (dummy), "=r" (dummy2) - : "1" (*m), "2" (val)); + "ldq_l %0,%2\n\t" + "bis %3,%3,%1\n\t" + "stq_c %1,%2\n\t" + "beq %1,1b\n" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "r" (val), "m" (*m)); return val; } -extern inline void * xchg_ptr(void *m, void *val) +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) + +/* + * This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid xchg(). + * + * This only works if the compiler isn't horribly bad at optimizing. + * gcc-2.5.8 reportedly can't handle this, but as that doesn't work + * too well on the alpha anyway.. + */ +extern void __xchg_called_with_bad_pointer(void); + +static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size) { - return (void *) xchg_u64((long *) m, (unsigned long) val); + switch (size) { + case 4: + return xchg_u32(ptr, x); + case 8: + return xchg_u64(ptr, x); + } + __xchg_called_with_bad_pointer(); + return x; } +/* + * Reset the machine. + */ +extern void hard_reset_now(void); + #endif /* __ASSEMBLY__ */ #endif diff --git a/include/asm-alpha/termbits.h b/include/asm-alpha/termbits.h new file mode 100644 index 000000000..0d0a33251 --- /dev/null +++ b/include/asm-alpha/termbits.h @@ -0,0 +1,177 @@ +#ifndef _ALPHA_TERMBITS_H +#define _ALPHA_TERMBITS_H + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +/* + * termios type and macro definitions. Be careful about adding stuff + * to this file since it's used in GNU libc and there are strict rules + * concerning namespace pollution. + */ + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t c_line; /* line discipline (== c_cc[19]) */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VEOF 0 +#define VEOL 1 +#define VEOL2 2 +#define VERASE 3 +#define VWERASE 4 +#define VKILL 5 +#define VREPRINT 6 +#define VSWTC 7 +#define VINTR 8 +#define VQUIT 9 +#define VSUSP 10 +#define VSTART 12 +#define VSTOP 13 +#define VLNEXT 14 +#define VDISCARD 15 +#define VMIN 16 +#define VTIME 17 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IXON 0001000 +#define IXOFF 0002000 +#if !defined(KERNEL) || defined(__USE_BSD) + /* POSIX.1 doesn't want these... */ +# define IXANY 0004000 +# define IUCLC 0010000 +# define IMAXBEL 0020000 +#endif + +/* c_oflag bits */ +#define OPOST 0000001 +#define ONLCR 0000002 +#define OLCUC 0000004 + +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 + +#define OFILL 00000100 +#define OFDEL 00000200 +#define NLDLY 00001400 +#define NL0 00000000 +#define NL1 00000400 +#define NL2 00001000 +#define NL3 00001400 +#define TABDLY 00006000 +#define TAB0 00000000 +#define TAB1 00002000 +#define TAB2 00004000 +#define TAB3 00006000 +#define CRDLY 00030000 +#define CR0 00000000 +#define CR1 00010000 +#define CR2 00020000 +#define CR3 00030000 +#define FFDLY 00040000 +#define FF0 00000000 +#define FF1 00040000 +#define BSDLY 00100000 +#define BS0 00000000 +#define BS1 00100000 +#define VTDLY 00200000 +#define VT0 00000000 +#define VT1 00200000 +#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ + +/* c_cflag bit meaning */ +#define CBAUD 0000037 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CBAUDEX 0000000 +#define B57600 00020 +#define B115200 00021 +#define B230400 00022 +#define B460800 00023 + +#define CSIZE 00001400 +#define CS5 00000000 +#define CS6 00000400 +#define CS7 00001000 +#define CS8 00001400 + +#define CSTOPB 00002000 +#define CREAD 00004000 +#define PARENB 00010000 +#define PARODD 00020000 +#define HUPCL 00040000 + +#define CLOCAL 00100000 +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0x00000080 +#define ICANON 0x00000100 +#define XCASE 0x00004000 +#define ECHO 0x00000008 +#define ECHOE 0x00000002 +#define ECHOK 0x00000004 +#define ECHONL 0x00000010 +#define NOFLSH 0x80000000 +#define TOSTOP 0x00400000 +#define ECHOCTL 0x00000040 +#define ECHOPRT 0x00000020 +#define ECHOKE 0x00000001 +#define FLUSHO 0x00800000 +#define PENDIN 0x20000000 +#define IEXTEN 0x00000400 + +/* Values for the ACTION argument to `tcflow'. */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* _ALPHA_TERMBITS_H */ diff --git a/include/asm-alpha/termios.h b/include/asm-alpha/termios.h index 4eb45be99..efa0fcb2d 100644 --- a/include/asm-alpha/termios.h +++ b/include/asm-alpha/termios.h @@ -1,9 +1,8 @@ #ifndef _ALPHA_TERMIOS_H #define _ALPHA_TERMIOS_H -#include <linux/types.h> - -#include <asm/ioctl.h> +#include <asm/ioctls.h> +#include <asm/termbits.h> struct sgttyb { char sg_ispeed; @@ -31,84 +30,6 @@ struct ltchars { char t_lnextc; }; -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCOUTQ 0x5411 -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 - struct winsize { unsigned short ws_row; unsigned short ws_col; @@ -126,40 +47,13 @@ struct termio { unsigned char c_cc[NCC]; /* control characters */ }; -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t c_line; /* line discipline (== c_cc[19]) */ - int c_ispeed; /* input speed */ - int c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VEOF 0 -#define VEOL 1 -#define VEOL2 2 -#define VERASE 3 -#define VWERASE 4 -#define VKILL 5 -#define VREPRINT 6 -#define VSWTC 7 -#define VINTR 8 -#define VQUIT 9 -#define VSUSP 10 -#define VSTART 12 -#define VSTOP 13 -#define VLNEXT 14 -#define VDISCARD 15 -#define VTIME 17 -#define VMIN 16 - /* - * ..and the same for c_cc in the termio structure.. - * Oh, how I love being backwardly compatible. + * c_cc characters in the termio structure. Oh, how I love being + * backwardly compatible. Notice that character 4 and 5 are + * interpreted differently depending on whether ICANON is set in + * c_lflag. If it's set, they are used as _VEOF and _VEOL, otherwise + * as _VMIN and V_TIME. This is for compatibility with OSF/1 (which + * is compatible with sysV)... */ #define _VINTR 0 #define _VQUIT 1 @@ -172,163 +66,73 @@ struct termios { #define _VEOL2 6 #define _VSWTC 7 -#ifdef __KERNEL__ -/* intr=^C quit=^| erase=del kill=^U - eof=^D vtime=\0 vmin=\1 sxtc=\0 - start=^Q stop=^S susp=^Z eol=\0 - reprint=^R discard=^U werase=^W lnext=^V - eol2=\0 -*/ -#define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\000\001" -#endif - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IXON 0001000 -#define IXOFF 0002000 -#define IXANY 0004000 -#define IUCLC 0010000 -#define IMAXBEL 0020000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define ONLCR 0000002 -#define OLCUC 0000004 - -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 - -#define OFILL 00000100 -#define OFDEL 00000200 -#define NLDLY 00001400 -#define NL0 00000000 -#define NL1 00000400 -#define NL2 00001000 -#define NL3 00001400 -#define TABDLY 00006000 -#define TAB0 00000000 -#define TAB1 00002000 -#define TAB2 00004000 -#define TAB3 00006000 -#define CRDLY 00030000 -#define CR0 00000000 -#define CR1 00010000 -#define CR2 00020000 -#define CR3 00030000 -#define FFDLY 00040000 -#define FF0 00000000 -#define FF1 00040000 -#define BSDLY 00100000 -#define BS0 00000000 -#define BS1 00100000 -#define VTDLY 00200000 -#define VT0 00000000 -#define VT1 00200000 -#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ - -/* c_cflag bit meaning */ -#define CBAUD 0000377 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CBAUDEX 0000020 -#define B57600 00020 -#define B115200 00021 -#define B230400 00022 - -#define CSIZE 00001400 -#define CS5 00000000 -#define CS6 00000400 -#define CS7 00001000 -#define CS8 00001400 - -#define CSTOPB 00002000 -#define CREAD 00004000 -#define PARENB 00010000 -#define PARODD 00020000 -#define HUPCL 00040000 - -#define CLOCAL 00100000 -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0x00000080 -#define ICANON 0x00000100 -#define XCASE 0x00004000 -#define ECHO 0x00000008 -#define ECHOE 0x00000002 -#define ECHOK 0x00000004 -#define ECHONL 0x00000010 -#define NOFLSH 0x80000000 -#define TOSTOP 0x00400000 -#define ECHOCTL 0x00000040 -#define ECHOPRT 0x00000020 -#define ECHOKE 0x00000001 -#define FLUSHO 0x00800000 -#define PENDIN 0x20000000 -#define IEXTEN 0x00000400 - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - - -/* tcflow() and TCXONC use these */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* tcflush() and TCFLSH use these */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* tcsetattr uses these */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - /* line disciplines */ #define N_TTY 0 #define N_SLIP 1 #define N_MOUSE 2 #define N_PPP 3 +#define N_AX25 5 + +#ifdef __KERNEL__ +/* eof=^D eol=\0 eol2=\0 erase=del + werase=^W kill=^U reprint=^R sxtc=\0 + intr=^C quit=^\ susp=^Z <OSF/1 VDSUSP> + start=^Q stop=^S lnext=^V discard=^U + vmin=\1 vtime=\0 +*/ +#define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000" -#endif +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +extern inline void trans_from_termio(struct termio * termio, + struct termios * termios) +{ +#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y)) + SET_LOW_BITS(termios->c_iflag, termio->c_iflag); + SET_LOW_BITS(termios->c_oflag, termio->c_oflag); + SET_LOW_BITS(termios->c_cflag, termio->c_cflag); + SET_LOW_BITS(termios->c_lflag, termio->c_lflag); +#undef SET_LOW_BITS + termios->c_cc[VINTR] = termio->c_cc[_VINTR]; + termios->c_cc[VQUIT] = termio->c_cc[_VQUIT]; + termios->c_cc[VERASE]= termio->c_cc[_VERASE]; + termios->c_cc[VKILL] = termio->c_cc[_VKILL]; + termios->c_cc[VEOF] = termio->c_cc[_VEOF]; + termios->c_cc[VMIN] = termio->c_cc[_VMIN]; + termios->c_cc[VEOL] = termio->c_cc[_VEOL]; + termios->c_cc[VTIME] = termio->c_cc[_VTIME]; + termios->c_cc[VEOL2] = termio->c_cc[_VEOL2]; + termios->c_cc[VSWTC] = termio->c_cc[_VSWTC]; +} + +/* + * Translate a "termios" structure into a "termio". Ugh. + * + * Note the "fun" _VMIN overloading. + */ +extern inline void trans_to_termio(struct termios * termios, + struct termio * termio) +{ + termio->c_iflag = termios->c_iflag; + termio->c_oflag = termios->c_oflag; + termio->c_cflag = termios->c_cflag; + termio->c_lflag = termios->c_lflag; + termio->c_line = termios->c_line; + termio->c_cc[_VINTR] = termios->c_cc[VINTR]; + termio->c_cc[_VQUIT] = termios->c_cc[VQUIT]; + termio->c_cc[_VERASE]= termios->c_cc[VERASE]; + termio->c_cc[_VKILL] = termios->c_cc[VKILL]; + termio->c_cc[_VEOF] = termios->c_cc[VEOF]; + termio->c_cc[_VEOL] = termios->c_cc[VEOL]; + termio->c_cc[_VEOL2] = termios->c_cc[VEOL2]; + termio->c_cc[_VSWTC] = termios->c_cc[VSWTC]; + if (!(termios->c_lflag & ICANON)) { + termio->c_cc[_VMIN] = termios->c_cc[VMIN]; + termio->c_cc[_VTIME] = termios->c_cc[VTIME]; + } +} + +#endif /* __KERNEL__ */ + +#endif /* _ALPHA_TERMIOS_H */ diff --git a/include/asm-alpha/types.h b/include/asm-alpha/types.h index 2654e4b42..28e5d487d 100644 --- a/include/asm-alpha/types.h +++ b/include/asm-alpha/types.h @@ -1,41 +1,15 @@ #ifndef _ALPHA_TYPES_H #define _ALPHA_TYPES_H -#ifndef _SIZE_T -#define _SIZE_T -typedef unsigned long size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef long ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef long ptrdiff_t; -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef long time_t; -#endif - -#ifndef _CLOCK_T -#define _CLOCK_T -typedef long clock_t; -#endif +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ -typedef int pid_t; -typedef unsigned int uid_t; -typedef unsigned int gid_t; -typedef unsigned int dev_t; -typedef unsigned int ino_t; -typedef unsigned int mode_t; typedef unsigned int umode_t; -typedef unsigned short nlink_t; -typedef int daddr_t; -typedef long off_t; /* * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the @@ -98,5 +72,4 @@ typedef unsigned long u64; #endif #endif /* __KERNEL__ */ - -#endif +#endif /* _ALPHA_TYPES_H */ diff --git a/include/asm-alpha/uaccess.h b/include/asm-alpha/uaccess.h new file mode 100644 index 000000000..526767e41 --- /dev/null +++ b/include/asm-alpha/uaccess.h @@ -0,0 +1,447 @@ +#ifndef __ALPHA_UACCESS_H +#define __ALPHA_UACCESS_H + +#include <linux/errno.h> +#include <linux/sched.h> + + +/* + * 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 KERNEL_DS (0UL) +#define USER_DS (-0x40000000000UL) + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define get_fs() (current->tss.fs) +#define set_fs(x) (current->tss.fs = (x)) +#define get_ds() (KERNEL_DS) + +/* + * Is a address valid? This does a straighforward calculation rather + * than tests. + * + * Address valid if: + * - "addr" doesn't have any high-bits set + * - AND "size" doesn't have any high-bits set + * - AND "addr+size" doesn't have any high-bits set + * - OR we are in kernel mode. + */ +#define __access_ok(addr,size,mask) \ + (((mask) & (addr | size | (addr+size))) == 0) +#define __access_mask get_fs() + +#define access_ok(type,addr,size) \ + __access_ok(((unsigned long)(addr)),(size),__access_mask) + +extern inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size) ? 0 : -EFAULT; +} + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + * + * As the alpha uses the same address space for kernel and user + * data, we can just do these as direct assignments. (Of course, the + * exception handling means that it's no longer "just"...) + * + * Careful to not + * (a) re-use the arguments for side effects (sizeof/typeof is ok) + * (b) require any knowledge of processes at this stage + */ +#define put_user(x,ptr) \ + __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)),__access_mask) +#define get_user(x,ptr) \ + __get_user_check((x),(ptr),sizeof(*(ptr)),__access_mask) + +/* + * The "__xxx" versions do not do address space checking, useful when + * doing multiple accesses to the same area (the programmer has to do the + * checks by hand with "access_ok()") + */ +#define __put_user(x,ptr) \ + __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) +#define __get_user(x,ptr) \ + __get_user_nocheck((x),(ptr),sizeof(*(ptr))) + +/* + * The "lda %1, 2b-1b(%0)" bits are magic to get the assembler to + * encode the bits we need for resolving the exception. See the + * more extensive comments with fixup_inline_exception below for + * more information. + */ + +extern void __get_user_unknown(void); + +#define __get_user_nocheck(x,ptr,size) \ +({ \ + long __gu_err = 0, __gu_val; \ + switch (size) { \ + case 1: __get_user_8(ptr); break; \ + case 2: __get_user_16(ptr); break; \ + case 4: __get_user_32(ptr); break; \ + case 8: __get_user_64(ptr); break; \ + default: __get_user_unknown(); break; \ + } \ + (x) = (__typeof__(*(ptr))) __gu_val; \ + __gu_err; \ +}) + +#define __get_user_check(x,ptr,size,mask) \ +({ \ + long __gu_err = -EFAULT, __gu_val = 0; \ + const __typeof__(*(ptr)) *__gu_addr = (ptr); \ + if (__access_ok((long)__gu_addr,size,mask)) { \ + __gu_err = 0; \ + switch (size) { \ + case 1: __get_user_8(__gu_addr); break; \ + case 2: __get_user_16(__gu_addr); break; \ + case 4: __get_user_32(__gu_addr); break; \ + case 8: __get_user_64(__gu_addr); break; \ + default: __get_user_unknown(); break; \ + } \ + } \ + (x) = (__typeof__(*(ptr))) __gu_val; \ + __gu_err; \ +}) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) (*(struct __large_struct *)(x)) + +#define __get_user_64(addr) \ + __asm__("1: ldq %0,%2\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=r"(__gu_val), "=r"(__gu_err) \ + : "m"(__m(addr)), "1"(__gu_err)) + +#define __get_user_32(addr) \ + __asm__("1: ldl %0,%2\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=r"(__gu_val), "=r"(__gu_err) \ + : "m"(__m(addr)), "1"(__gu_err)) + +#ifdef __HAVE_CPU_BWX +/* Those lucky bastards with ev56 and later cpus can do byte/word moves. */ + +#define __get_user_16(addr) \ + __asm__("1: ldwu %0,%2\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=r"(__gu_val), "=r"(__gu_err) \ + : "m"(__m(addr)), "1"(__gu_err)) + +#define __get_user_8(addr) \ + __asm__("1: ldbu %0,%2\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=r"(__gu_val), "=r"(__gu_err) \ + : "m"(__m(addr)), "1"(__gu_err)) +#else +/* Unfortunately, we can't get an unaligned access trap for the sub-word + load, so we have to do a general unaligned operation. */ + +#define __get_user_16(addr) \ +{ \ + long __gu_tmp; \ + __asm__("1: ldq_u %0,0(%3)\n" \ + "2: ldq_u %1,1(%3)\n" \ + " extwl %0,%3,%0\n" \ + " extwh %1,%3,%1\n" \ + " or %0,%1,%0\n" \ + "3:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 3b-1b(%2)\n" \ + " .gprel32 2b\n" \ + " lda %0, 2b-1b(%2)\n" \ + ".text" \ + : "=&r"(__gu_val), "=&r"(__gu_tmp), "=r"(__gu_err) \ + : "r"(addr), "2"(__gu_err)); \ +} + +#define __get_user_8(addr) \ + __asm__("1: ldq_u %0,0(%2)\n" \ + " extbl %0,%2,%0\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda %0, 2b-1b(%1)\n" \ + ".text" \ + : "=&r"(__gu_val), "=r"(__gu_err) \ + : "r"(addr), "1"(__gu_err)) +#endif + +extern void __put_user_unknown(void); + +#define __put_user_nocheck(x,ptr,size) \ +({ \ + long __pu_err = 0; \ + switch (size) { \ + case 1: __put_user_8(x,ptr); break; \ + case 2: __put_user_16(x,ptr); break; \ + case 4: __put_user_32(x,ptr); break; \ + case 8: __put_user_64(x,ptr); break; \ + default: __put_user_unknown(); break; \ + } \ + __pu_err; \ +}) + +#define __put_user_check(x,ptr,size,mask) \ +({ \ + long __pu_err = -EFAULT; \ + __typeof__(*(ptr)) *__pu_addr = (ptr); \ + if (__access_ok((long)__pu_addr,size,mask)) { \ + __pu_err = 0; \ + switch (size) { \ + case 1: __put_user_8(x,__pu_addr); break; \ + case 2: __put_user_16(x,__pu_addr); break; \ + case 4: __put_user_32(x,__pu_addr); break; \ + case 8: __put_user_64(x,__pu_addr); break; \ + default: __put_user_unknown(); break; \ + } \ + } \ + __pu_err; \ +}) + +/* + * The "__put_user_xx()" macros tell gcc they read from memory + * instead of writing: this is because they do not write to + * any memory gcc knows about, so there are no aliasing issues + */ +#define __put_user_64(x,addr) \ +__asm__ __volatile__("1: stq %r2,%1\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31,2b-1b(%0)\n" \ + ".text" \ + : "=r"(__pu_err) \ + : "m" (__m(addr)), "rJ" (x), "0"(__pu_err)) + +#define __put_user_32(x,addr) \ +__asm__ __volatile__("1: stl %r2,%1\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31,2b-1b(%0)\n" \ + ".text" \ + : "=r"(__pu_err) \ + : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) + +#ifdef __HAVE_CPU_BWX +/* Those lucky bastards with ev56 and later cpus can do byte/word moves. */ + +#define __put_user_16(x,addr) \ +__asm__ __volatile__("1: stw %r2,%1\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31,2b-1b(%0)\n" \ + ".text" \ + : "=r"(__pu_err) \ + : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) + +#define __put_user_8(x,addr) \ +__asm__ __volatile__("1: stb %r2,%1\n" \ + "2:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31,2b-1b(%0)\n" \ + ".text" \ + : "=r"(__pu_err) \ + : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) +#else +/* Unfortunately, we can't get an unaligned access trap for the sub-word + write, so we have to do a general unaligned operation. */ + +#define __put_user_16(x,addr) \ +{ \ + long __pu_tmp1, __pu_tmp2, __pu_tmp3, __pu_tmp4; \ + __asm__ __volatile__( \ + "1: ldq_u %2,1(%5)\n" \ + "2: ldq_u %1,0(%5)\n" \ + " inswh %6,%5,%4\n" \ + " inswl %6,%5,%3\n" \ + " mskwh %2,%5,%2\n" \ + " mskwl %1,%5,%1\n" \ + " or %2,%4,%2\n" \ + " or %1,%3,%1\n" \ + "3: stq_u %2,1(%5)\n" \ + "4: stq_u %1,0(%5)\n" \ + "5:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31, 5b-1b(%0)\n" \ + " .gprel32 2b\n" \ + " lda $31, 5b-2b(%0)\n" \ + " .gprel32 3b\n" \ + " lda $31, 5b-3b(%0)\n" \ + " .gprel32 4b\n" \ + " lda $31, 5b-4b(%0)\n" \ + ".text" \ + : "=r"(__pu_err), "=&r"(__pu_tmp1), \ + "=&r"(__pu_tmp2), "=&r"(__pu_tmp3), \ + "=&r"(__pu_tmp4) \ + : "r"(addr), "r"((unsigned long)(x)), "0"(__pu_err)); \ +} + +#define __put_user_8(x,addr) \ +{ \ + long __pu_tmp1, __pu_tmp2; \ + __asm__ __volatile__( \ + "1: ldq_u %1,0(%4)\n" \ + " insbl %3,%4,%2\n" \ + " mskbl %1,%4,%1\n" \ + " or %1,%2,%1\n" \ + "2: stq_u %1,0(%4)\n" \ + "3:\n" \ + ".section __ex_table,\"a\"\n" \ + " .gprel32 1b\n" \ + " lda $31, 3b-1b(%0)\n" \ + " .gprel32 2b\n" \ + " lda $31, 3b-2b(%0)\n" \ + ".text" \ + : "=r"(__pu_err), \ + "=&r"(__pu_tmp1), "=&r"(__pu_tmp2) \ + : "r"((unsigned long)(x)), "r"(addr), "0"(__pu_err)); \ +} +#endif + + +/* + * Complex access routines + */ + +#define copy_to_user(to,from,n) __copy_tofrom_user((to),(from),(n),__cu_to) +#define copy_from_user(to,from,n) __copy_tofrom_user((to),(from),(n),__cu_from) + +extern void __copy_user(void); + +#define __copy_tofrom_user(to,from,n,v) \ +({ \ + register void * __cu_to __asm__("$6") = (to); \ + register const void * __cu_from __asm__("$7") = (from); \ + register long __cu_len __asm__("$0") = (n); \ + if (__access_ok(((long)(v)),__cu_len,__access_mask)) { \ + __asm__ __volatile__( \ + "jsr $28,(%3),__copy_user" \ + : "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to) \ + : "r" (__copy_user), "0" (__cu_len), \ + "1" (__cu_from), "2" (__cu_to) \ + : "$1","$2","$3","$4","$5","$28","memory"); \ + } \ + __cu_len; \ +}) + +extern void __clear_user(void); + +#define clear_user(to,n) \ +({ \ + register void * __cl_to __asm__("$6") = (to); \ + register long __cl_len __asm__("$0") = (n); \ + if (__access_ok(((long)__cl_to),__cl_len,__access_mask)) { \ + __asm__ __volatile__( \ + "jsr $28,(%2),__clear_user" \ + : "=r"(__cl_len), "=r"(__cl_to) \ + : "r"(__clear_user), "0"(__cl_len), "1"(__cl_to)\ + : "$1","$2","$3","$4","$5","$28","memory"); \ + } \ + __cl_len; \ +}) + + +/* Returns: -EFAULT if exception before terminator, N if the entire + buffer filled, else strlen. */ + +extern long __strncpy_from_user(char *__to, const char *__from, long __to_len); + +#define strncpy_from_user(to,from,n) \ +({ \ + char * __sfu_to = (to); \ + const char * __sfu_from = (from); \ + long __sfu_ret = -EFAULT; \ + if (__access_ok(((long)__sfu_from),0,__access_mask)) \ + __sfu_ret = __strncpy_from_user(__sfu_to,__sfu_from,(n)); \ + __sfu_ret; \ +}) + +/* Returns: 0 if bad, string length+1 (memory size) of string if ok */ +extern long __strlen_user(const char *); + +extern inline long strlen_user(const char *str) +{ + return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0; +} + +/* + * About the exception table: + * + * - insn is a 32-bit offset off of the kernel's or module's gp. + * - nextinsn is a 16-bit offset off of the faulting instruction + * (not off of the *next* instruction as branches are). + * - errreg is the register in which to place -EFAULT. + * - valreg is the final target register for the load sequence + * and will be zeroed. + * + * Either errreg or valreg may be $31, in which case nothing happens. + * + * The exception fixup information "just so happens" to be arranged + * as in a MEM format instruction. This lets us emit our three + * values like so: + * + * lda valreg, nextinsn(errreg) + * + */ + +struct exception_table_entry +{ + signed int insn; + union exception_fixup { + unsigned unit; + struct { + signed int nextinsn : 16; + unsigned int errreg : 5; + unsigned int valreg : 5; + } bits; + } fixup; +}; + +/* Returns 0 if exception not found and fixup.unit otherwise. */ +extern unsigned search_exception_table(unsigned long); + +/* Returns the new pc */ +#define fixup_exception(map_reg, fixup_unit, pc) \ +({ \ + union exception_fixup __fie_fixup; \ + __fie_fixup.unit = fixup_unit; \ + if (__fie_fixup.bits.valreg != 31) \ + map_reg(__fie_fixup.bits.valreg) = 0; \ + if (__fie_fixup.bits.errreg != 31) \ + map_reg(__fie_fixup.bits.errreg) = -EFAULT; \ + (pc) + __fie_fixup.bits.nextinsn; \ +}) + + +#endif /* __ALPHA_UACCESS_H */ diff --git a/include/asm-alpha/unaligned.h b/include/asm-alpha/unaligned.h index 071477496..35da3d5ae 100644 --- a/include/asm-alpha/unaligned.h +++ b/include/asm-alpha/unaligned.h @@ -1,55 +1,72 @@ #ifndef __ALPHA_UNALIGNED_H #define __ALPHA_UNALIGNED_H +/* + * The main single-value unaligned transfer routines. + */ +#define get_unaligned(ptr) \ + ((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr)))) +#define put_unaligned(x,ptr) \ + __put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr))) + +/* + * This is a silly but good way to make sure that + * the get/put functions are indeed always optimized, + * and that we use the correct sizes. + */ +extern void bad_unaligned_access_length(void); + /* - * inline functions to do unaligned accesses.. See entUna in traps.c + * Elemental unaligned loads */ -extern inline unsigned long ldq_u(unsigned long * r11) + +extern inline unsigned long __uldq(const unsigned long * r11) { unsigned long r1,r2; __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extql %0,%2,%0\n\t" - "extqh %1,%2,%1\n\t" - "bis %1,%0,%0" + "extqh %1,%2,%1" :"=&r" (r1), "=&r" (r2) :"r" (r11), "m" (*r11), - "m" (*(unsigned long *)(7+(char *) r11))); - return r1; + "m" (*(const unsigned long *)(7+(char *) r11))); + return r1 | r2; } -extern inline unsigned long ldl_u(unsigned int * r11) +extern inline unsigned long __uldl(const unsigned int * r11) { unsigned long r1,r2; __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extll %0,%2,%0\n\t" - "extlh %1,%2,%1\n\t" - "bis %1,%0,%0" + "extlh %1,%2,%1" :"=&r" (r1), "=&r" (r2) :"r" (r11), "m" (*r11), - "m" (*(unsigned long *)(3+(char *) r11))); - return r1; + "m" (*(const unsigned long *)(3+(char *) r11))); + return r1 | r2; } -extern inline unsigned long ldw_u(unsigned short * r11) +extern inline unsigned long __uldw(const unsigned short * r11) { unsigned long r1,r2; __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extwl %0,%2,%0\n\t" - "extwh %1,%2,%1\n\t" - "bis %1,%0,%0" + "extwh %1,%2,%1" :"=&r" (r1), "=&r" (r2) :"r" (r11), "m" (*r11), - "m" (*(unsigned long *)(1+(char *) r11))); - return r1; + "m" (*(const unsigned long *)(1+(char *) r11))); + return r1 | r2; } -extern inline void stq_u(unsigned long r5, unsigned long * r11) +/* + * Elemental unaligned stores + */ + +extern inline void __ustq(unsigned long r5, unsigned long * r11) { unsigned long r1,r2,r3,r4; @@ -69,7 +86,7 @@ extern inline void stq_u(unsigned long r5, unsigned long * r11) :"r" (r5), "r" (r11)); } -extern inline void stl_u(unsigned long r5, unsigned int * r11) +extern inline void __ustl(unsigned long r5, unsigned int * r11) { unsigned long r1,r2,r3,r4; @@ -89,7 +106,7 @@ extern inline void stl_u(unsigned long r5, unsigned int * r11) :"r" (r5), "r" (r11)); } -extern inline void stw_u(unsigned long r5, unsigned short * r11) +extern inline void __ustw(unsigned long r5, unsigned short * r11) { unsigned long r1,r2,r3,r4; @@ -109,4 +126,46 @@ extern inline void stw_u(unsigned long r5, unsigned short * r11) :"r" (r5), "r" (r11)); } +extern inline unsigned long __get_unaligned(const void *ptr, size_t size) +{ + unsigned long val; + switch (size) { + case 1: + val = *(const unsigned char *)ptr; + break; + case 2: + val = __uldw((const unsigned short *)ptr); + break; + case 4: + val = __uldl((const unsigned int *)ptr); + break; + case 8: + val = __uldq((const unsigned long *)ptr); + break; + default: + bad_unaligned_access_length(); + } + return val; +} + +extern inline void __put_unaligned(unsigned long val, void *ptr, size_t size) +{ + switch (size) { + case 1: + *(unsigned char *)ptr = (val); + break; + case 2: + __ustw(val, (unsigned short *)ptr); + break; + case 4: + __ustl(val, (unsigned int *)ptr); + break; + case 8: + __ustq(val, (unsigned long *)ptr); + break; + default: + bad_unaligned_access_length(); + } +} + #endif diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h index 11a940a57..03f745481 100644 --- a/include/asm-alpha/unistd.h +++ b/include/asm-alpha/unistd.h @@ -1,57 +1,234 @@ #ifndef _ALPHA_UNISTD_H #define _ALPHA_UNISTD_H +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_close 6 +#define __NR_wait4 7 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_chdir 12 +#define __NR_fchdir 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_brk 17 +#define __NR_lseek 19 +#define __NR_getxpid 20 +#define __NR_setuid 23 +#define __NR_getxuid 24 +#define __NR_ptrace 26 +#define __NR_access 33 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_setpgid 39 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_open 45 +#define __NR_getxgid 47 +#define __NR_acct 51 +#define __NR_sigpending 52 +#define __NR_ioctl 54 +#define __NR_symlink 57 +#define __NR_readlink 58 +#define __NR_execve 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_getpgrp 63 +#define __NR_getpagesize 64 +#define __NR_stat 67 +#define __NR_lstat 68 +#define __NR_mmap 71 /* OSF/1 mmap is superset of Linux */ +#define __NR_munmap 73 +#define __NR_mprotect 74 +#define __NR_madvise 75 +#define __NR_vhangup 76 +#define __NR_getgroups 79 +#define __NR_setgroups 80 +#define __NR_setpgrp 82 /* BSD alias for setpgid */ +#define __NR_setitimer 83 +#define __NR_getitimer 86 +#define __NR_gethostname 87 +#define __NR_sethostname 88 +#define __NR_getdtablesize 89 +#define __NR_dup2 90 +#define __NR_fstat 91 +#define __NR_fcntl 92 +#define __NR_select 93 +#define __NR_fsync 95 +#define __NR_setpriority 96 +#define __NR_socket 97 +#define __NR_connect 98 +#define __NR_accept 99 +#define __NR_getpriority 100 +#define __NR_send 101 +#define __NR_recv 102 +#define __NR_sigreturn 103 +#define __NR_bind 104 +#define __NR_setsockopt 105 +#define __NR_listen 106 +#define __NR_sigsuspend 111 +#define __NR_recvmsg 113 +#define __NR_sendmsg 114 +#define __NR_gettimeofday 116 +#define __NR_getrusage 117 +#define __NR_getsockopt 118 +#define __NR_readv 120 +#define __NR_writev 121 +#define __NR_settimeofday 122 +#define __NR_fchown 123 +#define __NR_fchmod 124 +#define __NR_recvfrom 125 +#define __NR_setreuid 126 +#define __NR_setregid 127 +#define __NR_rename 128 +#define __NR_truncate 129 +#define __NR_ftruncate 130 +#define __NR_flock 131 +#define __NR_setgid 132 +#define __NR_sendto 133 +#define __NR_shutdown 134 +#define __NR_socketpair 135 +#define __NR_mkdir 136 +#define __NR_rmdir 137 +#define __NR_utimes 138 +#define __NR_getpeername 141 +#define __NR_getrlimit 144 +#define __NR_setrlimit 145 +#define __NR_setsid 147 +#define __NR_quotactl 148 +#define __NR_getsockname 150 +#define __NR_sigaction 156 +#define __NR_setdomainname 166 +#define __NR_msgctl 200 +#define __NR_msgget 201 +#define __NR_msgrcv 202 +#define __NR_msgsnd 203 +#define __NR_semctl 204 +#define __NR_semget 205 +#define __NR_semop 206 +#define __NR_shmctl 210 +#define __NR_shmdt 211 +#define __NR_shmget 212 + +#define __NR_msync 217 + +#define __NR_getpgid 233 +#define __NR_getsid 234 + +#define __NR_sysfs 254 + /* - * ".long 131" is "PAL_callsys".. - * - * Duh, the alpha gcc compiler doesn't allow us to specify regs - * yet. I'll have to see about this later.. + * Linux-specific system calls begin at 300 */ +#define __NR_bdflush 300 +#define __NR_sethae 301 +#define __NR_mount 302 +#define __NR_adjtimex 303 +#define __NR_swapoff 304 +#define __NR_getdents 305 +#define __NR_create_module 306 +#define __NR_init_module 307 +#define __NR_delete_module 308 +#define __NR_get_kernel_syms 309 +#define __NR_syslog 310 +#define __NR_reboot 311 +#define __NR_clone 312 +#define __NR_uselib 313 +#define __NR_mlock 314 +#define __NR_munlock 315 +#define __NR_mlockall 316 +#define __NR_munlockall 317 +#define __NR_sysinfo 318 +#define __NR__sysctl 319 +#define __NR_idle 320 +#define __NR_umount 321 +#define __NR_swapon 322 +#define __NR_times 323 +#define __NR_personality 324 +#define __NR_setfsuid 325 +#define __NR_setfsgid 326 +#define __NR_ustat 327 +#define __NR_statfs 328 +#define __NR_fstatfs 329 +#define __NR_sched_setparam 330 +#define __NR_sched_getparam 331 +#define __NR_sched_setscheduler 332 +#define __NR_sched_getscheduler 333 +#define __NR_sched_yield 334 +#define __NR_sched_get_priority_max 335 +#define __NR_sched_get_priority_min 336 +#define __NR_sched_rr_get_interval 337 +#define __NR_afs_syscall 338 +#define __NR_uname 339 +#define __NR_nanosleep 340 +#define __NR_mremap 341 +#define __NR_nfsctl 342 +#define __NR_setresuid 343 +#define __NR_getresuid 344 +#define __NR_pciconfig_read 345 +#define __NR_pciconfig_write 346 + +#if defined(__LIBRARY__) && defined(__GNUC__) /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ - return (type) -1; \ +#define _syscall0(type, name) \ +type name(void) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name)); \ } -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ - return (type) -1; \ +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1); \ } -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ - return (type) -1; \ +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1, arg2); \ } -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ - return (type) -1; \ +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1, arg2, arg3); \ } #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - return (type) -1; \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1, arg2, arg3, arg4); \ } #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ - return (type) -1; \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ + extern long syscall (int, ...); \ + return syscall(__NR_##name, arg1, arg2, arg3, arg4); \ } +#endif /* __LIBRARY__ && __GNUC__ */ + #ifdef __KERNEL_SYSCALLS__ -extern unsigned long kernel_fork(void); -static inline unsigned long fork(void) +#include <linux/string.h> +#include <linux/signal.h> + +extern long __kernel_thread(unsigned long, int (*)(void *), void *); + +static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { - return kernel_fork(); + return __kernel_thread(flags | CLONE_VM, fn, arg); } extern void sys_idle(void); @@ -133,10 +310,10 @@ static inline int sync(void) return sys_sync(); } -extern int sys_waitpid(int, int *, int); +extern int sys_wait4(int, int *, int, struct rusage *); static inline pid_t waitpid(int pid, int * wait_stat, int flags) { - return sys_waitpid(pid,wait_stat,flags); + return sys_wait4(pid, wait_stat, flags, NULL); } static inline pid_t wait(int * wait_stat) diff --git a/include/asm-alpha/user.h b/include/asm-alpha/user.h new file mode 100644 index 000000000..c5519bf16 --- /dev/null +++ b/include/asm-alpha/user.h @@ -0,0 +1,52 @@ +#ifndef _ALPHA_USER_H +#define _ALPHA_USER_H + +#include <linux/ptrace.h> + +#include <asm/page.h> +#include <asm/reg.h> + +/* + * Core file format: The core file is written in such a way that gdb + * can understand it and provide useful information to the user (under + * linux we use the `trad-core' bfd, NOT the osf-core). The file contents + * are as follows: + * + * upage: 1 page consisting of a user struct that tells gdb + * what is present in the file. Directly after this is a + * copy of the task_struct, which is currently not used by gdb, + * but it may come in handy at some point. All of the registers + * are stored as part of the upage. The upage should always be + * only one page long. + * data: The data segment follows next. We use current->end_text to + * current->brk to pick up all of the user variables, plus any memory + * that may have been sbrk'ed. No attempt is made to determine if a + * page is demand-zero or if a page is totally unused, we just cover + * the entire range. All of the addresses are rounded in such a way + * that an integral number of pages is written. + * stack: We need the stack information in order to get a meaningful + * backtrace. We need to write the data from usp to + * current->start_stack, so we round each of these in order to be able + * to write an integer number of pages. + */ +struct user { + unsigned long regs[EF_SIZE/8+32]; /* integer and fp regs */ + size_t u_tsize; /* text size (pages) */ + size_t u_dsize; /* data size (pages) */ + size_t u_ssize; /* stack size (pages) */ + unsigned long start_code; /* text starting address */ + unsigned long start_data; /* data starting address */ + unsigned long start_stack; /* stack starting address */ + long int signal; /* signal causing core dump */ + struct regs * u_ar0; /* help gdb find registers */ + unsigned long magic; /* identifies a core file */ + char u_comm[32]; /* user command name */ +}; + +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_DATA_START_ADDR (u.start_data) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif /* _ALPHA_USER_H */ diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h new file mode 100644 index 000000000..57b14024c --- /dev/null +++ b/include/asm-generic/unaligned.h @@ -0,0 +1,20 @@ +#ifndef _ASM_GENERIC_UNALIGNED_H_ +#define _ASM_GENERIC_UNALIGNED_H_ + +/* + * For the benefit of those who are trying to port Linux to another + * architecture, here are some C-language equivalents. + */ + +#include <asm/string.h> + + +#define get_unaligned(ptr) \ + ({ __typeof__(*(ptr)) __tmp; memcpy(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) + +#define put_unaligned(val, ptr) \ + ({ __typeof__(*(ptr)) __tmp = (val); \ + memcpy((ptr), &__tmp, sizeof(*(ptr))); \ + (void)0; }) + +#endif /* _ASM_GENERIC_UNALIGNED_H */ diff --git a/include/asm-i386/a.out.h b/include/asm-i386/a.out.h new file mode 100644 index 000000000..ab17bb8e5 --- /dev/null +++ b/include/asm-i386/a.out.h @@ -0,0 +1,26 @@ +#ifndef __I386_A_OUT_H__ +#define __I386_A_OUT_H__ + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#ifdef __KERNEL__ + +#define STACK_TOP TASK_SIZE + +#endif + +#endif /* __A_OUT_GNU_H__ */ diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h new file mode 100644 index 000000000..1b9d99f76 --- /dev/null +++ b/include/asm-i386/atomic.h @@ -0,0 +1,67 @@ +#ifndef __ARCH_I386_ATOMIC__ +#define __ARCH_I386_ATOMIC__ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +#ifdef __SMP__ +#define LOCK "lock ; " +#else +#define LOCK "" +#endif + +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) + +typedef int atomic_t; + +static __inline__ void atomic_add(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__( + LOCK "addl %1,%0" + :"=m" (__atomic_fool_gcc(v)) + :"ir" (i), "m" (__atomic_fool_gcc(v))); +} + +static __inline__ void atomic_sub(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__( + LOCK "subl %1,%0" + :"=m" (__atomic_fool_gcc(v)) + :"ir" (i), "m" (__atomic_fool_gcc(v))); +} + +static __inline__ void atomic_inc(atomic_t *v) +{ + __asm__ __volatile__( + LOCK "incl %0" + :"=m" (__atomic_fool_gcc(v)) + :"m" (__atomic_fool_gcc(v))); +} + +static __inline__ void atomic_dec(atomic_t *v) +{ + __asm__ __volatile__( + LOCK "decl %0" + :"=m" (__atomic_fool_gcc(v)) + :"m" (__atomic_fool_gcc(v))); +} + +static __inline__ int atomic_dec_and_test(atomic_t *v) +{ + unsigned char c; + + __asm__ __volatile__( + LOCK "decl %0; sete %1" + :"=m" (__atomic_fool_gcc(v)), "=qm" (c) + :"m" (__atomic_fool_gcc(v))); + return c != 0; +} + +#endif diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h index ee339bd64..d220f6f51 100644 --- a/include/asm-i386/bitops.h +++ b/include/asm-i386/bitops.h @@ -13,86 +13,89 @@ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). */ +#ifdef __SMP__ +#define LOCK_PREFIX "lock ; " +#define SMPVOL volatile +#else +#define LOCK_PREFIX "" +#define SMPVOL +#endif + /* * Some hacks to defeat gcc over-optimizations.. */ struct __dummy { unsigned long a[100]; }; #define ADDR (*(struct __dummy *) addr) +#define CONST_ADDR (*(const struct __dummy *) addr) -extern __inline__ int set_bit(int nr, void * addr) +extern __inline__ int set_bit(int nr, SMPVOL void * addr) { int oldbit; - __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0" + __asm__ __volatile__(LOCK_PREFIX + "btsl %2,%1\n\tsbbl %0,%0" :"=r" (oldbit),"=m" (ADDR) - :"r" (nr)); + :"ir" (nr)); return oldbit; } -extern __inline__ int clear_bit(int nr, void * addr) +extern __inline__ int clear_bit(int nr, SMPVOL void * addr) { int oldbit; - __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0" + __asm__ __volatile__(LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" :"=r" (oldbit),"=m" (ADDR) - :"r" (nr)); + :"ir" (nr)); return oldbit; } -extern __inline__ int change_bit(int nr, void * addr) +extern __inline__ int change_bit(int nr, SMPVOL void * addr) { int oldbit; - __asm__ __volatile__("btcl %2,%1\n\tsbbl %0,%0" + __asm__ __volatile__(LOCK_PREFIX + "btcl %2,%1\n\tsbbl %0,%0" :"=r" (oldbit),"=m" (ADDR) - :"r" (nr)); + :"ir" (nr)); return oldbit; } /* - * This routine doesn't need to be atomic, but it's faster to code it - * this way. + * This routine doesn't need to be atomic. */ -extern __inline__ int test_bit(int nr, void * addr) +extern __inline__ int test_bit(int nr, const SMPVOL void * addr) { - int oldbit; - - __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit) - :"m" (ADDR),"r" (nr)); - return oldbit; + return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0; } /* * Find-bit routines.. */ -extern inline int find_first_zero_bit(void * addr, unsigned size) +extern __inline__ int find_first_zero_bit(void * addr, unsigned size) { int res; if (!size) return 0; - __asm__(" - cld - movl $-1,%%eax - repe; scasl - je 1f - subl $4,%%edi - movl (%%edi),%%eax - notl %%eax - bsfl %%eax,%%edx - jmp 2f -1: xorl %%edx,%%edx -2: subl %%ebx,%%edi - shll $3,%%edi - addl %%edi,%%edx" + __asm__("cld\n\t" + "movl $-1,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "xorl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" :"=d" (res) :"c" ((size + 31) >> 5), "D" (addr), "b" (addr) - :"ax", "bx", "cx", "di"); + :"ax", "cx", "di"); return res; } -extern inline int find_next_zero_bit (void * addr, int size, int offset) +extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) { unsigned long * p = ((unsigned long *) addr) + (offset >> 5); int set = 0, bit = offset & 31, res; @@ -101,11 +104,10 @@ extern inline int find_next_zero_bit (void * addr, int size, int offset) /* * Look for zero in first byte */ - __asm__(" - bsfl %1,%0 - jne 1f - movl $32, %0 -1: " + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" : "=r" (set) : "r" (~(*p >> bit))); if (set < (32 - bit)) @@ -124,7 +126,7 @@ extern inline int find_next_zero_bit (void * addr, int size, int offset) * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. */ -extern inline unsigned long ffz(unsigned long word) +extern __inline__ unsigned long ffz(unsigned long word) { __asm__("bsfl %1,%0" :"=r" (word) @@ -132,4 +134,14 @@ extern inline unsigned long ffz(unsigned long word) return word; } +#ifdef __KERNEL__ + +#define ext2_set_bit set_bit +#define ext2_clear_bit clear_bit +#define ext2_test_bit test_bit +#define ext2_find_first_zero_bit find_first_zero_bit +#define ext2_find_next_zero_bit find_next_zero_bit + +#endif /* __KERNEL__ */ + #endif /* _I386_BITOPS_H */ diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h index 2d40c0d9b..1f7b33910 100644 --- a/include/asm-i386/bugs.h +++ b/include/asm-i386/bugs.h @@ -11,6 +11,8 @@ * void check_bugs(void); */ +#include <linux/config.h> + #define CONFIG_BUGi386 static void no_halt(char *s, int *ints) @@ -108,8 +110,24 @@ static void check_hlt(void) printk("Ok.\n"); } +static void check_tlb(void) +{ +#ifndef CONFIG_M386 + /* + * The 386 chips don't support TLB finegrained invalidation. + * They will fault when they hit an invlpg instruction. + */ + if (x86 == 3) { + printk("CPU is a 386 and this kernel was compiled for 486 or better.\n"); + printk("Giving up.\n"); + for (;;) ; + } +#endif +} + static void check_bugs(void) { + check_tlb(); check_fpu(); check_hlt(); system_utsname.machine[1] = '0' + x86; diff --git a/include/asm-i386/byteorder.h b/include/asm-i386/byteorder.h index 03eb42f8e..7dff2a869 100644 --- a/include/asm-i386/byteorder.h +++ b/include/asm-i386/byteorder.h @@ -6,12 +6,32 @@ #undef htonl #undef htons -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 #endif -#ifndef LITTLE_ENDIAN_BITFIELD -#define LITTLE_ENDIAN_BITFIELD +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD +#endif + +/* For avoiding bswap on i386 */ +#ifdef __KERNEL__ +#include <linux/config.h> + +/* + * In-kernel byte order macros to handle stuff like + * byte-order-dependent filesystems etc. + */ +#define cpu_to_le32(x) (x) +#define le32_to_cpu(x) (x) +#define cpu_to_le16(x) (x) +#define le16_to_cpu(x) (x) + +#define cpu_to_be32(x) htonl((x)) +#define be32_to_cpu(x) ntohl((x)) +#define cpu_to_be16(x) htons((x)) +#define be16_to_cpu(x) ntohs((x)) + #endif extern unsigned long int ntohl(unsigned long int); @@ -19,19 +39,23 @@ extern unsigned short int ntohs(unsigned short int); extern unsigned long int htonl(unsigned long int); extern unsigned short int htons(unsigned short int); -extern unsigned long int __ntohl(unsigned long int); -extern unsigned short int __ntohs(unsigned short int); -extern unsigned long int __constant_ntohl(unsigned long int); -extern unsigned short int __constant_ntohs(unsigned short int); +extern __inline__ unsigned long int __ntohl(unsigned long int); +extern __inline__ unsigned short int __ntohs(unsigned short int); +extern __inline__ unsigned long int __constant_ntohl(unsigned long int); +extern __inline__ unsigned short int __constant_ntohs(unsigned short int); extern __inline__ unsigned long int __ntohl(unsigned long int x) { +#if defined(__KERNEL__) && !defined(CONFIG_M386) + __asm__("bswap %0" : "=r" (x) : "0" (x)); +#else __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ "rorl $16,%0\n\t" /* swap words */ "xchgb %b0,%h0" /* swap higher bytes */ :"=q" (x) : "0" (x)); +#endif return x; } diff --git a/include/asm-i386/checksum.h b/include/asm-i386/checksum.h new file mode 100644 index 000000000..72ba38307 --- /dev/null +++ b/include/asm-i386/checksum.h @@ -0,0 +1,145 @@ +#ifndef _I386_CHECKSUM_H +#define _I386_CHECKSUM_H + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum); + + +/* + * the same as csum_partial, but copies from user space (but on the x86 + * we have just one address space, so this is identical to the above) + */ +#define csum_partial_copy_fromuser csum_partial_copy + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by + * Arnt Gulbrandsen. + */ +static inline unsigned short ip_fast_csum(unsigned char * iph, + unsigned int ihl) { + unsigned int sum; + + __asm__ __volatile__(" + movl (%1), %0 + subl $4, %2 + jbe 2f + addl 4(%1), %0 + adcl 8(%1), %0 + adcl 12(%1), %0 +1: adcl 16(%1), %0 + lea 4(%1), %1 + decl %2 + jne 1b + adcl $0, %0 + movl %0, %2 + shrl $16, %0 + addw %w2, %w0 + adcl $0, %0 + notl %0 +2: + " + /* Since the input registers which are loaded with iph and ipl + are modified, we must also specify them as outputs, or gcc + will assume they contain their original values. */ + : "=r" (sum), "=r" (iph), "=r" (ihl) + : "1" (iph), "2" (ihl)); + return(sum); +} + +/* + * Fold a partial checksum + */ + +static inline unsigned int csum_fold(unsigned int sum) +{ + __asm__(" + addl %1, %0 + adcl $0xffff, %0 + " + : "=r" (sum) + : "r" (sum << 16), "0" (sum & 0xffff0000) + ); + return (~sum) >> 16; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ + +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum) { + __asm__(" + addl %1, %0 + adcl %2, %0 + adcl %3, %0 + adcl $0, %0 + " + : "=r" (sum) + : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum)); + return csum_fold(sum); +} +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline unsigned short ip_compute_csum(unsigned char * buff, int len) { + return csum_fold (csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int sum) +{ + __asm__(" + addl 0(%1), %0 + adcl 4(%1), %0 + adcl 8(%1), %0 + adcl 12(%1), %0 + adcl 0(%2), %0 + adcl 4(%2), %0 + adcl 8(%2), %0 + adcl 12(%2), %0 + adcl %3, %0 + adcl %4, %0 + adcl $0, %0 + " + : "=&r" (sum) + : "r" (saddr), "r" (daddr), + "r"(htonl((__u32) (len))), "r"(htonl(proto)), "0"(sum)); + + return csum_fold(sum); +} + +#endif diff --git a/include/asm-i386/delay.h b/include/asm-i386/delay.h index e408db01b..e22e8d6b2 100644 --- a/include/asm-i386/delay.h +++ b/include/asm-i386/delay.h @@ -6,10 +6,18 @@ * * Delay routines, using a pre-computed "loops_per_second" value. */ + +#ifdef __SMP__ +#include <asm/smp.h> +#endif extern __inline__ void __delay(int loops) { - __asm__(".align 2,0x90\n1:\tdecl %0\n\tjns 1b": :"a" (loops):"ax"); + __asm__ __volatile__( + ".align 2,0x90\n1:\tdecl %0\n\tjns 1b" + :/* no outputs */ + :"a" (loops) + :"ax"); } /* @@ -27,8 +35,13 @@ extern __inline__ void udelay(unsigned long usecs) usecs *= 0x000010c6; /* 2**32 / 1000000 */ __asm__("mull %0" :"=d" (usecs) +#ifdef __SMP__ + :"a" (usecs),"0" (cpu_data[smp_processor_id()].udelay_val) +#else :"a" (usecs),"0" (loops_per_sec) +#endif :"ax"); + __delay(usecs); } diff --git a/include/asm-i386/dma.h b/include/asm-i386/dma.h index e5e3251b2..0d45967da 100644 --- a/include/asm-i386/dma.h +++ b/include/asm-i386/dma.h @@ -70,7 +70,7 @@ #define MAX_DMA_CHANNELS 8 /* The maximum address that we can perform a DMA transfer to on this platform */ -#define MAX_DMA_ADDRESS 0x1000000 +#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ @@ -264,8 +264,7 @@ static __inline__ int get_dma_residue(unsigned int dmanr) /* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, char * device_id); /* reserve a DMA channel */ +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ - #endif /* _ASM_DMA_H */ diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h new file mode 100644 index 000000000..71009ec5c --- /dev/null +++ b/include/asm-i386/elf.h @@ -0,0 +1,67 @@ +#ifndef __ASMi386_ELF_H +#define __ASMi386_ELF_H + +/* + * ELF register definitions.. + */ + +#include <asm/ptrace.h> +#include <asm/user.h> + +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]; + +typedef struct user_i387_struct elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) ) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB; +#define ELF_ARCH EM_386 + + /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program + starts %edx contains a pointer to a function which might be + registered using `atexit'. This provides a mean for the + dynamic linker to call DT_FINI functions for shared libraries + that have been loaded before the code runs. + + A value of 0 tells we have no such handler. */ +#define ELF_PLAT_INIT(_r) _r->edx = 0 + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +/* Wow, the "main" arch needs arch dependent functions too.. :) */ + +/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is + now struct_user_regs, they are different) */ + +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ + pr_reg[0] = regs->ebx; \ + pr_reg[1] = regs->ecx; \ + pr_reg[2] = regs->edx; \ + pr_reg[3] = regs->esi; \ + pr_reg[4] = regs->edi; \ + pr_reg[5] = regs->ebp; \ + pr_reg[6] = regs->eax; \ + pr_reg[7] = regs->xds; \ + pr_reg[8] = regs->xes; \ + /* fake once used fs and gs selectors? */ \ + pr_reg[9] = regs->xds; /* was fs and __fs */ \ + pr_reg[10] = regs->xds; /* was gs and __gs */ \ + pr_reg[11] = regs->orig_eax; \ + pr_reg[12] = regs->eip; \ + pr_reg[13] = regs->xcs; \ + pr_reg[14] = regs->eflags; \ + pr_reg[15] = regs->esp; \ + pr_reg[16] = regs->xss; + +#endif diff --git a/include/asm-i386/errno.h b/include/asm-i386/errno.h index 4ff8c5c78..1936cb745 100644 --- a/include/asm-i386/errno.h +++ b/include/asm-i386/errno.h @@ -58,7 +58,9 @@ #define ENOANO 55 /* No anode */ #define EBADRQC 56 /* Invalid request code */ #define EBADSLT 57 /* Invalid slot */ -#define EDEADLOCK 58 /* File locking deadlock error */ + +#define EDEADLOCK EDEADLK + #define EBFONT 59 /* Bad font file format */ #define ENOSTR 60 /* Device not a stream */ #define ENODATA 61 /* No data available */ diff --git a/include/asm-i386/fcntl.h b/include/asm-i386/fcntl.h index 0cb8fcdba..369ac5153 100644 --- a/include/asm-i386/fcntl.h +++ b/include/asm-i386/fcntl.h @@ -48,11 +48,6 @@ blocking */ #define LOCK_UN 8 /* remove lock */ -#ifdef __KERNEL__ -#define F_POSIX 1 -#define F_FLOCK 2 -#endif /* __KERNEL__ */ - struct flock { short l_type; short l_whence; diff --git a/include/asm-i386/floppy.h b/include/asm-i386/floppy.h new file mode 100644 index 000000000..06a3fa1b6 --- /dev/null +++ b/include/asm-i386/floppy.h @@ -0,0 +1,301 @@ +#ifndef __ASM_I386_FLOPPY_H +#define __ASM_I386_FLOPPY_H + +#include <linux/vmalloc.h> + +#define SW fd_routine[use_virtual_dma&1] + + +#define fd_inb(port) inb_p(port) +#define fd_outb(port,value) outb_p(port,value) + +#define fd_enable_dma() SW._enable_dma(FLOPPY_DMA) +#define fd_disable_dma() SW._disable_dma(FLOPPY_DMA) +#define fd_request_dma() SW._request_dma(FLOPPY_DMA,"floppy") +#define fd_free_dma() SW._free_dma(FLOPPY_DMA) +#define fd_clear_dma_ff() SW._clear_dma_ff(FLOPPY_DMA) +#define fd_set_dma_mode(mode) SW._set_dma_mode(FLOPPY_DMA,mode) +#define fd_set_dma_addr(addr) SW._set_dma_addr(FLOPPY_DMA,addr) +#define fd_set_dma_count(count) SW._set_dma_count(FLOPPY_DMA,count) +#define fd_enable_irq() enable_irq(FLOPPY_IRQ) +#define fd_disable_irq() disable_irq(FLOPPY_IRQ) +#define fd_cacheflush(addr,size) /* nothing */ +#define fd_request_irq() SW._request_irq(FLOPPY_IRQ, floppy_interrupt, \ + SA_INTERRUPT|SA_SAMPLE_RANDOM, \ + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) +#define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA) +#define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size) +#define fd_dma_mem_free(addr,size) SW._dma_mem_free(addr,size) + +static int virtual_dma_count=0; +static int virtual_dma_residue=0; +static char *virtual_dma_addr=0; +static int virtual_dma_mode=0; +static int doing_pdma=0; + +static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs) +{ + register unsigned char st; + +#undef TRACE_FLPY_INT +#undef NO_FLOPPY_ASSEMBLER + +#ifdef TRACE_FLPY_INT + static int calls=0; + static int bytes=0; + static int dma_wait=0; +#endif + if(!doing_pdma) { + floppy_interrupt(irq, dev_id, regs); + return; + } + +#ifdef TRACE_FLPY_INT + if(!calls) + bytes = virtual_dma_count; +#endif + +#ifndef NO_FLOPPY_ASSEMBLER + __asm__ ( + "testl %1,%1 + je 3f +1: inb %w4,%b0 + andb $160,%b0 + cmpb $160,%b0 + jne 2f + incw %w4 + testl %3,%3 + jne 4f + inb %w4,%b0 + movb %0,(%2) + jmp 5f +4: movb (%2),%0 + outb %b0,%w4 +5: decw %w4 + outb %0,$0x80 + decl %1 + incl %2 + testl %1,%1 + jne 1b +3: inb %w4,%b0 +2: " + : "=a" ((char) st), + "=c" ((long) virtual_dma_count), + "=S" ((long) virtual_dma_addr) + : "b" ((long) virtual_dma_mode), + "d" ((short) virtual_dma_port+4), + "1" ((long) virtual_dma_count), + "2" ((long) virtual_dma_addr)); +#else + { + register int lcount; + register char *lptr; + + st = 1; + for(lcount=virtual_dma_count, lptr=virtual_dma_addr; + lcount; lcount--, lptr++) { + st=inb(virtual_dma_port+4) & 0xa0 ; + if(st != 0xa0) + break; + if(virtual_dma_mode) + outb_p(*lptr, virtual_dma_port+5); + else + *lptr = inb_p(virtual_dma_port+5); + st = inb(virtual_dma_port+4); + } + virtual_dma_count = lcount; + virtual_dma_addr = lptr; + } +#endif + +#ifdef TRACE_FLPY_INT + calls++; +#endif + if(st == 0x20) + return; + if(!(st & 0x20)) { + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; +#ifdef TRACE_FLPY_INT + printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", + virtual_dma_count, virtual_dma_residue, calls, bytes, + dma_wait); + calls = 0; + dma_wait=0; +#endif + doing_pdma = 0; + floppy_interrupt(irq, dev_id, regs); + return; + } +#ifdef TRACE_FLPY_INT + if(!virtual_dma_count) + dma_wait++; +#endif +} + +static void vdma_enable_dma(unsigned int dummy) +{ + doing_pdma = 1; +} + +static void vdma_disable_dma(unsigned int dummy) +{ + doing_pdma = 0; + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; +} + +static int vdma_request_dma(unsigned int dmanr, const char * device_id) +{ + return 0; +} + +static void vdma_nop(unsigned int dummy) +{ +} + +static void vdma_set_dma_mode(unsigned int dummy,char mode) +{ + virtual_dma_mode = (mode == DMA_MODE_WRITE); +} + +static void hset_dma_addr(unsigned int no, char *addr) +{ + set_dma_addr(no, virt_to_bus(addr)); +} + +static void vdma_set_dma_addr(unsigned int dummy, char *addr) +{ + virtual_dma_addr = addr; +} + +static void vdma_set_dma_count(unsigned int dummy,unsigned int count) +{ + virtual_dma_count = count; + virtual_dma_residue = 0; +} + +static int vdma_get_dma_residue(unsigned int dummy) +{ + return virtual_dma_count + virtual_dma_residue; +} + + +static int vdma_request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, + const char *device, + void *dev_id) +{ + return request_irq(irq, floppy_hardint,SA_INTERRUPT,device, dev_id); + +} + +/* Pure 2^n version of get_order */ +extern __inline__ int __get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +static unsigned long dma_mem_alloc(unsigned long size) +{ + return __get_dma_pages(GFP_KERNEL,__get_order(size)); +} + +static void dma_mem_free(unsigned long addr, unsigned long size) +{ + free_pages(addr, __get_order(size)); +} + +static unsigned long vdma_mem_alloc(unsigned long size) +{ + return (unsigned long) vmalloc(size); +} + +static void vdma_mem_free(unsigned long addr, unsigned long size) +{ + return vfree((void *)addr); +} + +struct fd_routine_l { + void (*_enable_dma)(unsigned int dummy); + void (*_disable_dma)(unsigned int dummy); + int (*_request_dma)(unsigned int dmanr, const char * device_id); + void (*_free_dma)(unsigned int dmanr); + void (*_clear_dma_ff)(unsigned int dummy); + void (*_set_dma_mode)(unsigned int dummy, char mode); + void (*_set_dma_addr)(unsigned int dummy, char *addr); + void (*_set_dma_count)(unsigned int dummy, unsigned int count); + int (*_get_dma_residue)(unsigned int dummy); + int (*_request_irq)(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, + const char *device, + void *dev_id); + unsigned long (*_dma_mem_alloc) (unsigned long size); + void (*_dma_mem_free)(unsigned long addr, unsigned long size); +} fd_routine[] = { + { + enable_dma, + disable_dma, + request_dma, + free_dma, + clear_dma_ff, + set_dma_mode, + hset_dma_addr, + set_dma_count, + get_dma_residue, + request_irq, + dma_mem_alloc, + dma_mem_free + }, + { + vdma_enable_dma, + vdma_disable_dma, + vdma_request_dma, + vdma_nop, + vdma_nop, + vdma_set_dma_mode, + vdma_set_dma_addr, + vdma_set_dma_count, + vdma_get_dma_residue, + vdma_request_irq, + vdma_mem_alloc, + vdma_mem_free + } +}; + +__inline__ void virtual_dma_init(void) +{ + /* Nothing to do on an i386 */ +} + +static int FDC1 = 0x3f0; +static int FDC2 = -1; + +#define FLOPPY0_TYPE ((CMOS_READ(0x10) >> 4) & 15) +#define FLOPPY1_TYPE (CMOS_READ(0x10) & 15) + +#define N_FDC 2 +#define N_DRIVE 8 + +/* + * The DMA channel used by the floppy controller cannot access data at + * addresses >= 16MB + * + * Went back to the 1MB limit, as some people had problems with the floppy + * driver otherwise. It doesn't matter much for performance anyway, as most + * floppy accesses go through the track buffer. + */ +#define CROSS_64KB(a,s) (((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64) && ! (use_virtual_dma & 1)) + +#endif /* __ASM_I386_FLOPPY_H */ diff --git a/include/asm-i386/i82489.h b/include/asm-i386/i82489.h new file mode 100644 index 000000000..8c36eb273 --- /dev/null +++ b/include/asm-i386/i82489.h @@ -0,0 +1,88 @@ +#ifndef __ASM_I82489_H +#define __ASM_I82489_H + +/* + * Offsets for programming the 82489 and Pentium integrated APIC + * + * Alan Cox <Alan.Cox@linux.org>, 1995. + */ + +#define APIC_ID 0x20 +#define GET_APIC_ID(x) (((x)>>24)&0x0F) +#define APIC_VERSION 0x30 +#define APIC_TASKPRI 0x80 +#define APIC_TPRI_MASK 0xFF +#define APIC_ARBPRI 0x90 +#define APIC_PROCPRI 0xA0 +#define APIC_EOI 0xB0 +#define APIC_EIO_ACK 0x0 /* Write this to the EOI register */ +#define APIC_RRR 0xC0 +#define APIC_LDR 0xD0 +#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF) +#define APIC_DFR 0xE0 +#define GET_APIC_DFR(x) (((x)>>28)&0x0F) +#define SET_APIC_DFR(x) ((x)<<28) +#define APIC_SPIV 0xF0 +#define APIC_ISR 0x100 +#define APIC_TMR 0x180 +#define APIC_IRR 0x200 +#define APIC_ESR 0x280 +#define APIC_ESR_SEND_CS 0x00001 +#define APIC_ESR_RECV_CS 0x00002 +#define APIC_ESR_SEND_ACC 0x00004 +#define APIC_ESR_RECV_ACC 0x00008 +#define APIC_ESR_SENDILL 0x00020 +#define APIC_ESR_RECVILL 0x00040 +#define APIC_ESR_ILLREGA 0x00080 +#define APIC_ICR 0x300 +#define APIC_DEST_FIELD 0x00000 +#define APIC_DEST_SELF 0x40000 +#define APIC_DEST_ALLINC 0x80000 +#define APIC_DEST_ALLBUT 0xC0000 +#define APIC_DEST_RR_MASK 0x30000 +#define APIC_DEST_RR_INVALID 0x00000 +#define APIC_DEST_RR_INPROG 0x10000 +#define APIC_DEST_RR_VALID 0x20000 +#define APIC_DEST_LEVELTRIG 0x08000 +#define APIC_DEST_ASSERT 0x04000 +#define APIC_DEST_BUSY 0x01000 +#define APIC_DEST_LOGICAL 0x00800 +#define APIC_DEST_DM_FIXED 0x00000 +#define APIC_DEST_DM_LOWEST 0x00100 +#define APIC_DEST_DM_SMI 0x00200 +#define APIC_DEST_DM_REMRD 0x00300 +#define APIC_DEST_DM_NMI 0x00400 +#define APIC_DEST_DM_INIT 0x00500 +#define APIC_DEST_DM_STARTUP 0x00600 +#define APIC_DEST_VECTOR_MASK 0x000FF +#define APIC_ICR2 0x310 +#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF) +#define SET_APIC_DEST_FIELD(x) ((x)<<24) +#define APIC_LVTT 0x320 +#define APIC_LVT0 0x350 +#define APIC_LVT_TIMER_PERIODIC (1<<17) +#define APIC_LVT_MASKED (1<<16) +#define APIC_LVT_LEVEL_TRIGGER (1<<15) +#define APIC_LVT_REMOTE_IRR (1<<14) +#define APIC_INPUT_POLARITY (1<<13) +#define APIC_SEND_PENDING (1<<12) +#define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) +#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) +#define APIC_MODE_FIXED 0x0 +#define APIC_MODE_NMI 0x4 +#define APIC_MODE_EXINT 0x7 +#define APIC_LVT1 0x360 +#define APIC_LVERR 0x370 +#define APIC_TMICT 0x380 +#define APIC_TMCCT 0x390 +#define APIC_TDCR 0x3E0 +#define APIC_TDR_DIV_1 0xB +#define APIC_TDR_DIV_2 0x0 +#define APIC_TDR_DIV_4 0x1 +#define APIC_TDR_DIV_8 0x2 +#define APIC_TDR_DIV_16 0x3 +#define APIC_TDR_DIV_32 0x8 +#define APIC_TDR_DIV_64 0x9 +#define APIC_TDR_DIV_128 0xA + +#endif diff --git a/include/asm-i386/ide.h b/include/asm-i386/ide.h new file mode 100644 index 000000000..a2d797037 --- /dev/null +++ b/include/asm-i386/ide.h @@ -0,0 +1,119 @@ +/* + * linux/include/asm-i386/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* + * This file contains the i386 architecture specific IDE code. + */ + +#ifndef __ASMi386_IDE_H +#define __ASMi386_IDE_H + +#ifdef __KERNEL__ + +typedef unsigned short ide_ioreg_t; + +#ifndef MAX_HWIFS +#define MAX_HWIFS 4 +#endif + +#define ide_sti() sti() + +static __inline__ int ide_default_irq(ide_ioreg_t base) +{ + switch (base) { + case 0x1f0: return 14; + case 0x170: return 15; + case 0x1e8: return 11; + case 0x168: return 10; + default: + return 0; + } +} + +static __inline__ ide_ioreg_t ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + case 2: return 0x1e8; + case 3: return 0x168; + default: + return 0; + } +} + +static __inline__ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) +{ + ide_ioreg_t port = base; + int i = 8; + + while (i--) + *p++ = port++; + *p++ = base + 0x206; + if (irq != NULL) + *irq = 0; +} + +typedef union { + unsigned all : 8; /* all of the bits together */ + struct { + unsigned head : 4; /* always zeros here */ + unsigned unit : 1; /* drive select number, 0 or 1 */ + unsigned bit5 : 1; /* always 1 */ + unsigned lba : 1; /* using LBA instead of CHS */ + unsigned bit7 : 1; /* always 1 */ + } b; + } select_t; + +static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *device, void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name) +{ + request_region(from, extent, name); +} + +static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +/* + * The following are not needed for the non-m68k ports + */ +static __inline__ int ide_ack_intr (ide_ioreg_t base_port, ide_ioreg_t irq_port) +{ + return(1); +} + +static __inline__ void ide_fix_driveid(struct hd_driveid *id) +{ +} + +static __inline__ void ide_release_lock (int *ide_lock) +{ +} + +static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data) +{ +} + +#endif /* __KERNEL__ */ + +#endif /* __ASMi386_IDE_H */ diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h index 4b7163592..142662e94 100644 --- a/include/asm-i386/io.h +++ b/include/asm-i386/io.h @@ -38,28 +38,6 @@ #endif /* - * Change virtual addresses to physical addresses and vv. - * These are trivial on the 1:1 Linux/i386 mapping (but if we ever - * make the kernel segment mapped at 0, we need to do translation - * on the i386 as well) - */ -extern inline unsigned long virt_to_phys(void * address) -{ - return (unsigned long) address; -} - -extern inline void * phys_to_virt(unsigned long address) -{ - return (void *) address; -} - -/* - * IO bus memory addresses are also 1:1 with the physical address - */ -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - -/* * Talk about misusing macros.. */ @@ -71,21 +49,21 @@ __asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" #define __OUT(s,s1,x) \ __OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); } \ -__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "i" (port)); } \ +__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); } \ __OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \ -__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "i" (port)); SLOW_DOWN_IO; } +__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; } #define __IN1(s) \ -extern inline unsigned int __in##s(unsigned short port) { unsigned int _v; +extern inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v; #define __IN2(s,s1,s2) \ __asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" #define __IN(s,s1,i...) \ __IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \ -__IN1(s##c) __IN2(s,s1,"") : "=a" (_v) : "i" (port) ,##i ); return _v; } \ +__IN1(s##c) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \ __IN1(s##_p) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \ -__IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "i" (port) ,##i ); SLOW_DOWN_IO; return _v; } +__IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; } #define __INS(s) \ extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \ @@ -97,9 +75,17 @@ extern inline void outs##s(unsigned short port, const void * addr, unsigned long { __asm__ __volatile__ ("cld ; rep ; outs" #s \ : "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } -__IN(b,"b","0" (0)) -__IN(w,"w","0" (0)) +#define RETURN_TYPE unsigned char +/* __IN(b,"b","0" (0)) */ +__IN(b,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned short +/* __IN(w,"w","0" (0)) */ +__IN(w,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned int __IN(l,"") +#undef RETURN_TYPE __OUT(b,"b",char) __OUT(w,"w",short) @@ -115,7 +101,7 @@ __OUTS(l) /* * Note that due to the way __builtin_constant_p() works, you - * - can't use it inside a inline function (it will never be true) + * - can't use it inside an inline function (it will never be true) * - you don't have to worry about side effects within the __builtin.. */ #define outb(val,port) \ @@ -178,4 +164,76 @@ __OUTS(l) __inlc_p(port) : \ __inl_p(port)) +#ifdef __KERNEL__ + +#include <asm/page.h> + +#define __io_virt(x) ((void *)(PAGE_OFFSET | (unsigned long)(x))) +#define __io_phys(x) ((unsigned long)(x) & ~PAGE_OFFSET) +/* + * Change virtual addresses to physical addresses and vv. + * These are pretty trivial + */ +extern inline unsigned long virt_to_phys(volatile void * address) +{ + return __io_phys(address); +} + +extern inline void * phys_to_virt(unsigned long address) +{ + return __io_virt(address); +} + +extern void * ioremap(unsigned long offset, unsigned long size); +extern void iounmap(void *addr); + +/* + * IO bus memory addresses are also 1:1 with the physical address + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the x86 architecture, we just read/write the + * memory location directly. + */ + +#define readb(addr) (*(volatile unsigned char *) __io_virt(addr)) +#define readw(addr) (*(volatile unsigned short *) __io_virt(addr)) +#define readl(addr) (*(volatile unsigned int *) __io_virt(addr)) + +#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) +#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) +#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) + +#define memset_io(a,b,c) memset(__io_virt(a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c)) +#define memcpy_toio(a,b,c) memcpy(__io_virt(a),(b),(c)) + +/* + * Again, i386 does not require mem IO specific function. + */ + +#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d)) + +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#endif /* __KERNEL__ */ + #endif diff --git a/include/asm-i386/ioctl.h b/include/asm-i386/ioctl.h new file mode 100644 index 000000000..c75f20ade --- /dev/null +++ b/include/asm-i386/ioctl.h @@ -0,0 +1,75 @@ +/* $Id: ioctl.h,v 1.5 1993/07/19 21:53:50 root Exp root $ + * + * linux/ioctl.h for Linux by H.H. Bergman. + */ + +#ifndef _ASMI386_IOCTL_H +#define _ASMI386_IOCTL_H + +/* ioctl command encoding: 32 bits total, command in lower 16 bits, + * size of the parameter structure in the lower 14 bits of the + * upper 16 bits. + * Encoding the size of the parameter structure in the ioctl request + * is useful for catching programs compiled with old versions + * and to avoid overwriting user space outside the user buffer area. + * The highest 2 bits are reserved for indicating the ``access mode''. + * NOTE: This limits the max parameter size to 16kB -1 ! + */ + +/* + * The following is for compatibility across the various Linux + * platforms. The i386 ioctl numbering scheme doesn't really enforce + * a type field. De facto, however, the top 8 bits of the lower 16 + * bits are indeed used as a type field, so we might just as well make + * this explicit here. Please be sure to use the decoding macros + * below from now on. + */ +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits. + */ +#define _IOC_NONE 0U +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode ioctl numbers.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* ...and for the drivers/sound files... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* _ASMI386_IOCTL_H */ diff --git a/include/asm-i386/ioctls.h b/include/asm-i386/ioctls.h new file mode 100644 index 000000000..60e0806e5 --- /dev/null +++ b/include/asm-i386/ioctls.h @@ -0,0 +1,74 @@ +#ifndef __ARCH_I386_IOCTLS_H__ +#define __ARCH_I386_IOCTLS_H__ + +#include <asm/ioctl.h> + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif diff --git a/include/asm-i386/ipc.h b/include/asm-i386/ipc.h new file mode 100644 index 000000000..f368d14c8 --- /dev/null +++ b/include/asm-i386/ipc.h @@ -0,0 +1,28 @@ +#ifndef __i386_IPC_H__ +#define __i386_IPC_H__ + +/* + * These are used to wrap system calls on x86. + * + * See arch/i386/kernel/sys_i386.c for ugly details.. + */ +struct ipc_kludge { + struct msgbuf *msgp; + long msgtyp; +}; + +#define SEMOP 1 +#define SEMGET 2 +#define SEMCTL 3 +#define MSGSND 11 +#define MSGRCV 12 +#define MSGGET 13 +#define MSGCTL 14 +#define SHMAT 21 +#define SHMDT 22 +#define SHMGET 23 +#define SHMCTL 24 + +#define IPCCALL(version,op) ((version)<<16 | (op)) + +#endif diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h index d9a45530c..ed2287ebb 100644 --- a/include/asm-i386/irq.h +++ b/include/asm-i386/irq.h @@ -5,21 +5,28 @@ * linux/include/asm/irq.h * * (C) 1992, 1993 Linus Torvalds + * + * IRQ/IPI changes taken from work by Thomas Radke <tomsoft@informatik.tu-chemnitz.de> */ #include <linux/linkage.h> #include <asm/segment.h> +#define NR_IRQS 16 + +#define TIMER_IRQ 0 + extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); #define __STR(x) #x #define STR(x) __STR(x) - + +#define GET_CURRENT \ + "movl " SYMBOL_NAME_STR(current_set) ",%ebx\n\t" + #define SAVE_ALL \ "cld\n\t" \ - "push %gs\n\t" \ - "push %fs\n\t" \ "push %es\n\t" \ "push %ds\n\t" \ "pushl %eax\n\t" \ @@ -31,11 +38,7 @@ extern void enable_irq(unsigned int); "pushl %ebx\n\t" \ "movl $" STR(KERNEL_DS) ",%edx\n\t" \ "mov %dx,%ds\n\t" \ - "mov %dx,%es\n\t" \ - "movl $" STR(USER_DS) ",%edx\n\t" \ - "mov %dx,%fs\n\t" \ - "movl $0,%edx\n\t" \ - "movl %edx,%db7\n\t" + "mov %dx,%es\n\t" /* * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers, @@ -75,24 +78,24 @@ extern void enable_irq(unsigned int); * a bit - without them it seems that the harddisk driver won't work on * all hardware. Arghh. */ -#define ACK_FIRST(mask) \ +#define ACK_FIRST(mask,nr) \ "inb $0x21,%al\n\t" \ "jmp 1f\n" \ "1:\tjmp 1f\n" \ - "1:\torb $" #mask ",_cache_21\n\t" \ - "movb _cache_21,%al\n\t" \ + "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_21)"\n\t" \ + "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \ "outb %al,$0x21\n\t" \ "jmp 1f\n" \ "1:\tjmp 1f\n" \ "1:\tmovb $0x20,%al\n\t" \ "outb %al,$0x20\n\t" -#define ACK_SECOND(mask) \ +#define ACK_SECOND(mask,nr) \ "inb $0xA1,%al\n\t" \ "jmp 1f\n" \ "1:\tjmp 1f\n" \ - "1:\torb $" #mask ",_cache_A1\n\t" \ - "movb _cache_A1,%al\n\t" \ + "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_A1)"\n\t" \ + "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \ "outb %al,$0xA1\n\t" \ "jmp 1f\n" \ "1:\tjmp 1f\n" \ @@ -106,60 +109,297 @@ extern void enable_irq(unsigned int); "inb $0x21,%al\n\t" \ "jmp 1f\n" \ "1:\tjmp 1f\n" \ - "1:\tandb $~(" #mask "),_cache_21\n\t" \ - "movb _cache_21,%al\n\t" \ + "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_21)"\n\t" \ + "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \ "outb %al,$0x21\n\t" #define UNBLK_SECOND(mask) \ "inb $0xA1,%al\n\t" \ "jmp 1f\n" \ "1:\tjmp 1f\n" \ - "1:\tandb $~(" #mask "),_cache_A1\n\t" \ - "movb _cache_A1,%al\n\t" \ + "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_A1)"\n\t" \ + "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \ "outb %al,$0xA1\n\t" #define IRQ_NAME2(nr) nr##_interrupt(void) #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) #define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr) #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr) + +#ifdef __SMP__ + +#ifndef __SMP_PROF__ +#define SMP_PROF_INT_SPINS +#define SMP_PROF_IPI_CNT +#else +#define SMP_PROF_INT_SPINS "incl "SYMBOL_NAME_STR(smp_spins)"(,%eax,4)\n\t" +#define SMP_PROF_IPI_CNT "incl "SYMBOL_NAME_STR(ipi_count)"\n\t" +#endif + +#define GET_PROCESSOR_ID \ + "movl "SYMBOL_NAME_STR(apic_reg)", %edx\n\t" \ + "movl 32(%edx), %eax\n\t" \ + "shrl $24,%eax\n\t" \ + "andb $0x0F,%al\n\t" + +#define GET_CURRENT \ + "movl " SYMBOL_NAME_STR(current_set) "(,%eax,4),%ebx\n\t" + +#define ENTER_KERNEL \ + "pushl %eax\n\t" \ + "pushl %edx\n\t" \ + "pushfl\n\t" \ + "cli\n\t" \ + GET_PROCESSOR_ID \ + GET_CURRENT \ + "btsl $" STR(SMP_FROM_INT) ","SYMBOL_NAME_STR(smp_proc_in_lock)"(,%eax,4)\n\t" \ + "1: " \ + "lock\n\t" \ + "btsl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \ + "jnc 3f\n\t" \ + "cmpb "SYMBOL_NAME_STR(active_kernel_processor)", %al\n\t" \ + "je 4f\n\t" \ + "2: " \ + SMP_PROF_INT_SPINS \ + "btl %al, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \ + "jnc 5f\n\t" \ + "lock\n\t" \ + "btrl %al, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \ + "jnc 5f\n\t" \ + "movl %cr3,%edx\n\t" \ + "movl %edx,%cr3\n" \ + "5: btl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \ + "jc 2b\n\t" \ + "jmp 1b\n\t" \ + "3: " \ + "movb %al, "SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \ + "4: " \ + "incl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \ + "popfl\n\t" \ + "popl %edx\n\t" \ + "popl %eax\n\t" + +#define LEAVE_KERNEL \ + GET_PROCESSOR_ID \ + "btrl $" STR(SMP_FROM_INT) ","SYMBOL_NAME_STR(smp_proc_in_lock)"(,%eax,4)\n\t" \ + "pushfl\n\t" \ + "cli\n\t" \ + "decl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \ + "jnz 1f\n\t" \ + "movb $" STR (NO_PROC_ID) ", "SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \ + "lock\n\t" \ + "btrl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \ + "1: " \ + "popfl\n\t" + +/* + * the syscall count inc is a gross hack because ret_from_syscall is used by both irq and + * syscall return paths (urghh). + */ + #define BUILD_IRQ(chip,nr,mask) \ asmlinkage void IRQ_NAME(nr); \ asmlinkage void FAST_IRQ_NAME(nr); \ asmlinkage void BAD_IRQ_NAME(nr); \ __asm__( \ -"\n.align 4\n" \ -"_IRQ" #nr "_interrupt:\n\t" \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ "pushl $-"#nr"-2\n\t" \ SAVE_ALL \ - ACK_##chip(mask) \ - "incl _intr_count\n\t"\ + ENTER_KERNEL \ + ACK_##chip(mask,(nr&7)) \ + "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\ "sti\n\t" \ - "movl %esp,%ebx\n\t" \ - "pushl %ebx\n\t" \ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ + "pushl $" #nr "\n\t" \ + "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \ + "addl $8,%esp\n\t" \ + "cli\n\t" \ + UNBLK_##chip(mask) \ + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \ + "jmp ret_from_sys_call\n" \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \ + SAVE_MOST \ + ENTER_KERNEL \ + ACK_##chip(mask,(nr&7)) \ + "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + "pushl $" #nr "\n\t" \ + "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \ + "addl $4,%esp\n\t" \ + "cli\n\t" \ + UNBLK_##chip(mask) \ + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + LEAVE_KERNEL \ + RESTORE_MOST \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \ + SAVE_MOST \ + ENTER_KERNEL \ + ACK_##chip(mask,(nr&7)) \ + LEAVE_KERNEL \ + RESTORE_MOST); + + +#define BUILD_TIMER_IRQ(chip,nr,mask) \ +asmlinkage void IRQ_NAME(nr); \ +asmlinkage void FAST_IRQ_NAME(nr); \ +asmlinkage void BAD_IRQ_NAME(nr); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \ +SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \ +SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ + "pushl $-"#nr"-2\n\t" \ + SAVE_ALL \ + ENTER_KERNEL \ + ACK_##chip(mask,(nr&7)) \ + "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ + "pushl $" #nr "\n\t" \ + "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \ + "addl $8,%esp\n\t" \ + "cli\n\t" \ + UNBLK_##chip(mask) \ + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \ + "jmp ret_from_sys_call\n"); + + +/* + * Message pass must be a fast IRQ.. + */ + +#define BUILD_MSGIRQ(chip,nr,mask) \ +asmlinkage void IRQ_NAME(nr); \ +asmlinkage void FAST_IRQ_NAME(nr); \ +asmlinkage void BAD_IRQ_NAME(nr); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ + "pushl $-"#nr"-2\n\t" \ + SAVE_ALL \ + ENTER_KERNEL \ + ACK_##chip(mask,(nr&7)) \ + "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\ + "sti\n\t" \ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ "pushl $" #nr "\n\t" \ - "call _do_IRQ\n\t" \ + "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \ "addl $8,%esp\n\t" \ "cli\n\t" \ UNBLK_##chip(mask) \ - "decl _intr_count\n\t" \ + GET_PROCESSOR_ID \ + "btrl $" STR(SMP_FROM_INT) ","SYMBOL_NAME_STR(smp_proc_in_lock)"(,%eax,4)\n\t" \ + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \ "jmp ret_from_sys_call\n" \ -"\n.align 4\n" \ -"_fast_IRQ" #nr "_interrupt:\n\t" \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \ SAVE_MOST \ - ACK_##chip(mask) \ - "incl _intr_count\n\t" \ + ACK_##chip(mask,(nr&7)) \ + SMP_PROF_IPI_CNT \ "pushl $" #nr "\n\t" \ - "call _do_fast_IRQ\n\t" \ + "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \ "addl $4,%esp\n\t" \ "cli\n\t" \ UNBLK_##chip(mask) \ - "decl _intr_count\n\t" \ RESTORE_MOST \ -"\n\n.align 4\n" \ -"_bad_IRQ" #nr "_interrupt:\n\t" \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \ SAVE_MOST \ - ACK_##chip(mask) \ + ACK_##chip(mask,(nr&7)) \ RESTORE_MOST); +#define BUILD_RESCHEDIRQ(nr) \ +asmlinkage void IRQ_NAME(nr); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ + "pushl $-"#nr"-2\n\t" \ + SAVE_ALL \ + ENTER_KERNEL \ + "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\ + "sti\n\t" \ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ + "pushl $" #nr "\n\t" \ + "call "SYMBOL_NAME_STR(smp_reschedule_irq)"\n\t" \ + "addl $8,%esp\n\t" \ + "cli\n\t" \ + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \ + "jmp ret_from_sys_call\n"); +#else + +#define BUILD_IRQ(chip,nr,mask) \ +asmlinkage void IRQ_NAME(nr); \ +asmlinkage void FAST_IRQ_NAME(nr); \ +asmlinkage void BAD_IRQ_NAME(nr); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ + "pushl $-"#nr"-2\n\t" \ + SAVE_ALL \ + ACK_##chip(mask,(nr&7)) \ + "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\ + "sti\n\t" \ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ + "pushl $" #nr "\n\t" \ + "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \ + "addl $8,%esp\n\t" \ + "cli\n\t" \ + UNBLK_##chip(mask) \ + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + GET_CURRENT \ + "jmp ret_from_sys_call\n" \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \ + SAVE_MOST \ + ACK_##chip(mask,(nr&7)) \ + "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + "pushl $" #nr "\n\t" \ + "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \ + "addl $4,%esp\n\t" \ + "cli\n\t" \ + UNBLK_##chip(mask) \ + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + RESTORE_MOST \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \ + SAVE_MOST \ + ACK_##chip(mask,(nr&7)) \ + RESTORE_MOST); + +#define BUILD_TIMER_IRQ(chip,nr,mask) \ +asmlinkage void IRQ_NAME(nr); \ +asmlinkage void FAST_IRQ_NAME(nr); \ +asmlinkage void BAD_IRQ_NAME(nr); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \ +SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \ +SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ + "pushl $-"#nr"-2\n\t" \ + SAVE_ALL \ + ACK_##chip(mask,(nr&7)) \ + "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ + "pushl $" #nr "\n\t" \ + "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \ + "addl $8,%esp\n\t" \ + "cli\n\t" \ + UNBLK_##chip(mask) \ + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \ + GET_CURRENT \ + "jmp ret_from_sys_call\n"); + +#endif #endif diff --git a/include/asm-i386/keyboard.h b/include/asm-i386/keyboard.h new file mode 100644 index 000000000..76fa2186c --- /dev/null +++ b/include/asm-i386/keyboard.h @@ -0,0 +1,26 @@ +/* + * CPU specific parts of the keyboard driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef __ASM_i386_KEYBOARD_H +#define __ASM_i386_KEYBOARD_H + +#include <asm/io.h> + +#define KEYBOARD_IRQ 1 + +#define kbd_inb_p(port) inb_p(port) +#define kbd_inb(port) inb(port) +#define kbd_outb_p(data,port) outb_p(data,port) +#define kbd_outb(data,port) outb(data,port) + +extern __inline__ void +keyboard_setup() +{ + request_region(0x60,16,"keyboard"); +} + +#endif /* __ASM_i386_KEYBOARD_H */ diff --git a/include/linux/ldt.h b/include/asm-i386/ldt.h index 83add4248..84440bf54 100644 --- a/include/linux/ldt.h +++ b/include/asm-i386/ldt.h @@ -26,9 +26,4 @@ struct modify_ldt_ldt_s { #define MODIFY_LDT_CONTENTS_STACK 1 #define MODIFY_LDT_CONTENTS_CODE 2 -extern int get_ldt(void *buffer); -extern int set_ldt_entry(int entry, unsigned long base, unsigned int limit, - int seg_32bit_flag, int contents, int read_only_flag, - int limit_in_pages_flag); - #endif diff --git a/include/asm-i386/locks.h b/include/asm-i386/locks.h new file mode 100644 index 000000000..357d309fa --- /dev/null +++ b/include/asm-i386/locks.h @@ -0,0 +1,133 @@ +/* + * SMP locks primitives for building ix86 locks + * (not yet used). + * + * Alan Cox, alan@cymru.net, 1995 + */ + +/* + * This would be much easier but far less clear and easy + * to borrow for other processors if it was just assembler. + */ + +extern __inline__ void prim_spin_lock(struct spinlock *sp) +{ + int processor=smp_processor_id(); + + /* + * Grab the lock bit + */ + + while(lock_set_bit(0,&sp->lock)) + { + /* + * Failed, but that's cos we own it! + */ + + if(sp->cpu==processor) + { + sp->users++; + return 0; + } + /* + * Spin in the cache S state if possible + */ + while(sp->lock) + { + /* + * Wait for any invalidates to go off + */ + + if(smp_invalidate_needed&(1<<processor)); + while(lock_clear_bit(processor,&smp_invalidate_needed)) + local_flush_tlb(); + sp->spins++; + } + /* + * Someone wrote the line, we go 'I' and get + * the cache entry. Now try to regrab + */ + } + sp->users++;sp->cpu=processor; + return 1; +} + +/* + * Release a spin lock + */ + +extern __inline__ int prim_spin_unlock(struct spinlock *sp) +{ + /* This is safe. The decrement is still guarded by the lock. A multilock would + not be safe this way */ + if(!--sp->users) + { + lock_clear_bit(0,&sp->lock);sp->cpu= NO_PROC_ID; + return 1; + } + return 0; +} + + +/* + * Non blocking lock grab + */ + +extern __inline__ int prim_spin_lock_nb(struct spinlock *sp) +{ + if(lock_set_bit(0,&sp->lock)) + return 0; /* Locked already */ + sp->users++; + return 1; /* We got the lock */ +} + + +/* + * These wrap the locking primitives up for usage + */ + +extern __inline__ void spinlock(struct spinlock *sp) +{ + if(sp->priority<current->lock_order) + panic("lock order violation: %s (%d)\n", sp->name, current->lock_order); + if(prim_spin_lock(sp)) + { + /* + * We got a new lock. Update the priority chain + */ + sp->oldpri=current->lock_order; + current->lock_order=sp->priority; + } +} + +extern __inline__ void spinunlock(struct spinlock *sp) +{ + if(current->lock_order!=sp->priority) + panic("lock release order violation %s (%d)\n", sp->name, current->lock_order); + if(prim_spin_unlock(sp)) + { + /* + * Update the debugging lock priority chain. We dumped + * our last right to the lock. + */ + current->lock_order=sp->oldpri; + } +} + +extern __inline__ void spintestlock(struct spinlock *sp) +{ + /* + * We do no sanity checks, it's legal to optimistically + * get a lower lock. + */ + prim_spin_lock_nb(sp); +} + +extern __inline__ void spintestunlock(struct spinlock *sp) +{ + /* + * A testlock doesn't update the lock chain so we + * must not update it on free + */ + prim_spin_unlock(sp); +} diff --git a/include/linux/math_emu.h b/include/asm-i386/math_emu.h index 0d9606d94..d1b0134cc 100644 --- a/include/linux/math_emu.h +++ b/include/asm-i386/math_emu.h @@ -1,5 +1,10 @@ -#ifndef _LINUX_MATH_EMU_H -#define _LINUX_MATH_EMU_H +#ifndef _I386_MATH_EMU_H +#define _I386_MATH_EMU_H + +#include <asm/sigcontext.h> + +void restore_i387_soft(struct _fpstate *buf); +struct _fpstate * save_i387_soft(struct _fpstate * buf); struct fpu_reg { char sign; @@ -26,8 +31,6 @@ struct info { long ___eax; long ___ds; long ___es; - long ___fs; - long ___gs; long ___orig_eax; long ___eip; long ___cs; diff --git a/include/asm-i386/mc146818rtc.h b/include/asm-i386/mc146818rtc.h new file mode 100644 index 000000000..594996a6d --- /dev/null +++ b/include/asm-i386/mc146818rtc.h @@ -0,0 +1,23 @@ +/* + * Machine dependend access functions for RTC registers. + */ +#ifndef __ASM_I386_MC146818RTC_H +#define __ASM_I386_MC146818RTC_H + +#include <asm/io.h> + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 +#endif + +#define CMOS_READ(addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#endif /* __ASM_I386_MC146818RTC_H */ diff --git a/include/asm-i386/mman.h b/include/asm-i386/mman.h new file mode 100644 index 000000000..c5bd25f73 --- /dev/null +++ b/include/asm-i386/mman.h @@ -0,0 +1,32 @@ +#ifndef __I386_MMAN_H__ +#define __I386_MMAN_H__ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __I386_MMAN_H__ */ diff --git a/include/asm-i386/mmu_context.h b/include/asm-i386/mmu_context.h new file mode 100644 index 000000000..1f4751cc2 --- /dev/null +++ b/include/asm-i386/mmu_context.h @@ -0,0 +1,9 @@ +#ifndef __I386_MMU_CONTEXT_H +#define __I386_MMU_CONTEXT_H + +/* + * get a new mmu context.. x86's don't know about contexts. + */ +#define get_mmu_context(x) do { } while (0) + +#endif diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index 7ab435bbf..e5fc37276 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -8,9 +8,12 @@ #ifdef __KERNEL__ -#define CONFIG_STRICT_MM_TYPECHECKS +#define STRICT_MM_TYPECHECKS -#ifdef CONFIG_STRICT_MM_TYPECHECKS +#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) + +#ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ @@ -50,20 +53,28 @@ typedef unsigned long pgprot_t; #endif -#define invalidate() \ -__asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax") - -#define copy_page(from,to) memcpy((void *) to, (void *) from, PAGE_SIZE) +/* + * We special-case the C-O-W ZERO_PAGE, because it's such + * a common occurrence (no need to read the page to know + * that it's zero - better for the cache and memory subsystem). + */ +extern inline inline void copy_page(unsigned long from, unsigned long to) +{ + if (from == ZERO_PAGE) { + memset((void *) to, 0, PAGE_SIZE); + return; + } + memcpy((void *) to, (void *) from, PAGE_SIZE); +} /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) /* This handles the memory map.. */ -#define PAGE_OFFSET 0 -#define MAP_NR(addr) (((unsigned long)(addr)) >> PAGE_SHIFT) -#define MAP_PAGE_RESERVED (1<<15) - -typedef unsigned short mem_map_t; +#define PAGE_OFFSET 0xC0000000 +#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT) #endif /* __KERNEL__ */ diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 0099de93a..58990eb38 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -1,6 +1,8 @@ #ifndef _I386_PGTABLE_H #define _I386_PGTABLE_H +#include <linux/config.h> + /* * The Linux memory management assumes a three-level page table setup. On * the i386, we use that, but "fold" the mid level into the top-level page @@ -11,6 +13,158 @@ * the i386 page table tree. */ +/* Caches aren't brain-dead on the intel. */ +#define flush_cache_all() do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_range(mm, start, end) do { } while (0) +#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_page_to_ram(page) do { } while (0) + +/* + * 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_range(mm, start, end) flushes a range of pages + * + * ..but the i386 has somewhat limited tlb flushing capabilities, + * and page-granular flushes are available only on i486 and up. + */ + +#define __flush_tlb() \ +do { unsigned long tmpreg; __asm__ __volatile__("movl %%cr3,%0\n\tmovl %0,%%cr3":"=r" (tmpreg) : :"memory"); } while (0) + +#ifdef CONFIG_M386 +#define __flush_tlb_one(addr) flush_tlb() +#else +#define __flush_tlb_one(addr) \ +__asm__ __volatile__("invlpg %0": :"m" (*(char *) addr)) +#endif + +#ifndef __SMP__ + +#define flush_tlb() __flush_tlb() +#define flush_tlb_all() __flush_tlb() +#define local_flush_tlb() __flush_tlb() + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->mm) + __flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + if (vma->vm_mm == current->mm) + __flush_tlb_one(addr); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + if (mm == current->mm) + __flush_tlb(); +} + +#else + +/* + * We aren't very clever about this yet - SMP could certainly + * avoid some global flushes.. + */ + +#include <asm/smp.h> + +#define local_flush_tlb() \ + __flush_tlb() + + +#undef CLEVER_SMP_INVALIDATE +#ifdef CLEVER_SMP_INVALIDATE + +/* + * Smarter SMP flushing macros. + * c/o Linus Torvalds. + * + * These mean you can really definitely utterly forget about + * writing to user space from interrupts. (Its not allowed anyway). + * + * Doesn't currently work as Linus makes flush tlb calls before + * stuff like current/current->mm are setup properly + */ + +static inline void flush_tlb_current_task(void) +{ + if (current->mm->count == 1) /* just one copy of this mm */ + local_flush_tlb(); /* and that's us, so.. */ + else + smp_flush_tlb(); +} + +#define flush_tlb() flush_tlb_current_task() + +#define flush_tlb_all() smp_flush_tlb() + +static inline void flush_tlb_mm(struct mm_struct * mm) +{ + if (mm == current->mm && mm->count == 1) + local_flush_tlb(); + else + smp_flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct * vma, + unsigned long va) +{ + if (vma->vm_mm == current->mm && current->mm->count == 1) + __flush_tlb_one(va); + else + smp_flush_tlb(); +} + +static inline void flush_tlb_range(struct mm_struct * mm, + unsigned long start, unsigned long end) +{ + flush_tlb_mm(mm); +} + + +#else + +#define flush_tlb() \ + smp_flush_tlb() + +#define flush_tlb_all() flush_tlb() + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + flush_tlb(); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + flush_tlb(); +} +#endif +#endif + + +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval)) + /* 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) @@ -37,23 +191,31 @@ * area for the same reason. ;) */ #define VMALLOC_OFFSET (8*1024*1024) -#define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -#define VMALLOC_VMADDR(x) (TASK_SIZE + (unsigned long)(x)) +#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +/* + * The 4MB page is guessing.. Detailed in the infamous "Chapter H" + * of the Pentium details, but assuming intel did the straightforward + * thing, this bit set in the page directory entry just means that + * the page directory entry points directly to a 4MB-aligned block of + * memory. + */ #define _PAGE_PRESENT 0x001 #define _PAGE_RW 0x002 #define _PAGE_USER 0x004 #define _PAGE_PCD 0x010 #define _PAGE_ACCESSED 0x020 #define _PAGE_DIRTY 0x040 -#define _PAGE_COW 0x200 /* implemented in software (one of the AVL bits) */ +#define _PAGE_4M 0x080 /* 4 MB page, Pentium+.. */ #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_PRESENT | _PAGE_ACCESSED) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_COW) +#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) @@ -80,15 +242,15 @@ #define __S111 PAGE_SHARED /* - * Define this if things work differently on a i386 and a i486: - * it will (on a i486) warn about kernel memory accesses that are + * 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 CONFIG_TEST_VERIFY_AREA +#undef TEST_VERIFY_AREA /* page table for 0-4MB for everybody */ extern unsigned long pg0[1024]; -/* zero page used for unitialized stuff */ +/* zero page used for uninitialized stuff */ extern unsigned long empty_zero_page[1024]; /* @@ -122,29 +284,20 @@ extern pte_t * __bad_pagetable(void); /* to set the page-dir */ #define SET_PAGE_DIR(tsk,pgdir) \ do { \ - (tsk)->tss.cr3 = (unsigned long) (pgdir); \ + unsigned long __pgdir = __pa(pgdir); \ + (tsk)->tss.cr3 = __pgdir; \ if ((tsk) == current) \ - __asm__ __volatile__("movl %0,%%cr3": :"a" ((tsk)->tss.cr3)); \ + __asm__ __volatile__("movl %0,%%cr3": :"r" (__pgdir)); \ } while (0) -extern unsigned long high_memory; +#define pte_none(x) (!pte_val(x)) +#define pte_present(x) (pte_val(x) & _PAGE_PRESENT) +#define pte_clear(xp) do { pte_val(*(xp)) = 0; } while (0) -extern inline int pte_none(pte_t pte) { return !pte_val(pte); } -extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } -extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; } -extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } -extern inline void pte_reuse(pte_t * ptep) -{ - if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(ptep)]++; -} - -extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); } -extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || pmd_val(pmd) > high_memory; } -extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; } -extern inline int pmd_inuse(pmd_t *pmdp) { return 0; } -extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; } -extern inline void pmd_reuse(pmd_t * pmdp) { } +#define pmd_none(x) (!pmd_val(x)) +#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)) = 0; } while (0) /* * The "pgd_xxx()" functions here are trivial for a folded two-level @@ -154,13 +307,7 @@ extern inline void pmd_reuse(pmd_t * pmdp) { } extern inline int pgd_none(pgd_t pgd) { return 0; } extern inline int pgd_bad(pgd_t pgd) { return 0; } extern inline int pgd_present(pgd_t pgd) { return 1; } -extern inline int pgd_inuse(pgd_t * pgdp) { return mem_map[MAP_NR(pgdp)] != 1; } extern inline void pgd_clear(pgd_t * pgdp) { } -extern inline void pgd_reuse(pgd_t * pgdp) -{ - if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(pgdp)]++; -} /* * The following only work if pte_present() is true. @@ -171,42 +318,41 @@ extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -extern inline int pte_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; } extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_RW; return pte; } extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -extern inline pte_t pte_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; } extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; } extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } -extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; } /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) -{ pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; } +#define mk_pte(page, pgprot) \ +({ pte_t __pte; pte_val(__pte) = __pa(page) + pgprot_val(pgprot); __pte; }) + +/* This takes a physical page address that is used by the remapping functions */ +#define mk_pte_phys(physpage, pgprot) \ +({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; }) extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } -extern inline unsigned long pte_page(pte_t pte) -{ return pte_val(pte) & PAGE_MASK; } +#define pte_page(pte) \ +((unsigned long) __va(pte_val(pte) & PAGE_MASK)) -extern inline unsigned long pmd_page(pmd_t pmd) -{ return pmd_val(pmd) & PAGE_MASK; } +#define pmd_page(pmd) \ +((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) /* to find an entry in a page-table-directory */ -extern inline pgd_t * pgd_offset(struct task_struct * tsk, unsigned long address) -{ - return (pgd_t *) tsk->tss.cr3 + (address >> PGDIR_SHIFT); -} +#define pgd_offset(mm, address) \ +((mm)->pgd + ((address) >> PGDIR_SHIFT)) /* Find an entry in the second-level page table.. */ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) @@ -215,19 +361,16 @@ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) } /* Find an entry in the third-level page table.. */ -extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) -{ - return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); -} +#define pte_offset(pmd, address) \ +((pte_t *) (pmd_page(*pmd) + ((address>>10) & ((PTRS_PER_PTE-1)<<2)))) /* * Allocate and free page tables. The xxx_kernel() versions are * used to allocate a kernel page table - this turns on ASN bits - * if any, and marks the page tables reserved. + * if any. */ extern inline void pte_free_kernel(pte_t * pte) { - mem_map[MAP_NR(pte)] = 1; free_page((unsigned long) pte); } @@ -238,21 +381,19 @@ extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (page) { - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page; - mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED; + pmd_val(*pmd) = _KERNPG_TABLE + __pa(page); return page + address; } - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; + pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE); return NULL; } free_page((unsigned long) page); } if (pmd_bad(*pmd)) { printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; + pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE); return NULL; } -printk("pte_alloc_kernel(): %08x\n", pmd_page(*pmd) + address) return (pte_t *) pmd_page(*pmd) + address; } @@ -262,6 +403,7 @@ printk("pte_alloc_kernel(): %08x\n", pmd_page(*pmd) + address) */ extern inline void pmd_free_kernel(pmd_t * pmd) { + pmd_val(*pmd) = 0; } extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address) @@ -276,25 +418,35 @@ extern inline void pte_free(pte_t * pte) extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) { - address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); - if (pmd_none(*pmd)) { - pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); - if (pmd_none(*pmd)) { - if (page) { - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page; - return page + address; - } - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; - return NULL; - } - free_page((unsigned long) page); - } - if (pmd_bad(*pmd)) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; - return NULL; - } - return (pte_t *) pmd_page(*pmd) + address; + address = (address >> (PAGE_SHIFT-2)) & 4*(PTRS_PER_PTE - 1); + +repeat: + if (pmd_none(*pmd)) + goto getnew; + if (pmd_bad(*pmd)) + goto fix; + return (pte_t *) (pmd_page(*pmd) + address); + +getnew: +{ + unsigned long page = __get_free_page(GFP_KERNEL); + if (!pmd_none(*pmd)) + goto freenew; + if (!page) + goto oom; + memset((void *) page, 0, PAGE_SIZE); + pmd_val(*pmd) = _PAGE_TABLE + __pa(page); + return (pte_t *) (page + address); +freenew: + free_page(page); + goto repeat; +} + +fix: + printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); +oom: + pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE); + return NULL; } /* @@ -303,6 +455,7 @@ extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) */ extern inline void pmd_free(pmd_t * pmd) { + pmd_val(*pmd) = 0; } extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) diff --git a/include/asm-i386/posix_types.h b/include/asm-i386/posix_types.h new file mode 100644 index 000000000..4da54d2be --- /dev/null +++ b/include/asm-i386/posix_types.h @@ -0,0 +1,64 @@ +#ifndef __ARCH_I386_POSIX_TYPES_H +#define __ARCH_I386_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#undef __FD_SET +#define __FD_SET(fd,fdsetp) \ + __asm__ __volatile__("btsl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_CLR +#define __FD_CLR(fd,fdsetp) \ + __asm__ __volatile__("btrl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_ISSET +#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ + unsigned char __result; \ + __asm__ __volatile__("btl %1,%2 ; setb %0" \ + :"=q" (__result) :"r" ((int) (fd)), \ + "m" (*(__kernel_fd_set *) (fdsetp))); \ + __result; })) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ + __asm__ __volatile__("cld ; rep ; stosl" \ + :"=m" (*(__kernel_fd_set *) (fdsetp)) \ + :"a" (0), "c" (__FDSET_LONGS), \ + "D" ((__kernel_fd_set *) (fdsetp)) :"cx","di") + +#endif diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 8acef7a19..de0611190 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -7,9 +7,14 @@ #ifndef __ASM_I386_PROCESSOR_H #define __ASM_I386_PROCESSOR_H +#include <asm/vm86.h> +#include <asm/math_emu.h> + /* * System setup and hardware bug flags.. + * [Note we don't test the 386 multiply bug or popad bug] */ + extern char hard_math; extern char x86; /* lower 4 bits */ extern char x86_vendor_id[13]; @@ -18,8 +23,9 @@ extern char x86_mask; /* lower 4 bits */ extern int x86_capability; /* field of flags */ extern int fdiv_bug; extern char ignore_irq13; -extern char wp_works_ok; /* doesn't work on a 386 */ +extern char wp_works_ok; /* doesn't work on a 386 */ extern char hlt_works_ok; /* problems on some 486Dx4's and old 386's */ +extern int have_cpuid; /* We have a CPUID */ /* * Bus types (default is ISA, but people can check others with these..) @@ -27,7 +33,6 @@ extern char hlt_works_ok; /* problems on some 486Dx4's and old 386's */ */ extern int EISA_bus; #define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ /* * User space process size: 3GB. This is hardcoded into a few places, @@ -49,6 +54,7 @@ struct i387_hard_struct { long foo; long fos; long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ + long status; /* software status information */ }; struct i387_soft_struct { @@ -97,7 +103,7 @@ struct thread_struct { unsigned short trace, bitmap; unsigned long io_bitmap[IO_BITMAP_SIZE+1]; unsigned long tr; - unsigned long cr2, trap_no, error_code; + unsigned long cr2, trap_no, error_code, segment; /* floating point info */ union i387_union i387; /* virtual 86 mode info */ @@ -106,30 +112,55 @@ struct thread_struct { unsigned long v86flags, v86mask, v86mode; }; -#define INIT_MMAP { &init_task, 0, 0x40000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } +#define INIT_MMAP { &init_mm, 0xC0000000, 0xFFFFF000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } #define INIT_TSS { \ 0,0, \ sizeof(init_kernel_stack) + (long) &init_kernel_stack, \ KERNEL_DS, 0, \ 0,0,0,0,0,0, \ - (long) &swapper_pg_dir, \ + (long) &swapper_pg_dir - PAGE_OFFSET, \ 0,0,0,0,0,0,0,0,0,0, \ USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0, \ _LDT(0),0, \ 0, 0x8000, \ {~0, }, /* ioperm */ \ - _TSS(0), 0, 0,0, \ + _TSS(0), 0, 0, 0, KERNEL_DS, \ { { 0, }, }, /* 387 state */ \ - NULL, 0, 0, 0, 0 /* vm86_info */ \ + NULL, 0, 0, 0, 0 /* vm86_info */, \ } -static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp) +#define alloc_kernel_stack() __get_free_page(GFP_KERNEL) +#define free_kernel_stack(page) free_page((page)) + +#define start_thread(regs, new_eip, new_esp) do {\ + unsigned long seg = USER_DS; \ + __asm__("mov %w0,%%fs ; mov %w0,%%gs":"=r" (seg) :"0" (seg)); \ + set_fs(seg); \ + regs->xds = seg; \ + regs->xes = seg; \ + regs->xss = seg; \ + regs->xcs = USER_CS; \ + regs->eip = new_eip; \ + regs->esp = new_esp; \ +} while (0) + +/* + * Return saved PC of a blocked thread. + */ +extern inline unsigned long thread_saved_pc(struct thread_struct *t) { - regs->cs = USER_CS; - regs->ds = regs->es = regs->ss = regs->fs = regs->gs = USER_DS; - regs->eip = eip; - regs->esp = esp; + return ((unsigned long *)t->esp)[3]; } +/* + * Return_address is a replacement for __builtin_return_address(count) + * which on certain architectures cannot reasonably be implemented in GCC + * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * Note that __builtin_return_address(x>=1) is forbidden because the GCC + * aborts compilation on some CPUs. It's simply not possible to unwind + * some CPU's stackframes. + */ +#define return_address() __builtin_return_address(0) + #endif /* __ASM_I386_PROCESSOR_H */ diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h index e379542cf..90aa9a55e 100644 --- a/include/asm-i386/ptrace.h +++ b/include/asm-i386/ptrace.h @@ -31,20 +31,19 @@ struct pt_regs { long edi; long ebp; long eax; - unsigned short ds, __dsu; - unsigned short es, __esu; - unsigned short fs, __fsu; - unsigned short gs, __gsu; + int xds; + int xes; long orig_eax; long eip; - unsigned short cs, __csu; + int xcs; long eflags; long esp; - unsigned short ss, __ssu; + int xss; }; #ifdef __KERNEL__ -#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->cs)) +#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) +#define instruction_pointer(regs) ((regs)->eip) extern void show_regs(struct pt_regs *); #endif diff --git a/include/asm-i386/resource.h b/include/asm-i386/resource.h index f5fa979cd..3143b5bb2 100644 --- a/include/asm-i386/resource.h +++ b/include/asm-i386/resource.h @@ -13,11 +13,27 @@ #define RLIMIT_RSS 5 /* max resident set size */ #define RLIMIT_NPROC 6 /* max number of processes */ #define RLIMIT_NOFILE 7 /* max number of open files */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ +#define RLIMIT_AS 9 /* address space limit */ -#ifdef notdef -#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space*/ -#endif +#define RLIM_NLIMITS 10 + +#ifdef __KERNEL__ + +#define INIT_RLIMITS \ +{ \ + { LONG_MAX, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ + { _STK_LIM, _STK_LIM }, \ + { 0, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ + { MAX_TASKS_PER_USER, MAX_TASKS_PER_USER }, \ + { NR_OPEN, NR_OPEN }, \ + { LONG_MAX, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ +} -#define RLIM_NLIMITS 8 +#endif /* __KERNEL__ */ #endif diff --git a/include/asm-i386/segment.h b/include/asm-i386/segment.h index bd9394cdb..d5f1ef6de 100644 --- a/include/asm-i386/segment.h +++ b/include/asm-i386/segment.h @@ -7,288 +7,4 @@ #define USER_CS 0x23 #define USER_DS 0x2B -#ifndef __ASSEMBLY__ - -/* - * Uh, these should become the main single-value transfer routines.. - * They automatically use the right size if we just have the right - * pointer type.. - */ -#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))) -#define get_user(ptr) __get_user((ptr),sizeof(*(ptr))) - -/* - * This is a silly but good way to make sure that - * the __put_user function is indeed always optimized, - * and that we use the correct sizes.. - */ -extern int bad_user_access_length(void); - -/* - * dummy pointer type structure.. gcc won't try to do something strange - * this way.. - */ -struct __segment_dummy { unsigned long a[100]; }; -#define __sd(x) ((struct __segment_dummy *) (x)) - -static inline void __put_user(unsigned long x, void * y, int size) -{ - switch (size) { - case 1: - __asm__ ("movb %b1,%%fs:%0" - :"=m" (*__sd(y)) - :"iq" ((unsigned char) x), "m" (*__sd(y))); - break; - case 2: - __asm__ ("movw %w1,%%fs:%0" - :"=m" (*__sd(y)) - :"iq" ((unsigned short) x), "m" (*__sd(y))); - break; - case 4: - __asm__ ("movl %1,%%fs:%0" - :"=m" (*__sd(y)) - :"ir" (x), "m" (*__sd(y))); - break; - default: - bad_user_access_length(); - } -} - -static inline unsigned long __get_user(const void * y, int size) -{ - unsigned long result; - - switch (size) { - case 1: - __asm__ ("movb %%fs:%1,%b0" - :"=q" (result) - :"m" (*__sd(y))); - return (unsigned char) result; - case 2: - __asm__ ("movw %%fs:%1,%w0" - :"=q" (result) - :"m" (*__sd(y))); - return (unsigned short) result; - case 4: - __asm__ ("movl %%fs:%1,%0" - :"=r" (result) - :"m" (*__sd(y))); - return result; - default: - return bad_user_access_length(); - } -} - -/* - * These are deprecated.. - */ - -static inline unsigned char get_user_byte(const char * addr) -{ - return __get_user(addr,1); -} - -#define get_fs_byte(addr) get_user_byte((char *)(addr)) - -static inline unsigned short get_user_word(const short *addr) -{ - return __get_user(addr, 2); -} - -#define get_fs_word(addr) get_user_word((short *)(addr)) - -static inline unsigned long get_user_long(const int *addr) -{ - return __get_user(addr, 4); -} - -#define get_fs_long(addr) get_user_long((int *)(addr)) - -static inline void put_user_byte(char val,char *addr) -{ - __put_user(val, addr, 1); -} - -#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) - -static inline void put_user_word(short val,short * addr) -{ - __put_user(val, addr, 2); -} - -#define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) - -static inline void put_user_long(unsigned long val,int * addr) -{ - __put_user(val, addr, 4); -} - -#define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) - -static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n) -{ -__asm__("cld\n\t" - "push %%es\n\t" - "push %%fs\n\t" - "pop %%es\n\t" - "testb $1,%%cl\n\t" - "je 1f\n\t" - "movsb\n" - "1:\ttestb $2,%%cl\n\t" - "je 2f\n\t" - "movsw\n" - "2:\tshrl $2,%%ecx\n\t" - "rep ; movsl\n\t" - "pop %%es" - : /* no outputs */ - :"c" (n),"D" ((long) to),"S" ((long) from) - :"cx","di","si"); -} - -static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - switch (n) { - case 0: - return; - case 1: - put_user_byte(*(const char *) from, (char *) to); - return; - case 2: - put_user_word(*(const short *) from, (short *) to); - return; - case 3: - put_user_word(*(const short *) from, (short *) to); - put_user_byte(*(2+(const char *) from), 2+(char *) to); - return; - case 4: - put_user_long(*(const int *) from, (int *) to); - return; - } -#define COMMON(x) \ -__asm__("cld\n\t" \ - "push %%es\n\t" \ - "push %%fs\n\t" \ - "pop %%es\n\t" \ - "rep ; movsl\n\t" \ - x \ - "pop %%es" \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("movsb\n\t"); - return; - case 2: - COMMON("movsw\n\t"); - return; - case 3: - COMMON("movsw\n\tmovsb\n\t"); - return; - } -#undef COMMON -} - -static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ -__asm__("cld\n\t" - "testb $1,%%cl\n\t" - "je 1f\n\t" - "fs ; movsb\n" - "1:\ttestb $2,%%cl\n\t" - "je 2f\n\t" - "fs ; movsw\n" - "2:\tshrl $2,%%ecx\n\t" - "rep ; fs ; movsl" - : /* no outputs */ - :"c" (n),"D" ((long) to),"S" ((long) from) - :"cx","di","si","memory"); -} - -static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - switch (n) { - case 0: - return; - case 1: - *(char *)to = get_user_byte((const char *) from); - return; - case 2: - *(short *)to = get_user_word((const short *) from); - return; - case 3: - *(short *) to = get_user_word((const short *) from); - *((char *) to + 2) = get_user_byte(2+(const char *) from); - return; - case 4: - *(int *) to = get_user_long((const int *) from); - return; - } -#define COMMON(x) \ -__asm__("cld\n\t" \ - "rep ; fs ; movsl\n\t" \ - x \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si","memory") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("fs ; movsb"); - return; - case 2: - COMMON("fs ; movsw"); - return; - case 3: - COMMON("fs ; movsw\n\tfs ; movsb"); - return; - } -#undef COMMON -} - -#define memcpy_fromfs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_fromfs((to),(from),(n)) : \ - __generic_memcpy_fromfs((to),(from),(n))) - -#define memcpy_tofs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_tofs((to),(from),(n)) : \ - __generic_memcpy_tofs((to),(from),(n))) - -/* - * Someone who knows GNU asm better than I should double check the following. - * It seems to work, but I don't know if I'm doing something subtly wrong. - * --- TYT, 11/24/91 - * [ nothing wrong here, Linus: I just changed the ax to be any reg ] - */ - -static inline unsigned long get_fs(void) -{ - unsigned long _v; - __asm__("mov %%fs,%w0":"=r" (_v):"0" (0)); - return _v; -} - -static inline unsigned long get_ds(void) -{ - unsigned long _v; - __asm__("mov %%ds,%w0":"=r" (_v):"0" (0)); - return _v; -} - -static inline void set_fs(unsigned long val) -{ - __asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val)); -} - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_SEGMENT_H */ +#endif diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h new file mode 100644 index 000000000..930b39edb --- /dev/null +++ b/include/asm-i386/semaphore.h @@ -0,0 +1,70 @@ +#ifndef _I386_SEMAPHORE_H +#define _I386_SEMAPHORE_H + +#include <linux/linkage.h> + +/* + * SMP- and interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + */ + +struct semaphore { + int count; + int waiting; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { 1, 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) + +asmlinkage void __down_failed(void /* special register calling convention */); +asmlinkage void __up_wakeup(void /* special register calling convention */); + +extern void __down(struct semaphore * sem); +extern void __up(struct semaphore * sem); + +/* + * This is ugly, but we want the default case to fall through. + * "down_failed" is a special asm handler that calls the C + * routine that actually waits. See arch/i386/lib/semaphore.S + */ +extern __inline__ void down(struct semaphore * sem) +{ + __asm__ __volatile__( + "# atomic down operation\n\t" +#ifdef __SMP__ + "lock ; " +#endif + "decl %0\n\t" + "movl $1f,%%eax\n\t" + "js " SYMBOL_NAME_STR(__down_failed) + "\n1:" + :/* no outputs */ + :"m" (sem->count), "c" (sem) + :"ax", "memory"); +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +extern __inline__ void up(struct semaphore * sem) +{ + __asm__ __volatile__( + "# atomic up operation\n\t" +#ifdef __SMP__ + "lock ; " +#endif + "incl %0\n\t" + "movl $1f,%%eax\n\t" + "jle " SYMBOL_NAME_STR(__up_wakeup) + "\n1:" + :/* no outputs */ + :"m" (sem->count), "c" (sem) + :"ax", "memory"); +} + +#endif diff --git a/include/asm-i386/shmparam.h b/include/asm-i386/shmparam.h new file mode 100644 index 000000000..522718965 --- /dev/null +++ b/include/asm-i386/shmparam.h @@ -0,0 +1,44 @@ +#ifndef _ASMI386_SHMPARAM_H +#define _ASMI386_SHMPARAM_H + +/* address range for shared memory attaches if no address passed to shmat() */ +#define SHM_RANGE_START 0x50000000 +#define SHM_RANGE_END 0x60000000 + +/* + * Format of a swap-entry for shared memory pages currently out in + * swap space (see also mm/swap.c). + * + * SWP_TYPE = SHM_SWP_TYPE + * SWP_OFFSET is used as follows: + * + * bits 0..6 : id of shared memory segment page belongs to (SHM_ID) + * bits 7..21: index of page within shared memory segment (SHM_IDX) + * (actually fewer bits get used since SHMMAX is so low) + */ + +/* + * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and + * there is a static array of size SHMMNI. + */ +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +/* + * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and + * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). + */ + +#define SHMMAX 0x1000000 /* max shared seg size (bytes) */ +#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ +#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ +#define SHMALL /* max shm system wide (pages) */ \ + (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ +#define SHMSEG SHMMNI /* max shared segs per process */ + +#endif /* _ASMI386_SHMPARAM_H */ diff --git a/include/asm-i386/sigcontext.h b/include/asm-i386/sigcontext.h new file mode 100644 index 000000000..3d8f51ea4 --- /dev/null +++ b/include/asm-i386/sigcontext.h @@ -0,0 +1,54 @@ +#ifndef _ASMi386_SIGCONTEXT_H +#define _ASMi386_SIGCONTEXT_H + +/* + * As documented in the iBCS2 standard.. + * + * The first part of "struct _fpstate" is just the + * normal i387 hardware setup, the extra "status" + * word is used to save the coprocessor status word + * before entering the handler. + */ +struct _fpreg { + unsigned short significand[4]; + unsigned short exponent; +}; + +struct _fpstate { + unsigned long cw, + sw, + tag, + ipoff, + cssel, + dataoff, + datasel; + struct _fpreg _st[8]; + unsigned long status; +}; + +struct sigcontext { + unsigned short gs, __gsh; + unsigned short fs, __fsh; + unsigned short es, __esh; + unsigned short ds, __dsh; + unsigned long edi; + unsigned long esi; + unsigned long ebp; + unsigned long esp; + unsigned long ebx; + unsigned long edx; + unsigned long ecx; + unsigned long eax; + unsigned long trapno; + unsigned long err; + unsigned long eip; + unsigned short cs, __csh; + unsigned long eflags; + unsigned long esp_at_signal; + unsigned short ss, __ssh; + struct _fpstate * fpstate; + unsigned long oldmask; + unsigned long cr2; +}; + +#endif diff --git a/include/asm-i386/signal.h b/include/asm-i386/signal.h index 271193975..c68928cd7 100644 --- a/include/asm-i386/signal.h +++ b/include/asm-i386/signal.h @@ -50,14 +50,28 @@ typedef unsigned long sigset_t; /* at least 32 bits */ * the changes in signal handling. LBT 010493. * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. */ #define SA_NOCLDSTOP 1 +#define SA_SHIRQ 0x04000000 #define SA_STACK 0x08000000 #define SA_RESTART 0x10000000 #define SA_INTERRUPT 0x20000000 #define SA_NOMASK 0x40000000 #define SA_ONESHOT 0x80000000 +#ifdef __KERNEL__ +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#endif + + #define SIG_BLOCK 0 /* for blocking signals */ #define SIG_UNBLOCK 1 /* for unblocking signals */ #define SIG_SETMASK 2 /* for setting the signal mask */ @@ -77,32 +91,7 @@ struct sigaction { }; #ifdef __KERNEL__ - -struct sigcontext_struct { - unsigned short gs, __gsh; - unsigned short fs, __fsh; - unsigned short es, __esh; - unsigned short ds, __dsh; - unsigned long edi; - unsigned long esi; - unsigned long ebp; - unsigned long esp; - unsigned long ebx; - unsigned long edx; - unsigned long ecx; - unsigned long eax; - unsigned long trapno; - unsigned long err; - unsigned long eip; - unsigned short cs, __csh; - unsigned long eflags; - unsigned long esp_at_signal; - unsigned short ss, __ssh; - unsigned long i387; - unsigned long oldmask; - unsigned long cr2; -}; - +#include <asm/sigcontext.h> #endif #endif diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h new file mode 100644 index 000000000..ff0caafe0 --- /dev/null +++ b/include/asm-i386/smp.h @@ -0,0 +1,258 @@ +#ifndef __ASM_SMP_H +#define __ASM_SMP_H + +#ifdef __SMP__ +#ifndef ASSEMBLY + +#include <asm/i82489.h> +#include <asm/bitops.h> +#include <linux/tasks.h> +#include <linux/ptrace.h> + +/* + * Support definitions for SMP machines following the intel multiprocessing + * specification + */ + +/* + * This tag identifies where the SMP configuration + * information is. + */ + +#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') + +struct intel_mp_floating +{ + char mpf_signature[4]; /* "_MP_" */ + unsigned long mpf_physptr; /* Configuration table address */ + unsigned char mpf_length; /* Our length (paragraphs) */ + unsigned char mpf_specification;/* Specification version */ + unsigned char mpf_checksum; /* Checksum (makes sum 0) */ + unsigned char mpf_feature1; /* Standard or configuration ? */ + unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ + unsigned char mpf_feature3; /* Unused (0) */ + unsigned char mpf_feature4; /* Unused (0) */ + unsigned char mpf_feature5; /* Unused (0) */ +}; + +struct mp_config_table +{ + char mpc_signature[4]; +#define MPC_SIGNATURE "PCMP" + unsigned short mpc_length; /* Size of table */ + char mpc_spec; /* 0x01 */ + char mpc_checksum; + char mpc_oem[8]; + char mpc_productid[12]; + unsigned long mpc_oemptr; /* 0 if not present */ + unsigned short mpc_oemsize; /* 0 if not present */ + unsigned short mpc_oemcount; + unsigned long mpc_lapic; /* APIC address */ + unsigned long reserved; +}; + +/* Followed by entries */ + +#define MP_PROCESSOR 0 +#define MP_BUS 1 +#define MP_IOAPIC 2 +#define MP_INTSRC 3 +#define MP_LINTSRC 4 + +struct mpc_config_processor +{ + unsigned char mpc_type; + unsigned char mpc_apicid; /* Local APIC number */ + unsigned char mpc_apicver; /* Its versions */ + unsigned char mpc_cpuflag; +#define CPU_ENABLED 1 /* Processor is available */ +#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */ + unsigned long mpc_cpufeature; +#define CPU_STEPPING_MASK 0x0F +#define CPU_MODEL_MASK 0xF0 +#define CPU_FAMILY_MASK 0xF00 + unsigned long mpc_featureflag; /* CPUID feature value */ + unsigned long mpc_reserved[2]; +}; + +struct mpc_config_bus +{ + unsigned char mpc_type; + unsigned char mpc_busid; + unsigned char mpc_bustype[6] __attribute((packed)); +}; + +#define BUSTYPE_EISA "EISA" +#define BUSTYPE_ISA "ISA" +#define BUSTYPE_INTERN "INTERN" /* Internal BUS */ +#define BUSTYPE_MCA "MCA" +#define BUSTYPE_VL "VL" /* Local bus */ +#define BUSTYPE_PCI "PCI" +#define BUSTYPE_PCMCIA "PCMCIA" + +/* We don't understand the others */ + +struct mpc_config_ioapic +{ + unsigned char mpc_type; + unsigned char mpc_apicid; + unsigned char mpc_apicver; + unsigned char mpc_flags; +#define MPC_APIC_USABLE 0x01 + unsigned long mpc_apicaddr; +}; + +struct mpc_config_intsrc +{ + unsigned char mpc_type; + unsigned char mpc_irqtype; + unsigned short mpc_irqflag; + unsigned char mpc_srcbus; + unsigned char mpc_srcbusirq; + unsigned char mpc_dstapic; + unsigned char mpc_dstirq; +}; + +#define MP_INT_VECTORED 0 +#define MP_INT_NMI 1 +#define MP_INT_SMI 2 +#define MP_INT_EXTINT 3 + +#define MP_IRQDIR_DEFAULT 0 +#define MP_IRQDIR_HIGH 1 +#define MP_IRQDIR_LOW 3 + + +struct mpc_config_intlocal +{ + unsigned char mpc_type; + unsigned char mpc_irqtype; + unsigned short mpc_irqflag; + unsigned char mpc_srcbusid; + unsigned char mpc_srcbusirq; + unsigned char mpc_destapic; +#define MP_APIC_ALL 0xFF + unsigned char mpc_destapiclint; +}; + + +/* + * Default configurations + * + * 1 2 CPU ISA 82489DX + * 2 2 CPU EISA 82489DX no IRQ 8 or timer chaining + * 3 2 CPU EISA 82489DX + * 4 2 CPU MCA 82489DX + * 5 2 CPU ISA+PCI + * 6 2 CPU EISA+PCI + * 7 2 CPU MCA+PCI + */ + +/* + * Per process x86 parameters + */ + +struct cpuinfo_x86 +{ + char hard_math; + char x86; + char x86_model; + char x86_mask; + char x86_vendor_id[16]; + int x86_capability; + int fdiv_bug; + int have_cpuid; + char wp_works_ok; + char hlt_works_ok; + unsigned long udelay_val; +}; + + +extern struct cpuinfo_x86 cpu_data[NR_CPUS]; + +/* + * Private routines/data + */ + +extern int smp_found_config; +extern int smp_scan_config(unsigned long, unsigned long); +extern unsigned long smp_alloc_memory(unsigned long mem_base); +extern unsigned char *apic_reg; +extern unsigned char *kernel_stacks[NR_CPUS]; +extern unsigned char boot_cpu_id; +extern unsigned long cpu_present_map; +extern volatile int cpu_number_map[NR_CPUS]; +extern volatile int cpu_logical_map[NR_CPUS]; +extern volatile unsigned long smp_invalidate_needed; +extern void smp_flush_tlb(void); +extern volatile unsigned long kernel_flag, kernel_counter; +extern volatile unsigned long cpu_callin_map[NR_CPUS]; +extern volatile unsigned char active_kernel_processor; +extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); +extern void smp_reschedule_irq(int cpl, struct pt_regs *regs); +extern unsigned long ipi_count; +extern void smp_invalidate_rcv(void); /* Process an NMI */ +extern volatile unsigned long kernel_counter; +extern volatile unsigned long syscall_count; + +/* + * General functions that each host system must provide. + */ + +extern void smp_callin(void); +extern void smp_boot_cpus(void); +extern void smp_store_cpu_info(int id); /* Store per cpu info (like the initial udelay numbers */ + +extern volatile unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */ +extern volatile unsigned long smp_process_available; + +/* + * APIC handlers: Note according to the Intel specification update + * you should put reads between APIC writes. + * Intel Pentium processor specification update [11AP, pg 64] + * "Back to Back Assertions of HOLD May Cause Lost APIC Write Cycle" + */ + +extern __inline void apic_write(unsigned long reg, unsigned long v) +{ + *((volatile unsigned long *)(apic_reg+reg))=v; +} + +extern __inline unsigned long apic_read(unsigned long reg) +{ + return *((volatile unsigned long *)(apic_reg+reg)); +} + +/* + * This function is needed by all SMP systems. It must _always_ be valid from the initial + * startup. This may require magic on some systems (in the i86 case we dig out the boot + * cpu id from the config and set up a fake apic_reg pointer so that before we activate + * the apic we get the right answer). Hopefully other processors are more sensible 8) + */ + +extern __inline int smp_processor_id(void) +{ + return GET_APIC_ID(apic_read(APIC_ID)); +} + +#endif /* !ASSEMBLY */ + +#define NO_PROC_ID 0xFF /* No processor magic marker */ + +/* + * This magic constant controls our willingness to transfer + * a process across CPUs. Such a transfer incurs misses on the L1 + * cache, and on a P6 or P5 with multiple L2 caches L2 hits. My + * gut feeling is this will vary by board in value. For a board + * with separate L2 cache it probably depends also on the RSS, and + * for a board with shared L2 cache it ought to decay fast as other + * processes are run. + */ + +#define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ + +#define SMP_FROM_INT 1 +#define SMP_FROM_SYSCALL 2 + +#endif +#endif diff --git a/include/asm-i386/smp_lock.h b/include/asm-i386/smp_lock.h new file mode 100644 index 000000000..a736f0a6c --- /dev/null +++ b/include/asm-i386/smp_lock.h @@ -0,0 +1,69 @@ +#ifndef __I386_SMPLOCK_H +#define __I386_SMPLOCK_H + +#ifdef __SMP__ + +/* + * Locking the kernel + */ + +extern __inline void lock_kernel(void) +{ + unsigned long flags; + int proc = smp_processor_id(); + + save_flags(flags); + cli(); + /* set_bit works atomic in SMP machines */ + while(set_bit(0, (void *)&kernel_flag)) + { + /* + * We just start another level if we have the lock + */ + if (proc == active_kernel_processor) + break; + do + { +#ifdef __SMP_PROF__ + smp_spins[smp_processor_id()]++; +#endif + /* + * Doing test_bit here doesn't lock the bus + */ + if (test_bit(proc, (void *)&smp_invalidate_needed)) + if (clear_bit(proc, (void *)&smp_invalidate_needed)) + local_flush_tlb(); + } + while(test_bit(0, (void *)&kernel_flag)); + } + /* + * We got the lock, so tell the world we are here and increment + * the level counter + */ + active_kernel_processor = proc; + kernel_counter++; + restore_flags(flags); +} + +extern __inline void unlock_kernel(void) +{ + unsigned long flags; + save_flags(flags); + cli(); + /* + * If it's the last level we have in the kernel, then + * free the lock + */ + if (kernel_counter == 0) + panic("Kernel counter wrong.\n"); /* FIXME: Why is kernel_counter sometimes 0 here? */ + + if(! --kernel_counter) + { + active_kernel_processor = NO_PROC_ID; + clear_bit(0, (void *)&kernel_flag); + } + restore_flags(flags); +} + +#endif +#endif diff --git a/include/asm-i386/socket.h b/include/asm-i386/socket.h new file mode 100644 index 000000000..dedf3bfc5 --- /dev/null +++ b/include/asm-i386/socket.h @@ -0,0 +1,42 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockoptions(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_RCVLOWAT 16 +#define SO_SNDLOWAT 17 +#define SO_RCVTIMEO 18 +#define SO_SNDTIMEO 19 + + +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-i386/sockios.h b/include/asm-i386/sockios.h new file mode 100644 index 000000000..6b747f8e2 --- /dev/null +++ b/include/asm-i386/sockios.h @@ -0,0 +1,12 @@ +#ifndef __ARCH_I386_SOCKIOS__ +#define __ARCH_I386_SOCKIOS__ + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +#endif diff --git a/include/asm-i386/stat.h b/include/asm-i386/stat.h index b4c648695..08132a76a 100644 --- a/include/asm-i386/stat.h +++ b/include/asm-i386/stat.h @@ -1,7 +1,7 @@ #ifndef _I386_STAT_H #define _I386_STAT_H -struct old_stat { +struct __old_kernel_stat { unsigned short st_dev; unsigned short st_ino; unsigned short st_mode; @@ -15,7 +15,7 @@ struct old_stat { unsigned long st_ctime; }; -struct new_stat { +struct stat { unsigned short st_dev; unsigned short __pad1; unsigned long st_ino; diff --git a/include/asm-i386/statfs.h b/include/asm-i386/statfs.h index 6efb74113..113d5d428 100644 --- a/include/asm-i386/statfs.h +++ b/include/asm-i386/statfs.h @@ -1,9 +1,13 @@ #ifndef _I386_STATFS_H #define _I386_STATFS_H -typedef struct { - long val[2]; -} fsid_t; +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif struct statfs { long f_type; @@ -13,7 +17,7 @@ struct statfs { long f_bavail; long f_files; long f_ffree; - fsid_t f_fsid; + __kernel_fsid_t f_fsid; long f_namelen; long f_spare[6]; }; diff --git a/include/asm-i386/string-486.h b/include/asm-i386/string-486.h new file mode 100644 index 000000000..50657fb35 --- /dev/null +++ b/include/asm-i386/string-486.h @@ -0,0 +1,694 @@ +#ifndef _I386_STRING_I486_H_ +#define _I386_STRING_I486_H_ + +/* + * This string-include defines all string functions as inline + * functions. Use gcc. It also assumes ds=es=data space, this should be + * normal. Most of the string-functions are rather heavily hand-optimized, + * see especially strtok,strstr,str[c]spn. They should work, but are not + * very easy to understand. Everything is done entirely within the register + * set, making the functions fast and clean. + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Revised and optimized for i486/pentium + * 1994/03/15 by Alberto Vignani/Davide Parodi @crf.it + * + * Split into 2 CPU specific files by Alan Cox to keep #ifdef noise down. + */ + +#define __HAVE_ARCH_STRCPY +extern inline char * strcpy(char * dest,const char *src) +{ +register char *tmp= (char *)dest; +register char dummy; +__asm__ __volatile__( + "\n1:\t" + "movb (%0),%2\n\t" + "incl %0\n\t" + "movb %2,(%1)\n\t" + "incl %1\n\t" + "testb %2,%2\n\t" + "jne 1b" + :"=r" (src), "=r" (tmp), "=q" (dummy) + :"0" (src), "1" (tmp) + :"memory"); +return dest; +} + +#define __HAVE_ARCH_STRNCPY +extern inline char * strncpy(char * dest,const char *src,size_t count) +{ +register char *tmp= (char *)dest; +register char dummy; +if (count) { +__asm__ __volatile__( + "\n1:\t" + "movb (%0),%2\n\t" + "incl %0\n\t" + "movb %2,(%1)\n\t" + "incl %1\n\t" + "decl %3\n\t" + "je 3f\n\t" + "testb %2,%2\n\t" + "jne 1b\n\t" + "2:\tmovb %2,(%1)\n\t" + "incl %1\n\t" + "decl %3\n\t" + "jne 2b\n\t" + "3:" + :"=r" (src), "=r" (tmp), "=q" (dummy), "=r" (count) + :"0" (src), "1" (tmp), "3" (count) + :"memory"); + } /* if (count) */ +return dest; +} + +#define __HAVE_ARCH_STRCAT +extern inline char * strcat(char * dest,const char * src) +{ +register char *tmp = (char *)(dest-1); +register char dummy; +__asm__ __volatile__( + "\n1:\tincl %1\n\t" + "cmpb $0,(%1)\n\t" + "jne 1b\n" + "2:\tmovb (%2),%b0\n\t" + "incl %2\n\t" + "movb %b0,(%1)\n\t" + "incl %1\n\t" + "testb %b0,%b0\n\t" + "jne 2b\n" + :"=q" (dummy), "=r" (tmp), "=r" (src) + :"1" (tmp), "2" (src) + :"memory"); +return dest; +} + +#define __HAVE_ARCH_STRNCAT +extern inline char * strncat(char * dest,const char * src,size_t count) +{ +register char *tmp = (char *)(dest-1); +register char dummy; +__asm__ __volatile__( + "\n1:\tincl %1\n\t" + "cmpb $0,(%1)\n\t" + "jne 1b\n" + "2:\tdecl %3\n\t" + "js 3f\n\t" + "movb (%2),%b0\n\t" + "incl %2\n\t" + "movb %b0,(%1)\n\t" + "incl %1\n\t" + "testb %b0,%b0\n\t" + "jne 2b\n" + "3:\txorl %0,%0\n\t" + "movb %b0,(%1)\n\t" + :"=q" (dummy), "=r" (tmp), "=r" (src), "=r" (count) + :"1" (tmp), "2" (src), "3" (count) + :"memory"); +return dest; +} + +#define __HAVE_ARCH_STRCMP +extern inline int strcmp(const char * cs,const char * ct) +{ +register int __res; +__asm__ __volatile__( + "\n1:\tmovb (%1),%b0\n\t" + "incl %1\n\t" + "cmpb %b0,(%2)\n\t" + "jne 2f\n\t" + "incl %2\n\t" + "testb %b0,%b0\n\t" + "jne 1b\n\t" + "xorl %0,%0\n\t" + "jmp 3f\n" + "2:\tmovl $1,%0\n\t" + "jb 3f\n\t" + "negl %0\n" + "3:" + :"=q" (__res), "=r" (cs), "=r" (ct) + :"1" (cs), "2" (ct) + : "memory" ); +return __res; +} + +#define __HAVE_ARCH_STRNCMP +extern inline int strncmp(const char * cs,const char * ct,size_t count) +{ +register int __res; +__asm__ __volatile__( + "\n1:\tdecl %3\n\t" + "js 2f\n\t" + "movb (%1),%b0\n\t" + "incl %1\n\t" + "cmpb %b0,(%2)\n\t" + "jne 3f\n\t" + "incl %2\n\t" + "testb %b0,%b0\n\t" + "jne 1b\n" + "2:\txorl %0,%0\n\t" + "jmp 4f\n" + "3:\tmovl $1,%0\n\t" + "jb 4f\n\t" + "negl %0\n" + "4:" + :"=q" (__res), "=r" (cs), "=r" (ct), "=r" (count) + :"1" (cs), "2" (ct), "3" (count)); +return __res; +} + +#define __HAVE_ARCH_STRCHR +extern inline char * strchr(const char * s, int c) +{ +register char * __res; +__asm__ __volatile__( + "movb %%al,%%ah\n" + "1:\tmovb (%1),%%al\n\t" + "cmpb %%ah,%%al\n\t" + "je 2f\n\t" + "incl %1\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "xorl %1,%1\n" + "2:\tmovl %1,%0\n\t" + :"=a" (__res), "=r" (s) + :"0" (c), "1" (s)); +return __res; +} + +#define __HAVE_ARCH_STRRCHR +extern inline char * strrchr(const char * s, int c) +{ +register char * __res; +__asm__ __volatile__( + "cld\n\t" + "movb %%al,%%ah\n" + "1:\tlodsb\n\t" + "cmpb %%ah,%%al\n\t" + "jne 2f\n\t" + "leal -1(%%esi),%0\n" + "2:\ttestb %%al,%%al\n\t" + "jne 1b" + :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si"); +return __res; +} + +#define __HAVE_ARCH_STRSPN +extern inline size_t strspn(const char * cs, const char * ct) +{ +register char * __res; +__asm__ __volatile__( + "cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "je 1b\n" + "2:\tdecl %0" + :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + :"ax","cx","dx","di"); +return __res-cs; +} + +#define __HAVE_ARCH_STRCSPN +extern inline size_t strcspn(const char * cs, const char * ct) +{ +register char * __res; +__asm__ __volatile__( + "cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "jne 1b\n" + "2:\tdecl %0" + :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + :"ax","cx","dx","di"); +return __res-cs; +} + +#define __HAVE_ARCH_STRPBRK +extern inline char * strpbrk(const char * cs,const char * ct) +{ +register char * __res; +__asm__ __volatile__( + "cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "jne 1b\n\t" + "decl %0\n\t" + "jmp 3f\n" + "2:\txorl %0,%0\n" + "3:" + :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + :"ax","cx","dx","di"); +return __res; +} + +#define __HAVE_ARCH_STRSTR +extern inline char * strstr(const char * cs,const char * ct) +{ +register char * __res; +__asm__ __volatile__( + "cld\n\t" \ + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */ + "movl %%ecx,%%edx\n" + "1:\tmovl %4,%%edi\n\t" + "movl %%esi,%%eax\n\t" + "movl %%edx,%%ecx\n\t" + "repe\n\t" + "cmpsb\n\t" + "je 2f\n\t" /* also works for empty string, see above */ + "xchgl %%eax,%%esi\n\t" + "incl %%esi\n\t" + "cmpb $0,-1(%%eax)\n\t" + "jne 1b\n\t" + "xorl %%eax,%%eax\n\t" + "2:" + :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct) + :"cx","dx","di","si"); +return __res; +} + +#define __HAVE_ARCH_STRLEN +extern inline size_t strlen(const char * s) +{ +/* + * slightly slower on a 486, but with better chances of + * register allocation + */ +register char dummy, *tmp= (char *)s; +__asm__ __volatile__( + "\n1:\t" + "movb\t(%0),%1\n\t" + "incl\t%0\n\t" + "testb\t%1,%1\n\t" + "jne\t1b" + :"=r" (tmp),"=q" (dummy) + :"0" (s) + : "memory" ); +return (tmp-s-1); +} + +/* Added by Gertjan van Wingerde to make minix and sysv module work */ +#define __HAVE_ARCH_STRNLEN +extern inline size_t strnlen(const char * s, size_t count) +{ +register int __res; +__asm__ __volatile__( + "movl %1,%0\n\t" + "jmp 2f\n" + "1:\tcmpb $0,(%0)\n\t" + "je 3f\n\t" + "incl %0\n" + "2:\tdecl %2\n\t" + "cmpl $-1,%2\n\t" + "jne 1b\n" + "3:\tsubl %1,%0" + :"=a" (__res):"c" (s),"d" (count)); +return __res; +} +/* end of additional stuff */ + +#define __HAVE_ARCH_STRTOK +extern inline char * strtok(char * s,const char * ct) +{ +register char * __res; +__asm__ __volatile__( + "testl %1,%1\n\t" + "jne 1f\n\t" + "testl %0,%0\n\t" + "je 8f\n\t" + "movl %0,%1\n" + "1:\txorl %0,%0\n\t" + "movl $-1,%%ecx\n\t" + "xorl %%eax,%%eax\n\t" + "cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "je 7f\n\t" /* empty delimiter-string */ + "movl %%ecx,%%edx\n" + "2:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 7f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "je 2b\n\t" + "decl %1\n\t" + "cmpb $0,(%1)\n\t" + "je 7f\n\t" + "movl %1,%0\n" + "3:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 5f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "jne 3b\n\t" + "decl %1\n\t" + "cmpb $0,(%1)\n\t" + "je 5f\n\t" + "movb $0,(%1)\n\t" + "incl %1\n\t" + "jmp 6f\n" + "5:\txorl %1,%1\n" + "6:\tcmpb $0,(%0)\n\t" + "jne 7f\n\t" + "xorl %0,%0\n" + "7:\ttestl %0,%0\n\t" + "jne 8f\n\t" + "movl %0,%1\n" + "8:" + :"=b" (__res),"=S" (___strtok) + :"0" (___strtok),"1" (s),"g" (ct) + :"ax","cx","dx","di","memory"); +return __res; +} + +#define __memcpy_c(d,s,count) \ +((count%4==0) ? \ + __memcpy_by4((d),(s),(count)) : \ + ((count%2==0) ? \ + __memcpy_by2((d),(s),(count)) : \ + __memcpy_g((d),(s),(count)))) + +#define __HAVE_ARCH_MEMCPY +#define memcpy(d,s,count) \ +(__builtin_constant_p(count) ? \ + __memcpy_c((d),(s),(count)) : \ + __memcpy_g((d),(s),(count))) + +/* + * These ought to get tweaked to do some cache priming. + */ + +extern inline void * __memcpy_by4(void * to, const void * from, size_t n) +{ +register void *tmp = (void *)to; +register int dummy1,dummy2; +__asm__ __volatile__ ( + "\n1:\tmovl (%2),%0\n\t" + "addl $4,%2\n\t" + "movl %0,(%1)\n\t" + "addl $4,%1\n\t" + "decl %3\n\t" + "jnz 1b" + :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) + :"1" (tmp), "2" (from), "3" (n/4) + :"memory"); +return (to); +} + +extern inline void * __memcpy_by2(void * to, const void * from, size_t n) +{ +register void *tmp = (void *)to; +register int dummy1,dummy2; +__asm__ __volatile__ ( + "shrl $1,%3\n\t" + "jz 2f\n" /* only a word */ + "1:\tmovl (%2),%0\n\t" + "addl $4,%2\n\t" + "movl %0,(%1)\n\t" + "addl $4,%1\n\t" + "decl %3\n\t" + "jnz 1b\n" + "2:\tmovw (%2),%w0\n\t" + "movw %w0,(%1)" + :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) + :"1" (tmp), "2" (from), "3" (n/2) + :"memory"); +return (to); +} + +extern inline void * __memcpy_g(void * to, const void * from, size_t n) +{ +register void *tmp = (void *)to; +__asm__ __volatile__ ( + "cld\n\t" + "shrl $1,%%ecx\n\t" + "jnc 1f\n\t" + "movsb\n" + "1:\tshrl $1,%%ecx\n\t" + "jnc 2f\n\t" + "movsw\n" + "2:\trep\n\t" + "movsl" + : /* no output */ + :"c" (n),"D" ((long) tmp),"S" ((long) from) + :"cx","di","si","memory"); +return (to); +} + + +#define __HAVE_ARCH_MEMMOVE +extern inline void * memmove(void * dest,const void * src, size_t n) +{ +register void *tmp = (void *)dest; +if (dest<src) +__asm__ __volatile__ ( + "cld\n\t" + "rep\n\t" + "movsb" + : /* no output */ + :"c" (n),"S" (src),"D" (tmp) + :"cx","si","di"); +else +__asm__ __volatile__ ( + "std\n\t" + "rep\n\t" + "movsb\n\t" + "cld" + : /* no output */ + :"c" (n), "S" (n-1+(const char *)src), "D" (n-1+(char *)tmp) + :"cx","si","di","memory"); +return dest; +} + +extern inline int memcmp(const void * cs,const void * ct,size_t count) +{ +register int __res; +__asm__ __volatile__( + "cld\n\t" + "repe\n\t" + "cmpsb\n\t" + "je 1f\n\t" + "sbbl %0,%0\n\t" + "orb $1,%b0\n" + "1:" + :"=abd" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count) + :"si","di","cx"); +return __res; +} + +#define __HAVE_ARCH_MEMCHR +extern inline void * memchr(const void * cs,int c,size_t count) +{ +register void * __res; +if (!count) + return NULL; +__asm__ __volatile__( + "cld\n\t" + "repne\n\t" + "scasb\n\t" + "je 1f\n\t" + "movl $1,%0\n" + "1:\tdecl %0" + :"=D" (__res):"a" (c),"D" (cs),"c" (count) + :"cx"); +return __res; +} + +#define __memset_cc(s,c,count) \ +((count%4==0) ? \ + __memset_cc_by4((s),(c),(count)) : \ + ((count%2==0) ? \ + __memset_cc_by2((s),(c),(count)) : \ + __memset_cg((s),(c),(count)))) + +#define __memset_gc(s,c,count) \ +((count%4==0) ? \ + __memset_gc_by4((s),(c),(count)) : \ + ((count%2==0) ? \ + __memset_gc_by2((s),(c),(count)) : \ + __memset_gg((s),(c),(count)))) + +#define __HAVE_ARCH_MEMSET +#define memset(s,c,count) \ +(__builtin_constant_p(c) ? \ + (__builtin_constant_p(count) ? \ + __memset_cc((s),(c),(count)) : \ + __memset_cg((s),(c),(count))) : \ + (__builtin_constant_p(count) ? \ + __memset_gc((s),(c),(count)) : \ + __memset_gg((s),(c),(count)))) + +extern inline void * __memset_cc_by4(void * s, char c, size_t count) +{ +/* + * register char *tmp = s; + */ +register char *tmp = (char *)s; +register int dummy; +__asm__ __volatile__ ( + "\n1:\tmovl %2,(%0)\n\t" + "addl $4,%0\n\t" + "decl %1\n\t" + "jnz 1b" + :"=r" (tmp), "=r" (dummy) + :"q" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/4) + :"memory"); +return s; +} + +extern inline void * __memset_cc_by2(void * s, char c, size_t count) +{ +register void *tmp = (void *)s; +register int dummy; +__asm__ __volatile__ ( + "shrl $1,%1\n\t" /* may be divisible also by 4 */ + "jz 2f\n" + "\n1:\tmovl %2,(%0)\n\t" + "addl $4,%0\n\t" + "decl %1\n\t" + "jnz 1b\n" + "2:\tmovw %w2,(%0)" + :"=r" (tmp), "=r" (dummy) + :"q" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/2) + :"memory"); +return s; +} + +extern inline void * __memset_gc_by4(void * s, char c, size_t count) +{ +register void *tmp = (void *)s; +register int dummy; +__asm__ __volatile__ ( + "movb %b0,%h0\n" + "pushw %w0\n\t" + "shll $16,%0\n\t" + "popw %w0\n" + "1:\tmovl %0,(%1)\n\t" + "addl $4,%1\n\t" + "decl %2\n\t" + "jnz 1b\n" + :"=q" (c), "=r" (tmp), "=r" (dummy) + :"0" ((unsigned) c), "1" (tmp), "2" (count/4) + :"memory"); +return s; +} + +extern inline void * __memset_gc_by2(void * s, char c, size_t count) +{ +register void *tmp = (void *)s; +register int dummy1,dummy2; +__asm__ __volatile__ ( + "movb %b0,%h0\n\t" + "shrl $1,%2\n\t" /* may be divisible also by 4 */ + "jz 2f\n\t" + "pushw %w0\n\t" + "shll $16,%0\n\t" + "popw %w0\n" + "1:\tmovl %0,(%1)\n\t" + "addl $4,%1\n\t" + "decl %2\n\t" + "jnz 1b\n" + "2:\tmovw %w0,(%1)" + :"=q" (dummy1), "=r" (tmp), "=r" (dummy2) + :"0" ((unsigned) c), "1" (tmp), "2" (count/2) + :"memory"); +return s; +} + +extern inline void * __memset_cg(void * s, char c, size_t count) +{ +register void *tmp = (void *)s; +__asm__ __volatile__ ( + "shrl $1,%%ecx\n\t" + "rep\n\t" + "stosw\n\t" + "jnc 1f\n\t" + "movb %%al,(%%edi)\n" + "1:" + : /* no output */ + :"c" (count),"D" (tmp), "a" (0x0101U * (unsigned char) c) + :"cx","di","memory"); +return s; +} + +extern inline void * __memset_gg(void * s,char c,size_t count) +{ +register void *tmp = (void *)s; +__asm__ __volatile__ ( + "movb %%al,%%ah\n\t" + "shrl $1,%%ecx\n\t" + "rep\n\t" + "stosw\n\t" + "jnc 1f\n\t" + "movb %%al,(%%edi)\n" + "1:" + : /* no output */ + :"c" (count),"D" (tmp), "a" (c) + :"cx","di","memory"); +return s; +} + + +/* + * find the first occurrence of byte 'c', or 1 past the area if none + */ +#define __HAVE_ARCH_MEMSCAN +extern inline void * memscan(void * addr, int c, size_t size) +{ + if (!size) + return addr; + __asm__("cld + repnz; scasb + jnz 1f + dec %%edi +1: " + : "=D" (addr), "=c" (size) + : "0" (addr), "1" (size), "a" (c)); + return addr; +} + +#endif diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h index 0f721576e..a7611c735 100644 --- a/include/asm-i386/string.h +++ b/include/asm-i386/string.h @@ -2,6 +2,19 @@ #define _I386_STRING_H_ /* + * On a 486 or Pentium, we are better off not using the + * byte string operations. But on a 386 or a PPro the + * byte string ops are faster than doing it by hand + * (MUCH faster on a Pentium). + * + * Also, the byte strings actually work correctly. Forget + * the i486 routines for now as they may be broken.. + */ +#if FIXED_486_STRING && (CPU == 486 || CPU == 586) +#include <asm/string-486.h> +#else + +/* * This string-include defines all string functions as inline * functions. Use gcc. It also assumes ds=es=data space, this should be * normal. Most of the string-functions are rather heavily hand-optimized, @@ -12,7 +25,8 @@ * * Copyright (C) 1991, 1992 Linus Torvalds */ - + +#define __HAVE_ARCH_STRCPY extern inline char * strcpy(char * dest,const char *src) { __asm__ __volatile__( @@ -26,6 +40,7 @@ __asm__ __volatile__( return dest; } +#define __HAVE_ARCH_STRNCPY extern inline char * strncpy(char * dest,const char *src,size_t count) { __asm__ __volatile__( @@ -44,6 +59,7 @@ __asm__ __volatile__( return dest; } +#define __HAVE_ARCH_STRCAT extern inline char * strcat(char * dest,const char * src) { __asm__ __volatile__( @@ -60,6 +76,7 @@ __asm__ __volatile__( return dest; } +#define __HAVE_ARCH_STRNCAT extern inline char * strncat(char * dest,const char * src,size_t count) { __asm__ __volatile__( @@ -82,6 +99,7 @@ __asm__ __volatile__( return dest; } +#define __HAVE_ARCH_STRCMP extern inline int strcmp(const char * cs,const char * ct) { register int __res; @@ -101,6 +119,7 @@ __asm__ __volatile__( return __res; } +#define __HAVE_ARCH_STRNCMP extern inline int strncmp(const char * cs,const char * ct,size_t count) { register int __res; @@ -122,6 +141,7 @@ __asm__ __volatile__( return __res; } +#define __HAVE_ARCH_STRCHR extern inline char * strchr(const char * s, int c) { register char * __res; @@ -140,6 +160,7 @@ __asm__ __volatile__( return __res; } +#define __HAVE_ARCH_STRRCHR extern inline char * strrchr(const char * s, int c) { register char * __res; @@ -156,6 +177,7 @@ __asm__ __volatile__( return __res; } +#define __HAVE_ARCH_STRSPN extern inline size_t strspn(const char * cs, const char * ct) { register char * __res; @@ -181,6 +203,7 @@ __asm__ __volatile__( return __res-cs; } +#define __HAVE_ARCH_STRCSPN extern inline size_t strcspn(const char * cs, const char * ct) { register char * __res; @@ -206,6 +229,7 @@ __asm__ __volatile__( return __res-cs; } +#define __HAVE_ARCH_STRPBRK extern inline char * strpbrk(const char * cs,const char * ct) { register char * __res; @@ -234,6 +258,7 @@ __asm__ __volatile__( return __res; } +#define __HAVE_ARCH_STRSTR extern inline char * strstr(const char * cs,const char * ct) { register char * __res; @@ -262,6 +287,7 @@ __asm__ __volatile__( return __res; } +#define __HAVE_ARCH_STRLEN extern inline size_t strlen(const char * s) { register int __res; @@ -275,8 +301,7 @@ __asm__ __volatile__( return __res; } -extern char * ___strtok; - +#define __HAVE_ARCH_STRTOK extern inline char * strtok(char * s,const char * ct) { register char * __res; @@ -342,15 +367,15 @@ extern inline void * __memcpy(void * to, const void * from, size_t n) __asm__ __volatile__( "cld\n\t" "rep ; movsl\n\t" - "testb $2,%%dl\n\t" + "testb $2,%b1\n\t" "je 1f\n\t" "movsw\n" - "1:\ttestb $1,%%dl\n\t" + "1:\ttestb $1,%b1\n\t" "je 2f\n\t" "movsb\n" "2:" : /* no output */ - :"c" (n/4), "d" (n),"D" ((long) to),"S" ((long) from) + :"c" (n/4), "q" (n),"D" ((long) to),"S" ((long) from) : "cx","di","si","memory"); return (to); } @@ -365,17 +390,39 @@ extern inline void * __constant_memcpy(void * to, const void * from, size_t n) case 0: return to; case 1: - *(unsigned char *)to = *(unsigned char *)from; + *(unsigned char *)to = *(const unsigned char *)from; return to; case 2: - *(unsigned short *)to = *(unsigned short *)from; + *(unsigned short *)to = *(const unsigned short *)from; return to; case 3: - *(unsigned short *)to = *(unsigned short *)from; - *(2+(unsigned char *)to) = *(2+(unsigned char *)from); + *(unsigned short *)to = *(const unsigned short *)from; + *(2+(unsigned char *)to) = *(2+(const unsigned char *)from); return to; case 4: - *(unsigned long *)to = *(unsigned long *)from; + *(unsigned long *)to = *(const unsigned long *)from; + return to; + case 8: + *(unsigned long *)to = *(const unsigned long *)from; + *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); + return to; + case 12: + *(unsigned long *)to = *(const unsigned long *)from; + *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); + *(2+(unsigned long *)to) = *(2+(const unsigned long *)from); + return to; + case 16: + *(unsigned long *)to = *(const unsigned long *)from; + *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); + *(2+(unsigned long *)to) = *(2+(const unsigned long *)from); + *(3+(unsigned long *)to) = *(3+(const unsigned long *)from); + return to; + case 20: + *(unsigned long *)to = *(const unsigned long *)from; + *(1+(unsigned long *)to) = *(1+(const unsigned long *)from); + *(2+(unsigned long *)to) = *(2+(const unsigned long *)from); + *(3+(unsigned long *)to) = *(3+(const unsigned long *)from); + *(4+(unsigned long *)to) = *(4+(const unsigned long *)from); return to; } #define COMMON(x) \ @@ -395,11 +442,13 @@ __asm__("cld\n\t" \ #undef COMMON } +#define __HAVE_ARCH_MEMCPY #define memcpy(t, f, n) \ (__builtin_constant_p(n) ? \ __constant_memcpy((t),(f),(n)) : \ __memcpy((t),(f),(n))) +#define __HAVE_ARCH_MEMMOVE extern inline void * memmove(void * dest,const void * src, size_t n) { if (dest<src) @@ -424,22 +473,9 @@ __asm__ __volatile__( return dest; } -extern inline int memcmp(const void * cs,const void * ct,size_t count) -{ -register int __res; -__asm__ __volatile__( - "cld\n\t" - "repe\n\t" - "cmpsb\n\t" - "je 1f\n\t" - "sbbl %%eax,%%eax\n\t" - "orb $1,%%al\n" - "1:" - :"=a" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count) - :"si","di","cx"); -return __res; -} +#define memcmp __builtin_memcmp +#define __HAVE_ARCH_MEMCHR extern inline void * memchr(const void * cs,int c,size_t count) { register void * __res; @@ -482,19 +518,38 @@ extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count __asm__ __volatile__( "cld\n\t" "rep ; stosl\n\t" - "testb $2,%%dl\n\t" + "testb $2,%b1\n\t" "je 1f\n\t" "stosw\n" - "1:\ttestb $1,%%dl\n\t" + "1:\ttestb $1,%b1\n\t" "je 2f\n\t" "stosb\n" "2:" : /* no output */ - :"a" (c), "d" (count), "c" (count/4), "D" ((long) s) + :"a" (c), "q" (count), "c" (count/4), "D" ((long) s) :"cx","di","memory"); return (s); } +/* Added by Gertjan van Wingerde to make minix and sysv module work */ +#define __HAVE_ARCH_STRNLEN +extern inline size_t strnlen(const char * s, size_t count) +{ +register int __res; +__asm__ __volatile__( + "movl %1,%0\n\t" + "jmp 2f\n" + "1:\tcmpb $0,(%0)\n\t" + "je 3f\n\t" + "incl %0\n" + "2:\tdecl %2\n\t" + "cmpl $-1,%2\n\t" + "jne 1b\n" + "3:\tsubl %1,%0" + :"=a" (__res):"c" (s),"d" (count)); +return __res; +} +/* end of additional stuff */ /* * This looks horribly ugly, but the compiler can optimize it totally, @@ -546,6 +601,7 @@ __asm__("cld\n\t" \ __constant_count_memset((s),(c),(count)) : \ __memset_generic((s),(c),(count))) +#define __HAVE_ARCH_MEMSET #define memset(s, c, count) \ (__builtin_constant_p(c) ? \ __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \ @@ -554,6 +610,7 @@ __asm__("cld\n\t" \ /* * find the first occurrence of byte 'c', or 1 past the area if none */ +#define __HAVE_ARCH_MEMSCAN extern inline void * memscan(void * addr, int c, size_t size) { if (!size) @@ -569,3 +626,4 @@ extern inline void * memscan(void * addr, int c, size_t size) } #endif +#endif diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index b4108d511..ae8c56a96 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h @@ -5,11 +5,12 @@ /* * Entry into gdt where to find first TSS. GDT layout: - * 0 - nul - * 1 - kernel code segment - * 2 - kernel data segment - * 3 - user code segment - * 4 - user data segment + * 0 - null + * 1 - not used + * 2 - kernel code segment + * 3 - kernel data segment + * 4 - user code segment + * 5 - user data segment * ... * 8 - TSS #0 * 9 - LDT #0 @@ -31,11 +32,11 @@ __asm__("str %%ax\n\t" \ /* This special macro can be used to load a debugging register */ -#define loaddebug(register) \ +#define loaddebug(tsk,register) \ __asm__("movl %0,%%edx\n\t" \ "movl %%edx,%%db" #register "\n\t" \ : /* no output */ \ - :"m" (current->debugreg[register]) \ + :"m" (tsk->debugreg[register]) \ :"dx"); @@ -47,28 +48,80 @@ __asm__("str %%ax\n\t" \ * * It also reloads the debug regs if necessary.. */ -#define switch_to(tsk) do { \ -__asm__("cli\n\t" \ - "xchgl %%ecx,_current\n\t" \ + + +#ifdef __SMP__ + /* + * Keep the lock depth straight. If we switch on an interrupt from + * kernel->user task we need to lose a depth, and if we switch the + * other way we need to gain a depth. Same layer switches come out + * the same. + * + * We spot a switch in user mode because the kernel counter is the + * same as the interrupt counter depth. (We never switch during the + * message/invalidate IPI). + * + * We fsave/fwait so that an exception goes off at the right time + * (as a call from the fsave or fwait in effect) rather than to + * the wrong process. + */ + +#define switch_to(prev,next) do { \ + cli();\ + if(prev->flags&PF_USEDFPU) \ + { \ + __asm__ __volatile__("fnsave %0":"=m" (prev->tss.i387.hard)); \ + __asm__ __volatile__("fwait"); \ + prev->flags&=~PF_USEDFPU; \ + } \ + prev->lock_depth=syscall_count; \ + kernel_counter+=next->lock_depth-prev->lock_depth; \ + syscall_count=next->lock_depth; \ +__asm__("pushl %%edx\n\t" \ + "movl "SYMBOL_NAME_STR(apic_reg)",%%edx\n\t" \ + "movl 0x20(%%edx), %%edx\n\t" \ + "shrl $22,%%edx\n\t" \ + "and $0x3C,%%edx\n\t" \ + "movl %%ecx,"SYMBOL_NAME_STR(current_set)"(,%%edx)\n\t" \ + "popl %%edx\n\t" \ "ljmp %0\n\t" \ "sti\n\t" \ - "cmpl %%ecx,_last_task_used_math\n\t" \ + : /* no output */ \ + :"m" (*(((char *)&next->tss.tr)-4)), \ + "c" (next)); \ + /* Now maybe reload the debug registers */ \ + if(prev->debugreg[7]){ \ + loaddebug(prev,0); \ + loaddebug(prev,1); \ + loaddebug(prev,2); \ + loaddebug(prev,3); \ + loaddebug(prev,6); \ + loaddebug(prev,7); \ + } \ +} while (0) + +#else +#define switch_to(prev,next) do { \ +__asm__("movl %2,"SYMBOL_NAME_STR(current_set)"\n\t" \ + "ljmp %0\n\t" \ + "cmpl %1,"SYMBOL_NAME_STR(last_task_used_math)"\n\t" \ "jne 1f\n\t" \ "clts\n" \ "1:" \ - : /* no output */ \ - :"m" (*(((char *)&tsk->tss.tr)-4)), \ - "c" (tsk) \ - :"cx"); \ + : /* no outputs */ \ + :"m" (*(((char *)&next->tss.tr)-4)), \ + "r" (prev), "r" (next)); \ /* Now maybe reload the debug registers */ \ - if(current->debugreg[7]){ \ - loaddebug(0); \ - loaddebug(1); \ - loaddebug(2); \ - loaddebug(3); \ - loaddebug(6); \ + if(prev->debugreg[7]){ \ + loaddebug(prev,0); \ + loaddebug(prev,1); \ + loaddebug(prev,2); \ + loaddebug(prev,3); \ + loaddebug(prev,6); \ + loaddebug(prev,7); \ } \ } while (0) +#endif #define _set_base(addr,base) \ __asm__("movw %%dx,%0\n\t" \ @@ -138,32 +191,35 @@ __asm__ __volatile__ ( \ :"ax") -extern inline unsigned long xchg_u8(char * m, unsigned long val) -{ - __asm__("xchgb %b0,%1":"=q" (val),"=m" (*m):"0" (val):"memory"); - return val; -} - -extern inline unsigned long xchg_u16(short * m, unsigned long val) -{ - __asm__("xchgw %w0,%1":"=r" (val),"=m" (*m):"0" (val):"memory"); - return val; -} - -extern inline unsigned long xchg_u32(int * m, unsigned long val) -{ - __asm__("xchgl %0,%1":"=r" (val),"=m" (*m):"0" (val):"memory"); - return val; -} +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) -extern inline int tas(char * m) -{ - return xchg_u8(m,1); -} +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((struct __xchg_dummy *)(x)) -extern inline void * xchg_ptr(void * m, void * val) +static inline unsigned long __xchg(unsigned long x, void * ptr, int size) { - return (void *) xchg_u32(m, (unsigned long) val); + switch (size) { + case 1: + __asm__("xchgb %b0,%1" + :"=q" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + case 2: + __asm__("xchgw %w0,%1" + :"=r" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + case 4: + __asm__("xchgl %0,%1" + :"=r" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + } + return x; } #define mb() __asm__ __volatile__ ("" : : :"memory") @@ -171,10 +227,10 @@ extern inline void * xchg_ptr(void * m, void * val) #define cli() __asm__ __volatile__ ("cli": : :"memory") #define save_flags(x) \ -__asm__ __volatile__("pushfl ; popl %0":"=r" (x): /* no input */ :"memory") +__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory") #define restore_flags(x) \ -__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"r" (x):"memory") +__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory") #define iret() __asm__ __volatile__ ("iret": : :"memory") @@ -221,7 +277,7 @@ __asm__ __volatile__ ("movw $" #limit ",%1\n\t" \ "movb %%ah,%6\n\t" \ "rorl $16,%%eax" \ : /* no output */ \ - :"a" (addr+0xc0000000), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \ + :"a" (addr), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \ "m" (*(n+5)), "m" (*(n+6)), "m" (*(n+7)) \ ) @@ -242,4 +298,9 @@ extern struct desc_struct default_ldt; void disable_hlt(void); void enable_hlt(void); +/* + * Reset the machine. + */ +extern void hard_reset_now(void); + #endif diff --git a/include/asm-i386/termbits.h b/include/asm-i386/termbits.h new file mode 100644 index 000000000..c40e6f052 --- /dev/null +++ b/include/asm-i386/termbits.h @@ -0,0 +1,160 @@ +#ifndef __ARCH_I386_TERMBITS_H__ +#define __ARCH_I386_TERMBITS_H__ + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h index ee89e14a1..76551dea9 100644 --- a/include/asm-i386/termios.h +++ b/include/asm-i386/termios.h @@ -1,68 +1,8 @@ #ifndef _I386_TERMIOS_H #define _I386_TERMIOS_H -/* 0x54 is just a magic number to make these relatively unique ('T') */ - -#define TCGETS 0x5401 -#define TCSETS 0x5402 -#define TCSETSW 0x5403 -#define TCSETSF 0x5404 -#define TCGETA 0x5405 -#define TCSETA 0x5406 -#define TCSETAW 0x5407 -#define TCSETAF 0x5408 -#define TCSBRK 0x5409 -#define TCXONC 0x540A -#define TCFLSH 0x540B -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E -#define TIOCGPGRP 0x540F -#define TIOCSPGRP 0x5410 -#define TIOCOUTQ 0x5411 -#define TIOCSTI 0x5412 -#define TIOCGWINSZ 0x5413 -#define TIOCSWINSZ 0x5414 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define FIONREAD 0x541B -#define TIOCINQ FIONREAD -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 -#define FIONBIO 0x5421 -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ -#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ -#define FIOCLEX 0x5451 -#define FIOASYNC 0x5452 -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 +#include <asm/termbits.h> +#include <asm/ioctls.h> struct winsize { unsigned short ws_row; @@ -81,37 +21,8 @@ struct termio { unsigned char c_cc[NCC]; /* control characters */ }; -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VTIME 5 -#define VMIN 6 -#define VSWTC 7 -#define VSTART 8 -#define VSTOP 9 -#define VSUSP 10 -#define VEOL 11 -#define VREPRINT 12 -#define VDISCARD 13 -#define VWERASE 14 -#define VLNEXT 15 -#define VEOL2 16 - #ifdef __KERNEL__ -/* intr=^C quit=^| erase=del kill=^U +/* intr=^C quit=^\ erase=del kill=^U eof=^D vtime=\0 vmin=\1 sxtc=\0 start=^Q stop=^S susp=^Z eol=\0 reprint=^R discard=^U werase=^W lnext=^V @@ -120,110 +31,6 @@ struct termios { #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" #endif -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IUCLC 0001000 -#define IXON 0002000 -#define IXANY 0004000 -#define IXOFF 0010000 -#define IMAXBEL 0020000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define OLCUC 0000002 -#define ONLCR 0000004 -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 -#define OFILL 0000100 -#define OFDEL 0000200 -#define NLDLY 0000400 -#define NL0 0000000 -#define NL1 0000400 -#define CRDLY 0003000 -#define CR0 0000000 -#define CR1 0001000 -#define CR2 0002000 -#define CR3 0003000 -#define TABDLY 0014000 -#define TAB0 0000000 -#define TAB1 0004000 -#define TAB2 0010000 -#define TAB3 0014000 -#define XTABS 0014000 -#define BSDLY 0020000 -#define BS0 0000000 -#define BS1 0020000 -#define VTDLY 0040000 -#define VT0 0000000 -#define VT1 0040000 -#define FFDLY 0100000 -#define FF0 0000000 -#define FF1 0100000 - -/* c_cflag bit meaning */ -#define CBAUD 0010017 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CSIZE 0000060 -#define CS5 0000000 -#define CS6 0000020 -#define CS7 0000040 -#define CS8 0000060 -#define CSTOPB 0000100 -#define CREAD 0000200 -#define PARENB 0000400 -#define PARODD 0001000 -#define HUPCL 0002000 -#define CLOCAL 0004000 -#define CBAUDEX 0010000 -#define B57600 0010001 -#define B115200 0010002 -#define B230400 0010003 -#define CIBAUD 002003600000 /* input baud rate (not used) */ -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0000001 -#define ICANON 0000002 -#define XCASE 0000004 -#define ECHO 0000010 -#define ECHOE 0000020 -#define ECHOK 0000040 -#define ECHONL 0000100 -#define NOFLSH 0000200 -#define TOSTOP 0000400 -#define ECHOCTL 0001000 -#define ECHOPRT 0002000 -#define ECHOKE 0004000 -#define FLUSHO 0010000 -#define PENDIN 0040000 -#define IEXTEN 0100000 - /* modem lines */ #define TIOCM_LE 0x001 #define TIOCM_DTR 0x002 @@ -238,29 +45,48 @@ struct termios { #define TIOCM_RI TIOCM_RNG /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - - -/* tcflow() and TCXONC use these */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* tcflush() and TCFLSH use these */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* tcsetattr uses these */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 /* line disciplines */ #define N_TTY 0 #define N_SLIP 1 #define N_MOUSE 2 #define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 -#endif +#ifdef __KERNEL__ + +#include <linux/string.h> + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +extern inline void trans_from_termio(struct termio * termio, + struct termios * termios) +{ +#define SET_LOW_BITS(x,y) (*(unsigned short *)(&x) = (y)) + SET_LOW_BITS(termios->c_iflag, termio->c_iflag); + SET_LOW_BITS(termios->c_oflag, termio->c_oflag); + SET_LOW_BITS(termios->c_cflag, termio->c_cflag); + SET_LOW_BITS(termios->c_lflag, termio->c_lflag); +#undef SET_LOW_BITS + memcpy(termios->c_cc, termio->c_cc, NCC); +} + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +extern inline void trans_to_termio(struct termios * termios, + struct termio * termio) +{ + termio->c_iflag = termios->c_iflag; + termio->c_oflag = termios->c_oflag; + termio->c_cflag = termios->c_cflag; + termio->c_lflag = termios->c_lflag; + termio->c_line = termios->c_line; + memcpy(termio->c_cc, termios->c_cc, NCC); +} + +#endif /* __KERNEL__ */ + +#endif /* _I386_TERMIOS_H */ diff --git a/include/asm-i386/types.h b/include/asm-i386/types.h index 359ea5ba8..71309ac82 100644 --- a/include/asm-i386/types.h +++ b/include/asm-i386/types.h @@ -1,41 +1,7 @@ #ifndef _I386_TYPES_H #define _I386_TYPES_H -#ifndef _SIZE_T -#define _SIZE_T -typedef unsigned int size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef int ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef int ptrdiff_t; -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef long time_t; -#endif - -#ifndef _CLOCK_T -#define _CLOCK_T -typedef long clock_t; -#endif - -typedef int pid_t; -typedef unsigned short uid_t; -typedef unsigned short gid_t; -typedef unsigned short dev_t; -typedef unsigned long ino_t; -typedef unsigned short mode_t; typedef unsigned short umode_t; -typedef unsigned short nlink_t; -typedef int daddr_t; -typedef long off_t; /* * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the @@ -48,8 +14,8 @@ typedef unsigned char __u8; typedef __signed__ short __s16; typedef unsigned short __u16; -typedef __signed__ long __s32; -typedef unsigned long __u32; +typedef __signed__ int __s32; +typedef unsigned int __u32; #if defined(__GNUC__) && !defined(__STRICT_ANSI__) typedef __signed__ long long __s64; @@ -67,8 +33,8 @@ typedef unsigned char u8; typedef signed short s16; typedef unsigned short u16; -typedef signed long s32; -typedef unsigned long u32; +typedef signed int s32; +typedef unsigned int u32; typedef signed long long s64; typedef unsigned long long u64; diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h new file mode 100644 index 000000000..2c81e938e --- /dev/null +++ b/include/asm-i386/uaccess.h @@ -0,0 +1,450 @@ +#ifndef __i386_UACCESS_H +#define __i386_UACCESS_H + +/* + * User space memory access functions + */ +#include <linux/sched.h> +#include <asm/segment.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 get_fs() (current->tss.segment) +#define set_fs(x) (current->tss.segment = (x)) +#define get_ds() (KERNEL_DS) + +/* + * Address Ok: + * + * low two bits of segment + * 00 (kernel) 11 (user) + * + * high 00 1 1 + * two 01 1 1 + * bits of 10 1 1 + * address 11 1 0 + */ +#define __addr_ok(x) \ + ((((unsigned long)(x)>>30)&get_fs()) != 3) + +#define __user_ok(addr,size) \ + ((size <= 0xC0000000UL) && (addr <= 0xC0000000UL - size)) +#define __kernel_ok \ + (!(get_fs() & 3)) + +extern int __verify_write(const void *, unsigned long); + +#if CPU > 386 +#define __access_ok(type,addr,size) \ + (__kernel_ok || __user_ok(addr,size)) +#else +#define __access_ok(type,addr,size) \ + (__kernel_ok || (__user_ok(addr,size) && \ + ((type) == VERIFY_READ || wp_works_ok || \ + __verify_write((void *)(addr),(size))))) +#endif /* CPU */ + +#define access_ok(type,addr,size) \ + __access_ok((type),(unsigned long)(addr),(size)) + +extern inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size) ? 0 : -EFAULT; +} + + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + * + * This gets kind of ugly. We want to return _two_ values in "get_user()" + * and yet we don't want to do any pointers, because that is too much + * of a performance impact. Thus we have a few rather ugly macros here, + * and hide all the uglyness from the user. + * + * The "__xxx" versions of the user access functions are versions that + * do not verify the address space, that must have been done previously + * with a separate "access_ok()" call (this is used when we do multiple + * accesses to the same area of user memory). + */ +#define get_user(x,ptr) \ + __get_user_check((x),(ptr),sizeof(*(ptr))) +#define put_user(x,ptr) \ + __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + +#define __get_user(x,ptr) \ + __get_user_nocheck((x),(ptr),sizeof(*(ptr))) +#define __put_user(x,ptr) \ + __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + + +extern long __put_user_bad(void); + +#define __put_user_nocheck(x,ptr,size) \ +({ \ + long __pu_err; \ + __put_user_size((x),(ptr),(size),__pu_err); \ + __pu_err; \ +}) + +#define __put_user_check(x,ptr,size) \ +({ \ + long __pu_err = -EFAULT; \ + __typeof__(*(ptr)) *__pu_addr = (ptr); \ + if (access_ok(VERIFY_WRITE,__pu_addr,size)) \ + __put_user_size((x),__pu_addr,(size),__pu_err); \ + __pu_err; \ +}) + +#define __put_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: __put_user_asm(x,ptr,retval,"b","b","iq"); break; \ + case 2: __put_user_asm(x,ptr,retval,"w","w","ir"); break; \ + case 4: __put_user_asm(x,ptr,retval,"l","","ir"); break; \ + default: __put_user_bad(); \ + } \ +} while (0) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) (*(struct __large_struct *)(x)) + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ +#define __put_user_asm(x, addr, err, itype, rtype, ltype) \ + __asm__ __volatile__( \ + "1: mov"itype" %"rtype"1,%2\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %3,%0\n" \ + " jmp 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".text" \ + : "=r"(err) \ + : ltype (x), "m"(__m(addr)), "i"(-EFAULT), "0"(err)) + + +#define __get_user_nocheck(x,ptr,size) \ +({ \ + long __gu_err, __gu_val; \ + __get_user_size(__gu_val,(ptr),(size),__gu_err); \ + (x) = (__typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) + +#define __get_user_check(x,ptr,size) \ +({ \ + long __gu_err = -EFAULT, __gu_val = 0; \ + const __typeof__(*(ptr)) *__gu_addr = (ptr); \ + if (access_ok(VERIFY_READ,__gu_addr,size)) \ + __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \ + (x) = (__typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) + +extern long __get_user_bad(void); + +#define __get_user_size(x,ptr,size,retval) \ +do { \ + retval = 0; \ + switch (size) { \ + case 1: __get_user_asm(x,ptr,retval,"b","b","=q"); break; \ + case 2: __get_user_asm(x,ptr,retval,"w","w","=r"); break; \ + case 4: __get_user_asm(x,ptr,retval,"l","","=r"); break; \ + default: (x) = __get_user_bad(); \ + } \ +} while (0) + +#define __get_user_asm(x, addr, err, itype, rtype, ltype) \ + __asm__ __volatile__( \ + "1: mov"itype" %2,%"rtype"1\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %3,%0\n" \ + " xor"itype" %"rtype"1,%"rtype"1\n" \ + " jmp 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".text" \ + : "=r"(err), ltype (x) \ + : "m"(__m(addr)), "i"(-EFAULT), "0"(err)) + + +/* + * Copy To/From Userspace + */ + +/* Generic arbitrary sized copy. */ +#define __copy_user(to,from,size) \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + " movl %1,%0\n" \ + "1: rep; movsb\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: lea 0(%1,%0,4),%0\n" \ + " jmp 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,2b\n" \ + ".text" \ + : "=c"(size) \ + : "r"(size & 3), "0"(size / 4), "D"(to), "S"(from) \ + : "di", "si", "memory") + +/* Optimize just a little bit when we know the size of the move. */ +#define __constant_copy_user(to, from, size) \ +do { \ + switch (size & 3) { \ + default: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1:\n" \ + ".section .fixup,\"ax\"\n" \ + "2: shl $2,%0\n" \ + " jmp 1b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,2b\n" \ + ".text" \ + : "=c"(size) \ + : "S"(from), "D"(to), "0"(size/4) \ + : "di", "si", "memory"); \ + break; \ + case 1: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1: movsb\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: shl $2,%0\n" \ + "4: incl %0\n" \ + " jmp 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,4b\n" \ + ".text" \ + : "=c"(size) \ + : "S"(from), "D"(to), "0"(size/4) \ + : "di", "si", "memory"); \ + break; \ + case 2: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1: movsw\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: shl $2,%0\n" \ + "4: addl $2,%0\n" \ + " jmp 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,4b\n" \ + ".text" \ + : "=c"(size) \ + : "S"(from), "D"(to), "0"(size/4) \ + : "di", "si", "memory"); \ + break; \ + case 3: \ + __asm__ __volatile__( \ + "0: rep; movsl\n" \ + "1: movsw\n" \ + "2: movsb\n" \ + "3:\n" \ + ".section .fixup,\"ax\"\n" \ + "4: shl $2,%0\n" \ + "5: addl $2,%0\n" \ + "6: incl %0\n" \ + " jmp 3b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,4b\n" \ + " .long 1b,5b\n" \ + " .long 2b,6b\n" \ + ".text" \ + : "=c"(size) \ + : "S"(from), "D"(to), "0"(size/4) \ + : "di", "si", "memory"); \ + break; \ + } \ +} while (0) + +static inline unsigned long +__generic_copy_to_user(void *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + __copy_user(to,from,n); + return n; +} + +static inline unsigned long +__constant_copy_to_user(void *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + __constant_copy_user(to,from,n); + return n; +} + +static inline unsigned long +__generic_copy_from_user(void *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + __copy_user(to,from,n); + return n; +} + +static inline unsigned long +__constant_copy_from_user(void *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + __constant_copy_user(to,from,n); + return n; +} + + +#define copy_to_user(to,from,n) \ + (__builtin_constant_p(n) ? \ + __constant_copy_to_user((to),(from),(n)) : \ + __generic_copy_to_user((to),(from),(n))) + +#define copy_from_user(to,from,n) \ + (__builtin_constant_p(n) ? \ + __constant_copy_from_user((to),(from),(n)) : \ + __generic_copy_from_user((to),(from),(n))) + + +/* + * Zero Userspace + */ + +#define __clear_user(addr,size) \ + __asm__ __volatile__( \ + "0: rep; stosl\n" \ + " movl %1,%0\n" \ + "1: rep; stosb\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: lea 0(%1,%0,4),%0\n" \ + " jmp 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,2b\n" \ + ".text" \ + : "=c"(size) \ + : "r"(size & 3), "0"(size / 4), "D"(addr), "a"(0) \ + : "di") + +static inline unsigned long +clear_user(void *to, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + __clear_user(to, n); + return n; +} + + +/* + * Copy a null terminated string from userspace. + */ + +#define __strncpy_from_user(dst,src,count,res) \ + __asm__ __volatile__( \ + " testl %1,%1\n" \ + " jz 2f\n" \ + "0: lodsb\n" \ + " stosb\n" \ + " testb %%al,%%al\n" \ + " jz 1f\n" \ + " decl %1\n" \ + " jnz 0b\n" \ + "1: subl %1,%0\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %2,%0\n" \ + " jmp 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,3b\n" \ + ".text" \ + : "=d"(res), "=c"(count) \ + : "i"(-EFAULT), "0"(count), "1"(count), "S"(src), "D"(dst) \ + : "si", "di", "ax", "memory") + +static inline long +strncpy_from_user(char *dst, const char *src, long count) +{ + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) + __strncpy_from_user(dst, src, count, res); + return res; +} + +/* + * Return the size of a string (including the ending 0) + * + * Return 0 for error + */ + +extern inline long strlen_user(const char *s) +{ + unsigned long res; + + __asm__ __volatile__( + "0: repne; scasb\n" + " notl %0\n" + "1:\n" + ".section .fixup,\"ax\"\n" + "2: xorl %0,%0\n" + " jmp 1b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 0b,2b\n" + ".text" + :"=c" (res), "=D" (s) + :"1" (s), "a" (0), "0" (-__addr_ok(s))); + return res & -__addr_ok(s); +} + +#endif /* __i386_UACCESS_H */ diff --git a/include/asm-i386/unaligned.h b/include/asm-i386/unaligned.h new file mode 100644 index 000000000..282ce190e --- /dev/null +++ b/include/asm-i386/unaligned.h @@ -0,0 +1,16 @@ +#ifndef __I386_UNALIGNED_H +#define __I386_UNALIGNED_H + +/* + * The i386 can do unaligned accesses itself. + * + * The strange macros are there to make sure these can't + * be misused in a way that makes them not work on other + * architectures where unaligned accesses aren't as simple. + */ + +#define get_unaligned(ptr) (*(ptr)) + +#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) + +#endif diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index 84196ac9e..403f481a3 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -1,6 +1,188 @@ #ifndef _ASM_I386_UNISTD_H_ #define _ASM_I386_UNISTD_H_ +/* + * This file contains the system call numbers. + */ + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl 110 +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86 113 +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_modify_ldt 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 + +/* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ type name(void) \ @@ -9,10 +191,7 @@ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name)); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +__syscall_return(type,__res); \ } #define _syscall1(type,name,type1,arg1) \ @@ -22,10 +201,7 @@ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1))); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +__syscall_return(type,__res); \ } #define _syscall2(type,name,type1,arg1,type2,arg2) \ @@ -35,10 +211,7 @@ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +__syscall_return(type,__res); \ } #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ @@ -49,10 +222,7 @@ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ "d" ((long)(arg3))); \ -if (__res>=0) \ - return (type) __res; \ -errno=-__res; \ -return -1; \ +__syscall_return(type,__res); \ } #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ @@ -63,10 +233,7 @@ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ "d" ((long)(arg3)),"S" ((long)(arg4))); \ -if (__res>=0) \ - return (type) __res; \ -errno=-__res; \ -return -1; \ +__syscall_return(type,__res); \ } #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ @@ -78,10 +245,7 @@ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \ -if (__res>=0) \ - return (type) __res; \ -errno=-__res; \ -return -1; \ +__syscall_return(type,__res); \ } #ifdef __KERNEL_SYSCALLS__ @@ -101,6 +265,7 @@ return -1; \ #define __NR__exit __NR_exit static inline _syscall0(int,idle) static inline _syscall0(int,fork) +static inline _syscall2(int,clone,unsigned long,flags,char *,esp) static inline _syscall0(int,pause) static inline _syscall0(int,setup) static inline _syscall0(int,sync) @@ -118,6 +283,36 @@ static inline pid_t wait(int * wait_stat) return waitpid(-1,wait_stat,0); } +/* + * This is the mechanism for creating a new kernel thread. + * + * NOTE! Only a kernel-only process(ie the swapper or direct descendants + * who haven't done an "execve()") should use this: it will work within + * a system call from a "real" process, but the process memory space will + * not be free'd until both the parent and the child have exited. + */ +static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + long retval; + + __asm__ __volatile__( + "movl %%esp,%%esi\n\t" + "int $0x80\n\t" /* Linux/i386 system call */ + "cmpl %%esp,%%esi\n\t" /* child or parent? */ + "je 1f\n\t" /* parent - jump */ + "pushl %3\n\t" /* push argument */ + "call *%4\n\t" /* call fn */ + "movl %2,%0\n\t" /* exit */ + "int $0x80\n" + "1:\t" + :"=a" (retval) + :"0" (__NR_clone), "i" (__NR_exit), + "r" (arg), "r" (fn), + "b" (flags | CLONE_VM) + :"si"); + return retval; +} + #endif #endif /* _ASM_I386_UNISTD_H_ */ diff --git a/include/asm-i386/user.h b/include/asm-i386/user.h new file mode 100644 index 000000000..b5acf0e74 --- /dev/null +++ b/include/asm-i386/user.h @@ -0,0 +1,94 @@ +#ifndef _I386_USER_H +#define _I386_USER_H + +#include <asm/page.h> +#include <linux/ptrace.h> +/* Core file format: The core file is written in such a way that gdb + can understand it and provide useful information to the user (under + linux we use the 'trad-core' bfd). There are quite a number of + obstacles to being able to view the contents of the floating point + registers, and until these are solved you will not be able to view the + contents of them. Actually, you can read in the core file and look at + the contents of the user struct to find out what the floating point + registers contain. + The actual file contents are as follows: + UPAGE: 1 page consisting of a user struct that tells gdb what is present + in the file. Directly after this is a copy of the task_struct, which + is currently not used by gdb, but it may come in useful at some point. + All of the registers are stored as part of the upage. The upage should + always be only one page. + DATA: The data area is stored. We use current->end_text to + current->brk to pick up all of the user variables, plus any memory + that may have been malloced. No attempt is made to determine if a page + is demand-zero or if a page is totally unused, we just cover the entire + range. All of the addresses are rounded in such a way that an integral + number of pages is written. + STACK: We need the stack information in order to get a meaningful + backtrace. We need to write the data from (esp) to + current->start_stack, so we round each of these off in order to be able + to write an integer number of pages. + The minimum core file size is 3 pages, or 12288 bytes. +*/ + +struct user_i387_struct { + long cwd; + long swd; + long twd; + long fip; + long fcs; + long foo; + long fos; + long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ +}; + +/* + * This is the old layout of "struct pt_regs", and + * is still the layout used by user mode (the new + * pt_regs doesn't have all registers as the kernel + * doesn't use the extra segment registers) + */ +struct user_regs_struct { + long ebx, ecx, edx, esi, edi, ebp, eax; + unsigned short ds, __ds, es, __es; + unsigned short fs, __fs, gs, __gs; + long orig_eax, eip; + unsigned short cs, __cs; + long eflags, esp; + unsigned short ss, __ss; +}; + +/* When the kernel dumps core, it starts by dumping the user struct - + this will be used by gdb to figure out where the data and stack segments + are within the file, and what virtual addresses to use. */ +struct user{ +/* We start with the registers, to mimic the way that "memory" is returned + from the ptrace(3,...) function. */ + struct user_regs_struct regs; /* Where the registers are actually stored */ +/* ptrace does not yet supply these. Someday.... */ + int u_fpvalid; /* True if math co-processor being used. */ + /* for this mess. Not yet used. */ + struct user_i387_struct i387; /* Math Co-processor registers. */ +/* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ + /* the registers. */ + struct user_i387_struct* u_fpstate; /* Math Co-processor pointer. */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ + int u_debugreg[8]; +}; +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif /* _I386_USER_H */ diff --git a/include/linux/vm86.h b/include/asm-i386/vm86.h index ceb10358f..ac45e0909 100644 --- a/include/linux/vm86.h +++ b/include/asm-i386/vm86.h @@ -64,8 +64,6 @@ struct vm86_regs { long eax; long __null_ds; long __null_es; - long __null_fs; - long __null_gs; long orig_eax; long eip; unsigned short cs, __csh; diff --git a/include/asm-m68k/a.out.h b/include/asm-m68k/a.out.h new file mode 100644 index 000000000..eda166277 --- /dev/null +++ b/include/asm-m68k/a.out.h @@ -0,0 +1,26 @@ +#ifndef __M68K_A_OUT_H__ +#define __M68K_A_OUT_H__ + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#ifdef __KERNEL__ + +#define STACK_TOP TASK_SIZE + +#endif + +#endif /* __M68K_A_OUT_H__ */ diff --git a/include/asm-m68k/amifd.h b/include/asm-m68k/amifd.h new file mode 100644 index 000000000..0c13747c3 --- /dev/null +++ b/include/asm-m68k/amifd.h @@ -0,0 +1,57 @@ +#ifndef _ASM_M68K_AMIFD_H +#define _ASM_M68K_AMIFD_H + +/* Definitions for the Amiga floppy driver */ + +#include <linux/fd.h> + +#define FD_MAX_UNITS 4 + +struct fd_data_type { + char *name; /* description of data type */ + int sects; /* sectors per track */ +#ifdef __STDC__ + int (*read_fkt)(int, unsigned char *, unsigned long, int); + void (*write_fkt)(int, unsigned long, unsigned char *, int); +#else + int (*read_fkt)(); /* read whole track */ + void (*write_fkt)(); /* write whole track */ +#endif +}; + +#ifndef ASSEMBLER +/* +** Floppy type descriptions +*/ + +struct fd_drive_type { + unsigned long code; /* code returned from drive */ + char *name; /* description of drive */ + unsigned int tracks; /* number of tracks */ + unsigned int heads; /* number of heads */ + unsigned int read_size; /* raw read size for one track */ + unsigned int write_size; /* raw write size for one track */ + unsigned int sect_mult; /* sectors and gap multiplier (HD = 2) */ + unsigned int precomp1; /* start track for precomp 1 */ + unsigned int precomp2; /* start track for precomp 2 */ + unsigned int step_delay; /* time (in ms) for delay after step */ + unsigned int settle_time; /* time to settle after dir change */ + unsigned int side_time; /* time needed to change sides */ +}; + +struct amiga_floppy_struct { + struct fd_drive_type *type; /* type of floppy for this unit */ + struct fd_data_type *dtype; /* type of floppy for this unit */ + int track; /* current track (-1 == unknown) */ + + int blocks; /* total # blocks on disk */ + int sects; /* number of sectors per track */ + + int disk; /* disk in drive (-1 == unknown) */ + int motor; /* true when motor is at speed */ + int busy; /* true when drive is active */ + int status; /* current error code for unit */ +}; +#endif + +#endif diff --git a/include/asm-m68k/amifdreg.h b/include/asm-m68k/amifdreg.h new file mode 100644 index 000000000..76188bf48 --- /dev/null +++ b/include/asm-m68k/amifdreg.h @@ -0,0 +1,81 @@ +#ifndef _LINUX_AMIFDREG_H +#define _LINUX_AMIFDREG_H + +/* +** CIAAPRA bits (read only) +*/ + +#define DSKRDY (0x1<<5) /* disk ready when low */ +#define DSKTRACK0 (0x1<<4) /* head at track zero when low */ +#define DSKPROT (0x1<<3) /* disk protected when low */ +#define DSKCHANGE (0x1<<2) /* low when disk removed */ + +/* +** CIAAPRB bits (read/write) +*/ + +#define DSKMOTOR (0x1<<7) /* motor on when low */ +#define DSKSEL3 (0x1<<6) /* select drive 3 when low */ +#define DSKSEL2 (0x1<<5) /* select drive 2 when low */ +#define DSKSEL1 (0x1<<4) /* select drive 1 when low */ +#define DSKSEL0 (0x1<<3) /* select drive 0 when low */ +#define DSKSIDE (0x1<<2) /* side selection: 0 = upper, 1 = lower */ +#define DSKDIREC (0x1<<1) /* step direction: 0=in, 1=out (to trk 0) */ +#define DSKSTEP (0x1) /* pulse low to step head 1 track */ + +/* +** DSKBYTR bits (read only) +*/ + +#define DSKBYT (1<<15) /* register contains valid byte when set */ +#define DMAON (1<<14) /* disk DMA enabled */ +#define DISKWRITE (1<<13) /* disk write bit in DSKLEN enabled */ +#define WORDEQUAL (1<<12) /* DSKSYNC register match when true */ +/* bits 7-0 are data */ + +/* +** ADKCON/ADKCONR bits +*/ + +#ifndef SETCLR +#define ADK_SETCLR (1<<15) /* control bit */ +#endif +#define ADK_PRECOMP1 (1<<14) /* precompensation selection */ +#define ADK_PRECOMP0 (1<<13) /* 00=none, 01=140ns, 10=280ns, 11=500ns */ +#define ADK_MFMPREC (1<<12) /* 0=GCR precomp., 1=MFM precomp. */ +#define ADK_WORDSYNC (1<<10) /* enable DSKSYNC auto DMA */ +#define ADK_MSBSYNC (1<<9) /* when 1, enable sync on MSbit (for GCR) */ +#define ADK_FAST (1<<8) /* bit cell: 0=2us (GCR), 1=1us (MFM) */ + +/* +** DSKLEN bits +*/ + +#define DSKLEN_DMAEN (1<<15) +#define DSKLEN_WRITE (1<<14) + +/* +** INTENA/INTREQ bits +*/ + +#define DSKINDEX (0x1<<4) /* DSKINDEX bit */ + +/* +** Misc +*/ + +#define MFM_SYNC 0x4489 /* standard MFM sync value */ + +/* Values for FD_COMMAND */ +#define FD_RECALIBRATE 0x07 /* move to track 0 */ +#define FD_SEEK 0x0F /* seek track */ +#define FD_READ 0xE6 /* read with MT, MFM, SKip deleted */ +#define FD_WRITE 0xC5 /* write with MT, MFM */ +#define FD_SENSEI 0x08 /* Sense Interrupt Status */ +#define FD_SPECIFY 0x03 /* specify HUT etc */ +#define FD_FORMAT 0x4D /* format one track */ +#define FD_VERSION 0x10 /* get version code */ +#define FD_CONFIGURE 0x13 /* configure FIFO operation */ +#define FD_PERPENDICULAR 0x12 /* perpendicular r/w mode */ + +#endif /* _LINUX_AMIFDREG_H */ diff --git a/include/asm-m68k/amigahw.h b/include/asm-m68k/amigahw.h new file mode 100644 index 000000000..f8268fa7d --- /dev/null +++ b/include/asm-m68k/amigahw.h @@ -0,0 +1,247 @@ +/* +** asm-m68k/amigahw.h -- This header defines some macros and pointers for +** the various Amiga custom hardware registers. +** The naming conventions used here conform to those +** used in the Amiga Hardware Reference Manual, 3rd Edition +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created: 9/24/92 by Greg Harp +*/ + +#ifndef _ASMm68k_AMIGAHW_H_ +#define _ASMm68k_AMIGAHW_H_ + +struct CUSTOM { + u_short bltddat; + u_short dmaconr; + u_short vposr; + u_short vhposr; + u_short dskdatr; + u_short joy0dat; + u_short joy1dat; + u_short clxdat; + u_short adkconr; + u_short pot0dat; + u_short pot1dat; + u_short potgor; + u_short serdatr; + u_short dskbytr; + u_short intenar; + u_short intreqr; + u_char *dskptr; + u_short dsklen; + u_short dskdat; + u_short refptr; + u_short vposw; + u_short vhposw; + u_short copcon; + u_short serdat; + u_short serper; + u_short potgo; + u_short joytest; + u_short strequ; + u_short strvbl; + u_short strhor; + u_short strlong; + u_short bltcon0; + u_short bltcon1; + u_short bltafwm; + u_short bltalwm; + u_char *bltcpt; + u_char *bltbpt; + u_char *bltapt; + u_char *bltdpt; + u_short bltsize; + u_char pad2d; + u_char bltcon0l; + u_short bltsizv; + u_short bltsizh; + u_short bltcmod; + u_short bltbmod; + u_short bltamod; + u_short bltdmod; + u_short spare2[4]; + u_short bltcdat; + u_short bltbdat; + u_short bltadat; + u_short spare3[3]; + u_short deniseid; + u_short dsksync; + u_short *cop1lc; + u_short *cop2lc; + u_short copjmp1; + u_short copjmp2; + u_short copins; + u_short diwstrt; + u_short diwstop; + u_short ddfstrt; + u_short ddfstop; + u_short dmacon; + u_short clxcon; + u_short intena; + u_short intreq; + u_short adkcon; + struct { + u_short *audlc; + u_short audlen; + u_short audper; + u_short audvol; + u_short auddat; + u_short audspare[2]; + } aud[4]; + u_char *bplpt[8]; + u_short bplcon0; + u_short bplcon1; + u_short bplcon2; + u_short bplcon3; + u_short bpl1mod; + u_short bpl2mod; + u_short bplcon4; + u_short clxcon2; + u_short bpldat[8]; + u_char *sprpt[8]; + struct { + u_short pos; + u_short ctl; + u_short dataa; + u_short datab; + } spr[8]; + u_short color[32]; + u_short htotal; + u_short hsstop; + u_short hbstrt; + u_short hbstop; + u_short vtotal; + u_short vsstop; + u_short vbstrt; + u_short vbstop; + u_short sprhstrt; + u_short sprhstop; + u_short bplhstrt; + u_short bplhstop; + u_short hhposw; + u_short hhposr; + u_short beamcon0; + u_short hsstrt; + u_short vsstrt; + u_short hcenter; + u_short diwhigh; + u_short spare4[11]; + u_short fmode; +}; + +/* + * DMA register bits + */ +#define DMAF_SETCLR (0x8000) +#define DMAF_AUD0 (0x0001) +#define DMAF_AUD1 (0x0002) +#define DMAF_AUD2 (0x0004) +#define DMAF_AUD3 (0x0008) +#define DMAF_DISK (0x0010) +#define DMAF_SPRITE (0x0020) +#define DMAF_BLITTER (0x0040) +#define DMAF_COPPER (0x0080) +#define DMAF_RASTER (0x0100) +#define DMAF_MASTER (0x0200) +#define DMAF_BLITHOG (0x0400) +#define DMAF_BLTNZERO (0x2000) +#define DMAF_BLTDONE (0x4000) +#define DMAF_ALL (0x01FF) + +struct CIA { + u_char pra; char pad0[0xff]; + u_char prb; char pad1[0xff]; + u_char ddra; char pad2[0xff]; + u_char ddrb; char pad3[0xff]; + u_char talo; char pad4[0xff]; + u_char tahi; char pad5[0xff]; + u_char tblo; char pad6[0xff]; + u_char tbhi; char pad7[0xff]; + u_char todlo; char pad8[0xff]; + u_char todmid; char pad9[0xff]; + u_char todhi; char pada[0x1ff]; + u_char sdr; char padb[0xff]; + u_char icr; char padc[0xff]; + u_char cra; char padd[0xff]; + u_char crb; char pade[0xff]; +}; + +#if 1 +#define zTwoBase (0x80000000) +#define ZTWO_PADDR(x) (((unsigned long)(x))-zTwoBase) +#define ZTWO_VADDR(x) (((unsigned long)(x))+zTwoBase) +#else +#define zTwoBase 0 +#define ZTWO_PADDR(x) (x) +#define ZTWO_VADDR(x) (x) +#endif + +#define CUSTOM_PHYSADDR (0xdff000) +#define custom ((*(volatile struct CUSTOM *)(zTwoBase+CUSTOM_PHYSADDR))) + +#define CIAA_PHYSADDR (0xbfe001) +#define CIAB_PHYSADDR (0xbfd000) +#define ciaa ((*(volatile struct CIA *)(zTwoBase + CIAA_PHYSADDR))) +#define ciab ((*(volatile struct CIA *)(zTwoBase + CIAB_PHYSADDR))) + +#define CHIP_PHYSADDR (0x000000) +#define chipaddr ((unsigned long)(zTwoBase + CHIP_PHYSADDR)) +void amiga_chip_init (void); +void *amiga_chip_alloc (long size); +void amiga_chip_free (void *); +unsigned long amiga_chip_avail( void ); /*MILAN*/ + +struct tod3000 { + unsigned int :28, second2:4; /* lower digit */ + unsigned int :28, second1:4; /* upper digit */ + unsigned int :28, minute2:4; /* lower digit */ + unsigned int :28, minute1:4; /* upper digit */ + unsigned int :28, hour2:4; /* lower digit */ + unsigned int :28, hour1:4; /* upper digit */ + unsigned int :28, weekday:4; + unsigned int :28, day2:4; /* lower digit */ + unsigned int :28, day1:4; /* upper digit */ + unsigned int :28, month2:4; /* lower digit */ + unsigned int :28, month1:4; /* upper digit */ + unsigned int :28, year2:4; /* lower digit */ + unsigned int :28, year1:4; /* upper digit */ + unsigned int :28, cntrl1:4; /* control-byte 1 */ + unsigned int :28, cntrl2:4; /* control-byte 2 */ + unsigned int :28, cntrl3:4; /* control-byte 3 */ +}; +#define TOD3000_CNTRL1_HOLD 0 +#define TOD3000_CNTRL1_FREE 9 +#define TOD_3000 ((struct tod3000 *)(zTwoBase+0xDC0000)) + +struct tod2000 { + unsigned int :28, second2:4; /* lower digit */ + unsigned int :28, second1:4; /* upper digit */ + unsigned int :28, minute2:4; /* lower digit */ + unsigned int :28, minute1:4; /* upper digit */ + unsigned int :28, hour2:4; /* lower digit */ + unsigned int :28, hour1:4; /* upper digit */ + unsigned int :28, day2:4; /* lower digit */ + unsigned int :28, day1:4; /* upper digit */ + unsigned int :28, month2:4; /* lower digit */ + unsigned int :28, month1:4; /* upper digit */ + unsigned int :28, year2:4; /* lower digit */ + unsigned int :28, year1:4; /* upper digit */ + unsigned int :28, weekday:4; + unsigned int :28, cntrl1:4; /* control-byte 1 */ + unsigned int :28, cntrl2:4; /* control-byte 2 */ + unsigned int :28, cntrl3:4; /* control-byte 3 */ +}; + +#define TOD2000_CNTRL1_HOLD (1<<0) +#define TOD2000_CNTRL1_BUSY (1<<1) +#define TOD2000_CNTRL3_24HMODE (1<<2) +#define TOD2000_HOUR1_PM (1<<2) +#define TOD_2000 ((struct tod2000 *)(zTwoBase+0xDC0000)) + +#endif /* asm-m68k/amigahw.h */ diff --git a/include/asm-m68k/amigaints.h b/include/asm-m68k/amigaints.h new file mode 100644 index 000000000..0c225ee7c --- /dev/null +++ b/include/asm-m68k/amigaints.h @@ -0,0 +1,123 @@ +/* +** amigaints.h -- Amiga Linux interrupt handling structs and prototypes +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created 10/2/92 by Greg Harp +*/ + +#ifndef _ASMm68k_AMIGAINTS_H_ +#define _ASMm68k_AMIGAINTS_H_ + +/* +** Amiga Interrupt sources. +** +*/ + +#define AMI_IRQS (24) +#define AMI_STD_IRQS (14) +#define CIA_IRQS (5) + +/* vertical blanking interrupt */ +#define IRQ_AMIGA_VERTB (IRQ_MACHSPEC | 0) + +/* copper interrupt */ +#define IRQ_AMIGA_COPPER (IRQ_MACHSPEC | 1) + +/* Audio interrupts */ +#define IRQ_AMIGA_AUD0 (IRQ_MACHSPEC | 2) +#define IRQ_AMIGA_AUD1 (IRQ_MACHSPEC | 3) +#define IRQ_AMIGA_AUD2 (IRQ_MACHSPEC | 4) +#define IRQ_AMIGA_AUD3 (IRQ_MACHSPEC | 5) + +/* Blitter done interrupt */ +#define IRQ_AMIGA_BLIT (IRQ_MACHSPEC | 6) + +/* floppy disk interrupts */ +#define IRQ_AMIGA_DSKSYN (IRQ_MACHSPEC | 7) +#define IRQ_AMIGA_DSKBLK (IRQ_MACHSPEC | 8) + +/* builtin serial port interrupts */ +#define IRQ_AMIGA_RBF (IRQ_MACHSPEC | 9) +#define IRQ_AMIGA_TBE (IRQ_MACHSPEC | 10) + +/* software interrupts */ +#define IRQ_AMIGA_SOFT (IRQ_MACHSPEC | 11) + +/* interrupts from external hardware */ +#define IRQ_AMIGA_PORTS (IRQ_MACHSPEC | 12) +#define IRQ_AMIGA_EXTER (IRQ_MACHSPEC | 13) + +/* CIA interrupt sources */ +#define IRQ_AMIGA_CIAA (IRQ_MACHSPEC | 14) +#define IRQ_AMIGA_CIAA_TA (IRQ_MACHSPEC | 14) +#define IRQ_AMIGA_CIAA_TB (IRQ_MACHSPEC | 15) +#define IRQ_AMIGA_CIAA_ALRM (IRQ_MACHSPEC | 16) +#define IRQ_AMIGA_CIAA_SP (IRQ_MACHSPEC | 17) +#define IRQ_AMIGA_CIAA_FLG (IRQ_MACHSPEC | 18) +#define IRQ_AMIGA_CIAB (IRQ_MACHSPEC | 19) +#define IRQ_AMIGA_CIAB_TA (IRQ_MACHSPEC | 19) +#define IRQ_AMIGA_CIAB_TB (IRQ_MACHSPEC | 20) +#define IRQ_AMIGA_CIAB_ALRM (IRQ_MACHSPEC | 21) +#define IRQ_AMIGA_CIAB_SP (IRQ_MACHSPEC | 22) +#define IRQ_AMIGA_CIAB_FLG (IRQ_MACHSPEC | 23) + +#define IRQ_FLOPPY IRQ_AMIGA_DSKBLK + +/* INTREQR masks */ +#define IRQ1_MASK 0x0007 /* INTREQR mask for IRQ 1 */ +#define IRQ2_MASK 0x0008 /* INTREQR mask for IRQ 2 */ +#define IRQ3_MASK 0x0070 /* INTREQR mask for IRQ 3 */ +#define IRQ4_MASK 0x0780 /* INTREQR mask for IRQ 4 */ +#define IRQ5_MASK 0x1800 /* INTREQR mask for IRQ 5 */ +#define IRQ6_MASK 0x2000 /* INTREQR mask for IRQ 6 */ +#define IRQ7_MASK 0x4000 /* INTREQR mask for IRQ 7 */ + +#define IF_SETCLR 0x8000 /* set/clr bit */ +#define IF_INTEN 0x4000 /* master interrupt bit in INT* registers */ +#define IF_EXTER 0x2000 /* external level 6 and CIA B interrupt */ +#define IF_DSKSYN 0x1000 /* disk sync interrupt */ +#define IF_RBF 0x0800 /* serial receive buffer full interrupt */ +#define IF_AUD3 0x0400 /* audio channel 3 done interrupt */ +#define IF_AUD2 0x0200 /* audio channel 2 done interrupt */ +#define IF_AUD1 0x0100 /* audio channel 1 done interrupt */ +#define IF_AUD0 0x0080 /* audio channel 0 done interrupt */ +#define IF_BLIT 0x0040 /* blitter done interrupt */ +#define IF_VERTB 0x0020 /* vertical blanking interrupt */ +#define IF_COPER 0x0010 /* copper interrupt */ +#define IF_PORTS 0x0008 /* external level 2 and CIA A interrupt */ +#define IF_SOFT 0x0004 /* software initiated interrupt */ +#define IF_DSKBLK 0x0002 /* diskblock DMA finished */ +#define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */ + +struct irq_server { + unsigned short count, reentrance; +}; + +extern void amiga_do_irq(int irq, struct pt_regs *fp); +extern void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server); + +/* CIA interrupt control register bits */ + +#define CIA_ICR_TA 0x01 +#define CIA_ICR_TB 0x02 +#define CIA_ICR_ALRM 0x04 +#define CIA_ICR_SP 0x08 +#define CIA_ICR_FLG 0x10 +#define CIA_ICR_ALL 0x1f +#define CIA_ICR_SETCLR 0x80 + +/* to access the interrupt control registers of CIA's use only +** these functions, they behave exactly like the amiga os routines +*/ + +extern struct ciabase ciaa_base, ciab_base; + +extern unsigned char cia_set_irq(struct ciabase *base, unsigned char mask); +extern unsigned char cia_able_irq(struct ciabase *base, unsigned char mask); + +#endif /* asm-m68k/amigaints.h */ diff --git a/include/asm-m68k/amigamouse.h b/include/asm-m68k/amigamouse.h new file mode 100644 index 000000000..7f90cff41 --- /dev/null +++ b/include/asm-m68k/amigamouse.h @@ -0,0 +1,26 @@ +#ifndef _ASMm68k_AMIGAMOUSE_H +#define _ASMm68k_AMIGAMOUSE_H + +/* + * linux/include/asm-m68k/amigamouse.h: header file for Amiga Mouse driver + * by Michael Rausch + */ + +/* +#define MSE_INT_OFF() outb(MSE_DISABLE_INTERRUPTS, MSE_CONTROL_PORT) +#define MSE_INT_ON() outb(MSE_ENABLE_INTERRUPTS, MSE_CONTROL_PORT) +*/ + +struct mouse_status { + unsigned char buttons; + unsigned char latch_buttons; + int dx; + int dy; + int present; + int ready; + int active; + struct wait_queue *wait; + struct fasync_struct *fasyncptr; +}; + +#endif diff --git a/include/asm-m68k/amigardb.h b/include/asm-m68k/amigardb.h new file mode 100644 index 000000000..57032469d --- /dev/null +++ b/include/asm-m68k/amigardb.h @@ -0,0 +1,126 @@ +#ifndef _LINUX_AMIGARDB_H +#define _LINUX_AMIGARDB_H 1 + +#define ULONG u_long +#define LONG long +#define UBYTE u_char + +/* definitions for the Amiga RigidDiskBlock layout, which always starts in + cylinder 0 of a medium. Taken from page 254f of the RKM: Devices */ + +struct RigidDiskBlock { + ULONG rdb_ID; /* 4 character identifier */ + ULONG rdb_SummedLongs; /* size of this checksummed structure */ + LONG rdb_ChkSum; /* block checksum (longword sum to zero) */ + ULONG rdb_HostID; /* SCSI Target ID of host */ + ULONG rdb_BlockBytes; /* size of disk blocks */ + ULONG rdb_Flags; /* see below for defines */ + /* block list heads */ + ULONG rdb_BadBlockList; /* optional bad block list */ + ULONG rdb_PartitionList; /* optional first partition block */ + ULONG rdb_FileSysHeaderList; /* optional file system header block */ + ULONG rdb_DriveInit; /* optional drive-specific init code */ + /* DriveInit(lun,rdb,ior): "C" stk & d0/a0/a1 */ + ULONG rdb_Reserved1[6]; /* set to $ffffffff */ + /* physical drive characteristics */ + ULONG rdb_Cylinders; /* number of drive cylinders */ + ULONG rdb_Sectors; /* sectors per track */ + ULONG rdb_Heads; /* number of drive heads */ + ULONG rdb_Interleave; /* interleave */ + ULONG rdb_Park; /* landing zone cylinder */ + ULONG rdb_Reserved2[3]; + ULONG rdb_WritePreComp; /* starting cylinder: write precompensation */ + ULONG rdb_ReducedWrite; /* starting cylinder: reduced write current */ + ULONG rdb_StepRate; /* drive step rate */ + ULONG rdb_Reserved3[5]; + /* logical drive characteristics */ + ULONG rdb_RDBBlocksLo; /* low block of range reserved for hardblocks */ + ULONG rdb_RDBBlocksHi; /* high block of range for these hardblocks */ + ULONG rdb_LoCylinder; /* low cylinder of partitionable disk area */ + ULONG rdb_HiCylinder; /* high cylinder of partitionable data area */ + ULONG rdb_CylBlocks; /* number of blocks available per cylinder */ + ULONG rdb_AutoParkSeconds; /* zero for no auto park */ + ULONG rdb_HighRDSKBlock; /* highest block used by RDSK */ + /* (not including replacement bad blocks) */ + ULONG rdb_Reserved4; + /* drive identification */ + char rdb_DiskVendor[8]; + char rdb_DiskProduct[16]; + char rdb_DiskRevision[4]; + char rdb_ControllerVendor[8]; + char rdb_ControllerProduct[16]; + char rdb_ControllerRevision[4]; + ULONG rdb_Reserved5[10]; +}; + +#define IDNAME_RIGIDDISK 0x5244534B /* 'RDSK' */ + +#define RDB_LOCATION_LIMIT 16 + +#define RDBFB_LAST 0 /* no disks exist to be configured after */ +#define RDBFF_LAST 0x01L /* this one on this controller */ +#define RDBFB_LASTLUN 1 /* no LUNs exist to be configured greater */ +#define RDBFF_LASTLUN 0x02L /* than this one at this SCSI Target ID */ +#define RDBFB_LASTTID 2 /* no Target IDs exist to be configured */ +#define RDBFF_LASTTID 0x04L /* greater than this one on this SCSI bus */ +#define RDBFB_NORESELECT 3 /* don't bother trying to perform reselection */ +#define RDBFF_NORESELECT 0x08L /* when talking to this drive */ +#define RDBFB_DISKID 4 /* rdb_Disk... identification valid */ +#define RDBFF_DISKID 0x10L +#define RDBFB_CTRLRID 5 /* rdb_Controller... identification valid */ +#define RDBFF_CTRLRID 0x20L + /* added 7/20/89 by commodore: */ +#define RDBFB_SYNCH 6 /* drive supports scsi synchronous mode */ +#define RDBFF_SYNCH 0x40L /* CAN BE DANGEROUS TO USE IF IT DOESN'T! */ + +struct PartitionBlock { + ULONG pb_ID; /* 4 character identifier */ + ULONG pb_SummedLongs; /* size of this checksummed structure */ + LONG pb_ChkSum; /* block checksum (longword sum to zero) */ + ULONG pb_HostID; /* SCSI Target ID of host */ + ULONG pb_Next; /* block number of the next PartitionBlock */ + ULONG pb_Flags; /* see below for defines */ + ULONG pb_Reserved1[2]; + ULONG pb_DevFlags; /* preferred flags for OpenDevice */ + UBYTE pb_DriveName[32]; /* preferred DOS device name: BSTR form */ + /* (not used if this name is in use) */ + ULONG pb_Reserved2[15]; /* filler to 32 longwords */ + ULONG pb_Environment[17]; /* environment vector for this partition */ + ULONG pb_EReserved[15]; /* reserved for future environment vector */ +}; + +#define IDNAME_PARTITION 0x50415254 /* 'PART' */ + +#define PBFB_BOOTABLE 0 /* this partition is intended to be bootable */ +#define PBFF_BOOTABLE 1L /* (expected directories and files exist) */ +#define PBFB_NOMOUNT 1 /* do not mount this partition (e.g. manually */ +#define PBFF_NOMOUNT 2L /* mounted, but space reserved here) */ + +/* this is from <dos/filehandler.h> */ + +#define DE_TABLESIZE 0 /* minimum value is 11 (includes NumBuffers) */ +#define DE_SIZEBLOCK 1 /* in longwords: standard value is 128 */ +#define DE_SECORG 2 /* not used; must be 0 */ +#define DE_NUMHEADS 3 /* # of heads (surfaces). drive specific */ +#define DE_SECSPERBLK 4 /* not used; must be 1 */ +#define DE_BLKSPERTRACK 5 /* blocks per track. drive specific */ +#define DE_RESERVEDBLKS 6 /* unavailable blocks at start. usually 2 */ +#define DE_PREFAC 7 /* not used; must be 0 */ +#define DE_INTERLEAVE 8 /* usually 0 */ +#define DE_LOWCYL 9 /* starting cylinder. typically 0 */ +#define DE_UPPERCYL 10 /* max cylinder. drive specific */ +#define DE_NUMBUFFERS 11 /* starting # of buffers. typically 5 */ +#define DE_MEMBUFTYPE 12 /* type of mem to allocate for buffers. */ +#define DE_BUFMEMTYPE 12 /* same as above, better name + * 1 is public, 3 is chip, 5 is fast */ +#define DE_MAXTRANSFER 13 /* Max number bytes to transfer at a time */ +#define DE_MASK 14 /* Address Mask to block out certain memory */ +#define DE_BOOTPRI 15 /* Boot priority for autoboot */ +#define DE_DOSTYPE 16 /* ASCII (HEX) string showing filesystem type; + * 0X444F5300 is old filesystem, + * 0X444F5301 is fast file system */ +#define DE_BAUD 17 /* Baud rate for serial handler */ +#define DE_CONTROL 18 /* Control word for handler/filesystem */ +#define DE_BOOTBLOCKS 19 /* Number of blocks containing boot code */ + +#endif /* _LINUX_AMIGARDB_H */ diff --git a/include/asm-m68k/amigatypes.h b/include/asm-m68k/amigatypes.h new file mode 100644 index 000000000..21a80d9dc --- /dev/null +++ b/include/asm-m68k/amigatypes.h @@ -0,0 +1,59 @@ +/* +** linux/amigatypes.h -- Types used in Amiga Linux kernel source +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created 09/29/92 by Greg Harp +** +** Moved all Zorro definitions to asm/zorro.h which is where they +** really belong - 24/11/95 Jes Sorensen +*/ + +#ifndef _LINUX_AMIGATYPES_H_ +#define _LINUX_AMIGATYPES_H_ + +#ifdef __KERNEL__ /* only if compiling the kernel */ +#include <linux/types.h> +#endif + +/* + * Different models of Amiga + */ +#define AMI_UNKNOWN (0) +#define AMI_500 (1) +#define AMI_500PLUS (2) +#define AMI_600 (3) +#define AMI_1000 (4) +#define AMI_1200 (5) +#define AMI_2000 (6) +#define AMI_2500 (7) +#define AMI_3000 (8) +#define AMI_3000T (9) +#define AMI_3000PLUS (10) +#define AMI_4000 (11) +#define AMI_4000T (12) +#define AMI_CDTV (13) +#define AMI_CD32 (14) +#define AMI_DRACO (15) + +/* + * chipsets + */ +#define CS_STONEAGE (0) +#define CS_OCS (1) +#define CS_ECS (2) +#define CS_AGA (3) + +/* + * Amiga clocks + */ + +extern u_long amiga_masterclock; /* 28 MHz */ +extern u_long amiga_colorclock; /* 3.5 MHz */ +#define amiga_eclock boot_info.bi_amiga.eclock /* 700 kHz */ + +#endif /* asm-m68k/amigatypes.h */ diff --git a/include/asm-m68k/amihdreg.h b/include/asm-m68k/amihdreg.h new file mode 100644 index 000000000..8e5a0d34d --- /dev/null +++ b/include/asm-m68k/amihdreg.h @@ -0,0 +1,31 @@ +#ifndef _LINUX_AMIHDREG_H +#define _LINUX_AMIHDREG_H + +/* + * This file contains some defines for the Amiga IDE hd controller. + * Various sources. Check out some definitions (see comments with + * a ques). + */ + +#define IDE_DISABLE_IRQ 0x02 +#define IDE_ENABLE_IRQ 0x00 + +/* Bases of the hard drive controller */ +#define HD_BASE_A4000 0xdd2020 +#define HD_BASE_A1200 0xda0000 + +/* Offsets from one of the above bases */ +#define AMI_HD_ERROR (0x06) /* see err-bits */ +#define AMI_HD_NSECTOR (0x0a) /* nr of sectors to read/write */ +#define AMI_HD_SECTOR (0x0e) /* starting sector */ +#define AMI_HD_LCYL (0x12) /* starting cylinder */ +#define AMI_HD_HCYL (0x16) /* high byte of starting cyl */ +#define AMI_HD_SELECT (0x1a) /* 101dhhhh , d=drive, hhhh=head */ +#define AMI_HD_STATUS (0x1e) /* see status-bits */ +#define AMI_HD_CMD (0x101a) + +/* These are at different offsets from the base */ +#define HD_A4000_IRQ (0xdd3020) /* MSB = 1, Harddisk is source of interrupt */ +#define HD_A1200_IRQ (0xda9000) /* MSB = 1, Harddisk is source of interrupt */ + +#endif diff --git a/include/asm-m68k/atafd.h b/include/asm-m68k/atafd.h new file mode 100644 index 000000000..8456889ee --- /dev/null +++ b/include/asm-m68k/atafd.h @@ -0,0 +1,12 @@ +#ifndef _ASM_M68K_FD_H +#define _ASM_M68K_FD_H + +/* Definitions for the Atari Floppy driver */ + +struct atari_format_descr { + int track; /* to be formatted */ + int head; /* "" "" */ + int sect_offset; /* offset of first sector */ +}; + +#endif diff --git a/include/asm-m68k/atafdreg.h b/include/asm-m68k/atafdreg.h new file mode 100644 index 000000000..8c4a8d5b6 --- /dev/null +++ b/include/asm-m68k/atafdreg.h @@ -0,0 +1,79 @@ +#ifndef _LINUX_FDREG_H +#define _LINUX_FDREG_H + +/* +** WD1772 stuff + */ + +/* register codes */ + +#define FDCSELREG_STP (0x80) /* command/status register */ +#define FDCSELREG_TRA (0x82) /* track register */ +#define FDCSELREG_SEC (0x84) /* sector register */ +#define FDCSELREG_DTA (0x86) /* data register */ + +/* register names for FDC_READ/WRITE macros */ + +#define FDCREG_CMD 0 +#define FDCREG_STATUS 0 +#define FDCREG_TRACK 2 +#define FDCREG_SECTOR 4 +#define FDCREG_DATA 6 + +/* command opcodes */ + +#define FDCCMD_RESTORE (0x00) /* - */ +#define FDCCMD_SEEK (0x10) /* | */ +#define FDCCMD_STEP (0x20) /* | TYP 1 Commands */ +#define FDCCMD_STIN (0x40) /* | */ +#define FDCCMD_STOT (0x60) /* - */ +#define FDCCMD_RDSEC (0x80) /* - TYP 2 Commands */ +#define FDCCMD_WRSEC (0xa0) /* - " */ +#define FDCCMD_RDADR (0xc0) /* - */ +#define FDCCMD_RDTRA (0xe0) /* | TYP 3 Commands */ +#define FDCCMD_WRTRA (0xf0) /* - */ +#define FDCCMD_FORCI (0xd0) /* - TYP 4 Command */ + +/* command modifier bits */ + +#define FDCCMDADD_SR6 (0x00) /* step rate settings */ +#define FDCCMDADD_SR12 (0x01) +#define FDCCMDADD_SR2 (0x02) +#define FDCCMDADD_SR3 (0x03) +#define FDCCMDADD_V (0x04) /* verify */ +#define FDCCMDADD_H (0x08) /* wait for spin-up */ +#define FDCCMDADD_U (0x10) /* update track register */ +#define FDCCMDADD_M (0x10) /* multiple sector access */ +#define FDCCMDADD_E (0x04) /* head settling flag */ +#define FDCCMDADD_P (0x02) /* precompensation off */ +#define FDCCMDADD_A0 (0x01) /* DAM flag */ + +/* status register bits */ + +#define FDCSTAT_MOTORON (0x80) /* motor on */ +#define FDCSTAT_WPROT (0x40) /* write protected (FDCCMD_WR*) */ +#define FDCSTAT_SPINUP (0x20) /* motor speed stable (Type I) */ +#define FDCSTAT_DELDAM (0x20) /* sector has deleted DAM (Type II+III) */ +#define FDCSTAT_RECNF (0x10) /* record not found */ +#define FDCSTAT_CRC (0x08) /* CRC error */ +#define FDCSTAT_TR00 (0x04) /* Track 00 flag (Type I) */ +#define FDCSTAT_LOST (0x04) /* Lost Data (Type II+III) */ +#define FDCSTAT_IDX (0x02) /* Index status (Type I) */ +#define FDCSTAT_DRQ (0x02) /* DRQ status (Type II+III) */ +#define FDCSTAT_BUSY (0x01) /* FDC is busy */ + + +/* PSG Port A Bit Nr 0 .. Side Sel .. 0 -> Side 1 1 -> Side 2 */ +#define DSKSIDE (0x01) + +#define DSKDRVNONE (0x06) +#define DSKDRV0 (0x02) +#define DSKDRV1 (0x04) + +/* step rates */ +#define FDCSTEP_6 0x00 +#define FDCSTEP_12 0x01 +#define FDCSTEP_2 0x02 +#define FDCSTEP_3 0x03 + +#endif diff --git a/include/asm-m68k/atari_SCCserial.h b/include/asm-m68k/atari_SCCserial.h new file mode 100644 index 000000000..fc08d4009 --- /dev/null +++ b/include/asm-m68k/atari_SCCserial.h @@ -0,0 +1,60 @@ +#ifndef _ATARI_SCCSERIAL_H +#define _ATARI_SCCSERIAL_H + +/* Special configuration ioctls for the Atari SCC5380 Serial + * Communications Controller + */ + +/* ioctl command codes */ + +#define TIOCGATSCC 0x54c0 /* get SCC configuration */ +#define TIOCSATSCC 0x54c1 /* set SCC configuration */ +#define TIOCDATSCC 0x54c2 /* reset configuration to defaults */ + +/* Clock sources */ + +#define CLK_RTxC 0 +#define CLK_TRxC 1 +#define CLK_PCLK 2 + +/* baud_bases for the common clocks in the Atari. These are the real + * frequencies divided by 16. + */ + +#define SCC_BAUD_BASE_TIMC 19200 /* 0.3072 MHz from TT-MFP, Timer C */ +#define SCC_BAUD_BASE_BCLK 153600 /* 2.4576 MHz */ +#define SCC_BAUD_BASE_PCLK4 229500 /* 3.6720 MHz */ +#define SCC_BAUD_BASE_PCLK 503374 /* 8.0539763 MHz */ +#define SCC_BAUD_BASE_NONE 0 /* for not connected or unused + * clock sources */ + +/* The SCC configuration structure */ + +struct atari_SCCserial { + unsigned RTxC_base; /* base_baud of RTxC */ + unsigned TRxC_base; /* base_baud of TRxC */ + unsigned PCLK_base; /* base_baud of PCLK, for both channels! */ + struct { + unsigned clksrc; /* CLK_RTxC, CLK_TRxC or CLK_PCLK */ + unsigned divisor; /* divisor for base baud, valid values: + * see below */ + } baud_table[17]; /* For 50, 75, 110, 135, 150, 200, 300, + * 600, 1200, 1800, 2400, 4800, 9600, + * 19200, 38400, 57600 and 115200 bps. The + * last two could be replaced by other + * rates > 38400 if they're not possible. + */ +}; + +/* The following divisors are valid: + * + * - CLK_RTxC: 1 or even (1, 2 and 4 are the direct modes, > 4 use + * the BRG) + * + * - CLK_TRxC: 1, 2 or 4 (no BRG, only direct modes possible) + * + * - CLK_PCLK: >= 4 and even (no direct modes, only BRG) + * + */ + +#endif /* _ATARI_SCCSERIAL_H */ diff --git a/include/asm-m68k/atari_SLM.h b/include/asm-m68k/atari_SLM.h new file mode 100644 index 000000000..42f4fcdd8 --- /dev/null +++ b/include/asm-m68k/atari_SLM.h @@ -0,0 +1,28 @@ + +#ifndef _ATARI_SLM_H +#define _ATARI_SLM_H + +/* Atari SLM laser printer specific ioctls */ + +#define SLMIOGSTAT 0xa100 +#define SLMIOGPSIZE 0xa101 +#define SLMIOGMFEED 0xa102 + +#define SLMIORESET 0xa140 + +#define SLMIOSPSIZE 0xa181 +#define SLMIOSMFEED 0xa182 + +/* Status returning structure (SLMIOGSTAT) */ +struct SLM_status { + int stat; /* numeric status code */ + char str[40]; /* status string */ +}; + +/* Paper size structure (SLMIO[GS]PSIZE) */ +struct SLM_paper_size { + int width; + int height; +}; + +#endif /* _ATARI_SLM_H */ diff --git a/include/asm-m68k/atari_acsi.h b/include/asm-m68k/atari_acsi.h new file mode 100644 index 000000000..31a882fbf --- /dev/null +++ b/include/asm-m68k/atari_acsi.h @@ -0,0 +1,37 @@ +#ifndef _ASM_ATARI_ACSI_H +#define _ASM_ATARI_ACSI_H + +/* Functions exported by drivers/block/acsi.c */ + +void acsi_delay_start( void ); +void acsi_delay_end( long usec ); +int acsi_wait_for_IRQ( unsigned timeout ); +int acsi_wait_for_noIRQ( unsigned timeout ); +int acsicmd_nodma( const char *cmd, int enable); +int acsi_getstatus( void ); +int acsi_extstatus( char *buffer, int cnt ); +void acsi_end_extstatus( void ); +int acsi_extcmd( unsigned char *buffer, int cnt ); + +/* The ACSI buffer is guarantueed to reside in ST-RAM and may be used by other + * drivers that work on the ACSI bus, too. It's data are valid only as long as + * the ST-DMA is locked. */ +extern char *acsi_buffer; +extern unsigned long phys_acsi_buffer; + +/* Utility macros */ + +/* Send one data byte over the bus and set mode for next operation + * with one move.l -- Atari recommends this... + */ + +#define DMA_LONG_WRITE(data,mode) \ + do { \ + *((unsigned long *)&dma_wd.fdc_acces_seccount) = \ + ((data)<<16) | (mode); \ + } while(0) + +#define ENABLE_IRQ() atari_turnon_irq( IRQ_MFP_ACSI ) +#define DISABLE_IRQ() atari_turnoff_irq( IRQ_MFP_ACSI ) + +#endif /* _ASM_ATARI_ACSI_H */ diff --git a/include/asm-m68k/atari_joystick.h b/include/asm-m68k/atari_joystick.h new file mode 100644 index 000000000..bdea2f486 --- /dev/null +++ b/include/asm-m68k/atari_joystick.h @@ -0,0 +1,22 @@ +#ifndef _LINUX_ATARI_JOYSTICK_H +#define _LINUX_ATARI_JOYSTICK_H + +/* + * linux/include/linux/atari_joystick.h + * header file for Atari Joystick driver + * by Robert de Vries (robert@and.nl) on 19Jul93 + */ + +void atari_joystick_interrupt(char*); +int atari_joystick_init(void); +extern int atari_mouse_buttons; + +struct joystick_status { + char fire; + char dir; + int ready; + int active; + struct wait_queue *wait; +}; + +#endif diff --git a/include/asm-m68k/atari_mouse.h b/include/asm-m68k/atari_mouse.h new file mode 100644 index 000000000..003bf2b21 --- /dev/null +++ b/include/asm-m68k/atari_mouse.h @@ -0,0 +1,20 @@ +#ifndef _LINUX_ATARI_MOUSE_H +#define _LINUX_ATARI_MOUSE_H + +/* + * linux/include/linux/atari_mouse.h + * header file for Atari Mouse driver + * by Robert de Vries (robert@and.nl) on 19Jul93 + */ + +struct mouse_status { + char buttons; + short dx; + short dy; + int ready; + int active; + struct wait_queue *wait; + struct fasync_struct *fasyncptr; +}; + +#endif diff --git a/include/asm-m68k/atari_rootsec.h b/include/asm-m68k/atari_rootsec.h new file mode 100644 index 000000000..2e6390f1d --- /dev/null +++ b/include/asm-m68k/atari_rootsec.h @@ -0,0 +1,34 @@ +#ifndef _LINUX_ATARI_ROOTSEC_H +#define _LINUX_ATARI_ROOTSEC_H + +/* + * linux/include/linux/atari_rootsec.h + * definitions for Atari Rootsector layout + * by Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de) + * + * modified for ICD/Supra partitioning scheme restricted to at most 12 + * partitions + * by Guenther Kelleter (guenther@pool.informatik.rwth-aachen.de) + */ + +struct partition_info +{ + u_char flg; /* bit 0: active; bit 7: bootable */ + char id[3]; /* "GEM", "BGM", "XGM", or other */ + u_long st; /* start of partition */ + u_long siz; /* length of partition */ +}; + +struct rootsector +{ + char unused[0x156]; /* room for boot code */ + struct partition_info icdpart[8]; /* info for ICD-partitions 5..12 */ + char unused2[0xc]; + u_long hd_siz; /* size of disk in blocks */ + struct partition_info part[4]; + u_long bsl_st; /* start of bad sector list */ + u_long bsl_cnt; /* length of bad sector list */ + u_short checksum; /* checksum for bootable disks */ +} __attribute__((__packed__)); + +#endif /* _LINUX_ATARI_ROOTSEC_H */ diff --git a/include/asm-m68k/atari_stdma.h b/include/asm-m68k/atari_stdma.h new file mode 100644 index 000000000..ddc92e199 --- /dev/null +++ b/include/asm-m68k/atari_stdma.h @@ -0,0 +1,22 @@ + +#ifndef _atari_stdma_h +#define _atari_stdma_h + + +#include <asm/irq.h> + + +/***************************** Prototypes *****************************/ + +void stdma_lock(void (*handler)(int, void *, struct pt_regs *), void *data); +void stdma_release( void ); +int stdma_others_waiting( void ); +int stdma_islocked( void ); +void *stdma_locked_by( void ); +void stdma_init( void ); + +/************************* End of Prototypes **************************/ + + + +#endif /* _atari_stdma_h */ diff --git a/include/asm-m68k/atarihdreg.h b/include/asm-m68k/atarihdreg.h new file mode 100644 index 000000000..bf0846001 --- /dev/null +++ b/include/asm-m68k/atarihdreg.h @@ -0,0 +1,24 @@ +#ifndef _LINUX_ATAHDREG_H +#define _LINUX_ATAHDREG_H + +/* + * This file contains some defines for the Falcon IDE hd controller. + * Various sources. Check out some definitions (see comments with + * a ques). + */ + +#define ATA_HD_BASE 0xfff00000 + +#define ATA_HD_DATA 0x00 /* _CTL when writing */ +#define ATA_HD_ERROR 0x05 /* see err-bits */ +#define ATA_HD_NSECTOR 0x09 /* nr of sectors to read/write */ +#define ATA_HD_SECTOR 0x0d /* starting sector */ +#define ATA_HD_LCYL 0x11 /* starting cylinder */ +#define ATA_HD_HCYL 0x15 /* high byte of starting cyl */ +#define ATA_HD_CURRENT 0x19 /* 101dhhhh , d=drive, hhhh=head */ +#define ATA_HD_STATUS 0x1d /* see status-bits */ + +#define ATA_HD_CMD 0x39 +#define ATA_HD_ALTSTATUS 0x39 /* same as HD_STATUS but doesn't clear irq */ + +#endif /* _LINUX_ATAHDREG_H */ diff --git a/include/asm-m68k/atarihw.h b/include/asm-m68k/atarihw.h new file mode 100644 index 000000000..3fccb4775 --- /dev/null +++ b/include/asm-m68k/atarihw.h @@ -0,0 +1,708 @@ +/* +** linux/atarihw.h -- This header defines some macros and pointers for +** the various Atari custom hardware registers. +** +** Copyright 1994 by Bj”rn Brauel +** +** 5/1/94 Roman Hodek: +** Added definitions for TT specific chips. +** +** 1996-09-13 lars brinkhoff <f93labr@dd.chalmers.se>: +** Finally added definitions for the matrix/codec and the DSP56001 host +** interface. +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +*/ + +#ifndef _LINUX_ATARIHW_H_ +#define _LINUX_ATARIHW_H_ + +#include <linux/types.h> + +/* Reading the MFP port register gives a machine independent delay, since the + * MFP always has a 8 MHz clock. This avoids problems with the varying length + * of nops on various machines. Somebody claimed that the tstb takes 600 ns. + */ +#define MFPDELAY() \ + __asm__ __volatile__ ( "tstb %0" : : "m" (mfp.par_dt_reg) : "cc" ); + +/* Memory used for screen ram and stdma buffers */ +void atari_stram_init (void); +void *atari_stram_alloc (long size, unsigned long *start_mem ); +void atari_stram_free (void *); + +extern int is_medusa; + +/* Do cache push/invalidate for DMA read/write. This function obeys the + * snooping on some machines (Medusa) and processors: The Medusa itself can + * snoop, but only the '040 can source data from its cache to DMA writes i.e., + * reads from memory). Both '040 and '060 invalidate cache entries on snooped + * DMA reads (i.e., writes to memory). + */ + +#include <linux/mm.h> +#include <asm/pgtable.h> + +static inline void dma_cache_maintenance( unsigned long paddr, + unsigned long len, + int writeflag ) + +{ + if (writeflag) { + if (!is_medusa || CPU_IS_060) + cache_push( paddr, len ); + } + else { + if (!is_medusa) + cache_clear( paddr, len ); + } +} + + +/* +** Shifter + */ +#define ST_LOW 0 +#define ST_MID 1 +#define ST_HIGH 2 +#define TT_LOW 7 +#define TT_MID 4 +#define TT_HIGH 6 + +#define SHF_BAS (0xffff8200) +struct SHIFTER + { + u_char pad1; + u_char bas_hi; + u_char pad2; + u_char bas_md; + u_char pad3; + u_char volatile vcounthi; + u_char pad4; + u_char volatile vcountmid; + u_char pad5; + u_char volatile vcountlow; + u_char volatile syncmode; + u_char pad6; + u_char pad7; + u_char bas_lo; + }; +# define shifter ((*(volatile struct SHIFTER *)SHF_BAS)) + +#define SHF_FBAS (0xffff820e) +struct SHIFTER_F030 + { + u_short off_next; + u_short scn_width; + }; +# define shifter_f030 ((*(volatile struct SHIFTER_F030 *)SHF_FBAS)) + + +#define SHF_TBAS (0xffff8200) +struct SHIFTER_TT { + u_char char_dummy0; + u_char bas_hi; /* video mem base addr, high and mid byte */ + u_char char_dummy1; + u_char bas_md; + u_char char_dummy2; + u_char vcount_hi; /* pointer to currently displayed byte */ + u_char char_dummy3; + u_char vcount_md; + u_char char_dummy4; + u_char vcount_lo; + u_short st_sync; /* ST compatible sync mode register, unused */ + u_char char_dummy5; + u_char bas_lo; /* video mem addr, low byte */ + u_char char_dummy6[2+3*16]; + /* $ffff8240: */ + u_short color_reg[16]; /* 16 color registers */ + u_char st_shiftmode; /* ST compatible shift mode register, unused */ + u_char char_dummy7; + u_short tt_shiftmode; /* TT shift mode register */ + + +}; +#define shifter_tt ((*(volatile struct SHIFTER_TT *)SHF_TBAS)) + +/* values for shifter_tt->tt_shiftmode */ +#define TT_SHIFTER_STLOW 0x0000 +#define TT_SHIFTER_STMID 0x0100 +#define TT_SHIFTER_STHIGH 0x0200 +#define TT_SHIFTER_TTLOW 0x0700 +#define TT_SHIFTER_TTMID 0x0400 +#define TT_SHIFTER_TTHIGH 0x0600 +#define TT_SHIFTER_MODEMASK 0x0700 +#define TT_SHIFTER_NUMMODE 0x0008 +#define TT_SHIFTER_PALETTE_MASK 0x000f +#define TT_SHIFTER_GRAYMODE 0x1000 + +/* 256 TT palette registers */ +#define TT_PALETTE_BASE (0xffff8400) +#define tt_palette ((volatile u_short *)TT_PALETTE_BASE) + +#define TT_PALETTE_RED_MASK 0x0f00 +#define TT_PALETTE_GREEN_MASK 0x00f0 +#define TT_PALETTE_BLUE_MASK 0x000f + +/* +** Falcon030 VIDEL Video Controller +** for description see File 'linux\tools\atari\hardware.txt + */ +#define f030_col ((u_long *) 0xffff9800) +#define f030_xreg ((u_short*) 0xffff8282) +#define f030_yreg ((u_short*) 0xffff82a2) +#define f030_creg ((u_short*) 0xffff82c0) +#define f030_sreg ((u_short*) 0xffff8260) +#define f030_mreg ((u_short*) 0xffff820a) +#define f030_linewidth ((u_short*) 0xffff820e) +#define f030_hscroll ((u_char*) 0xffff8265) + +#define VIDEL_BAS (0xffff8260) +struct VIDEL { + u_short st_shift; + u_short pad1; + u_char xoffset_s; + u_char xoffset; + u_short f_shift; + u_char pad2[0x1a]; + u_short hht; + u_short hbb; + u_short hbe; + u_short hdb; + u_short hde; + u_short hss; + u_char pad3[0x14]; + u_short vft; + u_short vbb; + u_short vbe; + u_short vdb; + u_short vde; + u_short vss; + u_char pad4[0x12]; + u_short control; + u_short mode; +}; +#define videl ((*(volatile struct VIDEL *)VIDEL_BAS)) + +/* +** DMA/WD1772 Disk Controller + */ + +#define FWD_BAS (0xffff8604) +struct DMA_WD + { + u_short fdc_acces_seccount; + u_short dma_mode_status; + u_char dma_vhi; /* Some extended ST-DMAs can handle 32 bit addresses */ + u_char dma_hi; + u_char char_dummy2; + u_char dma_md; + u_char char_dummy3; + u_char dma_lo; + u_short fdc_speed; + }; +# define dma_wd ((*(volatile struct DMA_WD *)FWD_BAS)) +/* alias */ +#define st_dma dma_wd +/* The two highest bytes of an extended DMA as a short; this is a must + * for the Medusa. + */ +#define st_dma_ext_dmahi (*((volatile unsigned short *)0xffff8608)) + +/* +** YM2149 Sound Chip +** access in bytes + */ + +#define YM_BAS (0xffff8800) +struct SOUND_YM + { + u_char rd_data_reg_sel; + u_char char_dummy1; + u_char wd_data; + }; +#define sound_ym ((*(volatile struct SOUND_YM *)YM_BAS)) + +/* TT SCSI DMA */ + +#define TT_SCSI_DMA_BAS (0xffff8700) +struct TT_DMA { + u_char char_dummy0; + u_char dma_addr_hi; + u_char char_dummy1; + u_char dma_addr_hmd; + u_char char_dummy2; + u_char dma_addr_lmd; + u_char char_dummy3; + u_char dma_addr_lo; + u_char char_dummy4; + u_char dma_cnt_hi; + u_char char_dummy5; + u_char dma_cnt_hmd; + u_char char_dummy6; + u_char dma_cnt_lmd; + u_char char_dummy7; + u_char dma_cnt_lo; + u_long dma_restdata; + u_short dma_ctrl; +}; +#define tt_scsi_dma ((*(volatile struct TT_DMA *)TT_SCSI_DMA_BAS)) + +/* TT SCSI Controller 5380 */ + +#define TT_5380_BAS (0xffff8781) +struct TT_5380 { + u_char scsi_data; + u_char char_dummy1; + u_char scsi_icr; + u_char char_dummy2; + u_char scsi_mode; + u_char char_dummy3; + u_char scsi_tcr; + u_char char_dummy4; + u_char scsi_idstat; + u_char char_dummy5; + u_char scsi_dmastat; + u_char char_dummy6; + u_char scsi_targrcv; + u_char char_dummy7; + u_char scsi_inircv; +}; +#define tt_scsi ((*(volatile struct TT_5380 *)TT_5380_BAS)) +#define tt_scsi_regp ((volatile char *)TT_5380_BAS) + + +/* +** Falcon DMA Sound Subsystem + */ + +#define MATRIX_BASE (0xffff8930) +struct MATRIX +{ + u_short source; + u_short destination; + u_char external_frequency_divider; + u_char internal_frequency_divider; +}; +#define matrix (*(volatile struct MATRIX *)MATRIX_BASE) + +#define CODEC_BASE (0xffff8936) +struct CODEC +{ + u_char tracks; + u_char input_source; +#define CODEC_SOURCE_MATRIX 1 +#define CODEC_SOURCE_ADC 2 + u_char adc_source; +#define ADC_SOURCE_RIGHT_PSG 1 +#define ADC_SOURCE_LEFT_PSG 2 + u_char gain; +#define CODEC_GAIN_RIGHT 0x0f +#define CODEC_GAIN_LEFT 0xf0 + u_char attenuation; +#define CODEC_ATTENUATION_RIGHT 0x0f +#define CODEC_ATTENUATION_LEFT 0xf0 + u_char unused1; + u_char status; +#define CODEC_OVERFLOW_RIGHT 1 +#define CODEC_OVERFLOW_LEFT 2 + u_char unused2, unused3, unused4, unused5; + u_char gpio_directions; +#define GPIO_IN 0 +#define GPIO_OUT 1 + u_char unused6; + u_char gpio_data; +}; +#define codec (*(volatile struct CODEC *)CODEC_BASE) + +/* +** Falcon Blitter +*/ + +#define BLT_BAS (0xffff8a00) + +struct BLITTER + { + u_short halftone[16]; + u_short src_x_inc; + u_short src_y_inc; + u_long src_address; + u_short endmask1; + u_short endmask2; + u_short endmask3; + u_short dst_x_inc; + u_short dst_y_inc; + u_long dst_address; + u_short wd_per_line; + u_short ln_per_bb; + u_short hlf_op_reg; + u_short log_op_reg; + u_short lin_nm_reg; + u_short skew_reg; + }; +# define blitter ((*(volatile struct BLITTER *)BLT_BAS)) + + +/* +** SCC Z8530 + */ + +#define SCC_BAS (0xffff8c81) +struct SCC + { + u_char cha_a_ctrl; + u_char char_dummy1; + u_char cha_a_data; + u_char char_dummy2; + u_char cha_b_ctrl; + u_char char_dummy3; + u_char cha_b_data; + }; +# define scc ((*(volatile struct SCC*)SCC_BAS)) + +/* The ESCC (Z85230) in an Atari ST. The channels are reversed! */ +# define st_escc ((*(volatile struct SCC*)0xfffffa31)) +# define st_escc_dsr ((*(volatile char *)0xfffffa39)) + +/* TT SCC DMA Controller (same chip as SCSI DMA) */ + +#define TT_SCC_DMA_BAS (0xffff8c00) +#define tt_scc_dma ((*(volatile struct TT_DMA *)TT_SCC_DMA_BAS)) + +/* +** VIDEL Palette Register + */ + +#define FPL_BAS (0xffff9800) +struct VIDEL_PALETTE + { + u_long reg[256]; + }; +# define videl_palette ((*(volatile struct VIDEL_PALETTE*)FPL_BAS)) + + +/* +** Falcon DSP Host Interface + */ + +#define DSP56K_HOST_INTERFACE_BASE (0xffffa200) +struct DSP56K_HOST_INTERFACE { + u_char icr; +#define DSP56K_ICR_RREQ 0x01 +#define DSP56K_ICR_TREQ 0x02 +#define DSP56K_ICR_HF0 0x08 +#define DSP56K_ICR_HF1 0x10 +#define DSP56K_ICR_HM0 0x20 +#define DSP56K_ICR_HM1 0x40 +#define DSP56K_ICR_INIT 0x80 + + u_char cvr; +#define DSP56K_CVR_HV_MASK 0x1f +#define DSP56K_CVR_HC 0x80 + + u_char isr; +#define DSP56K_ISR_RXDF 0x01 +#define DSP56K_ISR_TXDE 0x02 +#define DSP56K_ISR_TRDY 0x04 +#define DSP56K_ISR_HF2 0x08 +#define DSP56K_ISR_HF3 0x10 +#define DSP56K_ISR_DMA 0x40 +#define DSP56K_ISR_HREQ 0x80 + + u_char ivr; + + union { + u_char b[4]; + u_short w[2]; + u_long l; + } data; +}; +#define dsp56k_host_interface ((*(volatile struct DSP56K_HOST_INTERFACE *)DSP56K_HOST_INTERFACE_BASE)) + +/* +** MFP 68901 + */ + +#define MFP_BAS (0xfffffa01) +struct MFP + { + u_char par_dt_reg; + u_char char_dummy1; + u_char active_edge; + u_char char_dummy2; + u_char data_dir; + u_char char_dummy3; + u_char int_en_a; + u_char char_dummy4; + u_char int_en_b; + u_char char_dummy5; + u_char int_pn_a; + u_char char_dummy6; + u_char int_pn_b; + u_char char_dummy7; + u_char int_sv_a; + u_char char_dummy8; + u_char int_sv_b; + u_char char_dummy9; + u_char int_mk_a; + u_char char_dummy10; + u_char int_mk_b; + u_char char_dummy11; + u_char vec_adr; + u_char char_dummy12; + u_char tim_ct_a; + u_char char_dummy13; + u_char tim_ct_b; + u_char char_dummy14; + u_char tim_ct_cd; + u_char char_dummy15; + u_char tim_dt_a; + u_char char_dummy16; + u_char tim_dt_b; + u_char char_dummy17; + u_char tim_dt_c; + u_char char_dummy18; + u_char tim_dt_d; + u_char char_dummy19; + u_char sync_char; + u_char char_dummy20; + u_char usart_ctr; + u_char char_dummy21; + u_char rcv_stat; + u_char char_dummy22; + u_char trn_stat; + u_char char_dummy23; + u_char usart_dta; + }; +# define mfp ((*(volatile struct MFP*)MFP_BAS)) + +/* TT's second MFP */ + +#define TT_MFP_BAS (0xfffffa81) +# define tt_mfp ((*(volatile struct MFP*)TT_MFP_BAS)) + + +/* TT System Control Unit */ + +#define TT_SCU_BAS (0xffff8e01) +struct TT_SCU { + u_char sys_mask; + u_char char_dummy1; + u_char sys_stat; + u_char char_dummy2; + u_char softint; + u_char char_dummy3; + u_char vmeint; + u_char char_dummy4; + u_char gp_reg1; + u_char char_dummy5; + u_char gp_reg2; + u_char char_dummy6; + u_char vme_mask; + u_char char_dummy7; + u_char vme_stat; +}; +#define tt_scu ((*(volatile struct TT_SCU *)TT_SCU_BAS)) + +/* TT real time clock */ + +#define TT_RTC_BAS (0xffff8961) +struct TT_RTC { + u_char regsel; + u_char dummy; + u_char data; +}; +#define tt_rtc ((*(volatile struct TT_RTC *)TT_RTC_BAS)) + + +/* +** ACIA 6850 + */ +/* constants for the ACIA registers */ + +/* baudrate selection and reset (Baudrate = clock/factor) */ +#define ACIA_DIV1 0 +#define ACIA_DIV16 1 +#define ACIA_DIV64 2 +#define ACIA_RESET 3 + +/* character format */ +#define ACIA_D7E2S (0<<2) /* 7 data, even parity, 2 stop */ +#define ACIA_D7O2S (1<<2) /* 7 data, odd parity, 2 stop */ +#define ACIA_D7E1S (2<<2) /* 7 data, even parity, 1 stop */ +#define ACIA_D7O1S (3<<2) /* 7 data, odd parity, 1 stop */ +#define ACIA_D8N2S (4<<2) /* 8 data, no parity, 2 stop */ +#define ACIA_D8N1S (5<<2) /* 8 data, no parity, 1 stop */ +#define ACIA_D8E1S (6<<2) /* 8 data, even parity, 1 stop */ +#define ACIA_D8O1S (7<<2) /* 8 data, odd parity, 1 stop */ + +/* transmit control */ +#define ACIA_RLTID (0<<5) /* RTS low, TxINT disabled */ +#define ACIA_RLTIE (1<<5) /* RTS low, TxINT enabled */ +#define ACIA_RHTID (2<<5) /* RTS high, TxINT disabled */ +#define ACIA_RLTIDSB (3<<5) /* RTS low, TxINT disabled, send break */ + +/* receive control */ +#define ACIA_RID (0<<7) /* RxINT disabled */ +#define ACIA_RIE (1<<7) /* RxINT enabled */ + +/* status fields of the ACIA */ +#define ACIA_RDRF 1 /* Receive Data Register Full */ +#define ACIA_TDRE (1<<1) /* Transmit Data Register Empty */ +#define ACIA_DCD (1<<2) /* Data Carrier Detect */ +#define ACIA_CTS (1<<3) /* Clear To Send */ +#define ACIA_FE (1<<4) /* Framing Error */ +#define ACIA_OVRN (1<<5) /* Receiver Overrun */ +#define ACIA_PE (1<<6) /* Parity Error */ +#define ACIA_IRQ (1<<7) /* Interrupt Request */ + +#define ACIA_BAS (0xfffffc00) +struct ACIA + { + u_char key_ctrl; + u_char char_dummy1; + u_char key_data; + u_char char_dummy2; + u_char mid_ctrl; + u_char char_dummy3; + u_char mid_data; + }; +# define acia ((*(volatile struct ACIA*)ACIA_BAS)) + +#define TT_DMASND_BAS (0xffff8900) +struct TT_DMASND { + u_char int_ctrl; /* Falcon: Interrupt control */ + u_char ctrl; + u_char pad2; + u_char bas_hi; + u_char pad3; + u_char bas_mid; + u_char pad4; + u_char bas_low; + u_char pad5; + u_char addr_hi; + u_char pad6; + u_char addr_mid; + u_char pad7; + u_char addr_low; + u_char pad8; + u_char end_hi; + u_char pad9; + u_char end_mid; + u_char pad10; + u_char end_low; + u_char pad11[12]; + u_char track_select; /* Falcon */ + u_char mode; + u_char pad12[14]; + /* Falcon only: */ + u_short cbar_src; + u_short cbar_dst; + u_char ext_div; + u_char int_div; + u_char rec_track_select; + u_char dac_src; + u_char adc_src; + u_char input_gain; + u_short output_atten; +}; +# define tt_dmasnd ((*(volatile struct TT_DMASND *)TT_DMASND_BAS)) + +#define DMASND_CTRL_OFF 0x00 +#define DMASND_CTRL_ON 0x01 +#define DMASND_CTRL_REPEAT 0x02 +#define DMASND_MODE_MONO 0x80 +#define DMASND_MODE_STEREO 0x00 +#define DMASND_MODE_8BIT 0x00 +#define DMASND_MODE_16BIT 0x40 /* Falcon only */ +#define DMASND_MODE_6KHZ 0x00 /* Falcon: mute */ +#define DMASND_MODE_12KHZ 0x01 +#define DMASND_MODE_25KHZ 0x02 +#define DMASND_MODE_50KHZ 0x03 + +#define DMASNDSetBase(bufstart) \ + do { \ + tt_dmasnd.bas_hi = (unsigned char)(((bufstart) & 0xff0000) >> 16); \ + tt_dmasnd.bas_mid = (unsigned char)(((bufstart) & 0x00ff00) >> 8); \ + tt_dmasnd.bas_low = (unsigned char) ((bufstart) & 0x0000ff); \ + } while( 0 ) + +#define DMASNDGetAdr() ((tt_dmasnd.addr_hi << 16) + \ + (tt_dmasnd.addr_mid << 8) + \ + (tt_dmasnd.addr_low)) + +#define DMASNDSetEnd(bufend) \ + do { \ + tt_dmasnd.end_hi = (unsigned char)(((bufend) & 0xff0000) >> 16); \ + tt_dmasnd.end_mid = (unsigned char)(((bufend) & 0x00ff00) >> 8); \ + tt_dmasnd.end_low = (unsigned char) ((bufend) & 0x0000ff); \ + } while( 0 ) + + +#define TT_MICROWIRE_BAS (0xffff8922) +struct TT_MICROWIRE { + u_short data; + u_short mask; +}; +# define tt_microwire ((*(volatile struct TT_MICROWIRE *)TT_MICROWIRE_BAS)) + +#define MW_LM1992_ADDR 0x0400 + +#define MW_LM1992_VOLUME(dB) \ + (0x0c0 | ((dB) < -80 ? 0 : (dB) > 0 ? 40 : (((dB) + 80) / 2))) +#define MW_LM1992_BALLEFT(dB) \ + (0x140 | ((dB) < -40 ? 0 : (dB) > 0 ? 20 : (((dB) + 40) / 2))) +#define MW_LM1992_BALRIGHT(dB) \ + (0x100 | ((dB) < -40 ? 0 : (dB) > 0 ? 20 : (((dB) + 40) / 2))) +#define MW_LM1992_TREBLE(dB) \ + (0x080 | ((dB) < -12 ? 0 : (dB) > 12 ? 12 : (((dB) / 2) + 6))) +#define MW_LM1992_BASS(dB) \ + (0x040 | ((dB) < -12 ? 0 : (dB) > 12 ? 12 : (((dB) / 2) + 6))) + +#define MW_LM1992_PSG_LOW 0x000 +#define MW_LM1992_PSG_HIGH 0x001 +#define MW_LM1992_PSG_OFF 0x002 + +#define MSTE_RTC_BAS (0xfffffc21) + +struct MSTE_RTC { + u_char sec_ones; + u_char dummy1; + u_char sec_tens; + u_char dummy2; + u_char min_ones; + u_char dummy3; + u_char min_tens; + u_char dummy4; + u_char hr_ones; + u_char dummy5; + u_char hr_tens; + u_char dummy6; + u_char weekday; + u_char dummy7; + u_char day_ones; + u_char dummy8; + u_char day_tens; + u_char dummy9; + u_char mon_ones; + u_char dummy10; + u_char mon_tens; + u_char dummy11; + u_char year_ones; + u_char dummy12; + u_char year_tens; + u_char dummy13; + u_char mode; + u_char dummy14; + u_char test; + u_char dummy15; + u_char reset; +}; + +#define mste_rtc ((*(volatile struct MSTE_RTC *)MSTE_RTC_BAS)) + +#endif /* linux/atarihw.h */ + diff --git a/include/asm-m68k/atariints.h b/include/asm-m68k/atariints.h new file mode 100644 index 000000000..e2bb42b4c --- /dev/null +++ b/include/asm-m68k/atariints.h @@ -0,0 +1,221 @@ +/* +** atariints.h -- Atari Linux interrupt handling structs and prototypes +** +** Copyright 1994 by Bj”rn Brauel +** +** 5/2/94 Roman Hodek: +** TT interrupt definitions added. +** +** 12/02/96: (Roman) +** Adapted to new int handling scheme (see ataints.c); revised numbering +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +*/ + +#ifndef _LINUX_ATARIINTS_H_ +#define _LINUX_ATARIINTS_H_ + +#include <asm/irq.h> +#include <asm/atarihw.h> + +/* +** Atari Interrupt sources. +** +*/ + +#define STMFP_SOURCE_BASE 8 +#define TTMFP_SOURCE_BASE 24 +#define SCC_SOURCE_BASE 40 +#define VME_SOURCE_BASE 56 +#define VME_MAX_SOURCES 16 + +#define NUM_ATARI_SOURCES (VME_SOURCE_BASE+VME_MAX_SOURCES-STMFP_SOURCE_BASE) + +/* convert vector number to int source number */ +#define IRQ_VECTOR_TO_SOURCE(v) ((v) - ((v) < 0x20 ? 0x18 : (0x40-8))) + +/* convert irq_handler index to vector number */ +#define IRQ_SOURCE_TO_VECTOR(i) ((i) + ((i) < 8 ? 0x18 : (0x40-8))) + +/* interrupt service types */ +#define IRQ_TYPE_SLOW 0 +#define IRQ_TYPE_FAST 1 +#define IRQ_TYPE_PRIO 2 + +#define IRQ_SPURIOUS (IRQ_MACHSPEC | 0) + +/* auto-vector interrupts */ +#define IRQ_AUTO_1 (IRQ_MACHSPEC | 1) +#define IRQ_AUTO_2 (IRQ_MACHSPEC | 2) +#define IRQ_AUTO_3 (IRQ_MACHSPEC | 3) +#define IRQ_AUTO_4 (IRQ_MACHSPEC | 4) +#define IRQ_AUTO_5 (IRQ_MACHSPEC | 5) +#define IRQ_AUTO_6 (IRQ_MACHSPEC | 6) +#define IRQ_AUTO_7 (IRQ_MACHSPEC | 7) + +/* ST-MFP interrupts */ +#define IRQ_MFP_BUSY (IRQ_MACHSPEC | 8) +#define IRQ_MFP_DCD (IRQ_MACHSPEC | 9) +#define IRQ_MFP_CTS (IRQ_MACHSPEC | 10) +#define IRQ_MFP_GPU (IRQ_MACHSPEC | 11) +#define IRQ_MFP_TIMD (IRQ_MACHSPEC | 12) +#define IRQ_MFP_TIMC (IRQ_MACHSPEC | 13) +#define IRQ_MFP_ACIA (IRQ_MACHSPEC | 14) +#define IRQ_MFP_FDC (IRQ_MACHSPEC | 15) +#define IRQ_MFP_ACSI IRQ_MFP_FDC +#define IRQ_MFP_FSCSI IRQ_MFP_FDC +#define IRQ_MFP_IDE IRQ_MFP_FDC +#define IRQ_MFP_TIMB (IRQ_MACHSPEC | 16) +#define IRQ_MFP_SERERR (IRQ_MACHSPEC | 17) +#define IRQ_MFP_SEREMPT (IRQ_MACHSPEC | 18) +#define IRQ_MFP_RECERR (IRQ_MACHSPEC | 19) +#define IRQ_MFP_RECFULL (IRQ_MACHSPEC | 20) +#define IRQ_MFP_TIMA (IRQ_MACHSPEC | 21) +#define IRQ_MFP_RI (IRQ_MACHSPEC | 22) +#define IRQ_MFP_MMD (IRQ_MACHSPEC | 23) + +/* TT-MFP interrupts */ +#define IRQ_TT_MFP_IO0 (IRQ_MACHSPEC | 24) +#define IRQ_TT_MFP_IO1 (IRQ_MACHSPEC | 25) +#define IRQ_TT_MFP_SCC (IRQ_MACHSPEC | 26) +#define IRQ_TT_MFP_RI (IRQ_MACHSPEC | 27) +#define IRQ_TT_MFP_TIMD (IRQ_MACHSPEC | 28) +#define IRQ_TT_MFP_TIMC (IRQ_MACHSPEC | 29) +#define IRQ_TT_MFP_DRVRDY (IRQ_MACHSPEC | 30) +#define IRQ_TT_MFP_SCSIDMA (IRQ_MACHSPEC | 31) +#define IRQ_TT_MFP_TIMB (IRQ_MACHSPEC | 32) +#define IRQ_TT_MFP_SERERR (IRQ_MACHSPEC | 33) +#define IRQ_TT_MFP_SEREMPT (IRQ_MACHSPEC | 34) +#define IRQ_TT_MFP_RECERR (IRQ_MACHSPEC | 35) +#define IRQ_TT_MFP_RECFULL (IRQ_MACHSPEC | 36) +#define IRQ_TT_MFP_TIMA (IRQ_MACHSPEC | 37) +#define IRQ_TT_MFP_RTC (IRQ_MACHSPEC | 38) +#define IRQ_TT_MFP_SCSI (IRQ_MACHSPEC | 39) + +/* SCC interrupts */ +#define IRQ_SCCB_TX (IRQ_MACHSPEC | 40) +#define IRQ_SCCB_STAT (IRQ_MACHSPEC | 42) +#define IRQ_SCCB_RX (IRQ_MACHSPEC | 44) +#define IRQ_SCCB_SPCOND (IRQ_MACHSPEC | 46) +#define IRQ_SCCA_TX (IRQ_MACHSPEC | 48) +#define IRQ_SCCA_STAT (IRQ_MACHSPEC | 50) +#define IRQ_SCCA_RX (IRQ_MACHSPEC | 52) +#define IRQ_SCCA_SPCOND (IRQ_MACHSPEC | 54) + + +#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ +#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ + + +#define MFP_ENABLE 0 +#define MFP_PENDING 1 +#define MFP_SERVICE 2 +#define MFP_MASK 3 + +/* Utility functions for setting/clearing bits in the interrupt registers of + * the MFP. 'type' should be constant, if 'irq' is constant, too, code size is + * reduced. set_mfp_bit() is nonsense for PENDING and SERVICE registers. */ + +static inline int get_mfp_bit( unsigned irq, int type ) + +{ unsigned char mask, *reg; + + mask = 1 << (irq & 7); + reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + return( *reg & mask ); +} + +static inline void set_mfp_bit( unsigned irq, int type ) + +{ unsigned char mask, *reg; + + mask = 1 << (irq & 7); + reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + __asm__ __volatile__ ( "orb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); +} + +static inline void clear_mfp_bit( unsigned irq, int type ) + +{ unsigned char mask, *reg; + + mask = ~(1 << (irq & 7)); + reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + if (type == MFP_PENDING || type == MFP_SERVICE) + __asm__ __volatile__ ( "moveb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); + else + __asm__ __volatile__ ( "andb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); +} + +/* + * {en,dis}able_irq have the usual semantics of temporary blocking the + * interrupt, but not loosing requests that happen between disabling and + * enabling. This is done with the MFP mask registers. + */ + +static inline void atari_enable_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + set_mfp_bit( irq, MFP_MASK ); +} + +static inline void atari_disable_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_MASK ); +} + +/* + * In opposite to {en,dis}able_irq, requests between turn{off,on}_irq are not + * "stored" + */ + +extern inline void atari_turnon_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + set_mfp_bit( irq, MFP_ENABLE ); +} + +extern inline void atari_turnoff_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_ENABLE ); + clear_mfp_bit( irq, MFP_PENDING ); +} + +extern inline void atari_clear_pending_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_PENDING ); +} + +extern inline int atari_irq_pending( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return( 0 ); + return( get_mfp_bit( irq, MFP_PENDING ) ); +} + +unsigned long atari_register_vme_int( void ); +void atari_unregister_vme_int( unsigned long ); + +#endif /* linux/atariints.h */ diff --git a/include/asm-m68k/atarikb.h b/include/asm-m68k/atarikb.h new file mode 100644 index 000000000..18926058f --- /dev/null +++ b/include/asm-m68k/atarikb.h @@ -0,0 +1,40 @@ +/* +** atarikb.h -- This header contains the prototypes of functions of +** the intelligent keyboard of the Atari needed by the +** mouse and joystick drivers. +** +** Copyright 1994 by Robert de Vries +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created: 20 Feb 1994 by Robert de Vries +*/ + +#ifndef _LINUX_ATARIKB_H +#define _LINUX_ATARIKB_H + +void ikbd_write(const char *, int); +void ikbd_mouse_button_action(int mode); +void ikbd_mouse_rel_pos(void); +void ikbd_mouse_abs_pos(int xmax, int ymax); +void ikbd_mouse_kbd_mode(int dx, int dy); +void ikbd_mouse_thresh(int x, int y); +void ikbd_mouse_scale(int x, int y); +void ikbd_mouse_pos_get(int *x, int *y); +void ikbd_mouse_pos_set(int x, int y); +void ikbd_mouse_y0_bot(void); +void ikbd_mouse_y0_top(void); +void ikbd_mouse_disable(void); +void ikbd_joystick_event_on(void); +void ikbd_joystick_event_off(void); +void ikbd_joystick_get_state(void); +void ikbd_joystick_disable(void); + +/* Hook for MIDI serial driver */ +extern void (*atari_MIDI_interrupt_hook) (void); +/* Hook for mouse driver */ +extern void (*atari_mouse_interrupt_hook) (char *); + +#endif /* _LINUX_ATARIKB_H */ diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h new file mode 100644 index 000000000..8ea909203 --- /dev/null +++ b/include/asm-m68k/atomic.h @@ -0,0 +1,42 @@ +#ifndef __ARCH_M68K_ATOMIC__ +#define __ARCH_M68K_ATOMIC__ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +/* + * We do not have SMP m68k systems, so we don't have to deal with that. + */ + +typedef int atomic_t; + +static __inline__ void atomic_add(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__("addl %1,%0" : : "m" (*v), "id" (i)); +} + +static __inline__ void atomic_sub(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__("subl %1,%0" : : "m" (*v), "id" (i)); +} + +static __inline__ void atomic_inc(atomic_t *v) +{ + __asm__ __volatile__("addql #1,%0" : : "m" (*v)); +} + +static __inline__ void atomic_dec(atomic_t *v) +{ + __asm__ __volatile__("subql #1,%0" : : "m" (*v)); +} + +static __inline__ int atomic_dec_and_test(atomic_t *v) +{ + char c; + __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c) : "m" (*v)); + return c != 0; +} + +#endif /* __ARCH_M68K_ATOMIC __ */ diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h index 901fa48a0..b63496040 100644 --- a/include/asm-m68k/bitops.h +++ b/include/asm-m68k/bitops.h @@ -4,17 +4,14 @@ * Copyright 1992, Linus Torvalds. * * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ /* * Require 68020 or better. * - * They don't use the standard m680x0 bit ordering. - * Instead, the use the standard m680x0 bitfield ordering. - * - * Thus, bit 0 is the MSB of addr; bit 32 is the MSB of (addr+1). + * They use the standard big-endian m680x0 bit ordering. */ extern __inline__ int set_bit(int nr,void * vaddr) @@ -22,7 +19,7 @@ extern __inline__ int set_bit(int nr,void * vaddr) char retval; __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr), "a" (vaddr)); + : "=d" (retval) : "d" (nr^31), "a" (vaddr)); return retval; } @@ -32,7 +29,7 @@ extern __inline__ int clear_bit(int nr, void * vaddr) char retval; __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr), "a" (vaddr)); + : "=d" (retval) : "d" (nr^31), "a" (vaddr)); return retval; } @@ -42,61 +39,57 @@ extern __inline__ int change_bit(int nr, void * vaddr) char retval; __asm__ __volatile__ ("bfchg %2@{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr), "a" (vaddr)); + : "=d" (retval) : "d" (nr^31), "a" (vaddr)); return retval; } extern __inline__ int test_bit(int nr, const void * vaddr) { - char retval; - - __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr), "a" (vaddr)); - - return retval; + return ((1UL << (nr & 31)) & (((const unsigned int *) vaddr)[nr >> 5])) != 0; } -extern inline int find_first_zero_bit(void * vaddr, unsigned size) +extern __inline__ int find_first_zero_bit(void * vaddr, unsigned size) { - unsigned long res; - unsigned long *p; - unsigned long *addr = vaddr; + unsigned long *p = vaddr, *addr = vaddr; + unsigned long allones = ~0UL; + int res; + unsigned long num; if (!size) return 0; - __asm__ __volatile__ (" moveq #-1,d0\n\t" - "1:" - " cmpl %1@+,d0\n\t" - " bne 2f\n\t" - " subql #1,%0\n\t" - " bne 1b\n\t" - " bra 5f\n\t" - "2:" - " movel %1@-,d0\n\t" - " notl d0\n\t" - " bfffo d0{#0,#0},%0\n\t" - "5:" - : "=d" (res), "=a" (p) - : "0" ((size + 31) >> 5), "1" (addr) - : "d0"); - return ((p - addr) << 5) + res; -} - -static inline int find_next_zero_bit (void *vaddr, int size, + + size = (size >> 5) + ((size & 31) > 0); + while (*p++ == allones) + { + if (--size == 0) + return (p - addr) << 5; + } + + num = ~*--p; + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + return ((p - addr) << 5) + (res ^ 31); +} + +extern __inline__ int find_next_zero_bit (void *vaddr, int size, int offset) { unsigned long *addr = vaddr; unsigned long *p = addr + (offset >> 5); - int set = 0, bit = offset & 31, res; + int set = 0, bit = offset & 31UL, res; + + if (offset >= size) + return size; if (bit) { + unsigned long num = ~*p & (~0UL << bit); + /* Look for zero in first longword */ - __asm__("bfffo %1{#0,#0},%0" - : "=d" (set) - : "d" (~*p << bit)); - if (set < (32 - bit)) - return set + offset; + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + if (res < 32) + return (offset & ~31UL) + (res ^ 31); set = 32 - bit; p++; } @@ -109,12 +102,156 @@ static inline int find_next_zero_bit (void *vaddr, int size, * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. */ -extern inline unsigned long ffz(unsigned long word) +extern __inline__ unsigned long ffz(unsigned long word) { + int res; + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" - : "=d" (word) - : "d" (~(word))); - return word; + : "=d" (res) : "d" (~word & -~word)); + return res ^ 31; +} + +/* Bitmap functions for the minix filesystem */ + +extern __inline__ int +minix_find_first_zero_bit (const void *vaddr, unsigned size) +{ + const unsigned short *p = vaddr, *addr = vaddr; + int res; + unsigned short num; + + if (!size) + return 0; + + size = (size >> 4) + ((size & 15) > 0); + while (*p++ == 0xffff) + { + if (--size == 0) + return (p - addr) << 4; + } + + num = ~*--p; + __asm__ __volatile__ ("bfffo %1{#16,#16},%0" + : "=d" (res) : "d" (num & -num)); + return ((p - addr) << 4) + (res ^ 31); +} + +extern __inline__ int +minix_set_bit (int nr, void *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfset %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^15), "m" (*(char *)vaddr)); + + return retval; +} + +extern __inline__ int +minix_clear_bit (int nr, void *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^15), "m" (*(char *) vaddr)); + + return retval; +} + +extern __inline__ int +minix_test_bit (int nr, const void *vaddr) +{ + return ((1U << (nr & 15)) & (((const unsigned short *) vaddr)[nr >> 4])) != 0; +} + +/* Bitmap functions for the ext2 filesystem. */ + +extern __inline__ int +ext2_set_bit (int nr, void *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfset %2{%1,#1}; sne %0" + : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr)); + + return retval; +} + +extern __inline__ int +ext2_clear_bit (int nr, void *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfclr %2{%1,#1}; sne %0" + : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr)); + + return retval; +} + +extern __inline__ int +ext2_test_bit (int nr, const void *vaddr) +{ + return ((1U << (nr & 7)) & (((const unsigned char *) vaddr)[nr >> 3])) != 0; +} + +extern __inline__ int +ext2_find_first_zero_bit (const void *vaddr, unsigned size) +{ + const unsigned long *p = vaddr, *addr = vaddr; + int res; + + if (!size) + return 0; + + size = (size >> 5) + ((size & 31) > 0); + while (*p++ == ~0UL) + { + if (--size == 0) + return (p - addr) << 5; + } + + --p; + for (res = 0; res < 32; res++) + if (!ext2_test_bit (res, p)) + break; + return (p - addr) * 32 + res; +} + +extern __inline__ int +ext2_find_next_zero_bit (const void *vaddr, unsigned size, unsigned offset) +{ + const unsigned long *addr = vaddr; + const unsigned long *p = addr + (offset >> 5); + int bit = offset & 31UL, res; + + if (offset >= size) + return size; + + if (bit) { + /* Look for zero in first longword */ + for (res = bit; res < 32; res++) + if (!ext2_test_bit (res, p)) + return (p - addr) * 32 + res; + p++; + } + /* No zero yet, search remaining full bytes for a zero */ + res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); + return (p - addr) * 32 + res; +} + +/* Byte swapping. */ + +extern __inline__ unsigned short +swab16 (unsigned short val) +{ + return (val << 8) | (val >> 8); +} + +extern __inline__ unsigned int +swab32 (unsigned int val) +{ + __asm__ ("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); + return val; } #endif /* _M68K_BITOPS_H */ diff --git a/include/asm-m68k/bugs.h b/include/asm-m68k/bugs.h new file mode 100644 index 000000000..5f382dac3 --- /dev/null +++ b/include/asm-m68k/bugs.h @@ -0,0 +1,16 @@ +/* + * include/asm-m68k/bugs.h + * + * Copyright (C) 1994 Linus Torvalds + */ + +/* + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +static void check_bugs(void) +{ +} diff --git a/include/asm-m68k/byteorder.h b/include/asm-m68k/byteorder.h new file mode 100644 index 000000000..c6c9fc1e9 --- /dev/null +++ b/include/asm-m68k/byteorder.h @@ -0,0 +1,84 @@ +#ifndef _M68K_BYTEORDER_H +#define _M68K_BYTEORDER_H + +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif + +#ifndef __BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN_BITFIELD +#endif + +#ifdef __KERNEL__ +#include <linux/config.h> +#include <asm/types.h> + +/* + * In-kernel byte order macros to handle stuff like + * byte-order-dependent filesystems etc. + */ + +#define le16_to_cpu(__val) __swab16(__val) +#define le32_to_cpu(__val) __swab32(__val) +#define cpu_to_le32(__val) __swab32(__val) +#define cpu_to_le16(__val) __swab16(__val) + +extern __inline__ __u16 __swab16 (__u16 val) +{ + return (val << 8) | (val >> 8); +} + +extern __inline__ __u32 __swab32 (__u32 val) +{ + __asm__ ("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); + return val; +} + +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#define cpu_to_be16(x) (x) +#define be16_to_cpu(x) (x) + +#endif + +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +extern unsigned long int ntohl(unsigned long int); +extern unsigned short int ntohs(unsigned short int); +extern unsigned long int htonl(unsigned long int); +extern unsigned short int htons(unsigned short int); + +extern __inline__ unsigned long int __ntohl(unsigned long int); +extern __inline__ unsigned short int __ntohs(unsigned short int); + +extern __inline__ unsigned long int +__ntohl(unsigned long int x) +{ + return x; +} + +extern __inline__ unsigned short int +__ntohs(unsigned short int x) +{ + return x; +} + +#define __htonl(x) __ntohl(x) +#define __htons(x) __ntohs(x) + +#define __constant_htonl(x) (x) +#define __constant_htons(x) (x) +#define __constant_ntohl(x) (x) +#define __constant_ntohs(x) (x) + +#ifdef __OPTIMIZE__ +#define ntohl(x) __ntohl(x) +#define ntohs(x) __ntohs(x) +#define htonl(x) __htonl(x) +#define htons(x) __htons(x) +#endif + +#endif diff --git a/include/asm-m68k/cachectl.h b/include/asm-m68k/cachectl.h new file mode 100644 index 000000000..525978e95 --- /dev/null +++ b/include/asm-m68k/cachectl.h @@ -0,0 +1,14 @@ +#ifndef _M68K_CACHECTL_H +#define _M68K_CACHECTL_H + +/* Definitions for the cacheflush system call. */ + +#define FLUSH_SCOPE_LINE 1 /* Flush a cache line */ +#define FLUSH_SCOPE_PAGE 2 /* Flush a page */ +#define FLUSH_SCOPE_ALL 3 /* Flush the whole cache -- superuser only */ + +#define FLUSH_CACHE_DATA 1 /* Writeback and flush data cache */ +#define FLUSH_CACHE_INSN 2 /* Flush instruction cache */ +#define FLUSH_CACHE_BOTH 3 /* Flush both caches */ + +#endif /* _M68K_CACHECTL_H */ diff --git a/include/asm-m68k/checksum.h b/include/asm-m68k/checksum.h new file mode 100644 index 000000000..6b4976567 --- /dev/null +++ b/include/asm-m68k/checksum.h @@ -0,0 +1,113 @@ +#ifndef _M68K_CHECKSUM_H +#define _M68K_CHECKSUM_H + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial_copy, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum); + + +/* + * the same as csum_partial_copy, but copies from user space. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +unsigned int csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum); + + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + */ +static inline unsigned short +ip_fast_csum(unsigned char *iph, unsigned int ihl) +{ + unsigned int sum = 0; + + __asm__ ("subqw #1,%2\n" + "1:\t" + "movel %1@+,%/d0\n\t" + "addxl %/d0,%0\n\t" + "dbra %2,1b\n\t" + "movel %0,%/d0\n\t" + "swap %/d0\n\t" + "addxw %/d0,%0\n\t" + "clrw %/d0\n\t" + "addxw %/d0,%0\n\t" + : "=d" (sum), "=a" (iph), "=d" (ihl) + : "0" (sum), "1" (iph), "2" (ihl) + : "d0"); + return ~sum; +} + +/* + * Fold a partial checksum + */ + +static inline unsigned int csum_fold(unsigned int sum) +{ + unsigned int tmp = sum; + __asm__("swap %1\n\t" + "addw %1, %0\n\t" + "clrw %1\n\t" + "addxw %1, %0" + : "=&d" (sum), "=&d" (tmp) + : "0" (sum), "1" (sum)); + return ~sum; +} + + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ + +static inline unsigned short int +csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, + unsigned short proto, unsigned int sum) +{ + __asm__ ("addl %1,%0\n\t" + "addxl %4,%0\n\t" + "addxl %5,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=&d" (saddr) + : "0" (daddr), "1" (saddr), "d" (len + proto), + "d"(sum)); + return csum_fold(sum); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline unsigned short +ip_compute_csum(unsigned char * buff, int len) +{ + return csum_fold (csum_partial(buff, len, 0)); +} + +#endif /* _M68K_CHECKSUM_H */ diff --git a/include/asm-m68k/delay.h b/include/asm-m68k/delay.h index 804a654b7..731dd0b1a 100644 --- a/include/asm-m68k/delay.h +++ b/include/asm-m68k/delay.h @@ -7,18 +7,13 @@ * Delay routines, using a pre-computed "loops_per_second" value. */ -extern __inline__ void __delay(int loops) +extern __inline__ void __delay(unsigned long loops) { - __asm__("\n\tmovel %0,d0\n1:\tsubql #1,d0\n\tbpls 1b\n" - : /* no outputs */ - : "g" (loops) - : "d0"); + __asm__ __volatile__ ("1: subql #1,%0; jcc 1b" + : "=d" (loops) : "0" (loops)); } /* - * division by multiplication: you don't have to worry about - * loss of precision. - * * Use only for very small delays ( < 1 msec). Should probably use a * lookup table, really, as the multiplications take much too long with * short delays. This is a "reasonable" implementation, though (and the @@ -27,14 +22,23 @@ extern __inline__ void __delay(int loops) */ extern __inline__ void udelay(unsigned long usecs) { - asm ("mulul %1,d0,%0\n\t" - "divul %2,d0,%0" - : "=d" (usecs) - : "d" (usecs), - "i" (1000000), - "0" (loops_per_sec) - : "d0"); + unsigned long tmp; + + usecs *= 4295; /* 2**32 / 1000000 */ + __asm__ ("mulul %2,%0:%1" + : "=d" (usecs), "=d" (tmp) + : "d" (usecs), "1" (loops_per_sec)); __delay(usecs); } +extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) +{ + unsigned long tmp; + + __asm__ ("mulul %2,%0:%1; divul %3,%0:%1" + : "=d" (tmp), "=d" (a) + : "d" (b), "d" (c), "1" (a)); + return a; +} + #endif /* defined(_M68K_DELAY_H) */ diff --git a/include/asm-m68k/dma.h b/include/asm-m68k/dma.h index 2820f20a1..af73a0f6f 100644 --- a/include/asm-m68k/dma.h +++ b/include/asm-m68k/dma.h @@ -1,6 +1,12 @@ #ifndef _M68K_DMA_H #define _M68K_DMA_H 1 -/* dummy for m68k */ +/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k and any + occurrence should be flagged as an error. */ + +#define MAX_DMA_CHANNELS 8 + +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ #endif /* _M68K_DMA_H */ diff --git a/include/asm-m68k/elf.h b/include/asm-m68k/elf.h new file mode 100644 index 000000000..8ccf73858 --- /dev/null +++ b/include/asm-m68k/elf.h @@ -0,0 +1,64 @@ +#ifndef __ASMm68k_ELF_H +#define __ASMm68k_ELF_H + +/* + * ELF register definitions.. + */ + +#include <asm/ptrace.h> +#include <asm/user.h> + +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]; + +typedef struct user_m68kfp_struct elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x) == EM_68K) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB; +#define ELF_ARCH EM_68K + + /* For SVR4/m68k the function pointer to be registered with + `atexit' is passed in %a1. Although my copy of the ABI has + no such statement, it is actually used on ASV. */ +#define ELF_PLAT_INIT(_r) _r->a1 = 0 + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ + /* Bleech. */ \ + pr_reg[0] = regs->d1; \ + pr_reg[1] = regs->d2; \ + pr_reg[2] = regs->d3; \ + pr_reg[3] = regs->d4; \ + pr_reg[4] = regs->d5; \ + pr_reg[7] = regs->a0; \ + pr_reg[8] = regs->a1; \ + pr_reg[14] = regs->d0; \ + pr_reg[15] = rdusp(); \ + pr_reg[16] = regs->orig_d0; \ + pr_reg[17] = regs->sr; \ + pr_reg[18] = regs->pc; \ + pr_reg[19] = (regs->format << 12) | regs->vector; \ + { \ + struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \ + pr_reg[5] = sw->d6; \ + pr_reg[6] = sw->d7; \ + pr_reg[9] = sw->a2; \ + pr_reg[10] = sw->a3; \ + pr_reg[11] = sw->a4; \ + pr_reg[12] = sw->a5; \ + pr_reg[13] = sw->a6; \ + } + +#endif diff --git a/include/asm-m68k/errno.h b/include/asm-m68k/errno.h new file mode 100644 index 000000000..de8949f56 --- /dev/null +++ b/include/asm-m68k/errno.h @@ -0,0 +1,129 @@ +#ifndef _M68K_ERRNO_H +#define _M68K_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#endif /* _M68K_ERRNO_H */ diff --git a/include/asm-m68k/fcntl.h b/include/asm-m68k/fcntl.h new file mode 100644 index 000000000..c1f6ea405 --- /dev/null +++ b/include/asm-m68k/fcntl.h @@ -0,0 +1,59 @@ +#ifndef _M68K_FCNTL_H +#define _M68K_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#define O_SYNC 010000 +#define FASYNC 020000 /* fcntl, for BSD compatibility */ + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get f_flags */ +#define F_SETFD 2 /* set f_flags */ +#define F_GETFL 3 /* more flags (cloexec) */ +#define F_SETFL 4 +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +#endif /* _M68K_FCNTL_H */ diff --git a/include/asm-m68k/font.h b/include/asm-m68k/font.h new file mode 100644 index 000000000..926e7194c --- /dev/null +++ b/include/asm-m68k/font.h @@ -0,0 +1,35 @@ +/* + * asm-m68k/font.h -- `Soft' font definitions + * + * Created 1995 by Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_M68K_FONT_H_ +#define _ASM_M68K_FONT_H_ + +#include <linux/types.h> + + + /* + * Find a font with a specific name + */ + +extern int findsoftfont(char *name, int *width, int *height, u_char *data[]); + + + /* + * Get the default font for a specific screen size + */ + +extern void getdefaultfont(int xres, int yres, char *name[], int *width, + int *height, u_char *data[]); + + +/* Max. length for the name of a predefined font */ +#define MAX_FONT_NAME 32 + +#endif /* _ASM_M68K_FONT_H_ */ diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h new file mode 100644 index 000000000..ab5aaf261 --- /dev/null +++ b/include/asm-m68k/ide.h @@ -0,0 +1,522 @@ +/* + * linux/include/asm-m68k/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* Copyright(c) 1996 Kars de Jong */ +/* Based on the ide driver from 1.2.13pl8 */ + +/* + * Credits (alphabetical): + * + * - Bjoern Brauel + * - Kars de Jong + * - Torsten Ebeling + * - Dwight Engen + * - Thorsten Floeck + * - Roman Hodek + * - Guenther Kelleter + * - Chris Lawrence + * - Michael Rausch + * - Christian Sauer + * - Michael Schmitz + * - Jes Soerensen + * - Michael Thurm + * - Geert Uytterhoeven + */ + +#ifndef _M68K_IDE_H +#define _M68K_IDE_H + +#ifdef __KERNEL__ + +#include <linux/config.h> + +#ifdef CONFIG_AMIGA +#include <asm/amigahw.h> +#include <asm/amihdreg.h> +#include <asm/amigaints.h> +#endif /* CONFIG_AMIGA */ + +#ifdef CONFIG_ATARI +#include <asm/atarihw.h> +#include <asm/atarihdreg.h> +#include <asm/atariints.h> +#include <asm/atari_stdma.h> +#endif /* CONFIG_ATARI */ + +#include <asm/setup.h> +#include <asm/io.h> +#include <asm/irq.h> + +typedef unsigned char * ide_ioreg_t; + +#ifndef MAX_HWIFS +#define MAX_HWIFS 1 +#endif + +static __inline int ide_default_irq (ide_ioreg_t base) +{ + return 0; +} + +static __inline__ ide_ioreg_t ide_default_io_base (int index) +{ + if (index) + return NULL; +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) { + if (AMIGAHW_PRESENT(A4000_IDE)) { + printk("Gayle IDE interface (A%d style)\n", 4000); + return ((ide_ioreg_t)ZTWO_VADDR(HD_BASE_A4000)); + } + if (AMIGAHW_PRESENT(A1200_IDE)) { + printk("Gayle IDE interface (A%d style)\n", 1200); + return ((ide_ioreg_t)ZTWO_VADDR(HD_BASE_A1200)); + } + } +#endif /* CONFIG_AMIGA */ +#ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { + if (ATARIHW_PRESENT(IDE)) { + printk("Falcon IDE interface\n"); + return ((ide_ioreg_t) ATA_HD_BASE); + } + } +#endif /* CONFIG_ATARI */ + return NULL; +} + +static __inline__ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) +{ + *p++ = base; +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) { + *p++ = base + AMI_HD_ERROR; + *p++ = base + AMI_HD_NSECTOR; + *p++ = base + AMI_HD_SECTOR; + *p++ = base + AMI_HD_LCYL; + *p++ = base + AMI_HD_HCYL; + *p++ = base + AMI_HD_SELECT; + *p++ = base + AMI_HD_STATUS; + *p++ = base + AMI_HD_CMD; + if (AMIGAHW_PRESENT(A4000_IDE)) + *p++ = (ide_ioreg_t) ZTWO_VADDR(HD_A4000_IRQ); + else if (AMIGAHW_PRESENT(A1200_IDE)) + *p++ = (ide_ioreg_t) ZTWO_VADDR(HD_A1200_IRQ); + if (irq != NULL) + *irq = IRQ_AMIGA_PORTS; + } +#endif /* CONFIG_AMIGA */ +#ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { + *p++ = base + ATA_HD_ERROR; + *p++ = base + ATA_HD_NSECTOR; + *p++ = base + ATA_HD_SECTOR; + *p++ = base + ATA_HD_LCYL; + *p++ = base + ATA_HD_HCYL; + *p++ = base + ATA_HD_CURRENT; + *p++ = base + ATA_HD_STATUS; + *p++ = base + ATA_HD_CMD; + if (irq != NULL) + *irq = IRQ_MFP_IDE; + } +#endif /* CONFIG_ATARI */ +} + +typedef union { + unsigned all : 8; /* all of the bits together */ + struct { + 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 or 1 */ + unsigned head : 4; /* always zeros here */ + } b; + } select_t; + +static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *device, void *dev_id) +{ +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) + return request_irq(irq, handler, 0, device, dev_id); +#endif /* CONFIG_AMIGA */ + return 0; +} + +static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) +{ +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) + free_irq(irq, dev_id); +#endif /* CONFIG_AMIGA */ +} + +/* + * We should really implement those some day. + */ +static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent) +{ + return 0; +} + +static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name) +{ +} + +static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent) +{ +} + +#undef SUPPORT_SLOW_DATA_PORTS +#define SUPPORT_SLOW_DATA_PORTS 0 + +#undef SUPPORT_VLB_SYNC +#define SUPPORT_VLB_SYNC 0 + +#undef HD_DATA +#define HD_DATA NULL + +#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1) +#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1) + +#define insw(port, buf, nr) \ + if ((nr) % 16) \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a0@,%/a1@+; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "a0", "a1", "d6"); \ + else \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + lsrl #4,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "a0", "a1", "d6") + +#define outsw(port, buf, nr) \ + if ((nr) % 16) \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a1@+,%/a0@; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "a0", "a1", "d6"); \ + else \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + lsrl #4,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "a0", "a1", "d6") + +#ifdef CONFIG_ATARI +#define insl_swapw(data_reg, buffer, wcount) \ + insw_swapw(data_reg, buffer, (wcount)<<1) +#define outsl_swapw(data_reg, buffer, wcount) \ + outsw_swapw(data_reg, buffer, (wcount)<<1) + +#define insw_swapw(port, buf, nr) \ + if ((nr) % 8) \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "d0", "a0", "a1", "d6"); \ + else \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + lsrl #3,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "d0", "a0", "a1", "d6") + +#define outsw_swapw(port, buf, nr) \ + if ((nr) % 8) \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "d0", "a0", "a1", "d6"); \ + else \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + lsrl #3,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "d0", "a0", "a1", "d6") + +#endif /* CONFIG_ATARI */ + +static __inline__ int ide_ack_intr (ide_ioreg_t base_port, ide_ioreg_t irq_port) +{ +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) { + unsigned char ch; + ch = inb(irq_port); + if (!(ch & 0x80)) + return(0); + if (AMIGAHW_PRESENT(A1200_IDE)) { + (void) inb(base_port); + outb(0x7c | (ch & 0x03), irq_port); + } + } +#endif /* CONFIG_AMIGA */ + return(1); +} + +#define T_CHAR (0x0000) /* char: don't touch */ +#define T_SHORT (0x4000) /* short: 12 -> 21 */ +#define T_INT (0x8000) /* int: 1234 -> 4321 */ +#define T_TEXT (0xc000) /* text: 12 -> 21 */ + +#define T_MASK_TYPE (0xc000) +#define T_MASK_COUNT (0x3fff) + +#define D_CHAR(cnt) (T_CHAR | (cnt)) +#define D_SHORT(cnt) (T_SHORT | (cnt)) +#define D_INT(cnt) (T_INT | (cnt)) +#define D_TEXT(cnt) (T_TEXT | (cnt)) + +#ifdef CONFIG_AMIGA +static u_short driveid_types[] = { + D_SHORT(10), /* config - vendor2 */ + D_TEXT(20), /* serial_no */ + D_SHORT(3), /* buf_type - ecc_bytes */ + D_TEXT(48), /* fw_rev - model */ + D_CHAR(2), /* max_multsect - vendor3 */ + D_SHORT(1), /* dword_io */ + D_CHAR(2), /* vendor4 - capability */ + D_SHORT(1), /* reserved50 */ + D_CHAR(4), /* vendor5 - tDMA */ + D_SHORT(4), /* field_valid - cur_sectors */ + D_INT(1), /* cur_capacity */ + D_CHAR(2), /* multsect - multsect_valid */ + D_INT(1), /* lba_capacity */ + D_SHORT(194) /* dma_1word - reservedyy */ +}; + +#define num_driveid_types (sizeof(driveid_types)/sizeof(*driveid_types)) +#endif /* CONFIG_AMIGA */ + +static __inline__ void ide_fix_driveid(struct hd_driveid *id) +{ +#ifdef CONFIG_AMIGA + u_char *p = (u_char *)id; + int i, j, cnt; + u_char t; + + if (!MACH_IS_AMIGA) + return; + for (i = 0; i < num_driveid_types; i++) { + cnt = driveid_types[i] & T_MASK_COUNT; + switch (driveid_types[i] & T_MASK_TYPE) { + case T_CHAR: + p += cnt; + break; + case T_SHORT: + for (j = 0; j < cnt; j++) { + t = p[0]; + p[0] = p[1]; + p[1] = t; + p += 2; + } + break; + case T_INT: + for (j = 0; j < cnt; j++) { + t = p[0]; + p[0] = p[3]; + p[3] = t; + t = p[1]; + p[1] = p[2]; + p[2] = t; + p += 4; + } + break; + case T_TEXT: + for (j = 0; j < cnt; j += 2) { + t = p[0]; + p[0] = p[1]; + p[1] = t; + p += 2; + } + break; + } + } +#endif /* CONFIG_AMIGA */ +} + +static __inline__ void ide_release_lock (int *ide_lock) +{ +#ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { + if (*ide_lock == 0) { + printk("ide_release_lock: bug\n"); + return; + } + *ide_lock = 0; + stdma_release(); + } +#endif /* CONFIG_ATARI */ +} + +static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data) +{ +#ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { + if (*ide_lock == 0) { + if (intr_count > 0) + panic( "Falcon IDE hasn't ST-DMA lock in interrupt" ); + stdma_lock(handler, data); + *ide_lock = 1; + } + } +#endif /* CONFIG_ATARI */ +} + +/* + * On the Atari, we sometimes can't enable interrupts: + */ + +/* MSch: changed sti() to STI() wherever possible in ide.c; moved STI() def. + * to asm/ide.h + */ +/* The Atari interrupt structure strictly requires that the IPL isn't lowered + * uncontrolled in an interrupt handler. In the concrete case, the IDE + * interrupt is already a slow int, so the irq is already disabled at the time + * the handler is called, and the IPL has been lowered to the minimum value + * possible. To avoid going below that, STI() checks for being called inside + * an interrupt, and in that case it does nothing. Hope that is reasonable and + * works. (Roman) + */ +#if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) +#define ide_sti() \ + do { \ + if (!intr_count) sti(); \ + } while(0) +#elif defined(CONFIG_ATARI) +#define ide_sti() \ + do { \ + if (!MACH_IS_ATARI || !intr_count) sti(); \ + } while(0) +#else /* !defined(CONFIG_ATARI) */ +#define ide_sti() sti() +#endif + +#endif /* __KERNEL__ */ + +#endif /* _M68K_IDE_H */ diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h index 0cde22fd3..a9d65f743 100644 --- a/include/asm-m68k/io.h +++ b/include/asm-m68k/io.h @@ -1,24 +1,54 @@ #ifndef _M68K_IO_H #define _M68K_IO_H -static inline unsigned char get_user_byte_io(const char * addr) -{ - register unsigned char _v; +#ifdef __KERNEL__ + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the m68k architecture, we just read/write the + * memory location directly. + */ +#define readb(addr) (*(volatile unsigned char *) (addr)) +#define readw(addr) (*(volatile unsigned short *) (addr)) +#define readl(addr) (*(volatile unsigned int *) (addr)) + +#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b)) +#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b)) +#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b)) + +#define memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +#define inb_p(addr) readb(addr) +#define inb(addr) readb(addr) - __asm__ __volatile__ ("moveb %1,%0":"=r" (_v):"m" (*addr)); - return _v; +#define outb(x,addr) ((void) writeb(x,addr)) +#define outb_p(x,addr) outb(x,addr) + +/* + * Change virtual addresses to physical addresses and vv. + */ +extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const)); +extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); + +extern inline unsigned long virt_to_phys(volatile void * address) +{ + return mm_vtop((unsigned long)address); } -#define inb_p(addr) get_user_byte_io((char *)(addr)) -#define inb(addr) get_user_byte_io((char *)(addr)) -static inline void put_user_byte_io(char val,char *addr) +extern inline void * phys_to_virt(unsigned long address) { - __asm__ __volatile__ ("moveb %0,%1" - : /* no outputs */ - :"r" (val),"m" (*addr) - : "memory"); + return (void *) mm_ptov(address); } -#define outb_p(x,addr) put_user_byte_io((x),(char *)(addr)) -#define outb(x,addr) put_user_byte_io((x),(char *)(addr)) + +/* + * IO bus memory addresses are 1:1 with the physical address + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +#endif /* __KERNEL__ */ #endif /* _M68K_IO_H */ diff --git a/include/asm-m68k/ioctl.h b/include/asm-m68k/ioctl.h new file mode 100644 index 000000000..385aa8c7f --- /dev/null +++ b/include/asm-m68k/ioctl.h @@ -0,0 +1,80 @@ +/* $Id: ioctl.h,v 1.1 1996/08/24 12:43:44 root Exp $ + * + * linux/ioctl.h for Linux by H.H. Bergman. + */ + +#ifndef _M68K_IOCTL_H +#define _M68K_IOCTL_H + +/* ioctl command encoding: 32 bits total, command in lower 16 bits, + * size of the parameter structure in the lower 14 bits of the + * upper 16 bits. + * Encoding the size of the parameter structure in the ioctl request + * is useful for catching programs compiled with old versions + * and to avoid overwriting user space outside the user buffer area. + * The highest 2 bits are reserved for indicating the ``access mode''. + * NOTE: This limits the max parameter size to 16kB -1 ! + */ + +/* + * I don't really have any idea about what this should look like, so + * for the time being, this is heavily based on the PC definitions. + */ + +/* + * The following is for compatibility across the various Linux + * platforms. The i386 ioctl numbering scheme doesn't really enforce + * a type field. De facto, however, the top 8 bits of the lower 16 + * bits are indeed used as a type field, so we might just as well make + * this explicit here. Please be sure to use the decoding macros + * below from now on. + */ +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits. + */ +#define _IOC_NONE 0U +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode ioctl numbers.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* ...and for the drivers/sound files... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* _M68K_IOCTL_H */ diff --git a/include/asm-m68k/ioctls.h b/include/asm-m68k/ioctls.h new file mode 100644 index 000000000..77ad866b8 --- /dev/null +++ b/include/asm-m68k/ioctls.h @@ -0,0 +1,74 @@ +#ifndef __ARCH_M68K_IOCTLS_H__ +#define __ARCH_M68K_IOCTLS_H__ + +#include <asm/ioctl.h> + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* __ARCH_M68K_IOCTLS_H__ */ diff --git a/include/asm-m68k/ipc.h b/include/asm-m68k/ipc.h new file mode 100644 index 000000000..f1a75cc1d --- /dev/null +++ b/include/asm-m68k/ipc.h @@ -0,0 +1,28 @@ +#ifndef __m68k_IPC_H__ +#define __m68k_IPC_H__ + +/* + * These are used to wrap system calls on m68k. + * + * See arch/m68k/kernel/sys_m68k.c for ugly details.. + */ +struct ipc_kludge { + struct msgbuf *msgp; + long msgtyp; +}; + +#define SEMOP 1 +#define SEMGET 2 +#define SEMCTL 3 +#define MSGSND 11 +#define MSGRCV 12 +#define MSGGET 13 +#define MSGCTL 14 +#define SHMAT 21 +#define SHMDT 22 +#define SHMGET 23 +#define SHMCTL 24 + +#define IPCCALL(version,op) ((version)<<16 | (op)) + +#endif diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h index c8f300ca8..7789be42f 100644 --- a/include/asm-m68k/irq.h +++ b/include/asm-m68k/irq.h @@ -1,6 +1,101 @@ #ifndef _M68K_IRQ_H_ #define _M68K_IRQ_H_ -/* dummy for m68k */ +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +#include <linux/config.h> + +/* + * # of m68k interrupts + */ + +#define SYS_IRQS 8 + +/* + * This should be the same as the max(NUM_X_SOURCES) for all the + * different m68k hosts compiled into the kernel. + * Currently the Atari has 72 and the Amiga 24, but if both are + * supported in the kernel it is better to make room for 72. + */ +#if defined(CONFIG_ATARI) +#define NR_IRQS (72+SYS_IRQS) +#else +#define NR_IRQS (24+SYS_IRQS) +#endif + +/* + * Interrupt source definitions + * General interrupt sources are the level 1-7. + * Adding an interrupt service routine for one of these sources + * results in the addition of that routine to a chain of routines. + * Each one is called in succession. Each individual interrupt + * service routine should determine if the device associated with + * that routine requires service. + */ + +#define IRQ1 (1) /* level 1 interrupt */ +#define IRQ2 (2) /* level 2 interrupt */ +#define IRQ3 (3) /* level 3 interrupt */ +#define IRQ4 (4) /* level 4 interrupt */ +#define IRQ5 (5) /* level 5 interrupt */ +#define IRQ6 (6) /* level 6 interrupt */ +#define IRQ7 (7) /* level 7 interrupt (non-maskable) */ + +/* + * "Generic" interrupt sources + */ + +#define IRQ_SCHED_TIMER (8) /* interrupt source for scheduling timer */ + +/* + * Machine specific interrupt sources. + * + * Adding an interrupt service routine for a source with this bit + * set indicates a special machine specific interrupt source. + * The machine specific files define these sources. + */ + +#define IRQ_MACHSPEC (0x10000000L) +#define IRQ_IDX(irq) ((irq) & ~IRQ_MACHSPEC) + +/* + * various flags for request_irq() + */ +#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ +#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ +#define IRQ_FLG_FAST (0x0004) +#define IRQ_FLG_SLOW (0x0008) +#define IRQ_FLG_STD (0x8000) /* internally used */ + +/* + * This structure is used to chain together the ISRs for a particular + * interrupt source (if it supports chaining). + */ +typedef struct irq_node { + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; + struct irq_node *next; +} irq_node_t; + +/* + * This structure has only 4 elements for speed reasons + */ +typedef struct irq_handler { + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; +} irq_handler_t; + +/* count of spurious interrupts */ +extern volatile unsigned int num_spurious; + +/* + * This function returns a new irq_node_t + */ +extern irq_node_t *new_irq_node(void); #endif /* _M68K_IRQ_H_ */ diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h new file mode 100644 index 000000000..68302fe60 --- /dev/null +++ b/include/asm-m68k/machdep.h @@ -0,0 +1,45 @@ +#ifndef _M68K_MACHDEP_H +#define _M68K_MACHDEP_H + +struct pt_regs; +struct kbd_repeat; +struct mktime; +struct hwclk_time; +struct gendisk; +struct buffer_head; + +extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)); +/* machine dependent keyboard functions */ +extern int (*mach_keyb_init) (void); +extern int (*mach_kbdrate) (struct kbd_repeat *); +extern void (*mach_kbd_leds) (unsigned int); +/* machine dependent irq functions */ +extern void (*mach_init_IRQ) (void); +extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); +extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id); +extern int (*mach_free_irq) (unsigned int irq, void *dev_id); +extern void (*mach_enable_irq) (unsigned int irq); +extern void (*mach_disable_irq) (unsigned int irq); +extern int (*mach_get_irq_list) (char *buf); +extern void (*mach_process_int) (int irq, struct pt_regs *fp); +/* machine dependent timer functions */ +extern unsigned long (*mach_gettimeoffset)(void); +extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour, + int *min, int *sec); +extern int (*mach_hwclk)(int, struct hwclk_time*); +extern int (*mach_set_clock_mmss)(unsigned long); +extern void (*mach_mksound)( unsigned int count, unsigned int ticks ); +extern void (*mach_reset)( void ); +extern int (*mach_floppy_init) (void); +extern unsigned long (*mach_hd_init) (unsigned long, unsigned long); +extern void (*mach_hd_setup)(char *, int *); +extern void (*waitbut)(void); +extern struct fb_info *(*mach_fb_init)(long *); +extern long mach_max_dma_address; +extern void (*mach_debug_init)(void); +extern void (*mach_video_setup)(char *, int *); +extern void (*mach_floppy_setup)(char *, int *); +extern void (*mach_floppy_eject)(void); + +#endif /* _M68K_MACHDEP_H */ diff --git a/include/asm-m68k/mman.h b/include/asm-m68k/mman.h new file mode 100644 index 000000000..cbee6c998 --- /dev/null +++ b/include/asm-m68k/mman.h @@ -0,0 +1,32 @@ +#ifndef __M68K_MMAN_H__ +#define __M68K_MMAN_H__ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __M68K_MMAN_H__ */ diff --git a/include/asm-m68k/mmu_context.h b/include/asm-m68k/mmu_context.h new file mode 100644 index 000000000..c5def1604 --- /dev/null +++ b/include/asm-m68k/mmu_context.h @@ -0,0 +1,9 @@ +#ifndef __68K_MMU_CONTEXT_H +#define __68K_MMU_CONTEXT_H + +/* + * get a new mmu context.. do we need this on the m68k? + */ +#define get_mmu_context(x) do { } while (0) + +#endif diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h new file mode 100644 index 000000000..82dbe59c3 --- /dev/null +++ b/include/asm-m68k/page.h @@ -0,0 +1,67 @@ +#ifndef _M68K_PAGE_H +#define _M68K_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#define STRICT_MM_TYPECHECKS + +#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) + +#ifdef STRICT_MM_TYPECHECKS +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd[16]; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((&x)->pmd[0]) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#else +/* + * .. while these make it easier on the compiler + */ +typedef unsigned long pte_t; +typedef struct { unsigned long pmd[16]; } pmd_t; +typedef unsigned long pgd_t; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) ((&x)->pmd[0]) +#define pgd_val(x) (x) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) (x) +#define __pgprot(x) (x) + +#endif + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* This handles the memory map.. */ +#define PAGE_OFFSET 0 +#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT) + +#endif /* __KERNEL__ */ + +#endif /* _M68K_PAGE_H */ diff --git a/include/asm-m68k/param.h b/include/asm-m68k/param.h new file mode 100644 index 000000000..475002cef --- /dev/null +++ b/include/asm-m68k/param.h @@ -0,0 +1,20 @@ +#ifndef _M68K_PARAM_H +#define _M68K_PARAM_H + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NGROUPS +#define NGROUPS 32 +#endif + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _M68K_PARAM_H */ diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h new file mode 100644 index 000000000..429a68938 --- /dev/null +++ b/include/asm-m68k/pgtable.h @@ -0,0 +1,741 @@ +#ifndef _M68K_PGTABLE_H +#define _M68K_PGTABLE_H + +#include<asm/setup.h> + +#ifndef __ASSEMBLY__ + +/* + * This file contains the functions and defines necessary to modify and use + * the m68k page table tree. + */ + +/* + * flush all atc entries (user-space entries only for the 680[46]0). + */ +static inline void __flush_tlb(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".word 0xf510\n"::); /* pflushan */ + else + __asm__ __volatile__("pflusha\n"::); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + if (CPU_IS_040_OR_060) { + register unsigned long a0 __asm__ ("a0") = addr; + __asm__ __volatile__(".word 0xf508" /* pflush (%a0) */ + : : "a" (a0)); + } else + __asm__ __volatile__("pflush #0,#0,(%0)" : : "a" (addr)); +} + +#define flush_tlb() __flush_tlb() + +/* + * flush all atc entries (both kernel and user-space entries). + */ +static inline void flush_tlb_all(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".word 0xf518\n"::); /* pflusha */ + else + __asm__ __volatile__("pflusha\n"::); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->mm) + __flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + if (vma->vm_mm == current->mm) + __flush_tlb_one(addr); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + if (mm == current->mm) + __flush_tlb(); +} + +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) do{ \ + ((*(pteptr)) = (pteval)); \ + if (CPU_IS_060) \ + __asm__ __volatile__(".word 0xf518\n"::); /* pflusha */ \ + } 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 25 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * entries per page directory level: the m68k is configured as three-level, + * so we do have PMD level physically. + */ +#define PTRS_PER_PTE 1024 +#define PTRS_PER_PMD 8 +#define PTRS_PER_PGD 128 + +/* the no. of pointers that fit on a page: this will go away */ +#define PTRS_PER_PAGE (PAGE_SIZE/sizeof(void*)) + +typedef pgd_t pgd_table[PTRS_PER_PGD]; +typedef pmd_t pmd_table[PTRS_PER_PMD]; +typedef pte_t pte_table[PTRS_PER_PTE]; + +#define PGD_TABLES_PER_PAGE (PAGE_SIZE/sizeof(pgd_table)) +#define PMD_TABLES_PER_PAGE (PAGE_SIZE/sizeof(pmd_table)) +#define PTE_TABLES_PER_PAGE (PAGE_SIZE/sizeof(pte_table)) + +typedef pgd_table pgd_tablepage[PGD_TABLES_PER_PAGE]; +typedef pmd_table pmd_tablepage[PMD_TABLES_PER_PAGE]; +typedef pte_table pte_tablepage[PTE_TABLES_PER_PAGE]; + +/* 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. ;) + */ +#define VMALLOC_OFFSET (8*1024*1024) +#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) + +#endif /* __ASSEMBLY__ */ + +/* + * Definitions for MMU descriptors + */ +#define _PAGE_PRESENT 0x001 +#define _PAGE_SHORT 0x002 +#define _PAGE_RONLY 0x004 +#define _PAGE_ACCESSED 0x008 +#define _PAGE_DIRTY 0x010 +#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ +#define _PAGE_COW 0x800 /* implemented in software */ +#define _PAGE_NOCACHE030 0x040 /* 68030 no-cache mode */ +#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */ +#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */ +#define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */ +#define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */ + +#define _DESCTYPE_MASK 0x003 + +#define _CACHEMASK040 (~0x060) +#define _TABLE_MASK (0xfffffe00) + +#define _PAGE_TABLE (_PAGE_SHORT) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE) + +#ifndef __ASSEMBLY__ + +/* This is the cache mode to be used for pages containing page descriptors for + * processors >= '040. It is in pte_mknocache(), and the variable is defined + * and initialized in head.S */ +extern int m68k_pgtable_cachemode; + +#if defined(CONFIG_M68040_OR_M68060_ONLY) +#define mm_cachebits _PAGE_CACHE040 +#elif defined(CONFIG_M68020_OR_M68030_ONLY) +#define mm_cachebits 0 +#else +extern unsigned long mm_cachebits; +#endif + +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | mm_cachebits) + +/* Alternate definitions that are compile time constants, for + initializing protection_map. The cachebits are fixed later. */ +#define PAGE_NONE_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) +#define PAGE_SHARED_C __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) +#define PAGE_COPY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) +#define PAGE_READONLY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) + +/* + * The m68k 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_C +#define __P001 PAGE_READONLY_C +#define __P010 PAGE_COPY_C +#define __P011 PAGE_COPY_C +#define __P100 PAGE_READONLY_C +#define __P101 PAGE_READONLY_C +#define __P110 PAGE_COPY_C +#define __P111 PAGE_COPY_C + +#define __S000 PAGE_NONE_C +#define __S001 PAGE_READONLY_C +#define __S010 PAGE_SHARED_C +#define __S011 PAGE_SHARED_C +#define __S100 PAGE_READONLY_C +#define __S101 PAGE_READONLY_C +#define __S110 PAGE_SHARED_C +#define __S111 PAGE_SHARED_C + +/* zero page used for uninitialized stuff */ +extern unsigned long empty_zero_page; + +/* + * 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 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) + +/* For virtual address to physical address conversion */ +extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const)); +extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); +#define VTOP(addr) (mm_vtop((unsigned long)(addr))) +#define PTOV(addr) (mm_ptov((unsigned long)(addr))) + +/* + * 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) = VTOP(page) + pgprot_val(pgprot); __pte; }) +#define mk_pte_phys(physpage, pgprot) \ +({ pte_t __pte; pte_val(__pte) = VTOP(physpage) + pgprot_val(pgprot); __pte; }) + +extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } + +extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) +{ + int i; + + ptep = (pte_t *) VTOP(ptep); + for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16) + pmdp->pmd[i] = _PAGE_TABLE | _PAGE_ACCESSED | (unsigned long)ptep; +} + +/* early termination version of the above */ +extern inline void pmd_set_et(pmd_t * pmdp, pte_t * ptep) +{ + int i; + + ptep = (pte_t *) VTOP(ptep); + for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16) + pmdp->pmd[i] = _PAGE_PRESENT | _PAGE_ACCESSED | (unsigned long)ptep; +} + +extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) +{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | VTOP(pmdp); } + +extern inline unsigned long pte_page(pte_t pte) +{ return PTOV(pte_val(pte) & PAGE_MASK); } + +extern inline unsigned long pmd_page2(pmd_t *pmd) +{ return PTOV(pmd_val(*pmd) & _TABLE_MASK); } +#define pmd_page(pmd) pmd_page2(&(pmd)) + +extern inline unsigned long pgd_page(pgd_t pgd) +{ return PTOV(pgd_val(pgd) & _TABLE_MASK); } + +extern inline int pte_none(pte_t pte) { return !pte_val(pte); } +extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } +extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } + +extern inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); } +#define pmd_none(pmd) pmd_none2(&(pmd)) +extern inline int pmd_bad2(pmd_t *pmd) { return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE; } +#define pmd_bad(pmd) pmd_bad2(&(pmd)) +extern inline int pmd_present2(pmd_t *pmd) { return pmd_val(*pmd) & _PAGE_TABLE; } +#define pmd_present(pmd) pmd_present2(&(pmd)) +extern inline void pmd_clear(pmd_t * pmdp) +{ + short i; + + for (i = 15; i >= 0; i--) + pmdp->pmd[i] = 0; +} + +extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); } +extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE; } +extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_TABLE; } + +extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; } + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +extern inline int pte_read(pte_t pte) { return 1; } +extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY); } +extern inline int pte_exec(pte_t pte) { return 1; } +extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } + +extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } +extern inline pte_t pte_rdprotect(pte_t pte) { return pte; } +extern inline pte_t pte_exprotect(pte_t pte) { return pte; } +extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_RONLY; return pte; } +extern inline pte_t pte_mkread(pte_t pte) { return pte; } +extern inline pte_t pte_mkexec(pte_t pte) { return pte; } +extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } +extern inline pte_t pte_mknocache(pte_t pte) +{ + pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode; + return pte; +} +extern inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | _PAGE_CACHE040; return pte; } + +/* to set the page-dir */ +extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir) +{ + tsk->tss.crp[0] = 0x80000000 | _PAGE_TABLE; + tsk->tss.crp[1] = VTOP(pgdir); + if (tsk == current) { + if (CPU_IS_040_OR_060) + __asm__ __volatile__ ("movel %0@,%/d0\n\t" + ".long 0x4e7b0806\n\t" + /* movec d0,urp */ + : : "a" (&tsk->tss.crp[1]) + : "d0"); + else + __asm__ __volatile__ ("movec %/cacr,%/d0\n\t" + "oriw #0x0808,%/d0\n\t" + "movec %/d0,%/cacr\n\t" + "pmove %0@,%/crp\n\t" + : : "a" (&tsk->tss.crp[0]) + : "d0"); + } +} + +#define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) + +/* to find an entry in a page-table-directory */ +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) +{ + return mm->pgd + (address >> PGDIR_SHIFT); +} + +extern pgd_t swapper_pg_dir[128]; +extern pgd_t kernel_pg_dir[128]; + +extern inline pgd_t * pgd_offset_k(unsigned long address) +{ + return kernel_pg_dir + (address >> PGDIR_SHIFT); +} + + +/* Find an entry in the second-level page table.. */ +extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); +} + +/* Find an entry in the third-level page table.. */ +extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address) +{ + return (pte_t *) pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); +} + +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any. + */ + +extern inline void nocache_page (unsigned long vaddr) +{ + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + if(CPU_IS_060) + __asm__ __volatile__ ("movel %0,%/a0\n\t" + ".word 0xf470" + : : "g" (VTOP(vaddr)) + : "a0"); + + dir = pgd_offset_k(vaddr); + pmdp = pmd_offset(dir,vaddr); + ptep = pte_offset(pmdp,vaddr); + *ptep = pte_mknocache(*ptep); + } +} + +static inline void cache_page (unsigned long vaddr) +{ + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + dir = pgd_offset_k(vaddr); + pmdp = pmd_offset(dir,vaddr); + ptep = pte_offset(pmdp,vaddr); + *ptep = pte_mkcache(*ptep); + } +} + + +extern const char PgtabStr_bad_pmd[]; +extern const char PgtabStr_bad_pgd[]; +extern const char PgtabStr_bad_pmdk[]; +extern const char PgtabStr_bad_pgdk[]; + +extern inline void pte_free(pte_t * pte) +{ + cache_page((unsigned long)pte); + free_page((unsigned long) pte); +} + +extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t * page = (pte_t *)__get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + memset((void *) page, 0, PAGE_SIZE); + nocache_page((unsigned long)page); + pmd_set(pmd,page); + return page + address; + } + pmd_set(pmd, BAD_PAGETABLE); + return NULL; + } + free_page((unsigned long)page); + } + if (pmd_bad(*pmd)) { + printk(PgtabStr_bad_pmd, pmd_val(*pmd)); + pmd_set(pmd, BAD_PAGETABLE); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +extern pmd_t *get_pointer_table (void); +extern void free_pointer_table (pmd_t *); +extern pmd_t *get_kpointer_table (void); +extern void free_kpointer_table (pmd_t *); + +extern inline void pmd_free(pmd_t * pmd) +{ + free_pointer_table (pmd); +} + +extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) +{ + address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + if (pgd_none(*pgd)) { + pmd_t *page = get_pointer_table(); + if (pgd_none(*pgd)) { + if (page) { + pgd_set(pgd, page); + return page + address; + } + pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); + return NULL; + } + free_pointer_table(page); + } + if (pgd_bad(*pgd)) { + printk(PgtabStr_bad_pgd, pgd_val(*pgd)); + pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); + return NULL; + } + return (pmd_t *) pgd_page(*pgd) + address; +} + +extern inline void pte_free_kernel(pte_t * pte) +{ + cache_page((unsigned long)pte); + free_page((unsigned long) pte); +} + +extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + nocache_page((unsigned long)page); + pmd_set(pmd, page); + return page + address; + } + pmd_set(pmd, BAD_PAGETABLE); + return NULL; + } + free_page((unsigned long) page); + } + if (pmd_bad(*pmd)) { + printk(PgtabStr_bad_pmdk, pmd_val(*pmd)); + pmd_set(pmd, BAD_PAGETABLE); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +extern inline void pmd_free_kernel(pmd_t * pmd) +{ + free_kpointer_table(pmd); +} + +extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address) +{ + address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + if (pgd_none(*pgd)) { + pmd_t *page = get_kpointer_table(); + if (pgd_none(*pgd)) { + if (page) { + pgd_set(pgd, page); + return page + address; + } + pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); + return NULL; + } + free_kpointer_table(page); + } + if (pgd_bad(*pgd)) { + printk(PgtabStr_bad_pgdk, pgd_val(*pgd)); + pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); + return NULL; + } + return (pmd_t *) pgd_page(*pgd) + address; +} + +extern inline void pgd_free(pgd_t * pgd) +{ + free_pointer_table ((pmd_t *) pgd); +} + +extern inline pgd_t * pgd_alloc(void) +{ + return (pgd_t *)get_pointer_table (); +} + +#define flush_icache() \ +do { \ + if (CPU_IS_040_OR_060) \ + asm __volatile__ ("nop; .word 0xf498 /* cinva %%ic */"); \ + else \ + asm __volatile__ ("movec %/cacr,%/d0;" \ + "oriw %0,%/d0;" \ + "movec %/d0,%/cacr" \ + : /* no outputs */ \ + : "i" (FLUSH_I) \ + : "d0"); \ +} while (0) + +/* + * invalidate the cache for the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_clear (unsigned long paddr, int len); +/* + * push any dirty cache in the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_push (unsigned long paddr, int len); + +/* + * push and invalidate pages in the specified user virtual + * memory range. + */ +extern void cache_push_v (unsigned long vaddr, int len); + +/* cache code */ +#define FLUSH_I_AND_D (0x00000808) +#define FLUSH_I (0x00000008) + +/* This is needed whenever the virtual mapping of the current + process changes. */ +#define __flush_cache_all() \ + do { \ + if (CPU_IS_040_OR_060) \ + __asm__ __volatile__ ("nop; .word 0xf478\n" ::); \ + else \ + __asm__ __volatile__ ("movec %%cacr,%%d0\n\t" \ + "orw %0,%%d0\n\t" \ + "movec %%d0,%%cacr" \ + : : "di" (FLUSH_I_AND_D) : "d0"); \ + } while (0) + +#define __flush_cache_030() \ + do { \ + if (CPU_IS_020_OR_030) \ + __asm__ __volatile__ ("movec %%cacr,%%d0\n\t" \ + "orw %0,%%d0\n\t" \ + "movec %%d0,%%cacr" \ + : : "di" (FLUSH_I_AND_D) : "d0"); \ + } while (0) + +#define flush_cache_all() __flush_cache_all() + +extern inline void flush_cache_mm(struct mm_struct *mm) +{ +#if FLUSH_VIRTUAL_CACHE_040 + if (mm == current->mm) __flush_cache_all(); +#else + if (mm == current->mm) __flush_cache_030(); +#endif +} + +extern inline void flush_cache_range(struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + if (mm == current->mm){ +#if FLUSH_VIRTUAL_CACHE_040 + if (CPU_IS_040_OR_060) + cache_push_v(start, end-start); + else +#endif + __flush_cache_030(); + } +} + +extern inline void flush_cache_page(struct vm_area_struct *vma, + unsigned long vmaddr) +{ + if (vma->vm_mm == current->mm){ +#if FLUSH_VIRTUAL_CACHE_040 + if (CPU_IS_040_OR_060) + cache_push_v(vmaddr, PAGE_SIZE); + else +#endif + __flush_cache_030(); + } +} + +/* Push the page at kernel virtual address and clear the icache */ +extern inline void flush_page_to_ram (unsigned long address) +{ + if (CPU_IS_040_OR_060) { + register unsigned long tmp __asm ("a0") = VTOP(address); + __asm__ __volatile__ ("nop\n\t" + ".word 0xf470 /* cpushp %%dc,(%0) */\n\t" + ".word 0xf490 /* cinvp %%ic,(%0) */" + : : "a" (tmp)); + } + else + __asm volatile ("movec %%cacr,%%d0\n\t" + "orw %0,%%d0\n\t" + "movec %%d0,%%cacr" + : : "di" (FLUSH_I) : "d0"); +} + +/* Push n pages at kernel virtual address and clear the icache */ +extern inline void flush_pages_to_ram (unsigned long address, int n) +{ + if (CPU_IS_040_OR_060) { + while (n--) { + register unsigned long tmp __asm ("a0") = VTOP(address); + __asm__ __volatile__ ("nop\n\t" + ".word 0xf470 /* cpushp %%dc,(%0) */\n\t" + ".word 0xf490 /* cinvp %%ic,(%0) */" + : : "a" (tmp)); + address += PAGE_SIZE; + } + } + else + __asm volatile ("movec %%cacr,%%d0\n\t" + "orw %0,%%d0\n\t" + "movec %%d0,%%cacr" + : : "di" (FLUSH_I) : "d0"); +} + +/* + * Check if the addr/len goes up to the end of a physical + * memory chunk. Used for DMA functions. + */ +int mm_end_of_chunk (unsigned long addr, int len); + +/* + * Map some physical address range into the kernel address space. The + * code is copied and adapted from map_chunk(). + */ +extern unsigned long kernel_map(unsigned long paddr, unsigned long size, + int nocacheflag, unsigned long *memavailp ); +/* + * Change the cache mode of some kernel address range. + */ +extern void kernel_set_cachemode( unsigned long address, unsigned long size, + unsigned cmode ); + +/* Values for nocacheflag and cmode */ +#define KERNELMAP_FULL_CACHING 0 +#define KERNELMAP_NOCACHE_SER 1 +#define KERNELMAP_NOCACHE_NONSER 2 +#define KERNELMAP_NO_COPYBACK 3 + +/* + * The m68k doesn't have any external MMU info: the kernel page + * tables contain all the necessary information. + */ +extern inline void update_mmu_cache(struct vm_area_struct * vma, + unsigned long address, pte_t pte) +{ +} + +/* + * I don't know what is going on here, but since these were changed, + * swapping hasn't been working on the 68040. + */ + +#define SWP_TYPE(entry) (((entry) >> 2) & 0x7f) +#if 0 +#define SWP_OFFSET(entry) ((entry) >> 9) +#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9)) +#else +#define SWP_OFFSET(entry) ((entry) >> PAGE_SHIFT) +#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << PAGE_SHIFT)) +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* _M68K_PGTABLE_H */ diff --git a/include/asm-m68k/posix_types.h b/include/asm-m68k/posix_types.h new file mode 100644 index 000000000..535095971 --- /dev/null +++ b/include/asm-m68k/posix_types.h @@ -0,0 +1,51 @@ +#ifndef __ARCH_M68K_POSIX_TYPES_H +#define __ARCH_M68K_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) + +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) + +#undef __FD_ISSET +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h new file mode 100644 index 000000000..d228816af --- /dev/null +++ b/include/asm-m68k/processor.h @@ -0,0 +1,92 @@ +/* + * include/asm-m68k/processor.h + * + * Copyright (C) 1995 Hamish Macdonald + */ + +#ifndef __ASM_M68K_PROCESSOR_H +#define __ASM_M68K_PROCESSOR_H + +#include <asm/segment.h> + +/* + * User space process size: 3.75GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#define TASK_SIZE (0xF0000000UL) + +/* + * Bus types + */ +#define EISA_bus 0 +#define MCA_bus 0 + +/* MAX floating point unit state size (FSAVE/FRESTORE) */ +#define FPSTATESIZE (216/sizeof(unsigned char)) + +/* + * if you change this structure, you must change the code and offsets + * in m68k/machasm.S + */ + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short sr; /* saved status register */ + unsigned short fs; /* saved fs (sfc, dfc) */ + unsigned long crp[2]; /* cpu root pointer */ + unsigned long esp0; /* points to SR of stack frame */ + unsigned long fp[8*3]; + unsigned long fpcntl[3]; /* fp control regs */ + unsigned char fpstate[FPSTATESIZE]; /* floating point state */ +}; + +#define INIT_MMAP { &init_mm, 0, 0x40000000, __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED), VM_READ | VM_WRITE | VM_EXEC } + +#define INIT_TSS { \ + sizeof(init_kernel_stack) + (long) init_kernel_stack, 0, \ + PS_S, KERNEL_DS, \ + {0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \ +} + +#define alloc_kernel_stack() __get_free_page(GFP_KERNEL) +#define free_kernel_stack(page) free_page((page)) + +/* + * Do necessary setup to start up a newly executed thread. + */ +static inline void start_thread(struct pt_regs * regs, unsigned long pc, + unsigned long usp) +{ + unsigned long nilstate = 0; + + /* clear floating point state */ + __asm__ __volatile__ ("frestore %0@" : : "a" (&nilstate)); + + /* reads from user space */ + set_fs(USER_DS); + + regs->pc = pc; + regs->sr &= ~0x2000; + wrusp(usp); +} + +/* + * Return saved PC of a blocked thread. + */ +extern inline unsigned long thread_saved_pc(struct thread_struct *t) +{ + return ((unsigned long *)((struct switch_stack *)t->ksp)->a6)[1]; +} + +/* + * Return_address is a replacement for __builtin_return_address(count) + * which on certain architectures cannot reasonably be implemented in GCC + * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * Note that __builtin_return_address(x>=1) is forbidden because the GCC + * aborts compilation on some CPUs. It's simply not possible to unwind + * some CPU's stackframes. + */ +#define return_address() __builtin_return_address(0) + +#endif diff --git a/include/asm-m68k/ptrace.h b/include/asm-m68k/ptrace.h new file mode 100644 index 000000000..449b7bd8e --- /dev/null +++ b/include/asm-m68k/ptrace.h @@ -0,0 +1,73 @@ +#ifndef _M68K_PTRACE_H +#define _M68K_PTRACE_H + +#define PT_D1 0 +#define PT_D2 1 +#define PT_D3 2 +#define PT_D4 3 +#define PT_D5 4 +#define PT_D6 5 +#define PT_D7 6 +#define PT_A0 7 +#define PT_A1 8 +#define PT_A2 9 +#define PT_A3 10 +#define PT_A4 11 +#define PT_A5 12 +#define PT_A6 13 +#define PT_D0 14 +#define PT_USP 15 +#define PT_ORIG_D0 16 +#define PT_SR 17 +#define PT_PC 18 + +#ifndef __ASSEMBLY__ + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long d1; + long d2; + long d3; + long d4; + long d5; + long a0; + long a1; + long d0; + long orig_d0; + long stkadj; + unsigned short sr; + unsigned long pc; + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ +}; + +/* + * This is the extended stack used by signal handlers and the context + * switcher: it's pushed after the normal "struct pt_regs". + */ +struct switch_stack { + unsigned long d6; + unsigned long d7; + unsigned long a2; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long retpc; +}; + +#ifdef __KERNEL__ + +#ifndef PS_S +#define PS_S (0x2000) +#define PS_M (0x1000) +#endif + +#define user_mode(regs) (!((regs)->sr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _M68K_PTRACE_H */ diff --git a/include/asm-m68k/resource.h b/include/asm-m68k/resource.h new file mode 100644 index 000000000..f94ce2708 --- /dev/null +++ b/include/asm-m68k/resource.h @@ -0,0 +1,39 @@ +#ifndef _M68K_RESOURCE_H +#define _M68K_RESOURCE_H + +/* + * Resource limits + */ + +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_RSS 5 /* max resident set size */ +#define RLIMIT_NPROC 6 /* max number of processes */ +#define RLIMIT_NOFILE 7 /* max number of open files */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space*/ +#define RLIMIT_AS 9 /* address space limit */ + +#define RLIM_NLIMITS 10 + +#ifdef __KERNEL__ + +#define INIT_RLIMITS \ +{ \ + {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, \ + {_STK_LIM, _STK_LIM}, \ + { 0, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, \ + {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, \ + {NR_OPEN, NR_OPEN}, \ + {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX} \ +} + +#endif /* __KERNEL__ */ + +#endif /* _M68K_RESOURCE_H */ diff --git a/include/asm-m68k/segment.h b/include/asm-m68k/segment.h index 89079be3f..5fe0c033f 100644 --- a/include/asm-m68k/segment.h +++ b/include/asm-m68k/segment.h @@ -1,208 +1,21 @@ -/* - * linux/include/asm-m68k/segment.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive - * for more details. - */ - -/* - * 680x0 support added by Hamish Macdonald - */ - #ifndef _M68K_SEGMENT_H #define _M68K_SEGMENT_H -static inline unsigned char get_user_byte(const char * addr) -{ - register unsigned char _v; - - __asm__ __volatile__ ("movesb %1,%0":"=r" (_v):"m" (*addr)); - return _v; -} - -#define get_fs_byte(addr) get_user_byte((char *)(addr)) - -static inline unsigned short get_user_word(const short *addr) -{ - unsigned short _v; - - __asm__ __volatile__ ("movesw %1,%0":"=r" (_v):"m" (*addr)); - return _v; -} - -#define get_fs_word(addr) get_user_word((short *)(addr)) - -static inline unsigned long get_user_long(const int *addr) -{ - unsigned long _v; - - __asm__ __volatile__ ("movesl %1,%0":"=r" (_v):"m" (*addr)); \ - return _v; -} - -#define get_fs_long(addr) get_user_long((int *)(addr)) - -static inline void put_user_byte(char val,char *addr) -{ - __asm__ __volatile__ ("movesb %0,%1": /* no outputs */ :"r" (val),"m" (*addr) : "memory"); -} - -#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) - -static inline void put_user_word(short val,short * addr) -{ - __asm__ __volatile__ ("movesw %0,%1": /* no outputs */ :"r" (val),"m" (*addr) : "memory"); -} - -#define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) - -static inline void put_user_long(unsigned long val,int * addr) -{ - __asm__ __volatile__ ("movesl %0,%1": /* no outputs */ :"r" (val),"m" (*addr) : "memory"); -} - -#define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) - -static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - if (n == 0) return; - __asm__ __volatile__ ("1:\n\t" - "moveb %1@+,d0\n\t" - "movesb d0,%2@+\n\t" - "dbra %0,1b\n\t" - "clrw %0\n\t" - "subql #1,%0\n\t" - "bccs 1b" - : "=d" (n), "=a" (from), "=a" (to) - : "1" (from), "2" (to), "0" (n-1) - : "d0", "memory"); -} - -static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - if (n == 0) { - return; - } else if (n == 1) { - put_user_byte(*(const char *) from, (char *) to); - return; - } else if (n == 2) { - put_user_word(*(const short *) from, (short *) to); - return; - } else if (n == 3) { - put_user_word(*(const short *) from, (short *) to); - put_user_byte(*(2+(const char *) from), 2+(char *) to); - return; - } else if (n == 4) { - put_user_long(*(const int *) from, (int *) to); - return; - } -#if 0 -#define COMMON(x) \ -__asm__("cld\n\t" \ - "push %%es\n\t" \ - "push %%fs\n\t" \ - "pop %%es\n\t" \ - "rep ; movsl\n\t" \ - x \ - "pop %%es" \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("movsb\n\t"); - return; - case 2: - COMMON("movsw\n\t"); - return; - case 3: - COMMON("movsw\n\tmovsb\n\t"); - return; - } -#undef COMMON -#else - __generic_memcpy_tofs(to,from,n); +/* define constants */ +/* Address spaces (FC0-FC2) */ +#define USER_DATA (1) +#ifndef USER_DS +#define USER_DS (USER_DATA) #endif -} - -static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - if (n == 0) return; - __asm__ __volatile__ ("1:\n\t" - "movesb %1@+,d0\n\t" - "moveb d0,%2@+\n\t" - "dbra %0,1b\n\t" - "clrw %0\n\t" - "subql #1,%0\n\t" - "bccs 1b" - : "=d" (n), "=a" (from), "=a" (to) - : "1" (from), "2" (to), "0" (n-1) - : "d0", "memory"); -} - -static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - if (n == 0) { - return; - } else if (n == 1) { - *(char *)to = get_user_byte((const char *) from); - return; - } else if (n == 2) { - *(short *)to = get_user_word((const short *) from); - return; - } else if (n == 3) { - *(short *) to = get_user_word((const short *) from); - *(2+(char *) to) = get_user_byte(2+(const char *) from); - return; - } else if (n == 4) { - *(int *) to = get_user_long((const int *) from); - return; - } -#if 0 -#define COMMON(x) \ -__asm__("cld\n\t" \ - "rep ; fs ; movsl\n\t" \ - x \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si","memory") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("fs ; movsb"); - return; - case 2: - COMMON("fs ; movsw"); - return; - case 3: - COMMON("fs ; movsw\n\tfs ; movsb"); - return; - } -#undef COMMON -#else - __generic_memcpy_fromfs(to,from,n); +#define USER_PROGRAM (2) +#define SUPER_DATA (5) +#ifndef KERNEL_DS +#define KERNEL_DS (SUPER_DATA) #endif -} +#define SUPER_PROGRAM (6) +#define CPU_SPACE (7) -#define memcpy_fromfs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_fromfs((to),(from),(n)) : \ - __generic_memcpy_fromfs((to),(from),(n))) - -#define memcpy_tofs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_tofs((to),(from),(n)) : \ - __generic_memcpy_tofs((to),(from),(n))) +#ifndef __ASSEMBLY__ /* * Get/set the SFC/DFC registers for MOVES instructions @@ -211,7 +24,7 @@ __asm__("cld\n\t" \ static inline unsigned long get_fs(void) { unsigned long _v; - __asm__ ("movec dfc,%0":"=r" (_v):); + __asm__ ("movec %/dfc,%0":"=r" (_v):); return _v; } @@ -219,23 +32,16 @@ static inline unsigned long get_fs(void) static inline unsigned long get_ds(void) { /* return the supervisor data space code */ - return 0x5; + return KERNEL_DS; } static inline void set_fs(unsigned long val) { - __asm__ __volatile__ ("movec %0,sfc\n\t" - "movec %0,dfc\n\t" - : /* no outputs */ : "r" (val), "r" (val) : "memory"); + __asm__ __volatile__ ("movec %0,%/sfc\n\t" + "movec %0,%/dfc\n\t" + : /* no outputs */ : "r" (val) : "memory"); } -/* define constants */ -/* Address spaces (FC0-FC2) */ -#ifndef USER_DS -#define USER_DS (1) -#endif -#ifndef KERNEL_DS -#define KERNEL_DS (5) -#endif +#endif /* __ASSEMBLY__ */ #endif /* _M68K_SEGMENT_H */ diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h new file mode 100644 index 000000000..ef23201c3 --- /dev/null +++ b/include/asm-m68k/semaphore.h @@ -0,0 +1,68 @@ +#ifndef _M68K_SEMAPHORE_H +#define _M68K_SEMAPHORE_H + +#include <linux/linkage.h> + +/* + * SMP- and interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + * + * m68k version by Andreas Schwab + */ + +struct semaphore { + int count; + int waiting; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { 1, 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) + +asmlinkage void __down_failed(void /* special register calling convention */); +asmlinkage void __up_wakeup(void /* special register calling convention */); + +extern void __down(struct semaphore * sem); +extern void __up(struct semaphore * sem); + +/* + * This is ugly, but we want the default case to fall through. + * "down_failed" is a special asm handler that calls the C + * routine that actually waits. See arch/m68k/lib/semaphore.S + */ +extern inline void down(struct semaphore * sem) +{ + register struct semaphore *sem1 __asm__ ("%a1") = sem; + __asm__ __volatile__( + "| atomic down operation\n\t" + "lea %%pc@(1f),%%a0\n\t" + "subql #1,%0\n\t" + "jmi " SYMBOL_NAME_STR(__down_failed) "\n" + "1:" + : /* no outputs */ + : "m" (sem->count), "a" (sem1) + : "%a0", "memory"); +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +extern inline void up(struct semaphore * sem) +{ + register struct semaphore *sem1 __asm__ ("%a1") = sem; + __asm__ __volatile__( + "| atomic up operation\n\t" + "lea %%pc@(1f),%%a0\n\t" + "addql #1,%0\n\t" + "jle " SYMBOL_NAME_STR(__up_wakeup) "\n" + "1:" + : /* no outputs */ + : "m" (sem->count), "a" (sem1) + : "%a0", "memory"); +} + +#endif diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h new file mode 100644 index 000000000..fecf48e55 --- /dev/null +++ b/include/asm-m68k/serial.h @@ -0,0 +1,380 @@ +/* + * include/linux/serial.h + * + * Copyright (C) 1992 by Theodore Ts'o. + * + * Redistribution of this file is permitted under the terms of the GNU + * Public License (GPL) + */ + +#ifndef _M68K_SERIAL_H +#define _M68K_SERIAL_H + + +/* m68k serial port types are numbered from 100 to avoid interference + * with the PC types (1..4) + */ +#define PORT_UNKNOWN 0 +#define PORT_8250 1 +#define PORT_16450 2 +#define PORT_16550 3 +#define PORT_16550A 4 +#define PORT_CIRRUS 5 +#define SER_SCC_NORM 100 /* standard SCC channel */ +#define SER_SCC_DMA 101 /* SCC channel with DMA support */ +#define SER_MFP_CTRL 102 /* standard MFP port with modem control signals */ +#define SER_MFP_BARE 103 /* MFP port without modem controls */ +#define SER_MIDI 104 /* Atari MIDI */ +#define SER_AMIGA 105 /* Amiga built-in serial port */ +#define SER_IOEXT 106 /* Amiga GVP IO-Extender (16c552) */ +#define SER_MFC_III 107 /* Amiga BSC Multiface Card III (MC68681) */ + + +struct serial_struct { + int type; + int line; + int port; + int irq; + int flags; + int xmit_fifo_size; + int custom_divisor; + int baud_base; + unsigned short close_delay; + char reserved_char[2]; + int hub6; + unsigned short closing_wait; /* time to wait before closing */ + unsigned short closing_wait2; /* no longer used... */ + int reserved[4]; +}; + +/* + * For the close wait times, 0 means wait forever for serial port to + * flush its output. 65535 means don't wait at all. + */ +#define ASYNC_CLOSING_WAIT_INF 0 +#define ASYNC_CLOSING_WAIT_NONE 65535 + +/* This function tables does the abstraction from the underlying + * hardware: + * + * init(): Initialize the port as necessary, set RTS and DTR and + * enable interrupts. It does not need to set the speed and other + * parameters, because change_speed() is called, too. + * deinit(): Stop and shutdown the port (e.g. disable interrupts, ...) + * enab_tx_int(): Enable or disable the Tx Buffer Empty interrupt + * independently from other interrupt sources. If the int is + * enabled, the transmitter should also be restarted, i.e. if there + * are any chars to be sent, they should be put into the Tx + * register. The real en/disabling of the interrupt may be a no-op + * if there is no way to do this or it is too complex. This Tx ints + * are just disabled to save some interrupts if the transmitter is + * stopped anyway. But the restarting must be implemented! + * check_custom_divisor(): Check the given custom divisor for legality + * and return 0 if OK, non-zero otherwise. + * change_speed(): Set port speed, character size, number of stop + * bits and parity from the termios structure. If the user wants + * to set the speed with a custom divisor, he is required to + * check the baud_base first! + * throttle(): Set or clear the RTS line according to 'status'. + * set_break(): Set or clear the 'Send a Break' flag. + * get_serial_info(): Fill in the baud_base and custom_divisor + * fields of a serial_struct. It may also modify other fields, if + * needed. + * get_modem_info(): Return the status of RTS, DTR, DCD, RI, DSR and CTS. + * set_modem_info(): Set the status of RTS and DTR according to + * 'new_dtr' and 'new_rts', resp. 0 = clear, 1 = set, -1 = don't change + * ioctl(): Process any port-specific ioctl's. This pointer may be + * NULL, if the port has no own ioctl's. + * stop_receive(): Turn off the Rx part of the port, so no more characters + * will be received. This is called before shutting the port down. + * trans_empty(): Return !=0 if there are no more characters still to be + * sent out (Tx buffer register and FIFOs empty) + * check_open(): Is called before the port is opened. The driver can check + * if that's ok and return an error code, or keep track of the opening + * even before init() is called. Use deinit() for matching closing of the + * port. + * + */ + +struct async_struct; + +typedef struct { + void (*init)( struct async_struct *info ); + void (*deinit)( struct async_struct *info, int leave_dtr ); + void (*enab_tx_int)( struct async_struct *info, int enab_flag ); + int (*check_custom_divisor)( struct async_struct *info, int baud_base, + int divisor ); + void (*change_speed)( struct async_struct *info ); + void (*throttle)( struct async_struct *info, int status ); + void (*set_break)( struct async_struct *info, int break_flag ); + void (*get_serial_info)( struct async_struct *info, + struct serial_struct *retinfo ); + unsigned int (*get_modem_info)( struct async_struct *info ); + int (*set_modem_info)( struct async_struct *info, int new_dtr, + int new_rts ); + int (*ioctl)( struct tty_struct *tty, struct file *file, + struct async_struct *info, unsigned int cmd, + unsigned long arg ); + void (*stop_receive)( struct async_struct *info ); + int (*trans_empty)( struct async_struct *info ); + int (*check_open)( struct async_struct *info, struct tty_struct *tty, + struct file *file ); +} SERIALSWITCH; + +/* + * Definitions for async_struct (and serial_struct) flags field + */ +#define ASYNC_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes + on the callout port */ +#define ASYNC_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */ +#define ASYNC_SAK 0x0004 /* Secure Attention Key (Orange book) */ +#define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */ + +#define ASYNC_SPD_MASK 0x0030 +#define ASYNC_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */ + +#define ASYNC_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */ +#define ASYNC_SPD_CUST 0x0030 /* Use user-specified divisor */ + +#define ASYNC_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */ +#define ASYNC_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */ +#define ASYNC_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */ +#define ASYNC_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */ +#define ASYNC_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */ + +#define ASYNC_FLAGS 0x0FFF /* Possible legal async flags */ +#define ASYNC_USR_MASK 0x0430 /* Legal flags that non-privileged + * users can set or reset */ + +/* Internal flags used only by drivers/char/m68kserial.c */ +#define ASYNC_INITIALIZED 0x80000000 /* Serial port was initialized */ +#define ASYNC_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */ +#define ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device is active */ +#define ASYNC_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */ +#define ASYNC_CLOSING 0x08000000 /* Serial port is closing */ +#define ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */ +#define ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */ + +/* + * Serial input interrupt line counters -- external structure + * Four lines can interrupt: CTS, DSR, RI, DCD + */ +struct serial_icounter_struct { + int cts, dsr, rng, dcd; + int reserved[16]; +}; + + +#ifdef __KERNEL__ +/* + * This is our internal structure for each serial port's state. + * + * Many fields are paralleled by the structure used by the serial_struct + * structure. + * + * For definitions of the flags field, see tty.h + */ + +#include <linux/termios.h> +#include <linux/tqueue.h> + +/* + * Counters of the input lines (CTS, DSR, RI, CD) interrupts + */ +struct async_icount { + __u32 cts, dsr, rng, dcd; +}; + +struct async_struct { + int magic; + int baud_base; + int port; + int irq; + int flags; /* defined in tty.h */ + int hub6; /* HUB6 plus one */ + int type; + struct tty_struct *tty; + int read_status_mask; + int ignore_status_mask; + int timeout; + int xmit_fifo_size; + int custom_divisor; + int x_char; /* xon/xoff character */ + int close_delay; + unsigned short closing_wait; + unsigned short closing_wait2; + int IER; /* Interrupt Enable Register */ + int MCR; /* Modem control register */ + int MCR_noint; /* MCR with interrupts off */ + unsigned long event; + unsigned long last_active; + int line; + int count; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + long session; /* Session of opening process */ + long pgrp; /* pgrp of opening process */ + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; + int xmit_cnt; + struct tq_struct tqueue; + struct tq_struct tqueue_hangup; + struct termios normal_termios; + struct termios callout_termios; + struct wait_queue *open_wait; + struct wait_queue *close_wait; + struct wait_queue *delta_msr_wait; + struct async_icount icount; /* kernel counters for the 4 input interrupts */ + struct async_struct *next_port; /* For the linked list */ + struct async_struct *prev_port; + void *board_base; /* board-base address for use with + boards carrying several UART's, + like some Amiga boards. */ + unsigned short nr_uarts; /* UART-counter, that indicates + how many UART's there are on + the board. If the board has a + IRQ-register, this can be used + to check if any of the uarts, + on the board has requested an + interrupt, instead of checking + IRQ-registers on all UART's */ + SERIALSWITCH *sw; /* functions to manage this port */ +}; + +#define SERIAL_MAGIC 0x5301 + +/* + * The size of the serial xmit buffer is 1 page, or 4096 bytes + */ +#define SERIAL_XMIT_SIZE 4096 + +/* + * Events are used to schedule things to happen at timer-interrupt + * time, instead of at rs interrupt time. + */ +#define RS_EVENT_WRITE_WAKEUP 0 + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +/* Export to allow PCMCIA to use this - Dave Hinds */ +extern int register_serial(struct serial_struct *req); +extern void unregister_serial(int line); +extern struct async_struct rs_table[]; +extern task_queue tq_serial; + + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static __inline__ void rs_sched_event(struct async_struct *info, int event) +{ + info->event |= 1 << event; + queue_task_irq(&info->tqueue, &tq_serial); + mark_bh(SERIAL_BH); +} + +static __inline__ void rs_receive_char( struct async_struct *info, + int ch, int err ) +{ + struct tty_struct *tty = info->tty; + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + return; + tty->flip.count++; + if (err == TTY_BREAK) { + if (info->flags & ASYNC_SAK) + do_SAK(tty); + } + *tty->flip.flag_buf_ptr++ = err; + *tty->flip.char_buf_ptr++ = ch; + queue_task_irq(&tty->flip.tqueue, &tq_timer); +} + +static __inline__ int rs_get_tx_char( struct async_struct *info ) +{ + unsigned char ch; + + if (info->x_char) { + ch = info->x_char; + info->x_char = 0; + return( ch ); + } + + if (info->xmit_cnt <= 0 || info->tty->stopped || info->tty->hw_stopped) + return( -1 ); + + ch = info->xmit_buf[info->xmit_tail++]; + info->xmit_tail &= SERIAL_XMIT_SIZE - 1; + if (--info->xmit_cnt < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + return( ch ); +} + +static __inline__ int rs_no_more_tx( struct async_struct *info ) +{ + return( info->xmit_cnt <= 0 || + info->tty->stopped || + info->tty->hw_stopped ); +} + +static __inline__ void rs_dcd_changed( struct async_struct *info, int dcd ) + +{ + /* update input line counter */ + info->icount.dcd++; + wake_up_interruptible(&info->delta_msr_wait); + + if (info->flags & ASYNC_CHECK_CD) { +#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) + printk("ttyS%d CD now %s...", info->line, + dcd ? "on" : "off"); +#endif + if (dcd) { + wake_up_interruptible(&info->open_wait); + } else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_CALLOUT_NOHUP))) { +#ifdef SERIAL_DEBUG_OPEN + printk("scheduling hangup..."); +#endif + queue_task_irq(&info->tqueue_hangup, + &tq_scheduler); + } + } +} + + +void rs_stop( struct tty_struct *tty ); +void rs_start( struct tty_struct *tty ); + +static __inline__ void rs_check_cts( struct async_struct *info, int cts ) +{ + /* update input line counter */ + info->icount.cts++; + wake_up_interruptible(&info->delta_msr_wait); + + if ((info->flags & ASYNC_CTS_FLOW) && info->tty) + if (info->tty->hw_stopped) { + if (cts) { +#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) + printk("CTS tx start..."); +#endif + info->tty->hw_stopped = 0; + rs_start( info->tty ); + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + return; + } + } else { + if (!cts) { + info->tty->hw_stopped = 1; + rs_stop( info->tty ); + } + } + +} + + +#endif /* __KERNEL__ */ + +#endif /* _M68K_SERIAL_H */ diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h new file mode 100644 index 000000000..96f91963b --- /dev/null +++ b/include/asm-m68k/setup.h @@ -0,0 +1,397 @@ +/* +** asm/setup.h -- Definition of the Linux/m68k boot information structure +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created 09/29/92 by Greg Harp +** +** 5/2/94 Roman Hodek: +** Added bi_atari part of the machine dependent union bi_un; for now it +** contains just a model field to distinguish between TT and Falcon. +** 26/7/96 Roman Zippel: +** Renamed to setup.h; added some useful macros to allow gcc some +** optimizations if possible. +*/ + +#ifndef _M68K_SETUP_H +#define _M68K_SETUP_H + +#include <linux/config.h> +#include <asm/zorro.h> + +/* + * Amiga specific part of bootinfo structure. + */ + +#define NUM_AUTO 16 + +#ifndef __ASSEMBLY__ + +#define AMIGAHW_DECLARE(name) unsigned name : 1 +#define AMIGAHW_SET(name) (boot_info.bi_amiga.hw_present.name = 1) +#define AMIGAHW_PRESENT(name) (boot_info.bi_amiga.hw_present.name) + +struct bi_Amiga { + int model; /* Amiga Model (3000?) */ + int num_autocon; /* # of autoconfig devices found */ + struct ConfigDev autocon[NUM_AUTO]; /* up to 16 autoconfig devices */ +#ifdef HACKER_KERNEL + void (*exit_func)(void); /* addr of function to exit kernel */ + unsigned long chip_addr; /* start of chip memory (bytes) */ +#endif + unsigned long chip_size; /* size of chip memory (bytes) */ + unsigned char vblank; /* VBLANK frequency */ + unsigned char psfreq; /* power supply frequency */ + unsigned long eclock; /* EClock frequency */ + unsigned long chipset; /* native chipset present */ + struct { + /* video hardware */ + AMIGAHW_DECLARE(AMI_VIDEO); /* Amiga Video */ + AMIGAHW_DECLARE(AMI_BLITTER); /* Amiga Blitter */ + AMIGAHW_DECLARE(AMBER_FF); /* Amber Flicker Fixer */ + /* sound hardware */ + AMIGAHW_DECLARE(AMI_AUDIO); /* Amiga Audio */ + /* disk storage interfaces */ + AMIGAHW_DECLARE(AMI_FLOPPY); /* Amiga Floppy */ + AMIGAHW_DECLARE(A3000_SCSI); /* SCSI (wd33c93, A3000 alike) */ + AMIGAHW_DECLARE(A4000_SCSI); /* SCSI (ncr53c710, A4000T alike) */ + AMIGAHW_DECLARE(A1200_IDE); /* IDE (A1200 alike) */ + AMIGAHW_DECLARE(A4000_IDE); /* IDE (A4000 alike) */ + AMIGAHW_DECLARE(CD_ROM); /* CD ROM drive */ + /* other I/O hardware */ + AMIGAHW_DECLARE(AMI_KEYBOARD); /* Amiga Keyboard */ + AMIGAHW_DECLARE(AMI_MOUSE); /* Amiga Mouse */ + AMIGAHW_DECLARE(AMI_SERIAL); /* Amiga Serial */ + AMIGAHW_DECLARE(AMI_PARALLEL); /* Amiga Parallel */ + /* real time clocks */ + AMIGAHW_DECLARE(A2000_CLK); /* Hardware Clock (A2000 alike) */ + AMIGAHW_DECLARE(A3000_CLK); /* Hardware Clock (A3000 alike) */ + /* supporting hardware */ + AMIGAHW_DECLARE(CHIP_RAM); /* Chip RAM */ + AMIGAHW_DECLARE(PAULA); /* Paula (8364) */ + AMIGAHW_DECLARE(DENISE); /* Denise (8362) */ + AMIGAHW_DECLARE(DENISE_HR); /* Denise (8373) */ + AMIGAHW_DECLARE(LISA); /* Lisa (8375) */ + AMIGAHW_DECLARE(AGNUS_PAL); /* Normal/Fat PAL Agnus (8367/8371) */ + AMIGAHW_DECLARE(AGNUS_NTSC); /* Normal/Fat NTSC Agnus (8361/8370) */ + AMIGAHW_DECLARE(AGNUS_HR_PAL); /* Fat Hires PAL Agnus (8372) */ + AMIGAHW_DECLARE(AGNUS_HR_NTSC); /* Fat Hires NTSC Agnus (8372) */ + AMIGAHW_DECLARE(ALICE_PAL); /* PAL Alice (8374) */ + AMIGAHW_DECLARE(ALICE_NTSC); /* NTSC Alice (8374) */ + AMIGAHW_DECLARE(MAGIC_REKICK); /* A3000 Magic Hard Rekick */ + AMIGAHW_DECLARE(ZORRO); /* Zorro AutoConfig */ + } hw_present; +}; + +#else /* __ASSEMBLY__ */ + +BI_amiga_model = BI_un +BI_amiga_num_autcon = BI_amiga_model+4 +BI_amiga_autocon = BI_amiga_num_autcon+4 +#ifdef HACKER_KERNEL +BI_amiga_exit_func = BI_amiga_autocon+(CD_sizeof*NUM_AUTO) +BI_amiga_chip_addr = BI_amiga_exit_func+4 +BI_amiga_chip_size = BI_amiga_chip_addr+4 +#else +BI_amiga_chip_size = BI_amiga_autocon+(CD_sizeof*NUM_AUTO) +#endif +BI_amiga_vblank = BI_amiga_chip_size+4 +BI_amiga_psfreq = BI_amiga_vblank+1 +BI_amiga_eclock = BI_amiga_psfreq+1 +BI_amiga_chipset = BI_amiga_eclock+4 +BI_amiga_hw_present = BI_amiga_chipset+4 + +#endif /* __ASSEMBLY__ */ + +/* Atari specific part of bootinfo */ + +/* + * Define several Hardware-Chips for indication so that for the ATARI we do + * no longer decide whether it is a Falcon or other machine . It's just + * important what hardware the machine uses + */ + +/* ++roman 08/08/95: rewritten from ORing constants to a C bitfield */ + +#ifndef __ASSEMBLY__ + +#define ATARIHW_DECLARE(name) unsigned name : 1 +#define ATARIHW_SET(name) (boot_info.bi_atari.hw_present.name = 1) +#define ATARIHW_PRESENT(name) (boot_info.bi_atari.hw_present.name) + +struct bi_Atari { + struct { + /* video hardware */ + ATARIHW_DECLARE(STND_SHIFTER); /* ST-Shifter - no base low ! */ + ATARIHW_DECLARE(EXTD_SHIFTER); /* STe-Shifter - 24 bit address */ + ATARIHW_DECLARE(TT_SHIFTER); /* TT-Shifter */ + ATARIHW_DECLARE(VIDEL_SHIFTER); /* Falcon-Shifter */ + /* sound hardware */ + ATARIHW_DECLARE(YM_2149); /* Yamaha YM 2149 */ + ATARIHW_DECLARE(PCM_8BIT); /* PCM-Sound in STe-ATARI */ + ATARIHW_DECLARE(CODEC); /* CODEC Sound (Falcon) */ + /* disk storage interfaces */ + ATARIHW_DECLARE(TT_SCSI); /* Directly mapped NCR5380 */ + ATARIHW_DECLARE(ST_SCSI); /* NCR5380 via ST-DMA (Falcon) */ + ATARIHW_DECLARE(ACSI); /* Standard ACSI like in STs */ + ATARIHW_DECLARE(IDE); /* IDE Interface */ + ATARIHW_DECLARE(FDCSPEED); /* 8/16 MHz switch for FDC */ + /* other I/O hardware */ + ATARIHW_DECLARE(ST_MFP); /* The ST-MFP (there should + be no Atari without + it... but who knows?) */ + ATARIHW_DECLARE(TT_MFP); /* 2nd MFP */ + ATARIHW_DECLARE(SCC); /* Serial Communications Contr. */ + ATARIHW_DECLARE(ST_ESCC); /* SCC Z83230 in an ST */ + ATARIHW_DECLARE(ANALOG_JOY); /* Paddle Interface for STe + and Falcon */ + ATARIHW_DECLARE(MICROWIRE); /* Microwire Interface */ + /* DMA */ + ATARIHW_DECLARE(STND_DMA); /* 24 Bit limited ST-DMA */ + ATARIHW_DECLARE(EXTD_DMA); /* 32 Bit ST-DMA */ + ATARIHW_DECLARE(SCSI_DMA); /* DMA for the NCR5380 */ + ATARIHW_DECLARE(SCC_DMA); /* DMA for the SCC */ + /* real time clocks */ + ATARIHW_DECLARE(TT_CLK); /* TT compatible clock chip */ + ATARIHW_DECLARE(MSTE_CLK); /* Mega ST(E) clock chip */ + /* supporting hardware */ + ATARIHW_DECLARE(SCU); /* System Control Unit */ + ATARIHW_DECLARE(BLITTER); /* Blitter */ + ATARIHW_DECLARE(VME); /* VME Bus */ + } hw_present; + unsigned long mch_cookie; /* _MCH cookie from TOS */ +}; + +/* mch_cookie values (upper word) */ +#define ATARI_MCH_ST 0 +#define ATARI_MCH_STE 1 +#define ATARI_MCH_TT 2 +#define ATARI_MCH_FALCON 3 + +struct mem_info { + unsigned long addr; /* physical address of memory chunk */ + unsigned long size; /* length of memory chunk (in bytes) */ +}; + +#else /* __ASSEMBLY__ */ + +MI_addr = 0 +MI_size = MI_addr+4 +MI_sizeof = MI_size+4 + +#endif /* __ASSEMBLY__ */ + +#define NUM_MEMINFO 4 + +#define MACH_AMIGA 1 +#define MACH_ATARI 2 +#define MACH_MAC 3 + +/* + * CPU and FPU types + */ + +#define CPUB_68020 0 +#define CPUB_68030 1 +#define CPUB_68040 2 +#define CPUB_68060 3 +#define FPUB_68881 5 +#define FPUB_68882 6 +#define FPUB_68040 7 /* Internal FPU */ +#define FPUB_68060 8 /* Internal FPU */ + +#define CPU_68020 (1<<CPUB_68020) +#define CPU_68030 (1<<CPUB_68030) +#define CPU_68040 (1<<CPUB_68040) +#define CPU_68060 (1<<CPUB_68060) +#define CPU_MASK (31) +#define FPU_68881 (1<<FPUB_68881) +#define FPU_68882 (1<<FPUB_68882) +#define FPU_68040 (1<<FPUB_68040) /* Internal FPU */ +#define FPU_68060 (1<<FPUB_68060) /* Internal FPU */ +#define FPU_MASK (0xfe0) + +#define CL_SIZE (256) + +/* + * machine type definitions + */ + +#if !defined(CONFIG_AMIGA) +# define MACH_IS_AMIGA (0) +#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) +# define MACH_IS_AMIGA (boot_info.machtype == MACH_AMIGA) +#else +# define CONFIG_AMIGA_ONLY +# define MACH_IS_AMIGA (1) +# define MACH_TYPE (MACH_AMIGA) +#endif + +#if !defined(CONFIG_ATARI) +# define MACH_IS_ATARI (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) +# define MACH_IS_ATARI (boot_info.machtype == MACH_ATARI) +#else +# define CONFIG_ATARI_ONLY +# define MACH_IS_ATARI (1) +# define MACH_TYPE (MACH_ATARI) +#endif + +#if defined(CONFIG_MAC) +# error Currently no Mac support! +#endif + +#ifndef MACH_TYPE +# define MACH_TYPE (boot_info.machtype) +#endif + +/* + * cpu type definitions + */ + +#if !defined(CONFIG_M68020) +# define CPU_IS_020 (0) +#elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060) +# define CPU_IS_020 (boot_info.cputype & CPU_68020) +#else +# define CONFIG_M68020_ONLY +# define CPU_IS_020 (1) +#endif + +#if !defined(CONFIG_M68030) +# define CPU_IS_030 (0) +#elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060) +# define CPU_IS_030 (boot_info.cputype & CPU_68030) +#else +# define CONFIG_M68030_ONLY +# define CPU_IS_030 (1) +#endif + +#if !defined(CONFIG_M68040) +# define CPU_IS_040 (0) +#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060) +# define CPU_IS_040 (boot_info.cputype & CPU_68040) +#else +# define CONFIG_M68040_ONLY +# define CPU_IS_040 (1) +#endif + +#if !defined(CONFIG_M68060) +# define CPU_IS_060 (0) +#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040) +# define CPU_IS_060 (boot_info.cputype & CPU_68060) +#else +# define CONFIG_M68060_ONLY +# define CPU_IS_060 (1) +#endif + +#if !defined(CONFIG_M68020) && !defined(CONFIG_M68030) +# define CPU_IS_020_OR_030 (0) +#else +# define CONFIG_M68020_OR_M68030 +# if defined(CONFIG_M68040) || defined(CONFIG_M68060) +# define CPU_IS_020_OR_030 (!m68k_is040or060) +# else +# define CONFIG_M68020_OR_M68030_ONLY +# define CPU_IS_020_OR_030 (1) +# endif +#endif + +#if !defined(CONFIG_M68040) && !defined(CONFIG_M68060) +# define CPU_IS_040_OR_060 (0) +#else +# define CONFIG_M68040_OR_M68060 +# if defined(CONFIG_M68020) || defined(CONFIG_M68030) +# define CPU_IS_040_OR_060 (m68k_is040or060) +# else +# define CONFIG_M68040_OR_M68060_ONLY +# define CPU_IS_040_OR_060 (1) +# endif +#endif + +#define CPU_TYPE (boot_info.cputype) + +#ifndef __ASSEMBLY__ +#ifdef __KERNEL__ + /* + * m68k_is040or060 is != 0 for a '040 or higher; + * used numbers are 4 for 68040 and 6 for 68060. + */ + +extern int m68k_is040or060; +#endif + +struct bootinfo { + unsigned long machtype; /* machine type */ + unsigned long cputype; /* system CPU & FPU */ + struct mem_info memory[NUM_MEMINFO]; /* memory description */ + int num_memory; /* # of memory blocks found */ + unsigned long ramdisk_size; /* ramdisk size in 1024 byte blocks */ + unsigned long ramdisk_addr; /* address of the ram disk in mem */ + char command_line[CL_SIZE]; /* kernel command line parameters */ + union { + struct bi_Amiga bi_ami; /* Amiga specific information */ + struct bi_Atari bi_ata; /* Atari specific information */ + } bi_un; +}; +#define bi_amiga bi_un.bi_ami +#define bi_atari bi_un.bi_ata +#define bi_mac bi_un.bi_mac + +extern struct bootinfo + boot_info; + +#else /* __ASSEMBLY__ */ + +BI_machtype = 0 +BI_cputype = BI_machtype+4 +BI_memory = BI_cputype+4 +BI_num_memory = BI_memory+(MI_sizeof*NUM_MEMINFO) +BI_ramdisk_size = BI_num_memory+4 +BI_ramdisk_addr = BI_ramdisk_size+4 +BI_command_line = BI_ramdisk_addr+4 +BI_un = BI_command_line+CL_SIZE + +#endif /* __ASSEMBLY__ */ + + +/* + * Stuff for bootinfo interface versioning + * + * At the start of kernel code, a 'struct bootversion' is located. bootstrap + * checks for a matching version of the interface before booting a kernel, to + * avoid user confusion if kernel and bootstrap don't work together :-) + * + * If incompatible changes are made to the bootinfo interface, the major + * number below should be stepped (and the minor reset to 0) for the + * appropriate machine. If a change is backward-compatible, the minor should + * be stepped. "Backwards-compatible" means that booting will work, but + * certain features may not. + */ + +#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */ +#define MK_BI_VERSION(major,minor) (((major)<<16)+(minor)) +#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff) +#define BI_VERSION_MINOR(v) ((v) & 0xffff) + +#ifndef __ASSEMBLY__ + +struct bootversion { + unsigned short branch; + unsigned long magic; + struct { + unsigned long machtype; + unsigned long version; + } machversions[0]; +}; + +#endif /* __ASSEMBLY__ */ + +#define AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) +#define ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) + +#endif /* _M68K_SETUP_H */ diff --git a/include/asm-m68k/shm.h b/include/asm-m68k/shm.h new file mode 100644 index 000000000..f59bbc39f --- /dev/null +++ b/include/asm-m68k/shm.h @@ -0,0 +1,24 @@ +#ifndef _M68K_SHM_H +#define _M68K_SHM_H + +/* format of page table entries that correspond to shared memory pages + currently out in swap space (see also mm/swap.c): + bits 0-1 (PAGE_PRESENT) is = 0 + bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE + bits 31..9 are used like this: + bits 15..9 (SHM_ID) the id of the shared memory segment + bits 30..16 (SHM_IDX) the index of the page within the shared memory segment + (actually only bits 25..16 get used since SHMMAX is so low) + bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach +*/ +/* on the m68k both bits 0 and 1 must be zero */ + +#define SHM_ID_SHIFT 9 +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +#endif /* _M68K_SHM_H */ diff --git a/include/asm-m68k/shmparam.h b/include/asm-m68k/shmparam.h new file mode 100644 index 000000000..d9e6a9e05 --- /dev/null +++ b/include/asm-m68k/shmparam.h @@ -0,0 +1,44 @@ +#ifndef _M68K_SHMPARAM_H +#define _M68K_SHMPARAM_H + +/* address range for shared memory attaches if no address passed to shmat() */ +#define SHM_RANGE_START 0xC0000000 +#define SHM_RANGE_END 0xD0000000 + +/* + * Format of a swap-entry for shared memory pages currently out in + * swap space (see also mm/swap.c). + * + * SWP_TYPE = SHM_SWP_TYPE + * SWP_OFFSET is used as follows: + * + * bits 0..6 : id of shared memory segment page belongs to (SHM_ID) + * bits 7..21: index of page within shared memory segment (SHM_IDX) + * (actually fewer bits get used since SHMMAX is so low) + */ + +/* + * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and + * there is a static array of size SHMMNI. + */ +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +/* + * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and + * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). + */ + +#define SHMMAX 0x1000000 /* max shared seg size (bytes) */ +#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ +#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ +#define SHMALL /* max shm system wide (pages) */ \ + (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ +#define SHMSEG SHMMNI /* max shared segs per process */ + +#endif /* _M68K_SHMPARAM_H */ diff --git a/include/asm-m68k/sigcontext.h b/include/asm-m68k/sigcontext.h new file mode 100644 index 000000000..a2d28c218 --- /dev/null +++ b/include/asm-m68k/sigcontext.h @@ -0,0 +1,19 @@ +#ifndef _ASM_M68k_SIGCONTEXT_H +#define _ASM_M68k_SIGCONTEXT_H + +struct sigcontext { + unsigned long sc_mask; /* old sigmask */ + unsigned long sc_usp; /* old user stack pointer */ + unsigned long sc_d0; + unsigned long sc_d1; + unsigned long sc_a0; + unsigned long sc_a1; + unsigned short sc_sr; + unsigned long sc_pc; + unsigned short sc_formatvec; + unsigned long sc_fpregs[2*3]; /* room for two fp registers */ + unsigned long sc_fpcntl[3]; + unsigned char sc_fpstate[216]; +}; + +#endif diff --git a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h new file mode 100644 index 000000000..1069ccc55 --- /dev/null +++ b/include/asm-m68k/signal.h @@ -0,0 +1,96 @@ +#ifndef _M68K_SIGNAL_H +#define _M68K_SIGNAL_H + +typedef unsigned long sigset_t; /* at least 32 bits */ + +#define _NSIG 32 +#define NSIG _NSIG + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGUNUSED 31 + +/* + * sa_flags values: SA_STACK is not currently supported, but will allow the + * usage of signal stacks by using the (now obsolete) sa_restorer field in + * the sigaction structure as a stack pointer. This is now possible due to + * the changes in signal handling. LBT 010493. + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. + */ +#define SA_NOCLDSTOP 1 +#define SA_SHIRQ 0x04000000 +#define SA_STACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_INTERRUPT 0x20000000 +#define SA_NOMASK 0x40000000 +#define SA_ONESHOT 0x80000000 + +#ifdef __KERNEL__ +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#endif + +#define SIG_BLOCK 0 /* for blocking signals */ +#define SIG_UNBLOCK 1 /* for unblocking signals */ +#define SIG_SETMASK 2 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__sighandler_t)(int); + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +struct sigaction { + __sighandler_t sa_handler; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#ifdef __KERNEL__ +#include <asm/sigcontext.h> +#endif + +#endif /* _M68K_SIGNAL_H */ diff --git a/include/asm-m68k/socket.h b/include/asm-m68k/socket.h new file mode 100644 index 000000000..529a3ffef --- /dev/null +++ b/include/asm-m68k/socket.h @@ -0,0 +1,25 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockoptions(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-m68k/sockios.h b/include/asm-m68k/sockios.h new file mode 100644 index 000000000..85ace3da5 --- /dev/null +++ b/include/asm-m68k/sockios.h @@ -0,0 +1,12 @@ +#ifndef __ARCH_M68K_SOCKIOS__ +#define __ARCH_M68K_SOCKIOS__ + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +#endif /* __ARCH_M68K_SOCKIOS__ */ diff --git a/include/asm-m68k/stat.h b/include/asm-m68k/stat.h new file mode 100644 index 000000000..919520ff1 --- /dev/null +++ b/include/asm-m68k/stat.h @@ -0,0 +1,41 @@ +#ifndef _M68K_STAT_H +#define _M68K_STAT_H + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +struct stat { + unsigned short st_dev; + unsigned short __pad1; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _M68K_STAT_H */ diff --git a/include/asm-m68k/statfs.h b/include/asm-m68k/statfs.h new file mode 100644 index 000000000..1ee08965d --- /dev/null +++ b/include/asm-m68k/statfs.h @@ -0,0 +1,25 @@ +#ifndef _M68K_STATFS_H +#define _M68K_STATFS_H + +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif + +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_spare[6]; +}; + +#endif /* _M68K_STATFS_H */ diff --git a/include/asm-m68k/string.h b/include/asm-m68k/string.h index 70466ed5e..57f83e3fc 100644 --- a/include/asm-m68k/string.h +++ b/include/asm-m68k/string.h @@ -1,20 +1,23 @@ #ifndef _M68K_STRING_H_ #define _M68K_STRING_H_ -#define __USE_PORTABLE_STRINGS_H_ +#include <linux/config.h> +#include <asm/page.h> +#define __HAVE_ARCH_STRCPY extern inline char * strcpy(char * dest,const char *src) { char *xdest = dest; __asm__ __volatile__ ("1:\tmoveb %1@+,%0@+\n\t" - "bne 1b" + "jne 1b" : "=a" (dest), "=a" (src) : "0" (dest), "1" (src) : "memory"); return xdest; } +#define __HAVE_ARCH_STRNCPY extern inline char * strncpy(char *dest, const char *src, size_t n) { char *xdest = dest; @@ -24,9 +27,9 @@ extern inline char * strncpy(char *dest, const char *src, size_t n) __asm__ __volatile__ ("1:\tmoveb %1@+,%0@+\n\t" - "beq 2f\n\t" + "jeq 2f\n\t" "subql #1,%2\n\t" - "bne 1b\n\t" + "jne 1b\n\t" "2:" : "=a" (dest), "=a" (src), "=d" (n) : "0" (dest), "1" (src), "2" (n) @@ -34,10 +37,116 @@ extern inline char * strncpy(char *dest, const char *src, size_t n) return xdest; } -#define __USE_PORTABLE_strcat +#define __HAVE_ARCH_STRCAT +extern inline char * strcat(char * dest, const char * src) +{ + char *tmp = dest; + + while (*dest) + dest++; + while ((*dest++ = *src++)) + ; + + return tmp; +} -#define __USE_PORTABLE_strncat +#define __HAVE_ARCH_STRNCAT +extern inline char * strncat(char *dest, const char *src, size_t count) +{ + char *tmp = dest; + + if (count) { + while (*dest) + dest++; + while ((*dest++ = *src++)) { + if (--count == 0) { + *dest++='\0'; + break; + } + } + } + + return tmp; +} +#define __HAVE_ARCH_STRCHR +extern inline char * strchr(const char * s, int c) +{ + const char ch = c; + + for(; *s != ch; ++s) + if (*s == '\0') + return( NULL ); + return( (char *) s); +} + +#define __HAVE_ARCH_STRPBRK +extern inline char * strpbrk(const char * cs,const char * ct) +{ + const char *sc1,*sc2; + + for( sc1 = cs; *sc1 != '\0'; ++sc1) + for( sc2 = ct; *sc2 != '\0'; ++sc2) + if (*sc1 == *sc2) + return((char *) sc1); + return( NULL ); +} + +#define __HAVE_ARCH_STRSPN +extern inline size_t strspn(const char *s, const char *accept) +{ + const char *p; + const char *a; + size_t count = 0; + + for (p = s; *p != '\0'; ++p) + { + for (a = accept; *a != '\0'; ++a) + if (*p == *a) + break; + if (*a == '\0') + return count; + else + ++count; + } + + return count; +} + +#define __HAVE_ARCH_STRTOK +extern inline char * strtok(char * s,const char * ct) +{ + char *sbegin, *send; + + sbegin = s ? s : ___strtok; + if (!sbegin) { + return NULL; + } + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') { + ___strtok = NULL; + return( NULL ); + } + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + ___strtok = send; + return (sbegin); +} + +/* strstr !! */ + +#define __HAVE_ARCH_STRLEN +extern inline size_t strlen(const char * s) +{ + const char *sc; + for (sc = s; *sc != '\0'; ++sc) ; + return(sc - s); +} + +/* strnlen !! */ + +#define __HAVE_ARCH_STRCMP extern inline int strcmp(const char * cs,const char * ct) { char __res; @@ -45,10 +154,10 @@ extern inline int strcmp(const char * cs,const char * ct) __asm__ ("1:\tmoveb %0@+,%2\n\t" /* get *cs */ "cmpb %1@+,%2\n\t" /* compare a byte */ - "bne 2f\n\t" /* not equal, break out */ + "jne 2f\n\t" /* not equal, break out */ "tstb %2\n\t" /* at end of cs? */ - "bne 1b\n\t" /* no, keep going */ - "bra 3f\n\t" /* strings are equal */ + "jne 1b\n\t" /* no, keep going */ + "jra 3f\n\t" /* strings are equal */ "2:\tsubb %1@-,%2\n\t" /* *cs - *ct */ "3:" : "=a" (cs), "=a" (ct), "=d" (__res) @@ -56,6 +165,7 @@ extern inline int strcmp(const char * cs,const char * ct) return __res; } +#define __HAVE_ARCH_STRNCMP extern inline int strncmp(const char * cs,const char * ct,size_t count) { char __res; @@ -65,13 +175,13 @@ extern inline int strncmp(const char * cs,const char * ct,size_t count) __asm__ ("1:\tmovb %0@+,%3\n\t" /* get *cs */ "cmpb %1@+,%3\n\t" /* compare a byte */ - "bne 3f\n\t" /* not equal, break out */ + "jne 3f\n\t" /* not equal, break out */ "tstb %3\n\t" /* at end of cs? */ - "beq 4f\n\t" /* yes, all done */ + "jeq 4f\n\t" /* yes, all done */ "subql #1,%2\n\t" /* no, adjust count */ - "bne 1b\n\t" /* more to do, keep going */ + "jne 1b\n\t" /* more to do, keep going */ "2:\tmoveq #0,%3\n\t" /* strings are equal */ - "bra 4f\n\t" + "jra 4f\n\t" "3:\tsubb %1@-,%3\n\t" /* *cs - *ct */ "4:" : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res) @@ -79,76 +189,353 @@ extern inline int strncmp(const char * cs,const char * ct,size_t count) return __res; } -#define __USE_PORTABLE_strchr +#define __HAVE_ARCH_MEMSET +/* + * This is really ugly, but its highly optimizatiable by the + * compiler and is meant as compensation for gcc's missing + * __builtin_memset(). For the 680[23]0 it might be worth considering + * the optimal number of misaligned writes compared to the number of + * tests'n'branches needed to align the destination address. The + * 680[46]0 doesn't really care due to their copy-back caches. + * 10/09/96 - Jes Sorensen + */ +extern inline void * __memset_g(void * s, int c, size_t count) +{ + void *xs = s; + size_t temp; + + if (!count) + return xs; -#define __USE_PORTABLE_strlen + c &= 0xff; + c |= c << 8; + c |= c << 16; -#define __USE_PORTABLE_strspn + if (count < 36){ + long *ls = s; -#define __USE_PORTABLE_strpbrk + switch(count){ + case 32: case 33: case 34: case 35: + *ls++ = c; + case 28: case 29: case 30: case 31: + *ls++ = c; + case 24: case 25: case 26: case 27: + *ls++ = c; + case 20: case 21: case 22: case 23: + *ls++ = c; + case 16: case 17: case 18: case 19: + *ls++ = c; + case 12: case 13: case 14: case 15: + *ls++ = c; + case 8: case 9: case 10: case 11: + *ls++ = c; + case 4: case 5: case 6: case 7: + *ls++ = c; + break; + default: + break; + } + s = ls; + if (count & 0x02){ + short *ss = s; + *ss++ = c; + s = ss; + } + if (count & 0x01){ + char *cs = s; + *cs++ = c; + s = cs; + } + return xs; + } -#define __USE_PORTABLE_strtok + if ((long) s & 1) + { + char *cs = s; + *cs++ = c; + s = cs; + count--; + } + if (count > 2 && (long) s & 2) + { + short *ss = s; + *ss++ = c; + s = ss; + count -= 2; + } + temp = count >> 2; + if (temp) + { + long *ls = s; + temp--; + do + *ls++ = c; + while (temp--); + s = ls; + } + if (count & 2) + { + short *ss = s; + *ss++ = c; + s = ss; + } + if (count & 1) + { + char *cs = s; + *cs = c; + } + return xs; +} -extern inline void * memset(void * s,char c,size_t count) +/* + * __memset_page assumes that data is longword aligned. Most, if not + * all, of these page sized memsets are performed on page aligned + * areas, thus we do not need to check if the destination is longword + * aligned. Of course we suffer a serious performance loss if this is + * not the case but I think the risk of this ever happening is + * extremely small. We spend a lot of time clearing pages in + * get_empty_page() so I think it is worth it anyway. Besides, the + * 680[46]0 do not really care about misaligned writes due to their + * copy-back cache. + * + * The optimized case for the 680[46]0 is implemented using the move16 + * instruction. My tests showed that this implementation is 35-45% + * faster than the original implementation using movel, the only + * caveat is that the destination address must be 16-byte aligned. + * 01/09/96 - Jes Sorensen + */ +extern inline void * __memset_page(void * s,int c,size_t count) { - void *xs = s; + unsigned long data, tmp; + void *xs, *sp; + + xs = sp = s; + + c = c & 255; + data = c | (c << 8); + data |= data << 16; + +#if defined(CONFIG_OPTIMIZE_040) || defined(CONFIG_OPTIMIZE_060) + + if (((unsigned long) s) & 0x0f) + memset(s, c, count); + else{ + *((unsigned long *)(s))++ = data; + *((unsigned long *)(s))++ = data; + *((unsigned long *)(s))++ = data; + *((unsigned long *)(s))++ = data; + + __asm__ __volatile__("1:\t" + "move16 %2@+,%0@+\n\t" + "subqw #8,%2\n\t" + "subqw #8,%2\n\t" + "dbra %1,1b\n\t" + : "=a" (s), "=d" (tmp) + : "a" (sp), "0" (s), "1" ((count - 16) / 16 - 1) + ); + } + +#else + __asm__ __volatile__("1:\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "dbra %1,1b\n\t" + : "=a" (s), "=d" (tmp) + : "d" (data), "0" (s), "1" (count / 32 - 1) + ); +#endif - if (!count) - return xs; - __asm__ __volatile__ - ("1:\tmoveb %3,%0@+\n\t" - "subql #1,%1\n\t" - "bne 1b" - : "=a" (s), "=d" (count) - : "0" (s), "d" (c), "1" (count) - : "memory"); return xs; } -extern inline void * memcpy(void * to, const void * from, size_t n) +#define __memset_const(s,c,count) \ +((count==PAGE_SIZE) ? \ + __memset_page((s),(c),(count)) : \ + __memset_g((s),(c),(count))) + +#define memset(s, c, count) \ +(__builtin_constant_p(count) ? \ + __memset_const((s),(c),(count)) : \ + memset((s),(c),(count))) + +#define __HAVE_ARCH_MEMCPY +/* + * __builtin_memcpy() does not handle page-sized memcpys very well, + * thus following the same assumptions as for page-sized memsets, this + * function copies page-sized areas using an unrolled loop, without + * considering alignment. + * + * For the 680[46]0 only kernels we use the move16 instruction instead + * as it writes through the data-cache, invalidating the cache-lines + * touched. In this way we do not use up the entire data-cache (well, + * half of it on the 68060) by copying a page. An unrolled loop of two + * move16 instructions seem to the fastest. The only caveat is that + * both source and destination must be 16-byte aligned, if not we fall + * back to the generic memcpy function. - Jes + */ +extern inline void * __memcpy_page(void * to, const void * from, size_t count) { + unsigned long tmp; void *xto = to; - if (!n) - return xto; - __asm__ __volatile__ - ("1:\tmoveb %1@+,%0@+\n\t" - "subql #1,%2\n\t" - "bne 1b" - : "=a" (to), "=a" (from), "=d" (n) - : "0" (to), "1" (from), "2" (n) - : "memory" ); +#if defined(CONFIG_OPTIMIZE_040) || defined(CONFIG_OPTIMIZE_060) + + if (((unsigned long) to | (unsigned long) from) & 0x0f) + return memcpy(to, from, count); + + __asm__ __volatile__("1:\t" + "move16 %1@+,%0@+\n\t" + "move16 %1@+,%0@+\n\t" + "dbra %2,1b\n\t" + : "=a" (to), "=a" (from), "=d" (tmp) + : "0" (to), "1" (from) , "2" (count / 32 - 1) + ); +#else + __asm__ __volatile__("1:\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "dbra %2,1b\n\t" + : "=a" (to), "=a" (from), "=d" (tmp) + : "0" (to), "1" (from) , "2" (count / 32 - 1) + ); +#endif return xto; } +#define __memcpy_const(to, from, n) \ +((n==PAGE_SIZE) ? \ + __memcpy_page((to),(from),(n)) : \ + __builtin_memcpy((to),(from),(n))) + +#define memcpy(to, from, n) \ +(__builtin_constant_p(n) ? \ + __memcpy_const((to),(from),(n)) : \ + memcpy((to),(from),(n))) + +#define __HAVE_ARCH_MEMMOVE extern inline void * memmove(void * dest,const void * src, size_t n) { void *xdest = dest; + size_t temp; if (!n) return xdest; if (dest < src) - __asm__ __volatile__ - ("1:\tmoveb %1@+,%0@+\n\t" - "subql #1,%2\n\t" - "bne 1b" - : "=a" (dest), "=a" (src), "=d" (n) - : "0" (dest), "1" (src), "2" (n) - : "memory" ); + { + if ((long) dest & 1) + { + char *cdest = dest; + const char *csrc = src; + *cdest++ = *csrc++; + dest = cdest; + src = csrc; + n--; + } + if (n > 2 && (long) dest & 2) + { + short *sdest = dest; + const short *ssrc = src; + *sdest++ = *ssrc++; + dest = sdest; + src = ssrc; + n -= 2; + } + temp = n >> 2; + if (temp) + { + long *ldest = dest; + const long *lsrc = src; + temp--; + do + *ldest++ = *lsrc++; + while (temp--); + dest = ldest; + src = lsrc; + } + if (n & 2) + { + short *sdest = dest; + const short *ssrc = src; + *sdest++ = *ssrc++; + dest = sdest; + src = ssrc; + } + if (n & 1) + { + char *cdest = dest; + const char *csrc = src; + *cdest = *csrc; + } + } else - __asm__ __volatile__ - ("1:\tmoveb %1@-,%0@-\n\t" - "subql #1,%2\n\t" - "bne 1b" - : "=a" (dest), "=a" (src), "=d" (n) - : "0" (dest+n), "1" (src+n), "2" (n) - : "memory" ); + { + dest = (char *) dest + n; + src = (const char *) src + n; + if ((long) dest & 1) + { + char *cdest = dest; + const char *csrc = src; + *--cdest = *--csrc; + dest = cdest; + src = csrc; + n--; + } + if (n > 2 && (long) dest & 2) + { + short *sdest = dest; + const short *ssrc = src; + *--sdest = *--ssrc; + dest = sdest; + src = ssrc; + n -= 2; + } + temp = n >> 2; + if (temp) + { + long *ldest = dest; + const long *lsrc = src; + temp--; + do + *--ldest = *--lsrc; + while (temp--); + dest = ldest; + src = lsrc; + } + if (n & 2) + { + short *sdest = dest; + const short *ssrc = src; + *--sdest = *--ssrc; + dest = sdest; + src = ssrc; + } + if (n & 1) + { + char *cdest = dest; + const char *csrc = src; + *--cdest = *--csrc; + } + } return xdest; } -#define __USE_PORTABLE_memcmp - -#define __USE_PORTABLE_memscan +#define __HAVE_ARCH_MEMCMP +#define memcmp(cs, ct, n) \ +(__builtin_constant_p(n) ? \ + __builtin_memcmp((cs),(ct),(n)) : \ + memcmp((cs),(ct),(n))) #endif /* _M68K_STRING_H_ */ diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h index e987f1f46..859c748e3 100644 --- a/include/asm-m68k/system.h +++ b/include/asm-m68k/system.h @@ -1,53 +1,153 @@ +#ifndef _M68K_SYSTEM_H +#define _M68K_SYSTEM_H + +#include <linux/config.h> /* get configuration macros */ +#include <linux/linkage.h> +#include <asm/segment.h> + +extern inline unsigned long rdusp(void) { + unsigned long usp; + + __asm__ __volatile__("movec %/usp,%0" + : "=d" (usp)); + return usp; +} + +extern inline void wrusp(unsigned long usp) { + __asm__ __volatile__("movec %0,%/usp" + : + : "d" (usp)); +} + /* - * linux/include/asm-m68k/system.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive - * for more details. + * switch_to(n) should switch tasks to task ptr, first checking that + * ptr isn't the current task, in which case it does nothing. This + * also clears the TS-flag if the task we switched to has used the + * math co-processor latest. */ - /* - * 680x0 support added by Hamish Macdonald + * switch_to() saves the extra registers, that are not saved + * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and + * a0-a1. Some of these are used by schedule() and its predecessors + * and so we might get see unexpected behaviors when a task returns + * with unexpected register values. + * + * syscall stores these registers itself and none of them are used + * by syscall after the function in the syscall has been called. + * + * Beware that resume now expects *next to be in d1 and the offset of + * tss to be in a1. This saves a few instructions as we no longer have + * to push them onto the stack and read them back right after. + * + * 02/17/96 - Jes Sorensen (jds@kom.auc.dk) + * + * Changed 96/09/19 by Andreas Schwab + * pass prev in a0, next in a1, offset of tss in d1, and whether + * the mm structures are shared in d2 (to avoid atc flushing). */ +asmlinkage void resume(void); +#define switch_to(prev,next) { \ + register void *_prev __asm__ ("a0") = (prev); \ + register void *_next __asm__ ("a1") = (next); \ + register int _tssoff __asm__ ("d1") = (int)&((struct task_struct *)0)->tss; \ + register char _shared __asm__ ("d2") = ((prev)->mm == (next)->mm); \ + __asm__ __volatile__("jbsr " SYMBOL_NAME_STR(resume) "\n\t" \ + : : "a" (_prev), "a" (_next), "d" (_tssoff), \ + "d" (_shared) \ + : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1"); \ +} -#ifndef _M68K_SYSTEM_H -#define _M68K_SYSTEM_H +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) -#include <linux/config.h> /* get configuration macros */ +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) #if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC) /* block out HSYNC on the atari */ -#define sti() __asm__ __volatile__ ("andiw #0xfbff,sr": : : "memory") +#define sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory") #else /* portable version */ -#define sti() __asm__ __volatile__ ("andiw #0xf8ff,sr": : : "memory") +#define sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") #endif /* machine compilation types */ -#define cli() __asm__ __volatile__ ("oriw #0x0700,sr": : : "memory") +#define cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") #define nop() __asm__ __volatile__ ("nop"::) +#define mb() __asm__ __volatile__ ("" : : :"memory") #define save_flags(x) \ -__asm__ __volatile__("movew sr,%0":"=d" (x) : /* no input */ :"memory") +__asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory") #define restore_flags(x) \ -__asm__ __volatile__("movew %0,sr": /* no outputs */ :"d" (x) : "memory") +__asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory") #define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc") -#define move_to_user_mode() \ - __asm__ __volatile__ ("movel sp,usp\n\t" /* setup user sp */ \ - "movec %0,msp\n\t" /* setup kernel sp */ \ - "andiw #0xdfff,sr" /* return to user mode */ \ - : /* no output */ \ - : "r" (current->kernel_stack_page + PAGE_SIZE) \ - : "memory", "sp") - -static inline void clear_fpu(void) { - unsigned long nilstate = 0; - __asm__ __volatile__ ("frestore %0@" : : "a" (&nilstate)); +#ifndef CONFIG_RMW_INSNS +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + unsigned long tmp, flags; + + save_flags(flags); + cli(); + + switch (size) { + case 1: + __asm__ __volatile__ + ("moveb %2,%0\n\t" + "moveb %1,%2" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 2: + __asm__ __volatile__ + ("movew %2,%0\n\t" + "movew %1,%2" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("movel %2,%0\n\t" + "movel %1,%2" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + } + restore_flags(flags); + return tmp; } +#else +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + switch (size) { + case 1: + __asm__ __volatile__ + ("moveb %2,%0\n\t" + "1:\n\t" + "casb %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 2: + __asm__ __volatile__ + ("movew %2,%0\n\t" + "1:\n\t" + "casw %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("movel %2,%0\n\t" + "1:\n\t" + "casl %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + } + return x; +} +#endif -#define halt() \ - __asm__ __volatile__ ("halt") +/* + * Reset the machine. + */ +extern void hard_reset_now(void); #endif /* _M68K_SYSTEM_H */ diff --git a/include/asm-m68k/termbits.h b/include/asm-m68k/termbits.h new file mode 100644 index 000000000..78494acc0 --- /dev/null +++ b/include/asm-m68k/termbits.h @@ -0,0 +1,162 @@ +#ifndef __ARCH_M68K_TERMBITS_H__ +#define __ARCH_M68K_TERMBITS_H__ + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* __ARCH_M68K_TERMBITS_H__ */ diff --git a/include/asm-m68k/termios.h b/include/asm-m68k/termios.h new file mode 100644 index 000000000..4bedde47f --- /dev/null +++ b/include/asm-m68k/termios.h @@ -0,0 +1,90 @@ +#ifndef _M68K_TERMIOS_H +#define _M68K_TERMIOS_H + +#include <asm/termbits.h> +#include <asm/ioctls.h> + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 + +#ifdef __KERNEL__ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +extern inline void trans_from_termio(struct termio * termio, + struct termios * termios) +{ +#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y)) + SET_LOW_BITS(termios->c_iflag, termio->c_iflag); + SET_LOW_BITS(termios->c_oflag, termio->c_oflag); + SET_LOW_BITS(termios->c_cflag, termio->c_cflag); + SET_LOW_BITS(termios->c_lflag, termio->c_lflag); +#undef SET_LOW_BITS + memcpy(termios->c_cc, termio->c_cc, NCC); +} + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +extern inline void trans_to_termio(struct termios * termios, + struct termio * termio) +{ + termio->c_iflag = termios->c_iflag; + termio->c_oflag = termios->c_oflag; + termio->c_cflag = termios->c_cflag; + termio->c_lflag = termios->c_lflag; + termio->c_line = termios->c_line; + memcpy(termio->c_cc, termios->c_cc, NCC); +} + +#endif /* __KERNEL__ */ + +#endif /* _M68K_TERMIOS_H */ diff --git a/include/asm-m68k/traps.h b/include/asm-m68k/traps.h new file mode 100644 index 000000000..5b12398f5 --- /dev/null +++ b/include/asm-m68k/traps.h @@ -0,0 +1,241 @@ +/* + * linux/include/asm/traps.h + * + * Copyright (C) 1993 Hamish Macdonald + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _M68K_TRAPS_H +#define _M68K_TRAPS_H + +typedef void (*e_vector)(void); + +extern e_vector vectors[]; + +#define VEC_BUSERR (2) +#define VEC_ADDRERR (3) +#define VEC_ILLEGAL (4) +#define VEC_ZERODIV (5) +#define VEC_CHK (6) +#define VEC_TRAP (7) +#define VEC_PRIV (8) +#define VEC_TRACE (9) +#define VEC_LINE10 (10) +#define VEC_LINE11 (11) +#define VEC_RESV1 (12) +#define VEC_COPROC (13) +#define VEC_FORMAT (14) +#define VEC_UNINT (15) +#define VEC_SPUR (24) +#define VEC_INT1 (25) +#define VEC_INT2 (26) +#define VEC_INT3 (27) +#define VEC_INT4 (28) +#define VEC_INT5 (29) +#define VEC_INT6 (30) +#define VEC_INT7 (31) +#define VEC_SYS (32) +#define VEC_TRAP1 (33) +#define VEC_TRAP2 (34) +#define VEC_TRAP3 (35) +#define VEC_TRAP4 (36) +#define VEC_TRAP5 (37) +#define VEC_TRAP6 (38) +#define VEC_TRAP7 (39) +#define VEC_TRAP8 (40) +#define VEC_TRAP9 (41) +#define VEC_TRAP10 (42) +#define VEC_TRAP11 (43) +#define VEC_TRAP12 (44) +#define VEC_TRAP13 (45) +#define VEC_TRAP14 (46) +#define VEC_TRAP15 (47) +#define VEC_FPBRUC (48) +#define VEC_FPIR (49) +#define VEC_FPDIVZ (50) +#define VEC_FPUNDER (51) +#define VEC_FPOE (52) +#define VEC_FPOVER (53) +#define VEC_FPNAN (54) +#define VEC_FPUNSUP (55) +#define VEC_UNIMPEA (60) +#define VEC_UNIMPII (61) + +#define VECOFF(vec) ((vec)<<2) + +/* Status register bits */ +#define PS_T (0x8000) +#define PS_S (0x2000) +#define PS_M (0x1000) +#define PS_C (0x0001) + +/* bits for 68020/68030 special status word */ + +#define FC (0x8000) +#define FB (0x4000) +#define RC (0x2000) +#define RB (0x1000) +#define DF (0x0100) +#define RM (0x0080) +#define RW (0x0040) +#define SZ (0x0030) +#define DFC (0x0007) + +/* bits for 68030 MMU status register (mmusr,psr) */ + +#define MMU_B (0x8000) /* bus error */ +#define MMU_L (0x4000) /* limit violation */ +#define MMU_S (0x2000) /* supervisor violation */ +#define MMU_WP (0x0800) /* write-protected */ +#define MMU_I (0x0400) /* invalid descriptor */ +#define MMU_M (0x0200) /* ATC entry modified */ +#define MMU_T (0x0040) /* transparent translation */ +#define MMU_NUM (0x0007) /* number of levels traversed */ + + +/* bits for 68040 special status word */ +#define CP_040 (0x8000) +#define CU_040 (0x4000) +#define CT_040 (0x2000) +#define CM_040 (0x1000) +#define MA_040 (0x0800) +#define ATC_040 (0x0400) +#define LK_040 (0x0200) +#define RW_040 (0x0100) +#define SIZ_040 (0x0060) +#define TT_040 (0x0018) +#define TM_040 (0x0007) + +/* bits for 68040 write back status word */ +#define WBV_040 (0x80) +#define WBSIZ_040 (0x60) +#define WBBYT_040 (0x20) +#define WBWRD_040 (0x40) +#define WBLNG_040 (0x00) +#define WBTT_040 (0x18) +#define WBTM_040 (0x07) + +/* bus access size codes */ +#define BA_SIZE_BYTE (0x20) +#define BA_SIZE_WORD (0x40) +#define BA_SIZE_LONG (0x00) +#define BA_SIZE_LINE (0x60) + +/* bus access transfer type codes */ +#define BA_TT_MOVE16 (0x08) + +/* bits for 68040 MMU status register (mmusr) */ +#define MMU_B_040 (0x0800) +#define MMU_G_040 (0x0400) +#define MMU_S_040 (0x0080) +#define MMU_CM_040 (0x0060) +#define MMU_M_040 (0x0010) +#define MMU_WP_040 (0x0004) +#define MMU_T_040 (0x0002) +#define MMU_R_040 (0x0001) + +/* bits in the 68060 fault status long word (FSLW) */ +#define MMU060_MA (0x08000000) /* misaligned */ +#define MMU060_LK (0x02000000) /* locked transfer */ +#define MMU060_RW (0x01800000) /* read/write */ +# define MMU060_RW_W (0x00800000) /* write */ +# define MMU060_RW_R (0x01000000) /* read */ +# define MMU060_RW_RMW (0x01800000) /* read/modify/write */ +# define MMU060_W (0x00800000) /* general write, includes rmw */ +#define MMU060_SIZ (0x00600000) /* transfer size */ +#define MMU060_TT (0x00180000) /* transfer type (TT) bits */ +#define MMU060_TM (0x00070000) /* transfer modifier (TM) bits */ +#define MMU060_IO (0x00008000) /* instruction or operand */ +#define MMU060_PBE (0x00004000) /* push buffer bus error */ +#define MMU060_SBE (0x00002000) /* store buffer bus error */ +#define MMU060_PTA (0x00001000) /* pointer A fault */ +#define MMU060_PTB (0x00000800) /* pointer B fault */ +#define MMU060_IL (0x00000400) /* double indirect descr fault */ +#define MMU060_PF (0x00000200) /* page fault (invalid descr) */ +#define MMU060_SP (0x00000100) /* supervisor protection */ +#define MMU060_WP (0x00000080) /* write protection */ +#define MMU060_TWE (0x00000040) /* bus error on table search */ +#define MMU060_RE (0x00000020) /* bus error on read */ +#define MMU060_WE (0x00000010) /* bus error on write */ +#define MMU060_TTR (0x00000008) /* error caused by TTR translation */ +#define MMU060_BPE (0x00000004) /* branch prediction error */ +#define MMU060_SEE (0x00000001) /* software emulated error */ + +/* cases of missing or invalid descriptors */ +#define MMU060_DESC_ERR (MMU060_TWE | MMU060_PTA | MMU060_PTB | \ + MMU060_IL | MMU060_PF) +/* bits that indicate real errors */ +#define MMU060_ERR_BITS (MMU060_PBE | MMU060_SBE | MMU060_DESC_ERR | \ + MMU060_SP | MMU060_WP | MMU060_RE | \ + MMU060_WE) + +/* structure for stack frames */ + +struct frame { + struct pt_regs ptregs; + union { + struct { + unsigned long iaddr; /* instruction address */ + } fmt2; + struct { + unsigned long effaddr; /* effective address */ + } fmt3; + struct { + unsigned long effaddr; /* effective address */ + unsigned long pc; /* pc of faulted instr */ + } fmt4; + struct { + unsigned long effaddr; /* effective address */ + unsigned short ssw; /* special status word */ + unsigned short wb3s; /* write back 3 status */ + unsigned short wb2s; /* write back 2 status */ + unsigned short wb1s; /* write back 1 status */ + unsigned long faddr; /* fault address */ + unsigned long wb3a; /* write back 3 address */ + unsigned long wb3d; /* write back 3 data */ + unsigned long wb2a; /* write back 2 address */ + unsigned long wb2d; /* write back 2 data */ + unsigned long wb1a; /* write back 1 address */ + unsigned long wb1dpd0; /* write back 1 data/push data 0*/ + unsigned long pd1; /* push data 1*/ + unsigned long pd2; /* push data 2*/ + unsigned long pd3; /* push data 3*/ + } fmt7; + struct { + unsigned long iaddr; /* instruction address */ + unsigned short int1[4]; /* internal registers */ + } fmt9; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[2]; + } fmta; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[4]; + unsigned long baddr; /* stage B address */ + unsigned short int4[2]; + unsigned long dibuf; /* data cycle input buffer */ + unsigned short int5[3]; + unsigned ver : 4; /* stack frame version # */ + unsigned int6:12; + unsigned short int7[18]; + } fmtb; + } un; +}; + +#endif /* _M68K_TRAPS_H */ diff --git a/include/asm-m68k/types.h b/include/asm-m68k/types.h new file mode 100644 index 000000000..945edb982 --- /dev/null +++ b/include/asm-m68k/types.h @@ -0,0 +1,52 @@ +#ifndef _M68K_TYPES_H +#define _M68K_TYPES_H + +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#endif /* __KERNEL__ */ + +#endif /* _M68K_TYPES_H */ diff --git a/include/asm-m68k/uaccess.h b/include/asm-m68k/uaccess.h new file mode 100644 index 000000000..50ff178cd --- /dev/null +++ b/include/asm-m68k/uaccess.h @@ -0,0 +1,799 @@ +#ifndef __M68K_UACCESS_H +#define __M68K_UACCESS_H + +/* + * User space memory access functions + */ +#include <linux/sched.h> +#include <asm/segment.h> + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* We let the MMU do all checking */ +#define access_ok(type,addr,size) 1 + +extern inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size)?0:-EFAULT; +} + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + */ + +#define put_user(x, ptr) \ +({ \ + int __pu_err; \ + typeof(*(ptr)) __pu_val = (x); \ + switch (sizeof (*(ptr))) { \ + case 1: \ + __put_user_asm(__pu_err, __pu_val, ptr, b); \ + break; \ + case 2: \ + __put_user_asm(__pu_err, __pu_val, ptr, w); \ + break; \ + case 4: \ + __put_user_asm(__pu_err, __pu_val, ptr, l); \ + break; \ + default: \ + __pu_err = __put_user_bad(); \ + break; \ + } \ + __pu_err; \ +}) +#define __put_user(x, ptr) put_user(x, ptr) + +extern int __put_user_bad(void); + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ +#define __put_user_asm(err,x,ptr,bwl) \ +__asm__ __volatile__ \ + ("21:moves" #bwl " %2,%1\n" \ + "1:\n" \ + ".section .fixup,\"ax\"\n" \ + " .even\n" \ + "2: movel %3,%0\n" \ + " jra 1b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 21b,2b\n" \ + " .long 1b,2b\n" \ + ".text" \ + : "=d"(err) \ + : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0)) + +#define get_user(x, ptr) \ +({ \ + int __gu_err; \ + typeof(*(ptr)) __gu_val; \ + switch (sizeof(*(ptr))) { \ + case 1: \ + __get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \ + break; \ + case 2: \ + __get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \ + break; \ + case 4: \ + __get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \ + break; \ + default: \ + __gu_val = 0; \ + __gu_err = __get_user_bad(); \ + break; \ + } \ + (x) = __gu_val; \ + __gu_err; \ +}) +#define __get_user(x, ptr) get_user(x, ptr) + +extern int __get_user_bad(void); + +#define __get_user_asm(err,x,ptr,bwl,reg) \ +__asm__ __volatile__ \ + ("1: moves" #bwl " %2,%1\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + " .even\n" \ + "3: movel %3,%0\n" \ + " sub" #bwl " %1,%1\n" \ + " jra 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".text" \ + : "=d"(err), reg(x) \ + : "m"(*(ptr)), "i" (-EFAULT), "0"(0)) + +static inline unsigned long +__generic_copy_from_user(void *to, const void *from, unsigned long n) +{ + unsigned long tmp; + __asm__ __volatile__ + (" tstl %2\n" + " jeq 2f\n" + "1: movesl (%1)+,%3\n" + " movel %3,(%0)+\n" + " subql #1,%2\n" + " jne 1b\n" + "2: movel %4,%2\n" + " bclr #1,%2\n" + " jeq 4f\n" + "3: movesw (%1)+,%3\n" + " movew %3,(%0)+\n" + "4: bclr #0,%2\n" + " jeq 6f\n" + "5: movesb (%1)+,%3\n" + " moveb %3,(%0)+\n" + "6:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "7: lsll #2,%2\n" + " addl %4,%2\n" + " jra 6b\n" + "8: addql #2,%2\n" + " jra 6b\n" + "9: addql #1,%2\n" + " jra 6b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,7b\n" + " .long 3b,8b\n" + " .long 5b,9b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) + : "r"(n & 3), "0"(to), "1"(from), "2"(n/4) + : "d0", "memory"); + return n; +} + +static inline unsigned long +__generic_copy_to_user(void *to, const void *from, unsigned long n) +{ + unsigned long tmp; + __asm__ __volatile__ + (" tstl %2\n" + " jeq 3f\n" + "1: movel (%1)+,%3\n" + "22:movesl %3,(%0)+\n" + "2: subql #1,%2\n" + " jne 1b\n" + "3: movel %4,%2\n" + " bclr #1,%2\n" + " jeq 4f\n" + " movew (%1)+,%3\n" + "24:movesw %3,(%0)+\n" + "4: bclr #0,%2\n" + " jeq 5f\n" + " moveb (%1)+,%3\n" + "25:movesb %3,(%0)+\n" + "5:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "6: lsll #2,%2\n" + " addl %4,%2\n" + " jra 5b\n" + "7: addql #2,%2\n" + " jra 5b\n" + "8: addql #1,%2\n" + " jra 5b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 22b,6b\n" + " .long 2b,6b\n" + " .long 24b,7b\n" + " .long 4b,7b\n" + " .long 25b,8b\n" + " .long 5b,8b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) + : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)); + return n; +} + +#define __copy_from_user_big(to, from, n, fixup, copy) \ + __asm__ __volatile__ \ + ("10: movesl (%1)+,%%d0\n" \ + " movel %%d0,(%0)+\n" \ + " subql #1,%2\n" \ + " jne 10b\n" \ + ".section .fixup,\"ax\"\n" \ + " .even\n" \ + "11: lsll #2,%2\n" \ + fixup "\n" \ + " jra 12f\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 10b,11b\n" \ + ".text\n" \ + copy "\n" \ + ".text\n" \ + "12:" \ + : "=a"(to), "=a"(from), "=d"(n) \ + : "0"(to), "1"(from), "2"(n/4) \ + : "d0", "memory") + +static inline unsigned long +__constant_copy_from_user(void *to, const void *from, unsigned long n) +{ + switch (n) { + case 0: + break; + case 1: + __asm__ __volatile__ + ("1: movesb (%1)+,%%d0\n" + " moveb %%d0,(%0)+\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #1,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 2: + __asm__ __volatile__ + ("1: movesw (%1)+,%%d0\n" + " movew %%d0,(%0)+\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #2,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 3: + __asm__ __volatile__ + ("1: movesw (%1)+,%%d0\n" + " movew %%d0,(%0)+\n" + "2: movesb (%1)+,%%d0\n" + " moveb %%d0,(%0)+\n" + "3:" + ".section .fixup,\"ax\"\n" + " .even\n" + "4: addql #2,%2\n" + "5: addql #1,%2\n" + " jra 3b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,4b\n" + " .long 2b,5b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 4: + __asm__ __volatile__ + ("1: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "2:" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #4,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 8: + __asm__ __volatile__ + ("1: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "2: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "3:" + ".section .fixup,\"ax\"\n" + " .even\n" + "4: addql #4,%2\n" + "5: addql #4,%2\n" + " jra 3b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,4b\n" + " .long 2b,5b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 12: + __asm__ __volatile__ + ("1: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "2: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "3: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "4:" + ".section .fixup,\"ax\"\n" + " .even\n" + "5: addql #4,%2\n" + "6: addql #4,%2\n" + "7: addql #4,%2\n" + " jra 4b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,5b\n" + " .long 2b,6b\n" + " .long 3b,7b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 16: + __asm__ __volatile__ + ("1: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "2: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "3: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "4: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "5:" + ".section .fixup,\"ax\"\n" + " .even\n" + "6: addql #4,%2\n" + "7: addql #4,%2\n" + "8: addql #4,%2\n" + "9: addql #4,%2\n" + " jra 5b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,6b\n" + " .long 2b,7b\n" + " .long 3b,8b\n" + " .long 4b,9b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + default: + switch (n & 3) { + case 0: + __copy_from_user_big(to, from, n, "", ""); + break; + case 1: + __copy_from_user_big(to, from, n, + /* fixup */ + "1: addql #1,%2", + /* copy */ + "2: movesb (%1)+,%%d0\n" + " moveb %%d0,(%0)+\n" + ".section __ex_table,\"a\"\n" + " .long 2b,1b"); + break; + case 2: + __copy_from_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2", + /* copy */ + "2: movesw (%1)+,%%d0\n" + " movew %%d0,(%0)+\n" + ".section __ex_table,\"a\"\n" + " .long 2b,1b"); + break; + case 3: + __copy_from_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2" + "2: addql #1,%2", + /* copy */ + "3: movesw (%1)+,%%d0\n" + " movew %%d0,(%0)+\n" + "4: movesb (%1)+,%%d0\n" + " moveb %%d0,(%0)+\n" + ".section __ex_table,\"a\"\n" + " .long 3b,1b\n" + " .long 4b,2b"); + break; + } + break; + } + return n; +} + +#define __copy_to_user_big(to, from, n, fixup, copy) \ + __asm__ __volatile__ \ + ("10: movel (%1)+,%%d0\n" \ + "31: movesl %%d0,(%0)+\n" \ + "11: subql #1,%2\n" \ + " jne 10b\n" \ + ".section .fixup,\"ax\"\n" \ + " .even\n" \ + "12: lsll #2,%2\n" \ + fixup "\n" \ + " jra 13f\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 31b,12b\n" \ + " .long 11b,12b\n" \ + ".text\n" \ + copy "\n" \ + ".text\n" \ + "13:" \ + : "=a"(to), "=a"(from), "=d"(n) \ + : "0"(to), "1"(from), "2"(n/4) \ + : "d0") + +static inline unsigned long +__constant_copy_to_user(void *to, const void *from, unsigned long n) +{ + switch (n) { + case 0: + break; + case 1: + __asm__ __volatile__ + (" moveb (%1)+,%%d0\n" + "21:movesb %%d0,(%0)+\n" + "1:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "2: addql #1,%2\n" + " jra 1b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n " + " .long 21b,2b\n" + " .long 1b,2b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 2: + __asm__ __volatile__ + (" movew (%1)+,%%d0\n" + "21:movesw %%d0,(%0)+\n" + "1:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "2: addql #2,%2\n" + " jra 1b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,2b\n" + " .long 1b,2b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 3: + __asm__ __volatile__ + (" movew (%1)+,%%d0\n" + "21:movesw %%d0,(%0)+\n" + "1: moveb (%1)+,%%d0\n" + "22:movesb %%d0,(%0)+\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #2,%2\n" + "4: addql #1,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,3b\n" + " .long 1b,3b\n" + " .long 22b,4b\n" + " .long 2b,4b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 4: + __asm__ __volatile__ + (" movel (%1)+,%%d0\n" + "21:movesl %%d0,(%0)+\n" + "1:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "2: addql #4,%2\n" + " jra 1b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,2b\n" + " .long 1b,2b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 8: + __asm__ __volatile__ + (" movel (%1)+,%%d0\n" + "21:movesl %%d0,(%0)+\n" + "1: movel (%1)+,%%d0\n" + "22:movesl %%d0,(%0)+\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #4,%2\n" + "4: addql #4,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,3b\n" + " .long 1b,3b\n" + " .long 22b,4b\n" + " .long 2b,4b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 12: + __asm__ __volatile__ + (" movel (%1)+,%%d0\n" + "21:movesl %%d0,(%0)+\n" + "1: movel (%1)+,%%d0\n" + "22:movesl %%d0,(%0)+\n" + "2: movel (%1)+,%%d0\n" + "23:movesl %%d0,(%0)+\n" + "3:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "4: addql #4,%2\n" + "5: addql #4,%2\n" + "6: addql #4,%2\n" + " jra 3b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,4b\n" + " .long 1b,4b\n" + " .long 22b,5b\n" + " .long 2b,5b\n" + " .long 23b,6b\n" + " .long 3b,6b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 16: + __asm__ __volatile__ + (" movel (%1)+,%%d0\n" + "21:movesl %%d0,(%0)+\n" + "1: movel (%1)+,%%d0\n" + "22:movesl %%d0,(%0)+\n" + "2: movel (%1)+,%%d0\n" + "23:movesl %%d0,(%0)+\n" + "3: movel (%1)+,%%d0\n" + "24:movesl %%d0,(%0)+\n" + "4:" + ".section .fixup,\"ax\"\n" + " .even\n" + "5: addql #4,%2\n" + "6: addql #4,%2\n" + "7: addql #4,%2\n" + "8: addql #4,%2\n" + " jra 4b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,5b\n" + " .long 1b,5b\n" + " .long 22b,6b\n" + " .long 2b,6b\n" + " .long 23b,7b\n" + " .long 3b,7b\n" + " .long 24b,8b\n" + " .long 4b,8b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + default: + switch (n & 3) { + case 0: + __copy_to_user_big(to, from, n, "", ""); + break; + case 1: + __copy_to_user_big(to, from, n, + /* fixup */ + "1: addql #1,%2", + /* copy */ + " moveb (%1)+,%%d0\n" + "22:movesb %%d0,(%0)+\n" + "2:" + ".section __ex_table,\"a\"\n" + " .long 22b,1b\n" + " .long 2b,1b"); + break; + case 2: + __copy_to_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2", + /* copy */ + " movew (%1)+,%%d0\n" + "22:movesw %%d0,(%0)+\n" + "2:" + ".section __ex_table,\"a\"\n" + " .long 22b,1b\n" + " .long 2b,1b"); + break; + case 3: + __copy_to_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2" + "2: addql #1,%2", + /* copy */ + " movew (%1)+,%%d0\n" + "23:movesw %%d0,(%0)+\n" + "3: moveb (%1)+,%%d0\n" + "24:movesb %%d0,(%0)+\n" + "4:" + ".section __ex_table,\"a\"\n" + " .long 23b,1b\n" + " .long 3b,1b\n" + " .long 24b,2b\n" + " .long 4b,2b"); + break; + } + break; + } + return n; +} + +#define copy_from_user(to, from, n) \ +(__builtin_constant_p(n) ? \ + __constant_copy_from_user(to, from, n) : \ + __generic_copy_from_user(to, from, n)) + +#define copy_to_user(to, from, n) \ +(__builtin_constant_p(n) ? \ + __constant_copy_to_user(to, from, n) : \ + __generic_copy_to_user(to, from, n)) + +/* + * Copy a null terminated string from userspace. + */ + +static inline long +strncpy_from_user(char *dst, const char *src, long count) +{ + long res; + if (count == 0) return count; + __asm__ __volatile__ + ("1: movesb (%2)+,%%d0\n" + "12:moveb %%d0,(%1)+\n" + " jeq 2f\n" + " subql #1,%3\n" + " jne 1b\n" + "2: subl %3,%0\n" + "3:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "4: movel %4,%0\n" + " jra 3b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,4b\n" + " .long 12b,4b\n" + ".text" + : "=d"(res), "=a"(dst), "=a"(src), "=d"(count) + : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count) + : "d0", "memory"); + return res; +} + +/* + * Return the size of a string (including the ending 0) + * + * Return 0 for error + */ +static inline long strlen_user(const char * src) +{ + long res = (long) src; + __asm__ __volatile__ + ("1: movesb (%1)+,%%d0\n" + "12:tstb %%d0\n" + " jne 1b\n" + " subl %1,%0\n" + " negl %0\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: moveq %2,%0\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + " .long 12b,3b\n" + ".text" + : "=d"(res), "=a"(src) + : "i"(0), "0"(res), "1"(src) + : "d0", "memory"); + return res; +} + +/* + * Zero Userspace + */ + +static inline unsigned long +clear_user(void *to, unsigned long n) +{ + __asm__ __volatile__ + (" tstl %1\n" + " jeq 3f\n" + "1: movesl %3,(%0)+\n" + "2: subql #1,%1\n" + " jne 1b\n" + "3: movel %2,%1\n" + " bclr #1,%1\n" + " jeq 4f\n" + "24:movesw %3,(%0)+\n" + "4: bclr #0,%1\n" + " jeq 5f\n" + "25:movesb %3,(%0)+\n" + "5:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "6: lsll #2,%1\n" + " addl %2,%1\n" + " jra 5b\n" + "7: addql #2,%1\n" + " jra 5b\n" + "8: addql #1,%1\n" + " jra 5b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,6b\n" + " .long 2b,6b\n" + " .long 24b,7b\n" + " .long 4b,7b\n" + " .long 25b,8b\n" + " .long 5b,8b\n" + ".text" + : "=a"(to), "=d"(n) + : "r"(n & 3), "r"(0), "0"(to), "1"(n/4)); + return n; +} + +#endif /* _M68K_UACCESS_H */ diff --git a/include/asm-m68k/unaligned.h b/include/asm-m68k/unaligned.h new file mode 100644 index 000000000..479f15864 --- /dev/null +++ b/include/asm-m68k/unaligned.h @@ -0,0 +1,16 @@ +#ifndef __M68K_UNALIGNED_H +#define __M68K_UNALIGNED_H + +/* + * The m68k can do unaligned accesses itself. + * + * The strange macros are there to make sure these can't + * be misused in a way that makes them not work on other + * architectures where unaligned accesses aren't as simple. + */ + +#define get_unaligned(ptr) (*(ptr)) + +#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) + +#endif diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h index acad643bf..b55f296a7 100644 --- a/include/asm-m68k/unistd.h +++ b/include/asm-m68k/unistd.h @@ -1,114 +1,344 @@ #ifndef _ASM_M68K_UNISTD_H_ #define _ASM_M68K_UNISTD_H_ -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +/* + * This file contains the system call numbers. + */ + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl /* 110 */ not supported +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86 /* 113 */ not supported +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_cacheflush 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 + +/* user-visible error numbers are in the range -1 - -122: see + <asm-m68k/errno.h> */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + #define _syscall0(type,name) \ type name(void) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ +register long __res __asm__ ("%d0") = __NR_##name; \ __asm__ __volatile__ ("trap #0" \ : "=g" (__res) \ - : "0" (__NR_##name) \ - : "d0"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ + : "0" (__res) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall1(type,name,atype,a) \ type name(atype a) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)) \ - : "d0", "d1"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall2(type,name,atype,a,btype,b) \ type name(atype a,btype b) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "movel %3,d2\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)), \ - "g" ((long)(b)) \ - : "d0", "d1", "d2"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a), "d" (__b) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall3(type,name,atype,a,btype,b,ctype,c) \ type name(atype a,btype b,ctype c) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "movel %3,d2\n\t" \ - "movel %4,d3\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)), \ - "g" ((long)(b)), \ - "g" ((long)(c)) \ - : "d0", "d1", "d2", "d3"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +register long __c __asm__ ("%d3") = (long)(c); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a), "d" (__b), \ + "d" (__c) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ type name (atype a, btype b, ctype c, dtype d) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "movel %3,d2\n\t" \ - "movel %4,d3\n\t" \ - "movel %5,d4\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)), \ - "g" ((long)(b)), \ - "g" ((long)(c)), \ - "g" ((long)(d)) \ - : "d0", "d1", "d2", "d3", "d4"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +register long __c __asm__ ("%d3") = (long)(c); \ +register long __d __asm__ ("%d4") = (long)(d); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ type name (atype a,btype b,ctype c,dtype d,etype e) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "movel %3,d2\n\t" \ - "movel %4,d3\n\t" \ - "movel %5,d4\n\t" \ - "movel %6,d5\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)), \ - "g" ((long)(b)), \ - "g" ((long)(c)), \ - "g" ((long)(d)), \ - "g" ((long)(e)) \ - : "d0", "d1", "d2", "d3", "d4", "d5"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +register long __c __asm__ ("%d3") = (long)(c); \ +register long __d __asm__ ("%d4") = (long)(d); \ +register long __e __asm__ ("%d5") = (long)(e); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d), "d" (__e) \ + : "%d0"); \ +__syscall_return(type,__res); \ +} + +#ifdef __KERNEL_SYSCALLS__ + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ +#define __NR__exit __NR_exit +static inline _syscall0(int,idle) +static inline _syscall0(int,fork) +static inline _syscall2(int,clone,unsigned long,flags,char *,usp) +static inline _syscall0(int,pause) +static inline _syscall0(int,setup) +static inline _syscall0(int,sync) +static inline _syscall0(pid_t,setsid) +static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static inline _syscall1(int,dup,int,fd) +static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static inline _syscall3(int,open,const char *,file,int,flag,int,mode) +static inline _syscall1(int,close,int,fd) +static inline _syscall1(int,_exit,int,exitcode) +static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +/* + * This is the mechanism for creating a new kernel thread. + * + * NOTE! Only a kernel-only process(ie the swapper or direct descendants + * who haven't done an "execve()") should use this: it will work within + * a system call from a "real" process, but the process memory space will + * not be free'd until both the parent and the child have exited. + */ +static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + register long retval __asm__ ("d0") = __NR_clone; + register long clone_arg __asm__ ("d1") = flags | CLONE_VM; + unsigned long fs; + + fs = get_fs(); + set_fs (KERNEL_DS); + + __asm__ __volatile__ + ("trap #0\n\t" /* Linux/m68k system call */ + "tstl %0\n\t" /* child or parent */ + "jne 1f\n\t" /* parent - jump */ + "movel %3,%%sp@-\n\t" /* push argument */ + "jsr %4@\n\t" /* call fn */ + "movel %0,%%d1\n\t" /* pass exit value */ + "movel %2,%0\n\t" /* exit */ + "trap #0\n" + "1:" + : "=d" (retval) + : "0" (__NR_clone), "i" (__NR_exit), + "r" (arg), "a" (fn), "d" (clone_arg) + : "d0"); + + set_fs (fs); + return retval; } +static inline pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +#endif + #endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/include/asm-m68k/user.h b/include/asm-m68k/user.h new file mode 100644 index 000000000..126e23548 --- /dev/null +++ b/include/asm-m68k/user.h @@ -0,0 +1,88 @@ +#ifndef _M68K_USER_H +#define _M68K_USER_H + +#include <asm/page.h> +#include <linux/ptrace.h> +/* Core file format: The core file is written in such a way that gdb + can understand it and provide useful information to the user (under + linux we use the 'trad-core' bfd). There are quite a number of + obstacles to being able to view the contents of the floating point + registers, and until these are solved you will not be able to view the + contents of them. Actually, you can read in the core file and look at + the contents of the user struct to find out what the floating point + registers contain. + The actual file contents are as follows: + UPAGE: 1 page consisting of a user struct that tells gdb what is present + in the file. Directly after this is a copy of the task_struct, which + is currently not used by gdb, but it may come in useful at some point. + All of the registers are stored as part of the upage. The upage should + always be only one page. + DATA: The data area is stored. We use current->end_text to + current->brk to pick up all of the user variables, plus any memory + that may have been malloced. No attempt is made to determine if a page + is demand-zero or if a page is totally unused, we just cover the entire + range. All of the addresses are rounded in such a way that an integral + number of pages is written. + STACK: We need the stack information in order to get a meaningful + backtrace. We need to write the data from (esp) to + current->start_stack, so we round each of these off in order to be able + to write an integer number of pages. + The minimum core file size is 3 pages, or 12288 bytes. +*/ + +struct user_m68kfp_struct { + unsigned long fpregs[8*3]; /* fp0-fp7 registers */ + unsigned long fpcntl[3]; /* fp control regs */ +}; + +/* This is the old layout of "struct pt_regs" as of Linux 1.x, and + is still the layout used by user (the new pt_regs doesn't have + all registers). */ +struct user_regs_struct { + long d1,d2,d3,d4,d5,d6,d7; + long a0,a1,a2,a3,a4,a5,a6; + long d0; + long usp; + long orig_d0; + short stkadj; + short sr; + long pc; + short fmtvec; + short __fill; +}; + + +/* When the kernel dumps core, it starts by dumping the user struct - + this will be used by gdb to figure out where the data and stack segments + are within the file, and what virtual addresses to use. */ +struct user{ +/* We start with the registers, to mimic the way that "memory" is returned + from the ptrace(3,...) function. */ + struct user_regs_struct regs; /* Where the registers are actually stored */ +/* ptrace does not yet supply these. Someday.... */ + int u_fpvalid; /* True if math co-processor being used. */ + /* for this mess. Not yet used. */ + struct user_m68kfp_struct m68kfp; /* Math Co-processor registers. */ +/* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ + /* the registers. */ + struct user_m68kfp_struct* u_fpstate; /* Math Co-processor pointer. */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ +}; +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif diff --git a/include/asm-m68k/zorro.h b/include/asm-m68k/zorro.h new file mode 100644 index 000000000..adfc4617c --- /dev/null +++ b/include/asm-m68k/zorro.h @@ -0,0 +1,574 @@ +/* + * asm-m68k/zorro.h -- Amiga AutoConfig (Zorro) Expansion Device Definitions + * + * Copyright (C) 1995 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_M68K_ZORRO_H_ +#define _ASM_M68K_ZORRO_H_ + +#ifndef __ASSEMBLY__ + +#include <linux/config.h> +#include <asm/amigatypes.h> + + +/* + * Defined Board Manufacturers + * + * Please update arch/m68k/amiga/zorro.c if you make changes here + * Many IDs were obtained from ExpName/Identify ((C) Richard Körber) + * and by looking at the NetBSD-Amiga kernel sources + */ + +#define MANUF_PACIFIC (0x00D3) /* Pacific Peripherals */ +#define PROD_SE_2000_A500 (0x00) /* SE 2000 A500 */ +#define PROD_PACIFIC_HD (0x0A) /* HD Controller */ + +#define MANUF_KUPKE (0x00DD) /* Kupke */ +#define PROD_GOLEM_BOX_2 (0x00) /* Golem RAM Box 2MB */ + +#define MANUF_MEMPHIS (0x0100) /* Memphis */ +#define PROD_STORMBRINGER (0x00) /* Stormbringer */ + +#define MANUF_COMMODORE2 (0x0201) /* Commodore Braunschweig */ +#define PROD_A2088 (0x01) /* CBM A2088 XT Bridgeboard */ +#define PROD_A2286 (0x02) /* CBM A2286 AT Bridgeboard */ +#define PROD_A4091_2 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2386SX (0x67) /* CBM A2386-SX Bridgeboard */ + +#define MANUF_COMMODORE (0x0202) /* Commodore West Chester */ +#define PROD_A2090A (0x01) /* CBM A2090/A2090A HD Controller */ +#define PROD_A590 (0x02) /* CBM A590 SCSI Controller */ +#define PROD_A2091 (0x03) /* CBM A2091 SCSI Controller */ +#define PROD_A2090B (0x04) /* CBM A2090B 2090 Autoboot Card */ +#define PROD_ARCNET (0x09) /* CBM A2060 Arcnet Card */ +#define PROD_CBMRAM (0x0A) /* CBM A2052/58.RAM | 590/2091.RAM */ +#define PROD_A560RAM (0x20) /* CBM A560 Memory Module */ +#define PROD_A2232PROTO (0x45) /* CBM A2232 Serial Prototype */ +#define PROD_A2232 (0x46) /* CBM A2232 Serial Production */ +#define PROD_A2620 (0x50) /* CBM A2620 68020/RAM Card */ +#define PROD_A2630 (0x51) /* CBM A2630 68030/RAM Card */ +#define PROD_A4091 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2065_2 (0x5A) /* A2065 Ethernet Card */ +#define PROD_ROMULATOR (0x60) /* CBM Romulator Card */ +#define PROD_A3000TESTFIX (0x61) /* CBM A3000 Test Fixture */ +#define PROD_A2386SX_2 (0x67) /* A2386-SX Bridgeboard */ +#define PROD_A2065 (0x70) /* CBM A2065 Ethernet Card */ + +#define MANUF_COMMODORE3 (0x0203) /* Commodore West Chester */ +#define PROD_A2090A_CM (0x03) /* A2090A Combitec/MacroSystem */ + +#define MANUF_KCS (0x02FF) /* Kolff Computer Supplies */ +#define PROD_POWER_BOARD (0x00) /* KCS Power PC Board */ + +#define MANUF_CARDCO (0x03EC) /* Cardco */ +#define PROD_KRONOS_2000_SCSI (0x04) /* Kronos 2000 SCSI Controller */ +#define PROD_A1000_SCSI (0x0C) /* A1000 SCSI Controller */ +#define PROD_ESCORT_SCSI (0x0E) /* Escort SCSI Controller */ +#define PROD_CC_A2410 (0xF5) /* Cardco A2410 Hires Graphics Card */ + +#define MANUF_A_SQUARED (0x03ED) /* A-Squared */ +#define PROD_LIVE_2000 (0x01) /* Live! 2000 */ + +#define MANUF_COMSPEC (0x03EE) /* ComSpec Communications */ +#define PROD_AX2000 (0x01) /* AX2000 */ + +#define MANUF_ANAKIN (0x03F1) /* Anakin */ +#define PROD_EASYL (0x01) /* Easyl Tablet */ + +#define MANUF_MICROBOTICS (0x03F2) /* MicroBotics */ +#define PROD_STARBOARD_II (0x00) /* StarBoard II */ +#define PROD_STARDRIVE (0x02) /* StarDrive */ +#define PROD_8_UP_A (0x03) /* 8-Up (Rev A) */ +#define PROD_8_UP_Z (0x04) /* 8-Up (Rev Z) */ +#define PROD_VXL_RAM (0x44) /* VXL RAM */ +#define PROD_VXL_30 (0x45) /* VXL-30 Turbo Board */ +#define PROD_MBX_1200 (0x81) /* MBX 1200 */ +#define PROD_HARDFRAME_2000 (0x9E) /* Hardframe 2000 */ +#define PROD_MBX_1200_2 (0xC1) /* MBX 1200 */ + +#define MANUF_ACCESS (0x03F4) /* Access Associates */ + +#define MANUF_EXPANSION_TECH (0x03F6) /* Expansion Technologies */ + +#define MANUF_ASDG (0x03FF) /* ASDG */ +#define PROD_ASDG_MEMORY (0x01) /* Memory Expansion */ +#define PROD_ASDG_MEMORY_2 (0x02) /* Memory Expansion */ +#define PROD_LAN_ROVER (0xFE) /* Lan Rover Ethernet */ +#define PROD_TWIN_X (0xFF) /* Twin-X Serial Card */ + +#define MANUF_IMTRONICS (0x0404) /* Imtronics */ +#define PROD_HURRICANE_2800 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_2 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_UNIV_OF_LOWELL (0x0406) /* University of Lowell */ +#define PROD_A2410 (0x00) /* CBM A2410 Hires Graphics Card */ + +#define MANUF_AMERISTAR (0x041D) /* Ameristar */ +#define PROD_AMERISTAR2065 (0x01) /* A2065 Ethernet Card */ +#define PROD_A560 (0x09) /* Arcnet Card */ +#define PROD_A4066 (0x0A) /* A4066 Ethernet Card */ + +#define MANUF_SUPRA (0x0420) /* Supra */ +#define PROD_SUPRADRIVE_4x4 (0x01) /* SupraDrive 4x4 SCSI Controller */ +#define PROD_SUPRA_2000 (0x03) /* 2000 DMA HD */ +#define PROD_SUPRA_500 (0x05) /* 500 HD/RAM */ +#define PROD_SUPRA_500RX (0x09) /* 500RX/2000 RAM */ +#define PROD_SUPRA_500RX_2 (0x0A) /* 500RX/2000 RAM */ +#define PROD_SUPRA_2400ZI (0x0B) /* 2400zi Modem */ +#define PROD_WORDSYNC (0x0C) /* Supra Wordsync SCSI Controller */ +#define PROD_WORDSYNC_II (0x0D) /* Supra Wordsync II SCSI Controller */ +#define PROD_SUPRA_2400ZIPLUS (0x10) /* 2400zi+ Modem */ + +#define MANUF_CSA (0x0422) /* CSA */ +#define PROD_MAGNUM (0x11) /* Magnum 40 SCSI Controller */ +#define PROD_12GAUGE (0x15) /* 12 Gauge SCSI Controller */ + +#define MANUF_GVP3 (0x06E1) /* Great Valley Products */ +#define PROD_IMPACT (0x08) /* Impact SCSI/Memory */ + +#define MANUF_BYTEBOX (0x07DA) /* ByteBox */ +#define PROD_BYTEBOX_A500 (0x00) /* A500 */ + +#define MANUF_HACKER (0x07DB) /* Test only: no product definitions */ + +#define MANUF_POWER_COMPUTING (0x07DC) /* Power Computing (DKB) */ +#define PROD_DKB_3128 (0x0E) /* DKB 3128 RAM */ +#define PROD_VIPER_II_COBRA (0x12) /* Viper II Turbo Board (DKB Cobra) */ + +#define MANUF_GVP (0x07E1) /* Great Valley Products */ +#define PROD_IMPACT_I_4K (0x01) /* Impact Series-I SCSI 4K */ +#define PROD_IMPACT_I_16K_2 (0x02) /* Impact Series-I SCSI 16K/2 */ +#define PROD_IMPACT_I_16K_3 (0x03) /* Impact Series-I SCSI 16K/3 */ +#define PROD_IMPACT_3001_IDE (0x08) /* Impact 3001 IDE */ +#define PROD_IMPACT_3001_RAM (0x09) /* Impact 3001 RAM */ +#define PROD_GVPIISCSI (0x0B) /* GVP Series II SCSI Controller */ +#define PROD_GVPIISCSI_2 (0x09) /* evidence that the driver works + for this product code also */ +#define PROD_GVPIIRAM (0x0A) /* GVP Series II RAM */ +#define PROD_GVP (0x0B) /* This code is used by a wide range of + GVP products - use the epc to + identify it correctly */ +#define PROD_GVP_A2000_030 (0x0D) /* GVP A2000 68030 Turbo Board */ +#define PROD_IMPACT_3001_IDE_2 (0x0D) /* Impact 3001 IDE */ +#define PROD_GFORCE_040_SCSI (0x16) /* GForce 040 with SCSI (new) */ +#define PROD_GVPIV_24 (0x20) /* GVP IV-24 Graphics Board */ +#define PROD_GFORCE_040 (0xFF) /* GForce 040 Turbo Board */ +/* #define PROD_GVPIO_EXT (0xFF)*/ /* GVP I/O Extender */ + +#define MANUF_SYNERGY (0x07E5) /* Synergy */ + +#define MANUF_XETEC (0x07E6) /* Xetec */ +#define PROD_FASTCARD_SCSI (0x01) /* FastCard SCSI Controller */ +#define PROD_FASTCARD_RAM (0x02) /* FastCard RAM */ + +#define MANUF_PPI (0x07EA) /* Progressive Peripherals Inc. */ +#define PROD_MERCURY (0x00) /* Mercury Turbo Board */ +#define PROD_PPS_A3000_040 (0x01) /* PP&S A3000 68040 Turbo Board */ +#define PROD_PPS_A2000_040 (0x69) /* PP&S A2000 68040 Turbo Board */ +#define PROD_ZEUS (0x96) /* Zeus SCSI Controller */ +#define PROD_PPS_A500_040 (0xBB) /* PP&S A500 68040 Turbo Board */ + +#define MANUF_XEBEC (0x07EC) /* Xebec */ + +#define MANUF_SPIRIT (0x07F2) /* Spirit */ +#define PROD_HDA_506 (0x04) /* HDA 506 Harddisk */ +#define PROD_OCTABYTE_RAM (0x06) /* OctaByte RAM */ + +#define MANUF_BSC (0x07FE) /* BSC */ +#define PROD_ALF_3_SCSI (0x03) /* BSC ALF 3 SCSI Controller */ + +#define MANUF_BSC3 (0x0801) /* BSC */ +#define PROD_ALF_2_SCSI (0x01) /* ALF 2 SCSI Controller */ +#define PROD_ALF_3_SCSI_2 (0x03) /* ALF 3 SCSI Controller */ + +#define MANUF_C_LTD (0x0802) /* C Ltd. */ +#define PROD_KRONOS_SCSI (0x04) /* Kronos SCSI Controller */ +#define PROD_A1000_SCSI_2 (0x0C) /* A1000 SCSI Controller */ + +#define MANUF_JOCHHEIM (0x0804) /* Jochheim */ +#define PROD_JOCHHEIM_RAM (0x01) /* Jochheim RAM */ + +#define MANUF_CHECKPOINT (0x0807) /* Checkpoint Technologies */ +#define PROD_SERIAL_SOLUTION (0x00) /* Serial Solution */ + +#define MANUF_ICD (0x0817) /* ICD */ +#define PROD_ADVANTAGE_2000 (0x01) /* Advantage 2000 SCSI Controller */ + +#define MANUF_KUPKE2 (0x0819) /* Kupke */ +#define PROD_KUPKE_SCSI_II (0x02) /* Golem SCSI-II Controller */ +#define PROD_GOLEM_BOX (0x03) /* Golem Box */ +#define PROD_KUPKE_SCSI_AT (0x05) /* SCSI/AT Controller */ + +#define MANUF_HARDITAL (0x0820) /* Hardital Synthesis */ +#define PROD_TQM (0x14) /* TQM 68030+68882 Turbo Board */ + +#define MANUF_BSC2 (0x082C) /* BSC */ +#define PROD_OKTAGON_SCSI (0x05) /* BSC Oktagon 2008 SCSI Controller */ +#define PROD_TANDEM (0x06) /* BSC Tandem AT-2008/508 IDE */ +#define PROD_OKTAGON_RAM (0x08) /* BSC Oktagon 2008 RAM */ +#define PROD_MULTIFACE_I (0x10) /* Alfa Data MultiFace I */ +#define PROD_MULTIFACE_II (0x11) /* Alfa Data MultiFace II */ +#define PROD_MULTIFACE_III (0x12) /* Alfa Data MultiFace III */ +#define PROD_ISDN_MASTERCARD (0x40) /* BSC ISDN MasterCard */ +#define PROD_ISDN_MASTERCARD_2 (0x41) /* BSC ISDN MasterCard II */ + +#define MANUF_ADV_SYS_SOFT (0x0836) /* Advanced Systems & Software */ +#define PROD_NEXUS_SCSI (0x01) /* Nexus SCSI Controller */ +#define PROD_NEXUS_RAM (0x08) /* Nexus RAM */ + +#define MANUF_IMPULSE (0x0838) /* Impulse */ +#define PROD_FIRECRACKER_24 (0x00) /* FireCracker 24 */ + +#define MANUF_IVS (0x0840) /* IVS */ +#define PROD_GRANDSLAM (0x04) /* GrandSlam RAM */ +#define PROD_IVS_OVERDRIVE (0x10) /* OverDrive HD */ +#define PROD_TRUMPCARD_CLASSIC (0x30) /* Trumpcard Classic SCSI Controller */ +#define PROD_TRUMPCARD_PRO (0x34) /* Trumpcard Pro SCSI Controller */ +#define PROD_META_4 (0x40) /* Meta-4 RAM */ +#define PROD_VECTOR (0xF3) /* Vector SCSI Controller */ + +#define MANUF_VECTOR (0x0841) /* Vector */ +#define PROD_CONNECTION (0xE3) /* Connection Serial IO */ + +#define MANUF_XPERT_PRODEV (0x0845) /* XPert/ProDev */ +#define PROD_VISIONA_RAM (0x01) /* Visiona Graphics Board */ +#define PROD_VISIONA_REG (0x02) +#define PROD_MERLIN_RAM (0x03) /* Merlin Graphics Board */ +#define PROD_MERLIN_REG (0x04) + +#define MANUF_HYDRA_SYSTEMS (0x0849) /* Hydra Systems */ +#define PROD_AMIGANET (0x01) /* Amiganet Board */ + +#define MANUF_SUNRIZE (0x084F) /* Sunrize Industries */ +#define PROD_AD516 (0x02) /* AD516 Audio */ + +#define MANUF_TRICERATOPS (0x0850) /* Triceratops */ +#define PROD_TRICERATOPS (0x01) /* Triceratops Multi I/O Board */ + +#define MANUF_APPLIED_MAGIC (0x0851) /* Applied Magic Inc */ +#define PROD_DMI_RESOLVER (0x01) /* DMI Resolver Graphics Board */ +#define PROD_DIGITAL_BCASTER (0x06) /* Digital Broadcaster */ + +#define MANUF_GFX_BASE (0x085E) /* GFX-Base */ +#define PROD_GDA_1_RAM (0x00) /* GDA-1 Graphics Board */ +#define PROD_GDA_1_REG (0x01) + +#define MANUF_ROCTEC (0x0860) /* RocTec */ +#define PROD_RH_800C (0x01) /* RH 800C Hard Disk Controller */ +#define PROD_RH_800C_RAM (0x01) /* RH 800C RAM */ + +#define MANUF_HELFRICH1 (0x0861) /* Helfrich */ +#define PROD_RAINBOW3 (0x21) /* Rainbow3 Graphics Board */ + +#define MANUF_SW_RESULT_ENTS (0x0866) /* Software Result Enterprises */ +#define PROD_GG2PLUS (0x01) /* GG2+ Bus Converter */ + +#define MANUF_MASOBOSHI (0x086D) /* Masoboshi */ +#define PROD_MASTER_CARD_RAM (0x03) /* Master Card RAM */ +#define PROD_MASTER_CARD_SCSI (0x04) /* Master Card SCSI Controller */ +#define PROD_MVD_819 (0x07) /* MVD 819 */ + +#define MANUF_DELACOMP (0x0873) /* DelaComp */ +#define PROD_DELACOMP_RAM_2000 (0x01) /* RAM Expansion 2000 */ + +#define MANUF_VILLAGE_TRONIC (0x0877) /* Village Tronic */ +#define PROD_DOMINO_RAM (0x01) /* Domino Graphics Board (RAM) */ +#define PROD_DOMINO_REG (0x02) /* Domino Graphics Board (REG) */ +#define PROD_PICASSO_II_RAM (0x0B) /* Picasso II Graphics Board */ +#define PROD_PICASSO_II_REG (0x0C) +#define PROD_PICASSO_II_REG_2 (0x0D) +#define PROD_ARIADNE (0xC9) /* Ariadne Ethernet */ + +#define MANUF_UTILITIES_ULTD (0x087B) /* Utilities Unlimited */ +#define PROD_EMPLANT_DELUXE (0x15) /* Emplant Deluxe SCSI Controller */ +#define PROD_EMPLANT_DELUXE2 (0x20) /* Emplant Deluxe SCSI Controller */ + +#define MANUF_AMITRIX (0x0880) /* Amitrix */ +#define PROD_AMITRIX_MULTI_IO (0x01) /* Multi-IO */ +#define PROD_AMITRIX_CD_RAM (0x02) /* CD-RAM Memory */ + +#define MANUF_MTEC (0x0890) /* MTEC Germany */ +#define PROD_MTEC_68030 (0x03) /* 68030 Turbo Board */ +#define PROD_MTEC_T1230 (0x20) /* A1200 T68030/42 RTC Turbo Board */ +#define PROD_MTEC_RAM (0x22) /* MTEC 8MB RAM */ + +#define MANUF_GVP2 (0x0891) /* Great Valley Products */ +#define PROD_SPECTRUM_RAM (0x01) /* EGS 28/24 Spectrum Graphics Board */ +#define PROD_SPECTRUM_REG (0x02) + +#define MANUF_HELFRICH2 (0x0893) /* Helfrich */ +#define PROD_PICCOLO_RAM (0x05) /* Piccolo Graphics Board */ +#define PROD_PICCOLO_REG (0x06) +#define PROD_PEGGY_PLUS (0x07) /* PeggyPlus MPEG Decoder Board */ +#define PROD_VIDEOCRUNCHER (0x08) /* VideoCruncher */ +#define PROD_SD64_RAM (0x0A) /* SD64 Graphics Board */ +#define PROD_SD64_REG (0x0B) + +#define MANUF_MACROSYSTEMS (0x089B) /* MacroSystems USA */ +#define PROD_WARP_ENGINE (0x13) /* Warp Engine 40xx SCSI Controller */ + +#define MANUF_ELBOX (0x089E) /* ElBox Computer */ +#define PROD_ELBOX_1200 (0x06) /* Elbox 1200/4 RAM */ + +#define MANUF_HARMS_PROF (0x0A00) /* Harms Professional */ +#define PROD_HARMS_030_PLUS (0x10) /* 030 plus */ +#define PROD_3500_TURBO (0xD0) /* 3500 Turbo board */ + +#define MANUF_MICRONIK (0x0A50) /* Micronik */ +#define PROD_RCA_120 (0x0A) /* RCA 120 RAM */ + +#define MANUF_IMTRONICS2 (0x1028) /* Imtronics */ +#define PROD_HURRICANE_2800_3 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_4 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_KUPKE3 (0x1248) /* Kupke */ +#define PROD_GOLEM_3000 (0x01) /* Golem HD 3000 */ + +#define MANUF_INFORMATION (0x157C) /* Information */ +#define PROD_ISDN_ENGINE_I (0x64) /* ISDN Engine I */ + +#define MANUF_VORTEX (0x2017) /* Vortex */ +#define PROD_GOLDEN_GATE_386SX (0x07) /* Golden Gate 80386SX Board */ +#define PROD_GOLDEN_GATE_RAM (0x08) /* Golden Gate RAM */ +#define PROD_GOLDEN_GATE_486 (0x09) /* Golden Gate 80486 Board */ + +#define MANUF_DATAFLYER (0x2062) /* DataFlyer */ +#define PROD_DATAFLYER_4000SXS (0x01) /* DataFlyer 4000SX SCSI Controller */ +#define PROD_DATAFLYER_4000SXR (0x02) /* DataFlyer 4000SX RAM */ + +#define MANUF_READYSOFT (0x2100) /* ReadySoft */ +#define PROD_AMAX (0x01) /* AMax II/IV */ + +#define MANUF_PHASE5 (0x2140) /* Phase5 */ +#define PROD_BLIZZARD_RAM (0x01) /* Blizzard RAM */ +#define PROD_BLIZZARD (0x02) /* Blizzard */ +#define PROD_BLIZZARD_1220_IV (0x06) /* Blizzard 1220-IV Turbo Board */ +#define PROD_FASTLANE_RAM (0x0A) /* FastLane RAM */ +#define PROD_FASTLANE_SCSI (0x0B) /* FastLane/Blizzard 1230-II SCSI/CyberSCSI */ +#define PROD_CYBERSTORM_SCSI (0x0C) /* Blizzard 1220/CyberStorm */ +#define PROD_BLIZZARD_1230_III (0x0D) /* Blizzard 1230-III Turbo Board */ +#define PROD_BLIZZARD_1230_IV (0x11) /* Blizzard 1230-IV/1260 Turbo Board */ +#define PROD_BLIZZARD_2060SCSI (0x18) /* Blizzard 2060 SCSI Controller */ +#define PROD_CYBERSTORM_II (0x19) /* CyberStorm Mk II */ +#define PROD_CYBERVISION (0x22) /* CyberVision64 Graphics Board */ + +#define MANUF_DPS (0x2169) /* DPS */ +#define PROD_DPS_PAR (0x01) /* Personal Animation Recorder */ + +#define MANUF_APOLLO2 (0x2200) /* Apollo */ +#define PROD_A620 (0x00) /* A620 68020 Accelerator */ + +#define MANUF_APOLLO (0x2222) /* Apollo */ +#define PROD_AT_APOLLO (0x22) /* AT-Apollo */ +#define PROD_APOLLO_TURBO (0x23) /* Apollo Turbo Board */ + +#define MANUF_UWE_GERLACH (0x3FF7) /* Uwe Gerlach */ +#define PROD_UG_RAM_ROM (0xd4) /* RAM/ROM */ + +#define MANUF_MACROSYSTEMS2 (0x4754) /* MacroSystems Germany */ +#define PROD_MAESTRO (0x03) /* Maestro */ +#define PROD_VLAB (0x04) /* VLab */ +#define PROD_MAESTRO_PRO (0x05) /* Maestro Pro */ +#define PROD_RETINA_Z2 (0x06) /* Retina Z2 Graphics Board */ +#define PROD_MULTI_EVOLUTION (0x08) /* MultiEvolution */ +#define PROD_TOCCATA (0x0C) /* Toccata Sound Board */ +#define PROD_RETINA_Z3 (0x10) /* Retina Z3 Graphics Board */ +#define PROD_VLAB_MOTION (0x12) /* VLab Motion */ +#define PROD_FALCON_040 (0xFD) /* Falcon '040 Turbo Board */ + +#define MANUF_COMBITEC (0x6766) /* Combitec */ + +#define MANUF_SKI (0x8000) /* SKI Peripherals */ +#define PROD_SKI_SCSI_SERIAL (0x80) /* SCSI / Dual Serial */ + +#define MANUF_CAMERON (0xAA01) /* Cameron */ +#define PROD_CAMERON_SCANNER (0x10) /* Scanner Interface */ + +#define MANUF_REIS_WARE (0xAA11) /* Reis-Ware */ +#define PROD_RW_HANDYSCANNER (0x11) /* Handyscanner */ + + +/* Illegal Manufacturer IDs. These do NOT appear in arch/m68k/amiga/zorro.c! */ + +#define MANUF_HACKER_INC (0x07DB) /* Hacker Inc. */ +#define PROD_HACKER_SCSI (0x01) /* Hacker Inc. SCSI Controller */ + +#define MANUF_RES_MNGT_FORCE (0x07DB) /* Resource Management Force */ +#define PROD_QUICKNET (0x02) /* QuickNet Ethernet */ + +#define MANUF_VECTOR2 (0x07DB) /* Vector */ +#define PROD_CONNECTION_2 (0xE0) /* Vector Connection */ +#define PROD_CONNECTION_3 (0xE1) /* Vector Connection */ +#define PROD_CONNECTION_4 (0xE2) /* Vector Connection */ +#define PROD_CONNECTION_5 (0xE3) /* Vector Connection */ + + +/* + * GVP's identifies most of their product through the 'extended + * product code' (epc). The epc has to be and'ed with the GVP_PRODMASK + * before the identification. + */ + +#define GVP_PRODMASK (0xf8) +#define GVP_SCSICLKMASK (0x01) + +enum GVP_ident { + GVP_GFORCE_040 = 0x20, + GVP_GFORCE_040_SCSI = 0x30, + GVP_A1291_SCSI = 0x40, + GVP_COMBO_R4 = 0x60, + GVP_COMBO_R4_SCSI = 0x70, + GVP_PHONEPAK = 0x78, + GVP_IOEXT = 0x98, + GVP_GFORCE_030 = 0xa0, + GVP_GFORCE_030_SCSI = 0xb0, + GVP_A530 = 0xc0, + GVP_A530_SCSI = 0xd0, + GVP_COMBO_R3 = 0xe0, + GVP_COMBO_R3_SCSI = 0xf0, + GVP_SERIESII = 0xf8, +}; + +enum GVP_flags { + GVP_IO = 0x01, + GVP_ACCEL = 0x02, + GVP_SCSI = 0x04, + GVP_24BITDMA = 0x08, + GVP_25BITDMA = 0x10, + GVP_NOBANK = 0x20, + GVP_14MHZ = 0x40, +}; + + +struct Node { + struct Node *ln_Succ; /* Pointer to next (successor) */ + struct Node *ln_Pred; /* Pointer to previous (predecessor) */ + u_char ln_Type; + char ln_Pri; /* Priority, for sorting */ + char *ln_Name; /* ID string, null terminated */ +}; + +struct ExpansionRom { + /* -First 16 bytes of the expansion ROM */ + u_char er_Type; /* Board type, size and flags */ + u_char er_Product; /* Product number, assigned by manufacturer */ + u_char er_Flags; /* Flags */ + u_char er_Reserved03; /* Must be zero ($ff inverted) */ + u_short er_Manufacturer; /* Unique ID,ASSIGNED BY COMMODORE-AMIGA! */ + u_long er_SerialNumber; /* Available for use by manufacturer */ + u_short er_InitDiagVec; /* Offset to optional "DiagArea" structure */ + u_char er_Reserved0c; + u_char er_Reserved0d; + u_char er_Reserved0e; + u_char er_Reserved0f; +}; + +/* er_Type board type bits */ +#define ERT_TYPEMASK 0xc0 +#define ERT_ZORROII 0xc0 +#define ERT_ZORROIII 0x80 + +/* other bits defined in er_Type */ +#define ERTB_MEMLIST 5 /* Link RAM into free memory list */ +#define ERTF_MEMLIST (1<<5) + +struct ConfigDev { + struct Node cd_Node; + u_char cd_Flags; /* (read/write) */ + u_char cd_Pad; /* reserved */ + struct ExpansionRom cd_Rom; /* copy of board's expansion ROM */ + void *cd_BoardAddr; /* where in memory the board was placed */ + u_long cd_BoardSize; /* size of board in bytes */ + u_short cd_SlotAddr; /* which slot number (PRIVATE) */ + u_short cd_SlotSize; /* number of slots (PRIVATE) */ + void *cd_Driver; /* pointer to node of driver */ + struct ConfigDev *cd_NextCD; /* linked list of drivers to config */ + u_long cd_Unused[4]; /* for whatever the driver wants */ +}; + +#else /* __ASSEMBLY__ */ + +LN_Succ = 0 +LN_Pred = LN_Succ+4 +LN_Type = LN_Pred+4 +LN_Pri = LN_Type+1 +LN_Name = LN_Pri+1 +LN_sizeof = LN_Name+4 + +ER_Type = 0 +ER_Product = ER_Type+1 +ER_Flags = ER_Product+1 +ER_Reserved03 = ER_Flags+1 +ER_Manufacturer = ER_Reserved03+1 +ER_SerialNumber = ER_Manufacturer+2 +ER_InitDiagVec = ER_SerialNumber+4 +ER_Reserved0c = ER_InitDiagVec+2 +ER_Reserved0d = ER_Reserved0c+1 +ER_Reserved0e = ER_Reserved0d+1 +ER_Reserved0f = ER_Reserved0e+1 +ER_sizeof = ER_Reserved0f+1 + +CD_Node = 0 +CD_Flags = CD_Node+LN_sizeof +CD_Pad = CD_Flags+1 +CD_Rom = CD_Pad+1 +CD_BoardAddr = CD_Rom+ER_sizeof +CD_BoardSize = CD_BoardAddr+4 +CD_SlotAddr = CD_BoardSize+4 +CD_SlotSize = CD_SlotAddr+2 +CD_Driver = CD_SlotSize+2 +CD_NextCD = CD_Driver+4 +CD_Unused = CD_NextCD+4 +CD_sizeof = CD_Unused+(4*4) + +#endif /* __ASSEMBLY__ */ + +#ifndef __ASSEMBLY__ + +/* + * Zorro Functions + */ + +extern int zorro_find(int manuf, int prod, int part, int index); +extern struct ConfigDev *zorro_get_board(int key); +extern void zorro_config_board(int key, int part); +extern void zorro_unconfig_board(int key, int part); + + +/* + * Bitmask indicating portions of available Zorro II RAM that are unused + * by the system. Every bit represents a 64K chunk, for a maximum of 8MB + * (128 chunks, physical 0x00200000-0x009fffff). + * + * If you want to use (= allocate) portions of this RAM, you should clear + * the corresponding bits. + */ + +extern u_long zorro_unused_z2ram[4]; + +#define Z2RAM_START (0x00200000) +#define Z2RAM_END (0x00a00000) +#define Z2RAM_SIZE (0x00800000) +#define Z2RAM_CHUNKSIZE (0x00010000) +#define Z2RAM_CHUNKMASK (0x0000ffff) +#define Z2RAM_CHUNKSHIFT (16) + + +/* + * Verbose Board Identification + */ + +#ifdef CONFIG_ZORRO +extern void zorro_identify(void); +extern int zorro_get_list(char *buffer); +#endif CONFIG_ZORRO + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_M68K_ZORRO_H_ */ diff --git a/include/asm-mips/a.out.h b/include/asm-mips/a.out.h new file mode 100644 index 000000000..c50f2aa24 --- /dev/null +++ b/include/asm-mips/a.out.h @@ -0,0 +1,26 @@ +#ifndef __ASM_MIPS_A_OUT_H +#define __ASM_MIPS_A_OUT_H + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#ifdef __KERNEL__ + +#define STACK_TOP TASK_SIZE + +#endif + +#endif /* __ASM_MIPS_A_OUT_H */ diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h new file mode 100644 index 000000000..39259486e --- /dev/null +++ b/include/asm-mips/addrspace.h @@ -0,0 +1,52 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + * + * Defitions for the address spaces of the MIPS CPUs. + */ +#ifndef __ASM_MIPS_ADDRSPACE_H +#define __ASM_MIPS_ADDRSPACE_H + +/* + * Memory segments (32bit kernel mode addresses) + */ +#define KUSEG 0x00000000 +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 +#define KSEG2 0xc0000000 +#define KSEG3 0xe0000000 + +/* + * Returns the kernel segment base of a given address + */ +#define KSEGX(a) (((unsigned long)(a)) & 0xe0000000) + +/* + * Returns the physical address of a KSEG0/KSEG1 address + */ +#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) + +/* + * Map an address to a certain kernel segment + */ +#define KSEG0ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG0)) +#define KSEG1ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG1)) +#define KSEG2ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG2)) +#define KSEG3ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG3)) + +/* + * Memory segments (64bit kernel mode addresses) + */ +#define XKUSEG 0x0000000000000000 +#define XKSSEG 0x4000000000000000 +#define XKPHYS 0x8000000000000000 +#define XKSEG 0xc000000000000000 +#define CKSEG0 0xffffffff80000000 +#define CKSEG1 0xffffffffa0000000 +#define CKSSEG 0xffffffffc0000000 +#define CKSEG3 0xffffffffe0000000 + +#endif /* __ASM_MIPS_ADDRSPACE_H */ diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h index 12c9785d8..afb189d63 100644 --- a/include/asm-mips/asm.h +++ b/include/asm-mips/asm.h @@ -5,9 +5,9 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995 by Ralf Baechle + * Copyright (C) 1995, 1996 by Ralf Baechle * - * Some usefull macros for MIPS assembler code + * Some useful macros for MIPS assembler code * * Some of the routines below contain useless nops that will be optimized * away by gas in -O mode. These nops are however required to fill delay @@ -16,8 +16,7 @@ #ifndef __ASM_ASM_H #define __ASM_ASM_H -#include <linux/autoconf.h> -#include <asm/regdef.h> +#include <asm/sgidefs.h> #ifndef CAT #ifdef __STDC__ @@ -29,32 +28,14 @@ #endif /* - * Macros to handle different pointer sizes for 32/64-bit code + * Macros to handle different pointer/register sizes for 32/64-bit code + * + * 64 bit address space isn't used yet, so we may use the R3000 32 bit + * defines for now. */ -#if __mips == 3 -#define PTR .quad -#define PTRSIZE 8 -#define PTRLOG 3 -#define lp ld -#else #define PTR .word #define PTRSIZE 4 #define PTRLOG 2 -#define lp lw -#endif - -/* - * ELF specific declarations - */ -#ifdef __ELF__ -#define TYPE(symbol,_type) \ - .type symbol,@_type -#define SIZE(symbol,_size) \ - .size symbol,_size -#else -#define TYPE(symbol,type) -#define SIZE(symbol,size) -#endif /* * PIC specific declarations @@ -62,11 +43,11 @@ */ #ifdef __PIC__ #define CPRESTORE(register) \ - .cprestore register + .cprestore register #define CPADD(register) \ - .cpadd register + .cpadd register #define CPLOAD(register) \ - .cpload register + .cpload register #else #define CPRESTORE(register) #define CPADD(register) @@ -77,64 +58,67 @@ * LEAF - declare leaf routine */ #define LEAF(symbol) \ - .globl symbol; \ - .align 2; \ - TYPE(symbol,function); \ - .ent symbol,0; \ -symbol: .frame sp,0,ra + .globl symbol; \ + .align 2; \ + .type symbol,@function; \ + .ent symbol,0; \ +symbol: .frame sp,0,ra /* * NESTED - declare nested routine entry point */ #define NESTED(symbol, framesize, rpc) \ - .globl symbol; \ - .align 2; \ - TYPE(symbol,function); \ - .ent symbol,0; \ -symbol: .frame sp, framesize, rpc + .globl symbol; \ + .align 2; \ + .type symbol,@function; \ + .ent symbol,0; \ +symbol: .frame sp, framesize, rpc /* * END - mark end of function */ #define END(function) \ - .end function; \ - SIZE(function,.-function) + .end function; \ + .size function,.-function /* * EXPORT - export definition of symbol */ #define EXPORT(symbol) \ - .globl symbol; \ + .globl symbol; \ symbol: /* * ABS - export absolute symbol */ #define ABS(symbol,value) \ - .globl symbol; \ -symbol = value + .globl symbol; \ +symbol = value #define PANIC(msg) \ - la a0,8f; \ - jal panic; \ - nop; \ -9: b 9b; \ - nop; \ - TEXT(msg) + .set push; \ + .set reorder; \ + la a0,8f; \ + jal panic; \ +9: b 9b; \ + .set pop; \ + TEXT(msg) /* * Print formated string */ #define PRINT(string) \ - la a0,8f; \ - jal printk; \ - nop; \ - TEXT(string) + .set push; \ + .set reorder; \ + la a0,8f; \ + jal printk; \ + .set pop; \ + TEXT(string) #define TEXT(msg) \ - .data; \ -8: .asciiz msg; \ - .text + .data; \ +8: .asciiz msg; \ + .text; /* * Build text tables @@ -144,60 +128,33 @@ symbol = value .word 1f; \ .data; \ 1: .asciz string; \ - .text; - -/* - * Move to kernel mode and disable interrupts - * Set cp0 enable bit as sign that we're running on the kernel stack - * Use with .set noat! - */ -#define CLI \ - mfc0 AT,CP0_STATUS; \ - li t0,ST0_CU0|0x1f; \ - or AT,t0; \ - xori AT,0x1f; \ - mtc0 AT,CP0_STATUS; \ - -/* - * Move to kernel mode and enable interrupts - * Set cp0 enable bit as sign that we're running on the kernel stack - * Use with .set noat! - */ -#define STI \ - mfc0 AT,CP0_STATUS; \ - li t0,ST0_CU0|0x1f; \ - or AT,t0; \ - xori AT,0x1e; \ - mtc0 AT,CP0_STATUS; \ - -/* - * Special nop to fill load delay slots - */ -#ifndef __R4000__ -#define NOP nop -#else -#define NOP -#endif + .text /* * Return from exception */ -#if defined (CONFIG_CPU_R3000) +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) #define ERET rfe -#elif defined (CONFIG_CPU_R4X00) || defined (CONFIG_CPU_R4600) +#endif +#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS5) #define ERET \ - .set mips3; \ eret; \ - .set mips0 -#else -#error "Implement ERET macro!" + nop; \ + nop; \ + nop; \ + nop; \ + nop #endif /* - * R8000/R10000 (MIPS ISA IV) pref instruction. + * MIPS IV pref instruction. * Use with .set noreorder only! + * + * MIPS IV implementations are free to treat this as a nop. The R5000 + * is one of them. So we should have an option not to use this instruction. */ -#if defined (CONFIG_CPU_R8000) || defined(CONFIG_CPU_R10000) +#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) #define PREF(hint,addr) \ pref hint,addr #define PREFX(hint,addr) \ @@ -208,34 +165,226 @@ symbol = value #endif /* - * R8000/R10000 (MIPS ISA IV) movn/movz instructions and - * equivalents for old CPUs. Use with .set noreorder only! + * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. */ -#if defined (CONFIG_CPU_R8000) || defined (CONFIG_CPU_R10000) -#define MOVN(rd,rs,rt) \ - movn rd,rs,rt -#define MOVZ(rd,rs,rt) \ - movz rd,rs,rt -#elif defined (CONFIG_CPU_R4000) || defined (CONFIG_CPU_R6000) +#if _MIPS_ISA == _MIPS_ISA_MIPS1 #define MOVN(rd,rs,rt) \ - bnezl rt,9f \ - move rd,rs \ + .set push; \ + .set reorder; \ + beqz rt,9f; \ + move rd,rs; \ + .set pop; \ 9: #define MOVZ(rd,rs,rt) \ - beqzl rt,9f \ - movz rd,rt \ + .set push; \ + .set reorder; \ + bnez rt,9f; \ + move rd,rt; \ + .set pop; \ 9: -#else /* R2000, R3000 */ +#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) #define MOVN(rd,rs,rt) \ - beqz rt,9f \ - nop \ - move rd,rs \ + .set push; \ + .set noreorder; \ + bnezl rt,9f; \ + move rd,rs; \ + .set pop; \ 9: #define MOVZ(rd,rs,rt) \ - bneqz rt,9f \ - nop \ - movz rd,rt \ + .set push; \ + .set noreorder; \ + beqzl rt,9f; \ + movz rd,rs; \ + .set pop; \ 9: +#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) +#define MOVN(rd,rs,rt) \ + movn rd,rs,rt +#define MOVZ(rd,rs,rt) \ + movz rd,rs,rt +#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */ + +/* + * Stack alignment + */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) +#define ALSZ 7 +#define ALMASK ~7 +#endif +#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS5) +#define ALSZ 15 +#define ALMASK ~15 +#endif + +/* + * Size of a register + */ +#ifdef __mips64 +#define SZREG 8 +#else +#define SZREG 4 +#endif + +/* + * Use the following macros in assemblercode to load/store registers, + * pointers etc. + */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) +#define REG_S sw +#define REG_L lw +#define PTR_SUBU subu +#define PTR_ADDU addu +#endif +#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS5) +#define REG_S sd +#define REG_L ld +/* We still live in a 32 bit address space ... */ +#define PTR_SUBU subu +#define PTR_ADDU addu +#endif + +/* + * How to add/sub/load/store/shift C int variables. + */ +#if (_MIPS_SZINT == 32) +#define INT_ADD add +#define INT_ADDI addi +#define INT_ADDU addu +#define INT_ADDIU addiu +#define INT_SUB add +#define INT_SUBI subi +#define INT_SUBU subu +#define INT_SUBIU subu +#define INT_L lw +#define INT_S sw +#define LONG_SLL sll +#define LONG_SLLV sllv +#define LONG_SRL srl +#define LONG_SRLV srlv +#define LONG_SRA sra +#define LONG_SRAV srav +#endif + +#if (_MIPS_SZINT == 64) +#define INT_ADD dadd +#define INT_ADDI daddi +#define INT_ADDU daddu +#define INT_ADDIU daddiu +#define INT_SUB dadd +#define INT_SUBI dsubi +#define INT_SUBU dsubu +#define INT_SUBIU dsubu +#define INT_L ld +#define INT_S sd +#define LONG_SLL dsll +#define LONG_SLLV dsllv +#define LONG_SRL dsrl +#define LONG_SRLV dsrlv +#define LONG_SRA dsra +#define LONG_SRAV dsrav +#endif + +/* + * How to add/sub/load/store/shift C long variables. + */ +#if (_MIPS_SZLONG == 32) +#define LONG_ADD add +#define LONG_ADDI addi +#define LONG_ADDU addu +#define LONG_ADDIU addiu +#define LONG_SUB add +#define LONG_SUBI subi +#define LONG_SUBU subu +#define LONG_SUBIU subu +#define LONG_L lw +#define LONG_S sw +#define LONG_SLL sll +#define LONG_SLLV sllv +#define LONG_SRL srl +#define LONG_SRLV srlv +#define LONG_SRA sra +#define LONG_SRAV srav +#endif + +#if (_MIPS_SZLONG == 64) +#define LONG_ADD dadd +#define LONG_ADDI daddi +#define LONG_ADDU daddu +#define LONG_ADDIU daddiu +#define LONG_SUB dadd +#define LONG_SUBI dsubi +#define LONG_SUBU dsubu +#define LONG_SUBIU dsubu +#define LONG_L ld +#define LONG_S sd +#define LONG_SLL dsll +#define LONG_SLLV dsllv +#define LONG_SRL dsrl +#define LONG_SRLV dsrlv +#define LONG_SRA dsra +#define LONG_SRAV dsrav +#endif + +/* + * How to add/sub/load/store/shift pointers. + */ +#if (_MIPS_SZLONG == 32) +#define PTR_ADD add +#define PTR_ADDI addi +#define PTR_ADDU addu +#define PTR_ADDIU addiu +#define PTR_SUB add +#define PTR_SUBI subi +#define PTR_SUBU subu +#define PTR_SUBIU subu +#define PTR_L lw +#define PTR_S sw +#define PTR_SLL sll +#define PTR_SLLV sllv +#define PTR_SRL srl +#define PTR_SRLV srlv +#define PTR_SRA sra +#define PTR_SRAV srav + +#define PTR_SCALESHIFT 2 +#endif + +#if (_MIPS_SZLONG == 64) +#define PTR_ADD dadd +#define PTR_ADDI daddi +#define PTR_ADDU daddu +#define PTR_ADDIU daddiu +#define PTR_SUB dadd +#define PTR_SUBI dsubi +#define PTR_SUBU dsubu +#define PTR_SUBIU dsubu +#define PTR_L ld +#define PTR_S sd +#define PTR_SLL dsll +#define PTR_SLLV dsllv +#define PTR_SRL dsrl +#define PTR_SRLV dsrlv +#define PTR_SRA dsra +#define PTR_SRAV dsrav + +#define PTR_SCALESHIFT 3 +#endif + +/* + * Some cp0 registers were extended to 64bit for MIPS III. + */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) +#define MFC0 mfc0 +#define MTC0 mtc0 +#endif +#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS5) +#define MFC0 dmfc0 +#define MTC0 dmtc0 #endif #endif /* __ASM_ASM_H */ diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h new file mode 100644 index 000000000..1faf804c6 --- /dev/null +++ b/include/asm-mips/atomic.h @@ -0,0 +1,176 @@ +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + * + * But use these as seldom as possible since they are much more slower + * than regular operations. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_ATOMIC_H +#define __ASM_MIPS_ATOMIC_H + +#include <asm/sgidefs.h> + +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) + +typedef int atomic_t; + +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) + +#include <asm/system.h> + +/* + * The MIPS I implementation is only atomic with respect to + * interrupts. R3000 based multiprocessor machines are rare anyway ... + */ +extern __inline__ void atomic_add(atomic_t i, atomic_t * v) +{ + int flags; + + save_flags(flags); + cli(); + *v += i; + restore_flags(flags); +} + +extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) +{ + int flags; + + save_flags(flags); + cli(); + *v -= i; + restore_flags(flags); +} + +extern __inline__ int atomic_add_return(atomic_t i, atomic_t * v) +{ + int temp, flags; + + save_flags(flags); + cli(); + temp = *v; + temp += i; + *v = temp; + restore_flags(flags); + + return temp; +} + +extern __inline__ int atomic_sub_return(atomic_t i, atomic_t * v) +{ + int temp, flags; + + save_flags(flags); + cli(); + temp = *v; + temp -= i; + *v = temp; + restore_flags(flags); + + return temp; +} +#endif + +#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) +/* + * ... while for MIPS II and better we can use ll/sc instruction. This + * implementation is SMP safe ... + */ +extern __inline__ void atomic_add(atomic_t i, atomic_t * v) +{ + unsigned long temp; + + __asm__ __volatile__( + "1:\tll\t%0,%1\n\t" + "addu\t%0,%2\n\t" + "sc\t%0,%1\n\t" + "beqz\t%0,1b" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); +} + +extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) +{ + unsigned long temp; + + __asm__ __volatile__( + "1:\tll\t%0,%1\n\t" + "subu\t%0,%2\n\t" + "sc\t%0,%1\n\t" + "beqz\t%0,1b" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); +} + +/* + * Same as above, but return the result value + */ +extern __inline__ int atomic_add_return(atomic_t i, atomic_t * v) +{ + unsigned long temp, result; + + __asm__ __volatile__( + ".set\tnoreorder\n" + "1:\tll\t%1,%2\n\t" + "addu\t%0,%1,%3\n\t" + "sc\t%0,%2\n\t" + "beqz\t%0,1b\n\t" + "addu\t%0,%1,%3\n\t" + ".set\treorder" + :"=&r" (result), + "=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); + + return result; +} + +extern __inline__ int atomic_sub_return(atomic_t i, atomic_t * v) +{ + unsigned long temp, result; + + __asm__ __volatile__( + ".set\tnoreorder\n" + "1:\tll\t%1,%2\n\t" + "subu\t%0,%1,%3\n\t" + "sc\t%0,%2\n\t" + "beqz\t%0,1b\n\t" + "subu\t%0,%1,%3\n\t" + ".set\treorder" + :"=&r" (result), + "=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); + + return result; +} +#endif + +#define atomic_dec_return(v) atomic_sub_return(1,(v)) +#define atomic_inc_return(v) atomic_add_return(1,(v)) + +#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) + +#define atomic_inc(v) atomic_add(1,(v)) +#define atomic_dec(v) atomic_sub(1,(v)) + +#endif /* __ASM_MIPS_ATOMIC_H */ diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 255ec9ee2..4a7f8ab89 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -5,13 +5,33 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1994, 1995 Ralf Baechle + * Copyright (c) 1994, 1995, 1996 Ralf Baechle */ #ifndef __ASM_MIPS_BITOPS_H #define __ASM_MIPS_BITOPS_H -#ifdef __R4000__ +#include <asm/sgidefs.h> +/* + * Note that the bit operations are defined on arrays of 32 bit sized + * elements. With respect to a future 64 bit implementation it is + * wrong to use long *. Use u32 * or int *. + */ +extern __inline__ int set_bit(int nr, void *addr); +extern __inline__ int clear_bit(int nr, void *addr); +extern __inline__ int change_bit(int nr, void *addr); +extern __inline__ int test_bit(int nr, const void *addr); +extern __inline__ int find_first_zero_bit (void *addr, unsigned size); +extern __inline__ int find_next_zero_bit (void * addr, int size, int offset); +extern __inline__ unsigned long ffz(unsigned long word); + +#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) + +/* + * These functions for MIPS ISA > 1 are interrupt and SMP proof and + * interrupt friendly + */ #include <asm/mipsregs.h> /* @@ -62,19 +82,29 @@ extern __inline__ int change_bit(int nr, void *addr) return retval; } -#else /* !defined(__R4000__) */ +#else /* MIPS I */ +#ifdef __KERNEL__ +/* + * These functions are only used for MIPS ISA 1 CPUs. Since I don't + * believe that someone ever will run Linux/SMP on such a beast I don't + * worry about making them SMP proof. + */ #include <asm/system.h> -#ifdef __KERNEL__ /* - * Only disable interrupt for kernelmode stuff to keep some - * usermode stuff alive + * Only disable interrupt for kernel mode stuff to keep usermode stuff + * that dares to use kernel include files alive. */ #define __flags unsigned long flags #define __cli() cli() #define __save_flags(x) save_flags(x) #define __restore_flags(x) restore_flags(x) +#else +#define __flags +#define __cli() +#define __save_flags(x) +#define __restore_flags(x) #endif /* __KERNEL__ */ extern __inline__ int set_bit(int nr, void * addr) @@ -133,48 +163,56 @@ extern __inline__ int change_bit(int nr, void * addr) #undef __save_flags(x) #undef __restore_flags(x) -#endif /* !defined(__R4000__) */ +#endif /* MIPS I */ -extern __inline__ int test_bit(int nr, void *addr) +extern __inline__ int test_bit(int nr, const void *addr) { - int mask; - unsigned long *a; - - a = addr; - addr += nr >> 5; - mask = 1 << (nr & 0x1f); - return ((mask & *a) != 0); + return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0; } extern __inline__ int find_first_zero_bit (void *addr, unsigned size) { + unsigned long dummy; int res; if (!size) return 0; - __asm__(".set\tnoreorder\n\t" + __asm__ (".set\tnoreorder\n\t" ".set\tnoat\n" - "1:\tsubu\t$1,%2,%0\n\t" + "1:\tsubu\t$1,%6,%0\n\t" "blez\t$1,2f\n\t" - "lw\t$1,(%4)\n\t" - "addiu\t%4,%4,4\n\t" + "lw\t$1,(%5)\n\t" + "addiu\t%5,4\n\t" +#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) "beql\t%1,$1,1b\n\t" - "addiu\t%0,%0,32\n\t" + "addiu\t%0,32\n\t" +#else + "addiu\t%0,32\n\t" + "beq\t%1,$1,1b\n\t" + "nop\n\t" + "subu\t%0,32\n\t" +#endif +#ifdef __MIPSEB__ +#error "Fix this for big endian" +#endif /* __MIPSEB__ */ "li\t%1,1\n" - "1:\tand\t%4,$1,%1\n\t" - "beq\t$0,%4,2f\n\t" + "1:\tand\t%2,$1,%1\n\t" + "beqz\t%2,2f\n\t" "sll\t%1,%1,1\n\t" - "bne\t$0,%1,1b\n\t" + "bnez\t%1,1b\n\t" "add\t%0,%0,1\n\t" ".set\tat\n\t" ".set\treorder\n" "2:" - : "=r" (res) - : "r" ((unsigned int) 0xffffffff), - "r" (size), - "0" ((signed int) 0), - "r" (addr) + : "=r" (res), + "=r" (dummy), + "=r" (addr) + : "0" ((signed int) 0), + "1" ((unsigned int) 0xffffffff), + "2" (addr), + "r" (size) : "$1"); return res; @@ -182,26 +220,32 @@ extern __inline__ int find_first_zero_bit (void *addr, unsigned size) extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) { - unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + unsigned int *p = ((unsigned int *) addr) + (offset >> 5); int set = 0, bit = offset & 31, res; + unsigned long dummy; if (bit) { /* * Look for zero in first byte */ +#ifdef __MIPSEB__ +#error "Fix this for big endian byte order" +#endif __asm__(".set\tnoreorder\n\t" ".set\tnoat\n" - "1:\tand\t$1,%2,%1\n\t" - "beq\t$0,$1,2f\n\t" - "sll\t%2,%2,1\n\t" - "bne\t$0,%2,1b\n\t" - "addiu\t%0,%0,1\n\t" + "1:\tand\t$1,%4,%1\n\t" + "beqz\t$1,1f\n\t" + "sll\t%1,%1,1\n\t" + "bnez\t%1,1b\n\t" + "addiu\t%0,1\n\t" ".set\tat\n\t" ".set\treorder\n" - : "=r" (set) - : "r" (*p >> bit), - "r" (1), - "0" (0) + "1:" + : "=r" (set), + "=r" (dummy) + : "0" (0), + "1" (1 << bit), + "r" (*p) : "$1"); if (set < (32 - bit)) return set + offset; @@ -211,8 +255,8 @@ extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) /* * No zero yet, search remaining full bytes for a zero */ - res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); - return (offset + set + res); + res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr)); + return offset + set + res; } /* @@ -224,25 +268,36 @@ extern __inline__ unsigned long ffz(unsigned long word) unsigned int __res; unsigned int mask = 1; - __asm__ __volatile__ ( + __asm__ ( ".set\tnoreorder\n\t" ".set\tnoat\n\t" - "li\t%2,1\n" + "move\t%0,$0\n" "1:\tand\t$1,%2,%1\n\t" "beqz\t$1,2f\n\t" - "sll\t%2,1\n\t" - "bnez\t%2,1b\n\t" + "sll\t%1,1\n\t" + "bnez\t%1,1b\n\t" "addiu\t%0,1\n\t" ".set\tat\n\t" ".set\treorder\n" "2:\n\t" - : "=r" (__res), "=r" (word), "=r" (mask) - : "1" (~(word)), - "2" (mask), - "0" (0) + : "=&r" (__res), "=r" (mask) + : "r" (word), "1" (mask) : "$1"); return __res; } +#ifdef __KERNEL__ +#ifdef __MIPSEB__ +#error "Aieee... fix these sources for big endian machines" +#endif /* __MIPSEB__ */ + +#define ext2_set_bit set_bit +#define ext2_clear_bit clear_bit +#define ext2_test_bit test_bit +#define ext2_find_first_zero_bit find_first_zero_bit +#define ext2_find_next_zero_bit find_next_zero_bit + +#endif /* __KERNEL__ */ + #endif /* __ASM_MIPS_BITOPS_H */ diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 594b45b5d..a7e712b96 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -1,11 +1,8 @@ /* * bootinfo.h -- Definition of the Linux/MIPS boot information structure * - * Copyright (C) 1994 by Waldorf Electronics - * Written by Ralf Baechle and Andreas Busse - * - * Based on Linux/68k linux/include/linux/bootstrap.h - * Copyright (C) 1992 by Greg Harp + * Copyright (C) 1995, 1996 by Ralf Baechle, Andreas Busse, + * Stoned Elipot and Paul M. Antoine. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file README.legal in the main directory of this archive @@ -15,14 +12,64 @@ #define __ASM_MIPS_BOOTINFO_H /* - * Valid machtype values + * Valid machgroup values + */ +#define MACH_GROUP_UNKNOWN 0 /* whatever... */ +#define MACH_GROUP_JAZZ 1 /* Acer Pica 61, Mips Magnum 4000, Olivetti */ + /* M700-10 */ +#define MACH_GROUP_DEC 2 /* Digital */ +#define MACH_GROUP_ARC 3 /* Deskstation Tyne, rpc44, possibly other */ +#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ +#define MACH_GROUP_ACN 5 + +#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", "SNI", "ACN" } + +/* + * Valid machtype values for group unknown (low order halfword of mips_machtype) + */ +#define MACH_UNKNOWN 0 /* whatever... */ + +#define GROUP_UNKNOWN_NAMES { "unknown" } + +/* + * Valid machtype values for group JAZZ + */ +#define MACH_ACER_PICA_61 0 /* Acer PICA-61 (PICA1) */ +#define MACH_MIPS_MAGNUM_4000 1 /* Mips Magnum 4000 "RC4030" */ +#define MACH_OLIVETTI_M700 2 /* Olivetti M700-10 (-15 ??) */ + +#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" } + +/* + * Valid machtype for group DEC + */ +/* FIXME: this is a very fuzzy name, and we got a big "name space now" */ +/* So otiginal DEC codes can be used -Stoned */ +#define MACH_DECSTATION 0 /* DECStation 5000/2x for now */ + +#define GROUP_DEC_NAMES { "3min" } + +/* + * Valid machtype for group ARC + */ +#define MACH_DESKSTATION_RPC44 0 /* Deskstation rPC44 */ +#define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */ + +#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" } + +/* + * Valid machtype for group SNI_RM */ -#define MACH_UNKNOWN 0 /* whatever... */ -#define MACH_DESKSTATION_RPC44 1 /* Deskstation rPC44 */ -#define MACH_DESKSTATION_TYNE 2 /* Deskstation Tyne */ -#define MACH_ACER_PICA_61 3 /* Acer PICA-61 (PICA1) */ -#define MACH_MIPS_MAGNUM_4000 4 /* Mips Magnum 4000 "RC4030" */ -#define MACH_OLIVETTI_M700 5 /* Olivetti M700 */ +#define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */ + +#define GROUP_SNI_RM_NAMES { "RM200 PCI" } + +/* + * Valid machtype for group SNI_RM + */ +#define MACH_ACN_MIPS_BOARD 0 /* ACN MIPS single board */ + +#define GROUP_ACN_NAMES { "ACN" } /* * Valid cputype values @@ -48,200 +95,182 @@ #define CPU_R6000A 18 #define CPU_R8000 19 #define CPU_R10000 20 -#define CPU_LAST 20 - -#define CPU_NAMES { "UNKNOWN", "R2000", "R3000", "R3000A", "R3041", "R3051", \ +#define CPU_R4300 21 +#define CPU_R4650 22 +#define CPU_R4700 23 +#define CPU_R5000 24 +#define CPU_R5000A 25 +#define CPU_R4640 26 +#define CPU_LAST 26 + +#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \ "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \ "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \ - "R6000A", "R8000", "R10000" } + "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000", \ + "R5000A", "R4640" } #define CL_SIZE (80) #ifndef __LANGUAGE_ASSEMBLY__ /* - * Some machine parameters passed by MILO. Note that bootinfo - * *must* be in the data segment since the kernel clears the - * bss segment directly after startup. + * Some machine parameters passed by the bootloaders. */ struct drive_info_struct { char dummy[32]; - }; - -struct bootinfo { - /* - * machine type - */ - unsigned long machtype; - - /* - * system CPU & FPU - */ - unsigned long cputype; - - /* - * Installed RAM - */ - unsigned long memlower; - unsigned long memupper; - - /* - * Cache Sizes (0xffffffff = unknown) - */ - unsigned long icache_size; - unsigned long icache_linesize; - unsigned long dcache_size; - unsigned long dcache_linesize; - unsigned long scache_size; - unsigned long scache_linesize; - - /* - * TLB Info - */ - unsigned long tlb_entries; - - /* - * DMA buffer size (Deskstation only) - */ - unsigned long dma_cache_size; - unsigned long dma_cache_base; - - /* - * Ramdisk Info - */ - unsigned long ramdisk_size; /* ramdisk size in 1024 byte blocks */ - unsigned long ramdisk_base; /* address of the ram disk in mem */ - - /* - * Boot flags for the kernel - */ - unsigned long mount_root_rdonly; - struct drive_info_struct drive_info; - - /* - * Video ram info (not in tty.h) - */ - unsigned long vram_base; /* video ram base address */ - - char command_line[CL_SIZE]; /* kernel command line parameters */ - }; -#if 0 +/* This is the same as in Milo but renamed for the sake of kernel's */ +/* namespace */ +typedef struct mips_arc_DisplayInfo /* video adapter information */ +{ + unsigned short cursor_x; + unsigned short cursor_y; + unsigned short columns; + unsigned short lines; +} mips_arc_DisplayInfo; + /* * New style bootinfo * * Add new tags only at the end of the enum; *never* remove any tags * or you'll break compatibility! + * Which compatibility ? compatibility consideration lead to + * MS-DOG :) -Stoned */ -enum bi_tag { - /* - * not a real tag - */ - dummy, - - /* - * machine type - */ - machtype, - - /* - * system CPU & FPU - */ - cputype, +enum bi_tag { + /* + * not a real tag + */ + tag_dummy, + + /* + * machine type + */ + tag_machtype, + + /* + * system CPU & FPU + */ + tag_cputype, + + /* + * Installed RAM + */ + tag_memlower, + tag_memupper, + + /* + * Cache Sizes (0xffffffff = unknown) + */ + tag_icache_size, + tag_icache_linesize, + tag_dcache_size, + tag_dcache_linesize, + tag_scache_size, + tag_scache_linesize, + + /* + * TLB Info + */ + tag_tlb_entries, + + /* + * DMA buffer size (Deskstation only) + */ + tag_dma_cache_size, + tag_dma_cache_base, + + /* + * Ramdisk Info + */ + tag_ramdisk_size, /* ramdisk size in 1024 byte blocks */ + tag_ramdisk_base, /* address of the ram disk in mem */ + + /* + * Boot flags for the kernel + */ + tag_mount_root_rdonly, /* No longer used; use "ro" command + line argument instead. */ + tag_drive_info, + + /* + * Video ram info (not in tty.h) + */ + tag_vram_base, /* video ram base address */ + + tag_command_line, /* kernel command line parameters */ + + /* + * machine group + */ + tag_machgroup, /* - * Installed RAM + * info on the display from the ARC BIOS */ - memlower, - memupper, + tag_arcdisplayinfo, /* - * Cache Sizes (0xffffffff = unknown) + * tag to pass a complete struct screen_info */ - icache_size, - icache_linesize, - dcache_size, - dcache_linesize, - scache_size, - scache_linesize, + tag_screen_info - /* - * TLB Info - */ - tlb_entries, - - /* - * DMA buffer size (Deskstation only) - */ - dma_cache_size, - dma_cache_base, - - /* - * Ramdisk Info - */ - ramdisk_size, /* ramdisk size in 1024 byte blocks */ - ramdisk_base, /* address of the ram disk in mem */ - - /* - * Boot flags for the kernel - */ - mount_root_rdonly, - drive_info, - - /* - * Video ram info (not in tty.h) - */ - vram_base, /* video ram base address */ - - command_line /* kernel command line parameters */ - }; +/* struct defining a tag */ typedef struct { - bi_tag tag; - unsigned long size; + enum bi_tag tag; + unsigned long size; } tag; -#endif - -extern struct bootinfo boot_info; -/* - * Defaults, may be overwritten by milo. We initialize - * them to make sure that both boot_info and screen_info - * are in the .data segment since the .bss segment is - * cleared during startup. - */ -#define BOOT_INFO { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, {{0,}}, 0, "" } -#define SCREEN_INFO {0, 0, {0, }, 52, 3, 80, 4626, 3, 9, 50} - -#else /* !__LANGUAGE_ASSEMBLY__ */ +/* struct to define a tag and it's data */ +typedef struct { + tag t; + void* d; +} tag_def; + +/* macros for parsing tag list */ +#define TAGVALPTR(t) ((void*)(((void*)(t)) - ((t)->size))) +#define NEXTTAGPTR(t) ((void*)(TAGVALPTR(t) - (sizeof(tag)))) + +/* size macros for tag size field */ +#define UCHARSIZE (sizeof(unsigned char)) +#define ULONGSIZE (sizeof(unsigned long)) +#define UINTSIZE (sizeof(unsigned int)) +#define DRVINFOSIZE (sizeof(struct drive_info_struct)) +#define CMDLINESIZE (sizeof(char[CL_SIZE]) + +/* For tag readers aka the kernel */ +tag *bi_TagFind(enum bi_tag type); +void bi_EarlySnarf(void); + +/* For tag creators aka bootloaders */ +/* Now implemented in Milo 0.26 */ +int bi_TagAdd(enum bi_tag type, unsigned long size, void *data); +int bi_TagAddList(tag_def* taglist); +void bi_TagWalk(void); + +/* default values for screen_info variable */ +#define DEFAULT_SCREEN_INFO {0, 0, {0, }, 52, 3, 80, 4626, 3, 9, 50} +/* default values for drive info */ +#define DEFAULT_DRIVE_INFO { {0,}} /* - * Same structure, but as offsets for usage within assembler source. - * Don't mess with struct bootinfo without changing offsets too! + * These are the kernel variables initialized from + * the tag. And they have to be initialized to dummy/default + * values in setup.c (or whereever suitable) so they are in + * .data section */ - -#define OFFSET_BOOTINFO_MACHTYPE 0 -#define OFFSET_BOOTINFO_CPUTYPE 4 -#define OFFSET_BOOTINFO_MEMLOWER 8 -#define OFFSET_BOOTINFO_MEMUPPER 12 -#define OFFSET_BOOTINFO_ICACHE_SIZE 16 -#define OFFSET_BOOTINFO_ICACHE_LINESIZE 20 -#define OFFSET_BOOTINFO_DCACHE_SIZE 24 -#define OFFSET_BOOTINFO_DCACHE_LINESIZE 28 -#define OFFSET_BOOTINFO_SCACHE_SIZE 32 -#define OFFSET_BOOTINFO_SCACHE_LINESIZE 36 -#define OFFSET_BOOTINFO_TLB_ENTRIES 40 -#define OFFSET_BOOTINFO_DMA_CACHE_SIZE 44 -#define OFFSET_BOOTINFO_DMA_CACHE_BASE 48 -#define OFFSET_BOOTINFO_RAMDISK_SIZE 52 -#define OFFSET_BOOTINFO_RAMDISK_BASE 56 -#define OFFSET_BOOTINFO_MOUNT_RD_ONLY 60 -#define OFFSET_BOOTINFO_DRIVE_INFO 64 -#define OFFSET_BOOTINFO_VRAM_BASE 96 -#define OFFSET_BOOTINFO_COMMAND_LINE 100 +extern unsigned long mips_memory_upper; +extern unsigned long mips_cputype; +extern unsigned long mips_machtype; +extern unsigned long mips_machgroup; +extern unsigned long mips_tlb_entries; +extern unsigned long mips_vram_base; +extern unsigned long mips_dma_cache_size; +extern unsigned long mips_dma_cache_base; #endif /* __LANGUAGE_ASSEMBLY__ */ diff --git a/include/asm-mips/branch.h b/include/asm-mips/branch.h new file mode 100644 index 000000000..abca807ec --- /dev/null +++ b/include/asm-mips/branch.h @@ -0,0 +1,26 @@ +/* + * Branch and jump emulation. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ +#include <asm/ptrace.h> + +extern inline int delay_slot(struct pt_regs *regs) +{ + return regs->cp0_cause & CAUSEF_BD; +} + +extern int __compute_return_epc(struct pt_regs *regs); +extern inline int compute_return_epc(struct pt_regs *regs) +{ + if (delay_slot(regs)) { + return __compute_return_epc(regs); + } + + regs->cp0_epc += 4; + return 0; +} diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h index 41ca73366..f2c12e853 100644 --- a/include/asm-mips/bugs.h +++ b/include/asm-mips/bugs.h @@ -13,12 +13,11 @@ * void check_bugs(void); */ -extern struct bootinfo boot_info; static void check_wait(void) { printk("Checking for 'wait' instruction... "); - switch(boot_info.cputype) { + switch(mips_cputype) { case CPU_R4200: case CPU_R4600: wait_available = 1; diff --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h index 45abf2350..bf4c54a1f 100644 --- a/include/asm-mips/byteorder.h +++ b/include/asm-mips/byteorder.h @@ -1,94 +1,117 @@ +/* + * Functions depending of the byteorder. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996 by Ralf Baechle + */ #ifndef __ASM_MIPS_BYTEORDER_H #define __ASM_MIPS_BYTEORDER_H +extern unsigned long int ntohl(unsigned long int __x); +extern unsigned short int ntohs(unsigned short int __x); +extern unsigned short int htons(unsigned short int __x); +extern unsigned long int htonl(unsigned long int __x); + +#define __swap32(x) \ + ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \ + (((unsigned long int)(x) & 0x0000ff00U) << 8) | \ + (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \ + (((unsigned long int)(x) & 0xff000000U) >> 24))) +#define __swap16(x) \ + ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \ + (((unsigned short int)(x) & 0xff00) >> 8))) + +#if defined (__MIPSEB__) + +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN +#endif + +#ifndef __BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN_BITFIELD +#endif + +#define __constant_ntohl(x) (x) +#define __constant_ntohs(x) (x) +#define __constant_htonl(x) (x) +#define __constant_htons(x) (x) + +#ifdef __KERNEL__ + /* - * FIXME: Add big endian support + * In-kernel byte order macros to handle stuff like + * byte-order-dependent filesystems etc. */ -#undef ntohl -#undef ntohs -#undef htonl -#undef htons - -#ifdef __MIPSEL__ -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif +#define cpu_to_le32(x) __swap32((x)) +#define le32_to_cpu(x) __swap32((x)) +#define cpu_to_le16(x) __swap16((x)) +#define le16_to_cpu(x) __swap16((x)) + +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#define cpu_to_be16(x) (x) +#define be16_to_cpu(x) (x) + +#endif /* __KERNEL__ */ + +#elif defined (__MIPSEL__) -#ifndef LITTLE_ENDIAN_BITFIELD -#define LITTLE_ENDIAN_BITFIELD +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN #endif -#elif __MIPSEB__ -#define BIG_ENDIAN 4321 -#define BIG_ENDIAN_BITFIELD -#else -#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?" + +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD #endif -extern unsigned long int ntohl(unsigned long int); -extern unsigned short int ntohs(unsigned short int); -extern unsigned long int htonl(unsigned long int); -extern unsigned short int htons(unsigned short int); +#define __constant_ntohl(x) __swap32(x) +#define __constant_ntohs(x) __swap16(x) +#define __constant_htonl(x) __swap32(x) +#define __constant_htons(x) __swap16(x) -extern unsigned long int __ntohl(unsigned long int); -extern unsigned short int __ntohs(unsigned short int); -extern unsigned long int __constant_ntohl(unsigned long int); -extern unsigned short int __constant_ntohs(unsigned short int); +#ifdef __KERNEL__ /* - * The constant and non-constant versions here are the same. - * Maybe I'll come up with an mips-optimized routine for the - * non-constant ones (the constant ones don't need it: gcc - * will optimize it to the correct constant) + * In-kernel byte order macros to handle stuff like + * byte-order-dependent filesystems etc. */ +#define cpu_to_le32(x) (x) +#define le32_to_cpu(x) (x) +#define cpu_to_le16(x) (x) +#define le16_to_cpu(x) (x) + +#define cpu_to_be32(x) __swap32((x)) +#define be32_to_cpu(x) __swap32((x)) +#define cpu_to_be16(x) __swap16((x)) +#define be16_to_cpu(x) __swap16((x)) + +#endif /* __KERNEL__ */ -extern __inline__ unsigned long int -__ntohl(unsigned long int x) +#else +#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?" +#endif + +extern __inline__ unsigned long int ntohl(unsigned long int __x) { - return (((x & 0x000000ffU) << 24) | - ((x & 0x0000ff00U) << 8) | - ((x & 0x00ff0000U) >> 8) | - ((x & 0xff000000U) >> 24)); + return __constant_ntohl(__x); } -#define __constant_ntohl(x) \ - ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \ - (((unsigned long int)(x) & 0x0000ff00U) << 8) | \ - (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \ - (((unsigned long int)(x) & 0xff000000U) >> 24))) +extern __inline__ unsigned short int ntohs(unsigned short int __x) +{ + return __constant_ntohs(__x); +} -extern __inline__ unsigned short int -__ntohs(unsigned short int x) +extern __inline__ unsigned long int htonl(unsigned long int __x) { - return (((x & 0x00ff) << 8) | - ((x & 0xff00) >> 8)); + return __constant_htonl(__x); } -#define __constant_ntohs(x) \ - ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \ - (((unsigned short int)(x) & 0xff00) >> 8))) \ - -#define __htonl(x) __ntohl(x) -#define __htons(x) __ntohs(x) -#define __constant_htonl(x) __constant_ntohl(x) -#define __constant_htons(x) __constant_ntohs(x) - -#ifdef __OPTIMIZE__ -# define ntohl(x) \ -(__builtin_constant_p((long)(x)) ? \ - __constant_ntohl((x)) : \ - __ntohl((x))) -# define ntohs(x) \ -(__builtin_constant_p((short)(x)) ? \ - __constant_ntohs((x)) : \ - __ntohs((x))) -# define htonl(x) \ -(__builtin_constant_p((long)(x)) ? \ - __constant_htonl((x)) : \ - __htonl((x))) -# define htons(x) \ -(__builtin_constant_p((short)(x)) ? \ - __constant_htons((x)) : \ - __htons((x))) -#endif +extern __inline__ unsigned short int htons(unsigned short int __x) +{ + return __constant_htons(__x); +} #endif /* __ASM_MIPS_BYTEORDER_H */ diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h new file mode 100644 index 000000000..7add64caa --- /dev/null +++ b/include/asm-mips/cache.h @@ -0,0 +1,67 @@ +/* + * Defines related to MIPS caches. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * (C) Copyright 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_CACHE +#define __ASM_MIPS_CACHE + +/* + * Cache Operations + */ +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 +#define Index_Invalidate_SI 0x02 +#define Index_Writeback_Inv_SD 0x03 +#define Index_Load_Tag_I 0x04 +#define Index_Load_Tag_D 0x05 +#define Index_Load_Tag_SI 0x06 +#define Index_Load_Tag_SD 0x07 +#define Index_Store_Tag_I 0x08 +#define Index_Store_Tag_D 0x09 +#define Index_Store_Tag_SI 0x0A +#define Index_Store_Tag_SD 0x0B +#define Create_Dirty_Excl_D 0x0d +#define Create_Dirty_Excl_SD 0x0f +#define Hit_Invalidate_I 0x10 +#define Hit_Invalidate_D 0x11 +#define Hit_Invalidate_SI 0x12 +#define Hit_Invalidate_SD 0x13 +#define Fill 0x14 +#define Hit_Writeback_Inv_D 0x15 + /* 0x16 is unused */ +#define Hit_Writeback_Inv_SD 0x17 +#define Hit_Writeback_I 0x18 +#define Hit_Writeback_D 0x19 + /* 0x1a is unused */ +#define Hit_Writeback_SD 0x1b + /* 0x1c is unused */ + /* 0x1e is unused */ +#define Hit_Set_Virtual_SI 0x1e +#define Hit_Set_Virtual_SD 0x1f + +/* + * Flags for internal cacheflush call + * FIXME: CF_DMA is not implemented yet. + */ +#define CF_ICACHE (1<<0) /* flush instruction cache */ +#define CF_DCACHE (1<<1) /* writeback and flush data cache */ +#define CF_BCACHE (CF_ICACHE|CF_DCACHE) /* writeback and flush data cache */ +#define CF_VIRTUAL (1<<2) /* operate only on virtual caches */ +#define CF_PHYSICAL (1<<4) /* operate only on physical caches */ +#define CF_ALL (CF_VIRTUAL|CF_PHYSICAL)/* work on all cache types */ +#define CF_DMA (1<<5) /* Do DMA cache maintenance */ + +#ifndef __LANGUAGE_ASSEMBLY__ + +#include <linux/linkage.h> + +extern void (*mips_cache_init)(void); +extern asmlinkage void (*cacheflush)(unsigned long addr, unsigned long nbytes, unsigned int flags); + +#endif /* !__LANGUAGE_ASSEMBLY__ */ +#endif /* __ASM_MIPS_CACHE */ diff --git a/include/asm-mips/cachectl.h b/include/asm-mips/cachectl.h index 68105fb69..214d28918 100644 --- a/include/asm-mips/cachectl.h +++ b/include/asm-mips/cachectl.h @@ -1,37 +1,24 @@ /* - * include/asm-mips/cachectl.h + * cachectl.h -- defines for MIPS cache control system calls * - * Written by Ralf Baechle, - * Copyright (C) 1994 by Waldorf GMBH + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle */ #ifndef __ASM_MIPS_CACHECTL #define __ASM_MIPS_CACHECTL /* - * cachectl.h -- defines for MIPS cache control system calls - */ - -/* * Options for cacheflush system call */ #define ICACHE (1<<0) /* flush instruction cache */ #define DCACHE (1<<1) /* writeback and flush data cache */ #define BCACHE (ICACHE|DCACHE) /* flush both caches */ -#define CACHELINES 512 /* number of cachelines (kludgy) */ - /* - * Cache Operations - for use by assembler code + * Caching modes for the cachectl(2) call + * + * cachctl(2) is currently not supported and returns ENOSYS. */ -#define Index_Invalidate_I 0x00 -#define Index_Writeback_Inv_D 0x01 -#define Index_Load_Tag_D 0x05 - -#ifdef __KERNEL__ -#ifndef __LANGUAGE_ASSEMBLY__ - -extern int sys_cacheflush(void *addr, int nbytes, int cache); +#define CACHEABLE 0 /* make pages cacheable */ +#define UNCACHEABLE 1 /* make pages uncacheable */ -#endif -#endif #endif /* __ASM_MIPS_CACHECTL */ diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h new file mode 100644 index 000000000..08dd07707 --- /dev/null +++ b/include/asm-mips/checksum.h @@ -0,0 +1,251 @@ +/* + * include/asm-mips/checksum.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + */ +#ifndef __ASM_MIPS_CHECKSUM_H +#define __ASM_MIPS_CHECKSUM_H + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from user space (but on MIPS + * we have just one address space, so this is identical to the above) + */ +#define csum_partial_copy_fromuser csum_partial_copy + +/* + * Fold a partial checksum without adding pseudo headers + */ +static inline unsigned short int csum_fold(unsigned int sum) +{ + unsigned int __res; + + __asm__(" + .set noat + srl $1,%0,16 + andi %0,0xffff + addu $1,%0 + srl %0,$1,16 # addup halfword carry + andi $1,0xffff + addu $1,%0 + nor %0,$0,$1 + .set at" + : "=r"(__res) + : "0" (sum) + : "$1"); + + return __res; +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by + * Arnt Gulbrandsen. + */ +static inline unsigned short ip_fast_csum(unsigned char * iph, + unsigned int ihl) +{ + unsigned int sum; + unsigned long dummy; + + /* + * This is for 32-bit MIPS processors. + */ + __asm__ __volatile__(" + .set noreorder + .set noat + lw %0,(%1) + subu %2,4 + #blez %2,2f + sll %2,2 # delay slot + + lw %3,4(%1) + addu %2,%1 # delay slot + addu %0,%3 + sltu $1,%0,%3 + lw %3,8(%1) + addu %0,$1 + addu %0,%3 + sltu $1,%0,%3 + lw %3,12(%1) + addu %0,$1 + addu %0,%3 + sltu $1,%0,%3 + addu %0,$1 + +1: lw %3,16(%1) + addiu %1,4 + addu %0,%3 + sltu $1,%0,%3 + bne %2,%1,1b + addu %0,$1 # delay slot + +2: .set at + .set reorder" + : "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy) + : "1" (iph), "2" (ihl) + : "$1"); + + return csum_fold(sum); +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum) +{ + __asm__(" + .set noat + addu %0,%2 + sltu $1,%0,%2 + addu %0,$1 + addu %0,%3 + sltu $1,%0,%3 + addu %0,$1 + addu %0,%4 + sltu $1,%0,%4 + addu %0,$1 + + srl $1,%0,16 + andi %0,0xffff + addu %0,$1 + srl $1,%0,16 # addup halfword carry + andi %0,0xffff + addu %0,$1 + nor %0,$0,%0 + .set at" + : "=r" (sum) + : "0" (daddr), "r"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum) + : "$1"); + + return (unsigned short)sum; +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +static inline unsigned short ip_compute_csum(unsigned char * buff, int len) +{ + unsigned short int sum; + + __asm__(" + .set noat + srl $1,%0,16 + andi %0,0xffff + addu %0,$1 + sltu $1,%0,$1 + addu %0,$1 + nor %0,$0,%0 + .set at" + : "=r"(sum) + : "0" (csum_partial(buff, len, 0)) + : "$1"); + + return sum; +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int sum) +{ + __asm__(" + .set noreorder + .set noat + addu %0,%5 # proto (long in network byte order) + sltu $1,%0,%5 + addu %0,$1 + + addu %0,%6 # csum + sltu $1,%0,%6 + lw %1,0(%2) # four words source address + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,4(%2) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,8(%2) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,12(%2) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,0(%3) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,4(%3) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,8(%3) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,12(%3) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + .set noat + .set noreorder + " + : "=r" (sum), + "=r" (proto) + : "r" (saddr), + "r" (daddr), + "0" (htonl((__u32) (len))), + "1" (htonl(proto)), + "r"(sum) + : "$1"); + + return csum_fold(sum); +} + +#endif /* __ASM_MIPS_CHECKSUM_H */ diff --git a/include/asm-mips/dec/decstation.h b/include/asm-mips/dec/decstation.h new file mode 100644 index 000000000..cae4302d2 --- /dev/null +++ b/include/asm-mips/dec/decstation.h @@ -0,0 +1,54 @@ +/* + * General info common to all DECstation systems + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions + * are by curteousy of Chris Fraser. + * + * This file is under construction - you were warned! + */ + +#ifndef __ASM_DEC_DECSTATION_H +#define __ASM_DEC_DECSTATION_H + +/* + * REX functions -- these are for the new TURBOchannel style ROMs + */ +#define REX_PROM_MAGIC 0x30464354 /* passed in a2 */ + +#define REX_GETBITMAP 0x84 /* get mem bitmap */ +#define REX_GETCHAR 0x24 /* getch() */ +#define REX_PUTCHAR 0x13 /* putch() */ +#define REX_HALT 0x9c /* halt the system */ +#define REX_PRINTF 0x30 /* printf() */ +#define REX_PUTS 0x2c /* puts() */ +#define REX_SLOTADDR 0x6c /* slotaddr */ +#define REX_GETENV 0x64 /* get env. variable */ +#define REX_GETSYSID 0x80 /* get system id */ +#define REX_OPEN 0x54 /* open() */ +#define REX_READ 0x58 /* read() */ + + + +#ifndef __LANGUAGE_ASSEMBLY__ + +/* + * A structure to allow calling of the various DEC boot prom routines. + * FIXME: Don't know how well different DECStation boot prom revisions + * are accomodated. + */ +struct dec_prom { + void (*dec_prom_printf)(char *format, ...); + char *(*dec_prom_getenv)(char *name); + unsigned long (*dec_prom_getbitmap)(void); + unsigned long (*dec_prom_getsysid)(void); + char *(*dec_prom_gets)(char *s); + void (*dec_prom_halt)(const unsigned int); +}; + +#endif + +#endif /* __ASM_DEC_DECSTATION_H */ diff --git a/include/asm-mips/dec/kn02.h b/include/asm-mips/dec/kn02.h new file mode 100644 index 000000000..61df7b512 --- /dev/null +++ b/include/asm-mips/dec/kn02.h @@ -0,0 +1,52 @@ +/* + * Hardware info about DEC DECstation 5000/2xx systems (otherwise known + * as 3max or kn02. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions + * are by curteousy of Chris Fraser. + * + * This file is under construction - you were warned! + */ +#include <asm/segment.h> +#ifndef __ASM_MIPS_PMAX_H +#define __ASM_MIPS_PMAX_H + +/* + * The addresses below are virtual address. The mappings are + * created on startup via wired entries in the tlb. + */ + +#define PMAX_LOCAL_IO_SPACE 0xe0000000 + +/* + * Motherboard regs (kseg1 addresses) + */ +#define PMAX_SSR_ADDR KSEG1ADDR(0x1ff00000) /* system control & status reg */ + +/* + * SSR defines + */ +#define PMAX_SSR_LEDMASK 0x0000001000 /* diagnostic LED */ + +#ifndef __LANGUAGE_ASSEMBLY__ + +extern __inline__ void pmax_set_led(unsigned int bits) +{ + volatile unsigned int *led_register = (unsigned int *) PMAX_SSR_ADDR; + + *led_register = bits & PMAX_SSR_LEDMASK; +} + +#endif + +/* + * Some port addresses... + * FIXME: these addresses are incomplete and need tidying up! + */ +#define PMAX_RTC_BASE (KSEG1ADDR(0x1fe80000 + 0x200000)) /* ASIC + SL8 */ + +#endif /* __ASM_MIPS_PMAX_H */ diff --git a/include/asm-mips/dec/maxine.h b/include/asm-mips/dec/maxine.h new file mode 100644 index 000000000..3f908d5fb --- /dev/null +++ b/include/asm-mips/dec/maxine.h @@ -0,0 +1,52 @@ +/* + * Hardware info about DEC Personal DECStation systems (otherwise known + * as maxine (internal DEC codename). + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions + * are by curteousy of Chris Fraser. + * + * This file is under construction - you were warned! + */ + +#ifndef __ASM_DEC_MAXINE_H +#define __ASM_DEC_MAXINE_H + +/* + * The addresses below are virtual address. The mappings are + * created on startup via wired entries in the tlb. + */ + +#define PMAX_LOCAL_IO_SPACE 0xe0000000 + +/* + * Motherboard regs (kseg1 addresses) + */ +#define PMAX_SSR_ADDR KSEG1ADDR(0x1c040100) /* system support reg */ + +/* + * SSR defines + */ +#define PMAX_SSR_LEDMASK 0x00000001 /* power LED */ + +#ifndef __LANGUAGE_ASSEMBLY__ + +extern __inline__ void pmax_set_led(unsigned int bits) +{ + volatile unsigned int *led_register = (unsigned int *) PMAX_SSR_ADDR; + + *led_register = bits & PMAX_SSR_LEDMASK; +} + +#endif + +/* + * Some port addresses... + * FIXME: these addresses are incomplete and need tidying up! + */ +#define PMAX_RTC_BASE (KSEG1ADDR(0x1c000000 + 0x200000)) /* ASIC + SL8 */ + +#endif /* __ASM_DEC_MAXINE_H */ diff --git a/include/asm-mips/decstation.h b/include/asm-mips/decstation.h new file mode 100644 index 000000000..ac04ff097 --- /dev/null +++ b/include/asm-mips/decstation.h @@ -0,0 +1,254 @@ +/* + * Hardware info about DEC Personal DECStation systems (otherwise known + * as maxine or pmax (internal DEC codenames). + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Paul M. Antoine, some code and definitions are + * by curteousy of Chris Fraser. + * + * This file is under construction - you were warned! + */ + +#ifndef __ASM_MIPS_PMAX_H +#define __ASM_MIPS_PMAX_H + +/* + * The addresses below are virtual address. The mappings are + * created on startup via wired entries in the tlb. + */ + +#define PMAX_LOCAL_IO_SPACE 0xe0000000 + +/* + * Motherboard regs (kseg1 addresses) + */ +#define PMAX_SSR_ADDR 0xbc040100 /* system support reg */ + +/* + * SSR defines + */ +#define PMAX_SSR_LEDMASK 0x00000001 /* power LED */ + +/* + * REX functions -- these are for the new TURBOchannel style ROMs + */ +#define REX_PROM_MAGIC 0x30464354 /* passed in a2 */ + +#define REX_GETBITMAP 0x84 /* get mem bitmap */ +#define REX_GETCHAR 0x24 /* getch() */ +#define REX_PUTCHAR 0x13 /* putch() */ +#define REX_HALT 0x9c /* halt the system */ +#define REX_PRINTF 0x30 /* printf() */ +#define REX_PUTS 0x2c /* puts() */ +#define REX_SLOTADDR 0x6c /* slotaddr */ + +#ifndef __LANGUAGE_ASSEMBLY__ + +extern __inline__ void pmax_set_led(unsigned int bits) +{ + volatile unsigned int *led_register = (unsigned int *) PMAX_SSR_ADDR; + + *led_register = bits & PMAX_SSR_LEDMASK; +} + +/* + * Glue code to call the PMAX boot proms. + */ +extern asmlinkage void pmax_printf(const char *); + +#endif + +/* + * These are just hacked out of the JAZZ ones, no ideas really. + */ +#define PMAX_KEYBOARD_ADDRESS 0xe0005000 +#define PMAX_KEYBOARD_DATA 0xe0005000 +#define PMAX_KEYBOARD_COMMAND 0xe0005001 + +#ifndef __LANGUAGE_ASSEMBLY__ + +typedef struct { + unsigned char data; + unsigned char command; +} pmax_keyboard_hardware; + +typedef struct { + unsigned char pad0[3]; + unsigned char data; + unsigned char pad1[3]; + unsigned char command; +} mips_keyboard_hardware; + +/* + * For now. + */ +#define keyboard_hardware pmax_keyboard_hardware + +#endif + +/* + * Serial ports on DEC - maybe! + */ + +#define PMAX_SERIAL1_BASE (unsigned int)0xe0006000 +#define PMAX_SERIAL2_BASE (unsigned int)0xe0007000 + +/* + * Dummy Device Address. Used in pmaxdma.c + */ + +#define PMAX_DUMMY_DEVICE 0xe000d000 + +/* + * PMAX timer registers and interrupt no. + * Note that the hardware timer interrupt is actually on + * cpu level 6, but to keep compatibility with PC stuff + * it is remapped to vector 0. See arch/mips/kernel/entry.S. + */ +#define PMAX_TIMER_INTERVAL 0xe0000228 +#define PMAX_TIMER_REGISTER 0xe0000230 + +/* + * DRAM configuration register + */ +#ifndef __LANGUAGE_ASSEMBLY__ +#ifdef __MIPSEL__ +typedef struct { + unsigned int bank2 : 3; + unsigned int bank1 : 3; + unsigned int mem_bus_width : 1; + unsigned int reserved2 : 1; + unsigned int page_mode : 1; + unsigned int reserved1 : 23; +} dram_configuration; +#else /* defined (__MIPSEB__) */ +typedef struct { + unsigned int reserved1 : 23; + unsigned int page_mode : 1; + unsigned int reserved2 : 1; + unsigned int mem_bus_width : 1; + unsigned int bank1 : 3; + unsigned int bank2 : 3; +} dram_configuration; +#endif +#endif /* __LANGUAGE_ASSEMBLY__ */ + +#define PMAX_DRAM_CONFIG 0xe00fffe0 + +/* + * PMAX interrupt control registers + */ +#define PMAX_IO_IRQ_SOURCE 0xe0100000 +#define PMAX_IO_IRQ_ENABLE 0xe0100002 + +/* + * PMAX interrupt enable bits + */ +#define PMAX_IE_PARALLEL (1 << 0) +#define PMAX_IE_FLOPPY (1 << 1) +#define PMAX_IE_SOUND (1 << 2) +#define PMAX_IE_VIDEO (1 << 3) +#define PMAX_IE_ETHERNET (1 << 4) +#define PMAX_IE_SCSI (1 << 5) +#define PMAX_IE_KEYBOARD (1 << 6) +#define PMAX_IE_MOUSE (1 << 7) +#define PMAX_IE_SERIAL1 (1 << 8) +#define PMAX_IE_SERIAL2 (1 << 9) + +/* + * PMAX Interrupt Level definitions + */ + +#define PMAX_TIMER_IRQ 0 +#define PMAX_KEYBOARD_IRQ 1 +#define PMAX_ETHERNET_IRQ 2 /* 15 */ +#define PMAX_SERIAL1_IRQ 3 +#define PMAX_SERIAL2_IRQ 4 +#define PMAX_PARALLEL_IRQ 5 +#define PMAX_FLOPPY_IRQ 6 /* needs to be consistent with floppy driver! */ + +/* + * PMAX DMA Channels + * Note: Channels 4...7 are not used with respect to the Acer PICA-61 + * chipset which does not provide these DMA channels. + */ + +#define PMAX_SCSI_DMA 0 /* SCSI */ +#define PMAX_FLOPPY_DMA 1 /* FLOPPY */ +#define PMAX_AUDIOL_DMA 2 /* AUDIO L */ +#define PMAX_AUDIOR_DMA 3 /* AUDIO R */ + +/* + * PMAX R4030 MCT_ADR chip (DMA controller) + * Note: Virtual Addresses ! + */ + +#define PMAX_R4030_CONFIG 0xE0000000 /* R4030 config register */ +#define PMAX_R4030_REVISION 0xE0000008 /* same as PICA_ASIC_REVISION */ +#define PMAX_R4030_INV_ADDR 0xE0000010 /* Invalid Address register */ + +#define PMAX_R4030_TRSTBL_BASE 0xE0000018 /* Translation Table Base */ +#define PMAX_R4030_TRSTBL_LIM 0xE0000020 /* Translation Table Limit */ +#define PMAX_R4030_TRSTBL_INV 0xE0000028 /* Translation Table Invalidate */ + +#define PMAX_R4030_CACHE_MTNC 0xE0000030 /* Cache Maintenance */ +#define PMAX_R4030_R_FAIL_ADDR 0xE0000038 /* Remote Failed Address */ +#define PMAX_R4030_M_FAIL_ADDR 0xE0000040 /* Memory Failed Adresss */ + +#define PMAX_R4030_CACHE_PTAG 0xE0000048 /* I/O Cache Physical Tag */ +#define PMAX_R4030_CACHE_LTAG 0xE0000050 /* I/O Cache Logical Tag */ +#define PMAX_R4030_CACHE_BMASK 0xE0000058 /* I/O Cache Byte Mask */ +#define PMAX_R4030_CACHE_BWIN 0xE0000060 /* I/O Cache Buffer Window */ + +/* + * Remote Speed Registers. + * + * 0: free, 1: Ethernet, 2: SCSI, 3: Floppy, + * 4: RTC, 5: Kb./Mouse 6: serial 1, 7: serial 2, + * 8: parallel, 9: NVRAM, 10: CPU, 11: PROM, + * 12: reserved, 13: free, 14: 7seg LED, 15: ??? + */ + +#define PMAX_R4030_REM_SPEED 0xE0000070 /* 16 Remote Speed Registers */ + /* 0xE0000070,78,80... 0xE00000E8 */ +#define PMAX_R4030_IRQ_ENABLE 0xE00000E8 /* Internal Interrupt Enable */ + +#define PMAX_R4030_IRQ_SOURCE 0xE0000200 /* Interrupt Source Reg */ +#define PMAX_R4030_I386_ERROR 0xE0000208 /* i386/EISA Bus Error */ + + +/* + * Access the R4030 DMA and I/O Controller + */ + +#ifndef __LANGUAGE_ASSEMBLY__ + +extern inline unsigned short r4030_read_reg16(unsigned addr) { + unsigned short ret = *((volatile unsigned short *)addr); + __asm__ __volatile__("nop; nop; nop; nop;"); + return ret; +} + +extern inline unsigned int r4030_read_reg32(unsigned addr) { + unsigned int ret = *((volatile unsigned int *)addr); + __asm__ __volatile__("nop; nop; nop; nop;"); + return ret; +} + +extern inline void r4030_write_reg16(unsigned addr, unsigned val) { + *((volatile unsigned short *)addr) = val; + __asm__ __volatile__("nop; nop; nop; nop;"); +} + +extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val) { + *((volatile unsigned int *)addr) = val; + __asm__ __volatile__("nop; nop; nop; nop;"); +} + +#endif /* !LANGUAGE_ASSEMBLY__ */ + + +#endif /* __ASM_MIPS_PMAX_H */ diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h index b35498dc1..d7d6e269d 100644 --- a/include/asm-mips/delay.h +++ b/include/asm-mips/delay.h @@ -4,11 +4,9 @@ extern __inline__ void __delay(int loops) { __asm__ __volatile__ ( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "1:\tbne\t$0,%0,1b\n\t" - "subu\t%0,%0,1\n\t" - ".set\tat\n\t" + ".set\tnoreorder\n" + "1:\tbnez\t%0,1b\n\t" + "subu\t%0,1\n\t" ".set\treorder" :"=r" (loops) :"0" (loops)); @@ -36,7 +34,7 @@ extern __inline__ void udelay(unsigned long usecs) /* * The different variants for 32/64 bit are pure paranoia. The typical - * range of numbers that apprears for MIPS machines avoids overflows. + * range of numbers that appears for MIPS machines avoids overflows. */ extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) { diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h index 14f1f0dae..c3fd31d58 100644 --- a/include/asm-mips/dma.h +++ b/include/asm-mips/dma.h @@ -5,7 +5,7 @@ * and John Boyd, Nov. 1992. * * NOTE: all this is true *only* for ISA/EISA expansions on Mips boards - * and can only be used for expansion cards. Onboard DMA controller, such + * and can only be used for expansion cards. Onboard DMA controllers, such * as the R4030 on Jazz boards behave totally different! */ @@ -73,11 +73,13 @@ #define MAX_DMA_CHANNELS 8 -/* The maximum address that we can perform a DMA transfer to on this platform */ -#define MAX_DMA_ADDRESS 0x1000000 - -/* The maximum address that we can perform a DMA transfer to on this platform */ -#define MAX_DMA_ADDRESS 0x1000000 +/* + * The maximum address in KSEG0 that we can perform a DMA transfer to on this + * platform. This describes only the PC style part of the DMA logic like on + * Deskstations or Acer PICA but not the much more versatile DMA logic used + * for the local devices on Acer PICA or Magnums. + */ +#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ @@ -271,8 +273,7 @@ static __inline__ int get_dma_residue(unsigned int dmanr) /* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, char * device_id); /* reserve a DMA channel */ +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ - #endif /* __ASM_MIPS_DMA_H */ diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h new file mode 100644 index 000000000..527352711 --- /dev/null +++ b/include/asm-mips/elf.h @@ -0,0 +1,47 @@ +#ifndef __ASM_MIPS_ELF_H +#define __ASM_MIPS_ELF_H + +/* + * ELF register definitions + * This is "make it compile" stuff! + */ +#define ELF_NGREG 32 +#define ELF_NFPREG 32 + +typedef unsigned long elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + * Using EM_MIPS is actually wrong - this one is reserved for big endian + * machines only but there is no EM_ constant for little endian ... + */ +#define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_MIPS_RS4_BE) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#ifdef __MIPSEB__ +#define ELF_DATA ELFDATA2MSB; +#elif __MIPSEL__ +#define ELF_DATA ELFDATA2LSB; +#endif +#define ELF_ARCH EM_MIPS + + /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program + starts %edx contains a pointer to a function which might be + registered using `atexit'. This provides a mean for the + dynamic linker to call DT_FINI functions for shared libraries + that have been loaded before the code runs. + + A value of 0 tells we have no such handler. */ +#define ELF_PLAT_INIT(_r) _r->regs[2] = 0 + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +#endif /* __ASM_MIPS_ELF_H */ diff --git a/include/asm-mips/errno.h b/include/asm-mips/errno.h index f31e2b19f..dc4072a94 100644 --- a/include/asm-mips/errno.h +++ b/include/asm-mips/errno.h @@ -65,7 +65,14 @@ #define ENOANO 53 /* No anode */ #define EBADRQC 54 /* Invalid request code */ #define EBADSLT 55 /* Invalid slot */ +#if 0 #define EDEADLOCK 56 /* File locking deadlock error */ +#else +/* + * This needs to be fixed - DEADLOCK should be 45. + */ +#define EDEADLOCK EDEADLK /* File locking deadlock error */ +#endif #define EBFONT 59 /* Bad font file format */ #define ENOSTR 60 /* Device not a stream */ #define ENODATA 61 /* No data available */ @@ -137,6 +144,16 @@ #define EINPROGRESS 150 /* Operation now in progress */ #define ESTALE 151 /* Stale NFS file handle */ #define ECANCELED 158 /* AIO operation canceled */ + +/* + * IRIX 5 error number start from 1000. + * Stupid enough; ECANCELED gets redefined with a different value ... +#define ECANCELED 1000 + */ + +/* + * IRIX 4 compatibility error numbers. + */ #define EDQUOT 1133 /* Quota exceeded */ #define ENFSREMOTE 1134 /* ??? */ diff --git a/include/asm-mips/fcntl.h b/include/asm-mips/fcntl.h index 2a41e3da9..3606b252a 100644 --- a/include/asm-mips/fcntl.h +++ b/include/asm-mips/fcntl.h @@ -1,5 +1,5 @@ -#ifndef _I386_FCNTL_H -#define _I386_FCNTL_H +#ifndef __ASM_MIPS_FCNTL_H +#define __ASM_MIPS_FCNTL_H /* open/fcntl - O_SYNC is only implemented on blocks devices and on files located on an ext2 file system */ @@ -49,19 +49,14 @@ blocking */ #define LOCK_UN 8 /* remove lock */ -#ifdef __KERNEL__ -#define F_POSIX 1 -#define F_FLOCK 2 -#endif /* __KERNEL__ */ - typedef struct flock { short l_type; short l_whence; - off_t l_start; - off_t l_len; + __kernel_off_t l_start; + __kernel_off_t l_len; long l_sysid; /* XXXXXXXXXXXXXXXXXXXXXXXXX */ - pid_t l_pid; + __kernel_pid_t l_pid; long pad[4]; /* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */ } flock_t; -#endif +#endif /* __ASM_MIPS_FCNTL_H */ diff --git a/include/asm-mips/floppy.h b/include/asm-mips/floppy.h new file mode 100644 index 000000000..f639f5aed --- /dev/null +++ b/include/asm-mips/floppy.h @@ -0,0 +1,113 @@ +/* + * Architecture specific parts of the Floppy driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 + */ +#ifndef __ASM_MIPS_FLOPPY_H +#define __ASM_MIPS_FLOPPY_H + +#include <linux/config.h> +#include <asm/bootinfo.h> +#include <asm/jazz.h> +#include <asm/jazzdma.h> +#include <asm/mipsconfig.h> +#include <asm/vector.h> + +#define fd_inb(port) feature->fd_inb(port) +#define fd_outb(value,port) feature->fd_outb(value,port) + +#define fd_enable_dma() feature->fd_enable_dma() +#define fd_disable_dma() feature->fd_disable_dma() +#define fd_request_dma() feature->fd_request_dma() +#define fd_free_dma() feature->fd_free_dma() +#define fd_clear_dma_ff() feature->fd_clear_dma_ff() +#define fd_set_dma_mode(mode) feature->fd_set_dma_mode(mode) +#define fd_set_dma_addr(addr) feature->fd_set_dma_addr(virt_to_bus(addr)) +#define fd_set_dma_count(count) feature->fd_set_dma_count(count) +#define fd_get_dma_residue() feature->fd_get_dma_residue() +#define fd_enable_irq() feature->fd_enable_irq() +#define fd_disable_irq() feature->fd_disable_irq() +#define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \ + SA_INTERRUPT|SA_SAMPLE_RANDOM, \ + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL); + +#define MAX_BUFFER_SECTORS 24 + +/* Pure 2^n version of get_order */ +extern __inline__ int __get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +extern __inline__ unsigned long mips_dma_mem_alloc(unsigned long size) +{ + int order = __get_order(size); + unsigned long mem; + + mem = __get_dma_pages(GFP_KERNEL,order); + if(!mem) + return 0; +#ifdef CONFIG_MIPS_JAZZ + if (mips_machgroup == MACH_GROUP_JAZZ) + vdma_alloc(PHYSADDR(mem), size); +#endif + return mem; +} + +extern __inline__ void mips_dma_mem_free(unsigned long addr, unsigned long size) +{ +#ifdef CONFIG_MIPS_JAZZ + if (mips_machgroup == MACH_GROUP_JAZZ) + vdma_free(PHYSADDR(addr)); +#endif + free_pages(addr, __get_order(size)); +} + +#define fd_dma_mem_alloc(size) mips_dma_mem_alloc(size) +#define fd_dma_mem_free(mem,size) mips_dma_mem_free(mem,size) + +/* + * And on Mips's the CMOS info fails also ... + * + * FIXME: This information should come from the ARC configuration tree + * or whereever a particular machine has stored this ... + */ +#define FLOPPY0_TYPE 4 /* this is wrong for the Olli M700, but who cares... */ +#define FLOPPY1_TYPE 0 + +#define FDC1 ((mips_machgroup == MACH_GROUP_JAZZ) ? \ + JAZZ_FDC_BASE : 0x3f0) +static int FDC2=-1; + +#define N_FDC 1 /* do you *really* want a second controller? */ +#define N_DRIVE 8 + +/* + * The DMA channel used by the floppy controller cannot access data at + * addresses >= 16MB + * + * Went back to the 1MB limit, as some people had problems with the floppy + * driver otherwise. It doesn't matter much for performance anyway, as most + * floppy accesses go through the track buffer. + * + * On MIPSes using vdma, this actually means that *all* transfers go thru + * the * track buffer since 0x1000000 is always smaller than KSEG0/1. + * Actually this needs to be a bit more complicated since the so much different + * hardware available with MIPS CPUs ... + */ +#define CROSS_64KB(a,s) ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64) + +#endif /* __ASM_MIPS_FLOPPY_H */ diff --git a/include/asm-mips/fpregdef.h b/include/asm-mips/fpregdef.h new file mode 100644 index 000000000..b942b1831 --- /dev/null +++ b/include/asm-mips/fpregdef.h @@ -0,0 +1,52 @@ +/* + * Definitions for the FPU register names + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + */ +#ifndef __ASM_MIPS_FPREGDEF_H +#define __ASM_MIPS_FPREGDEF_H + +/* + * These definitions only cover the R3000-ish 16/32 register model. + * But we're trying to be R3000 friendly anyway ... + */ +#define fv0 $f0 /* return value */ +#define fv0f $f1 +#define fv1 $f2 +#define fv1f $f3 +#define fa0 $f12 /* argument registers */ +#define fa0f $f13 +#define fa1 $f14 +#define fa1f $f15 +#define ft0 $f4 /* caller saved */ +#define ft0f $f5 +#define ft1 $f6 +#define ft1f $f7 +#define ft2 $f8 +#define ft2f $f9 +#define ft3 $f10 +#define ft3f $f11 +#define ft4 $f16 +#define ft4f $f17 +#define ft5 $f18 +#define ft5f $f19 +#define fs0 $f20 /* callee saved */ +#define fs0f $f21 +#define fs1 $f22 +#define fs1f $f23 +#define fs2 $f24 +#define fs2f $f25 +#define fs3 $f26 +#define fs3f $f27 +#define fs4 $f28 +#define fs4f $f29 +#define fs5 $f30 +#define fs5f $f31 + +#define fcr31 $31 /* FPU status register */ + +#endif /* !defined (__ASM_MIPS_FPREGDEF_H) */ diff --git a/include/asm-mips/ide.h b/include/asm-mips/ide.h new file mode 100644 index 000000000..e6f925e64 --- /dev/null +++ b/include/asm-mips/ide.h @@ -0,0 +1,119 @@ +/* + * linux/include/asm-mips/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* + * This file contains the MIPS architecture specific IDE code. + */ + +#ifndef __ASM_MIPS_IDE_H +#define __ASM_MIPS_IDE_H + +#ifdef __KERNEL__ + +typedef unsigned short ide_ioreg_t; + +#ifndef MAX_HWIFS +#define MAX_HWIFS 4 +#endif + +#define ide_sti() sti() + +static __inline__ int ide_default_irq(ide_ioreg_t base) +{ + switch (base) { + case 0x1f0: return 14; + case 0x170: return 15; + case 0x1e8: return 11; + case 0x168: return 10; + default: + return 0; + } +} + +static __inline__ ide_ioreg_t ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + case 2: return 0x1e8; + case 3: return 0x168; + default: + return 0; + } +} + +static __inline__ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) +{ + ide_ioreg_t port = base; + int i = 8; + + while (i--) + *p++ = port++; + *p++ = base + 0x206; + if (irq != NULL) + *irq = 0; +} + +typedef union { + unsigned all : 8; /* all of the bits together */ + struct { + unsigned head : 4; /* always zeros here */ + unsigned unit : 1; /* drive select number, 0 or 1 */ + unsigned bit5 : 1; /* always 1 */ + unsigned lba : 1; /* using LBA instead of CHS */ + unsigned bit7 : 1; /* always 1 */ + } b; + } select_t; + +static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *device, void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name) +{ + request_region(from, extent, name); +} + +static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +/* + * The following are not needed for the non-m68k ports + */ +static __inline__ int ide_ack_intr (ide_ioreg_t base_port, ide_ioreg_t irq_port) +{ + return(1); +} + +static __inline__ void ide_fix_driveid(struct hd_driveid *id) +{ +} + +static __inline__ void ide_release_lock (int *ide_lock) +{ +} + +static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data) +{ +} + +#endif /* __KERNEL__ */ + +#endif /* __ASM_MIPS_IDE_H */ diff --git a/include/asm-mips/inst.h b/include/asm-mips/inst.h new file mode 100644 index 000000000..c4e291aeb --- /dev/null +++ b/include/asm-mips/inst.h @@ -0,0 +1,304 @@ +/* + * Format of an instruction in memory. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_INST_H +#define __ASM_MIPS_INST_H + +/* + * Major opcodes; before MIPS IV cop1x was called cop3. + */ +enum major_op { + spec_op, bcond_op, j_op, jal_op, + beq_op, bne_op, blez_op, bgtz_op, + addi_op, addiu_op, slti_op, sltiu_op, + andi_op, ori_op, xori_op, lui_op, + cop0_op, cop1_op, cop2_op, cop1x_op, + beql_op, bnel_op, blezl_op, bgtzl_op, + daddi_op, daddiu_op, ldl_op, ldr_op, + major_1c_op, major_1d_op, major_1e_op, major_1f_op, + lb_op, lh_op, lwl_op, lw_op, + lbu_op, lhu_op, lwr_op, lwu_op, + sb_op, sh_op, swl_op, sw_op, + sdl_op, sdr_op, swr_op, cache_op, + ll_op, lwc1_op, lwc2_op, pref_op, + lld_op, ldc1_op, ldc2_op, ld_op, + sc_op, swc1_op, swc2_op, major_3b_op, /* Opcode 0x3b is unused */ + scd_op, sdc1_op, sdc2_op, sd_op, +}; + +/* + * func field of spec opcode. + */ +enum spec_op { + sll_op, movc_op, srl_op, sra_op, + sllv_op, srlv_op, srav_op, spec1_unused_op, /* Opcode 0x07 is unused */ + jr_op, jalr_op, movz_op, movn_op, + syscall_op, break_op, spim_op, sync_op, + mfhi_op, mthi_op, mflo_op, mtlo_op, + dsllv_op, spec2_unused_op, dsrlv_op, dsrav_op, + mult_op, multu_op, div_op, divu_op, + dmult_op, dmultu_op, ddiv_op, ddivu_op, + add_op, addu_op, sub_op, subu_op, + and_op, or_op, xor_op, nor_op, + spec3_unused_op, spec4_unused_op, slt_op, sltu_op, + dadd_op, daddu_op, dsub_op, dsubu_op, + tge_op, tgeu_op, tlt_op, tltu_op, + teq_op, spec5_unused_op, tne_op, spec6_unused_op, + dsll_op, spec7_unused_op, dsrl_op, dsra_op, + dsll32_op, spec8_unused_op, dsrl32_op, dsra32_op, +}; + +/* + * rt field of bcond opcodes. + */ +enum rt_op { + bltz_op, bgez_op, bltzl_op, bgezl_op, + spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07, + tgei_op, tgeiu_op, tlti_op, tltiu_op, + teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op, + bltzal_op, bgezal_op, bltzall_op, bgezall_op + /* + * The others (0x14 - 0x1f) are unused. + */ +}; + +/* + * rs field of cop opcodes. + */ +enum cop_op { + mfc_op = 0x00, dmfc_op = 0x01, + cfc_op = 0x02, mtc_op = 0x04, + dmtc_op = 0x05, ctc_op = 0x06, + bc_op = 0x08, cop_op = 0x10, + copm_op = 0x18, +}; + +/* + * func field of cop0 coi opcodes. + */ +enum cop0_coi_func { + tlbr_op = 0x01, tlbwi_op = 0x02, + tlbwr_op = 0x06, tlbp_op = 0x08, + rfe_op = 0x10, eret_op = 0x18 +}; + +/* + * func field of cop0 com opcodes. + */ +enum cop0_com_func { + tlbr1_op = 0x01, tlbw_op = 0x02, + tlbp1_op = 0x08, dctr_op = 0x09, + dctw_op = 0x0a +}; + +/* + * fmt field of cop1 opcodes. + */ +enum cop1_fmt { + s_fmt, d_fmt, e_fmt, q_fmt, + w_fmt, l_fmt +}; + +/* + * func field of cop1 instructions using d, s or w format. + */ +enum cop1_sdw_func { + fadd_op = 0x00, fsub_op = 0x01, + fmul_op = 0x02, fdiv_op = 0x03, + fsqrt_op = 0x04, fabs_op = 0x05, + fmov_op = 0x06, fneg_op = 0x07, + froundl_op = 0x08, ftruncl_op = 0x09, + fceill_op = 0x0a, ffloorl_op = 0x0b, + fround_op = 0x0c, ftrunc_op = 0x0d, + fceil_op = 0x0e, ffloor_op = 0x0f, + fmovc_op = 0x11, fmovz_op = 0x12, + fmovn_op = 0x13, frecip_op = 0x15, + frsqrt_op = 0x16, fcvts_op = 0x20, + fcvtd_op = 0x21, fcvte_op = 0x22, + fcvtw_op = 0x24, fcvtl_op = 0x25, + fcmp_op = 0x30 +}; + +/* + * func field of cop1x opcodes (MIPS IV). + */ +enum cop1x_func { + lwxc1_op = 0x00, ldxc1_op = 0x01, + pfetch_op = 0x07, swxc1_op = 0x08, + sdxc1_op = 0x09, madd_s_op = 0x20, + madd_d_op = 0x21, madd_e_op = 0x22, + msub_s_op = 0x28, msub_d_op = 0x29, + msub_e_op = 0x2a, nmadd_s_op = 0x30, + nmadd_d_op = 0x31, nmadd_e_op = 0x32, + nmsub_s_op = 0x38, nmsub_d_op = 0x39, + nmsub_e_op = 0x3a +}; + +/* + * func field for mad opcodes (MIPS IV). + */ +enum mad_func { + madd_op = 0x08, msub_op = 0x0a, + nmadd_op = 0x0c, nmsub_op = 0x0e +}; + +/* + * Damn ... bitfields depend from byteorder :-( + */ +#ifdef __MIPSEB__ +struct j_format { /* Jump format */ + unsigned int opcode : 6; + unsigned int target : 26; +}; + +struct i_format { /* Immediate format (addi, lw, ...) */ + unsigned int opcode : 6; + unsigned int rs : 5; + unsigned int rt : 5; + signed int simmediate : 16; +}; + +struct u_format { /* Unsigned immediate format (ori, xori, ...) */ + unsigned int opcode : 6; + unsigned int rs : 5; + unsigned int rt : 5; + unsigned int uimmediate : 16; +}; + +struct c_format { /* Cache (>= R6000) format */ + unsigned int opcode : 6; + unsigned int rs : 5; + unsigned int c_op : 3; + unsigned int cache : 2; + unsigned int simmediate : 16; +}; + +struct r_format { /* Register format */ + unsigned int opcode : 6; + unsigned int rs : 5; + unsigned int rt : 5; + unsigned int rd : 5; + unsigned int re : 5; + unsigned int func : 6; +}; + +struct p_format { /* Performance counter format (R10000) */ + unsigned int opcode : 6; + unsigned int rs : 5; + unsigned int rt : 5; + unsigned int rd : 5; + unsigned int re : 5; + unsigned int func : 6; +}; + +struct f_format { /* FPU register format */ + unsigned int opcode : 6; + unsigned int : 1; + unsigned int fmt : 4; + unsigned int rt : 5; + unsigned int rd : 5; + unsigned int re : 5; + unsigned int func : 6; +}; + +struct ma_format { /* FPU multipy and add format (MIPS IV) */ + unsigned int opcode : 6; + unsigned int fr : 5; + unsigned int ft : 5; + unsigned int fs : 5; + unsigned int fd : 5; + unsigned int func : 4; + unsigned int fmt : 2; +}; + +#elif defined(__MIPSEL__) + +struct j_format { /* Jump format */ + unsigned int target : 26; + unsigned int opcode : 6; +}; + +struct i_format { /* Immediate format */ + signed int simmediate : 16; + unsigned int rt : 5; + unsigned int rs : 5; + unsigned int opcode : 6; +}; + +struct u_format { /* Unsigned immediate format */ + unsigned int uimmediate : 16; + unsigned int rt : 5; + unsigned int rs : 5; + unsigned int opcode : 6; +}; + +struct c_format { /* Cache (>= R6000) format */ + unsigned int simmediate : 16; + unsigned int cache : 2; + unsigned int c_op : 3; + unsigned int rs : 5; + unsigned int opcode : 6; +}; + +struct r_format { /* Register format */ + unsigned int func : 6; + unsigned int re : 5; + unsigned int rd : 5; + unsigned int rt : 5; + unsigned int rs : 5; + unsigned int opcode : 6; +}; + +struct p_format { /* Performance counter format (R10000) */ + unsigned int func : 6; + unsigned int re : 5; + unsigned int rd : 5; + unsigned int rt : 5; + unsigned int rs : 5; + unsigned int opcode : 6; +}; + +struct f_format { /* FPU register format */ + unsigned int func : 6; + unsigned int re : 5; + unsigned int rd : 5; + unsigned int rt : 5; + unsigned int fmt : 4; + unsigned int : 1; + unsigned int opcode : 6; +}; + +struct ma_format { /* FPU multipy and add format (MIPS IV) */ + unsigned int fmt : 2; + unsigned int func : 4; + unsigned int fd : 5; + unsigned int fs : 5; + unsigned int ft : 5; + unsigned int fr : 5; + unsigned int opcode : 6; +}; + +#else /* !defined (__MIPSEB__) && !defined (__MIPSEL__) */ +#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?" +#endif + +union mips_instruction { + unsigned int word; + unsigned short halfword[2]; + unsigned char byte[4]; + struct j_format j_format; + struct i_format i_format; + struct u_format u_format; + struct c_format c_format; + struct r_format r_format; + struct f_format f_format; + struct ma_format ma_format; +}; + +#endif /* __ASM_MIPS_INST_H */ diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 94f099066..591f6f46d 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -2,12 +2,15 @@ #define __ASM_MIPS_IO_H #include <asm/mipsconfig.h> +#include <asm/addrspace.h> /* * This file contains the definitions for the MIPS counterpart of the * x86 in/out instructions. This heap of macros and C results in much - * better code than the approach of doing it in plain C, though that's - * probably not needed. + * better code than the approach of doing it in plain C. The macros + * result in code that is to fast for certain hardware. On the other + * side the performance of the string functions should be improved for + * sake of certain devices like EIDE disks that do highspeed polled I/O. * * Ralf * @@ -46,6 +49,90 @@ #endif /* + * Change virtual addresses to physical addresses and vv. + * These are trivial on the 1:1 Linux/MIPS mapping + */ +extern inline unsigned long virt_to_phys(volatile void * address) +{ + return (unsigned long) address - KSEG0; +} + +extern inline void * phys_to_virt(unsigned long address) +{ + return (void *) address + KSEG0; +} + +extern void * ioremap(unsigned long phys_addr, unsigned long size); +extern void iounmap(void *addr); + +/* + * IO bus memory addresses are also 1:1 with the physical address + * FIXME: This assumption is wrong for the Deskstation Tyne + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +/* + * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped + * for the processor. + */ +extern unsigned long isa_slot_offset; + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the x86 architecture, we just read/write the + * memory location directly. + * + * On MIPS, we have the whole physical address space mapped at all + * times, so "ioremap()" and "iounmap()" do not need to do anything. + * (This isn't true for all machines but we still handle these cases + * with wired TLB entries anyway ...) + */ +extern inline void * ioremap(unsigned long phys_addr, unsigned long size) +{ + return (void *) KSEG1ADDR(phys_addr); +} + +extern inline void iounmap(void *addr) +{ +} + +#define readb(addr) (*(volatile unsigned char *) (isa_slot_offset + (unsigned long)(addr))) +#define readw(addr) (*(volatile unsigned short *) (isa_slot_offset + (unsigned long)(addr))) +#define readl(addr) (*(volatile unsigned int *) (isa_slot_offset + (unsigned long)(addr))) + +#define writeb(b,addr) (*(volatile unsigned char *) (isa_slot_offset + (unsigned long)(addr)) = (b)) +#define writew(b,addr) (*(volatile unsigned short *) (isa_slot_offset + (unsigned long)(addr)) = (b)) +#define writel(b,addr) (*(volatile unsigned int *) (isa_slot_offset + (unsigned long)(addr)) = (b)) + +#define memset_io(a,b,c) memset((void *)(isa_slot_offset + (unsigned long)a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(void *)(isa_slot_offset + (unsigned long)(b)),(c)) +#define memcpy_toio(a,b,c) memcpy((void *)(isa_slot_offset + (unsigned long)(a)),(b),(c)) + +/* + * We don't have csum_partial_copy_fromio() yet, so we cheat here and + * just copy it. The net code will then do the checksum later. + */ +#define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len)) + +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +/* * Talk about misusing macros.. */ @@ -57,35 +144,36 @@ __asm__ __volatile__ ("s" #m "\t%0,%1(%2)" #define __OUT(m,s) \ __OUT1(s) __OUT2(m) : : "r" (value), "i" (0), "r" (PORT_BASE+port)); } \ -__OUT1(s##c) __OUT2(m) : : "r" (value), "i" (port), "r" (PORT_BASE)); } \ +__OUT1(s##c) __OUT2(m) : : "r" (value), "ir" (port), "r" (PORT_BASE)); } \ __OUT1(s##_p) __OUT2(m) : : "r" (value), "i" (0), "r" (PORT_BASE+port)); \ SLOW_DOWN_IO; } \ -__OUT1(s##c_p) __OUT2(m) : : "r" (value), "i" (port), "r" (PORT_BASE)); \ +__OUT1(s##c_p) __OUT2(m) : : "r" (value), "ir" (port), "r" (PORT_BASE)); \ SLOW_DOWN_IO; } -#define __IN1(s) \ -extern inline unsigned int __in##s(unsigned int port) { unsigned int _v; +#define __IN1(t,s) \ +extern __inline__ t __in##s(unsigned int port) { t _v; /* - * Useless nops will be removed by the assembler + * Required nops will be inserted by the assembler */ #define __IN2(m) \ -__asm__ __volatile__ ("l" #m "u\t%0,%1(%2)\n\tnop" +__asm__ __volatile__ ("l" #m "\t%0,%1(%2)" -#define __IN(m,s) \ -__IN1(s) __IN2(m) : "=r" (_v) : "i" (0), "r" (PORT_BASE+port)); return _v; } \ -__IN1(s##c) __IN2(m) : "=r" (_v) : "i" (port), "r" (PORT_BASE)); return _v; } \ -__IN1(s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (PORT_BASE+port)); SLOW_DOWN_IO; return _v; } \ -__IN1(s##c_p) __IN2(m) : "=r" (_v) : "i" (port), "r" (PORT_BASE)); SLOW_DOWN_IO; return _v; } +#define __IN(t,m,s) \ +__IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (PORT_BASE+port)); return _v; } \ +__IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (PORT_BASE)); return _v; } \ +__IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (PORT_BASE+port)); SLOW_DOWN_IO; return _v; } \ +__IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (PORT_BASE)); SLOW_DOWN_IO; return _v; } #define __INS1(s) \ extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) { #define __INS2(m) \ +if (count) \ __asm__ __volatile__ ( \ ".set\tnoreorder\n\t" \ ".set\tnoat\n" \ - "1:\tl" #m "u\t$1,%4(%5)\n\t" \ + "1:\tl" #m "\t$1,%4(%5)\n\t" \ "subu\t%1,1\n\t" \ "s" #m "\t$1,(%0)\n\t" \ "bne\t$0,%1,1b\n\t" \ @@ -100,21 +188,22 @@ __INS1(s) __INS2(m) \ : "$1");} \ __INS1(s##c) __INS2(m) \ : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "i" (port), "r" (PORT_BASE), "I" (i) \ + : "0" (addr), "1" (count), "ir" (port), "r" (PORT_BASE), "I" (i) \ : "$1");} #define __OUTS1(s) \ extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) { #define __OUTS2(m) \ +if (count) \ __asm__ __volatile__ ( \ ".set\tnoreorder\n\t" \ ".set\tnoat\n" \ - "1:\tl" #m "u\t$1,(%0)\n\t" \ - "subu\t%1,%1,1\n\t" \ + "1:\tl" #m "\t$1,(%0)\n\t" \ + "subu\t%1,1\n\t" \ "s" #m "\t$1,%4(%5)\n\t" \ "bne\t$0,%1,1b\n\t" \ - "addiu\t%0,%0,%6\n\t" \ + "addiu\t%0,%6\n\t" \ ".set\tat\n\t" \ ".set\treorder" @@ -125,12 +214,12 @@ __OUTS1(s) __OUTS2(m) \ : "$1");} \ __OUTS1(s##c) __OUTS2(m) \ : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "i" (port), "r" (PORT_BASE), "I" (i) \ + : "0" (addr), "1" (count), "ir" (port), "r" (PORT_BASE), "I" (i) \ : "$1");} -__IN(b,b) -__IN(h,w) -__IN(w,l) +__IN(unsigned char,b,b) +__IN(unsigned short,h,w) +__IN(unsigned int,w,l) __OUT(b,b) __OUT(h,w) @@ -146,7 +235,7 @@ __OUTS(w,l,4) /* * Note that due to the way __builtin_constant_p() works, you - * - can't use it inside a inline function (it will never be true) + * - can't use it inside an inline function (it will never be true) * - you don't have to worry about side effects within the __builtin.. */ #define outb(val,port) \ diff --git a/include/asm-mips/ioctl.h b/include/asm-mips/ioctl.h new file mode 100644 index 000000000..360b22ce3 --- /dev/null +++ b/include/asm-mips/ioctl.h @@ -0,0 +1,90 @@ +/* + * Linux ioctl() stuff. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_IOCTL_H +#define __ASM_MIPS_IOCTL_H + +/* + * The original linux ioctl numbering scheme was just a general + * "anything goes" setup, where more or less random numbers were + * assigned. Sorry, I was clueless when I started out on this. + * + * On the alpha, we'll try to clean it up a bit, using a more sane + * ioctl numbering, and also trying to be compatible with OSF/1 in + * the process. I'd like to clean it up for the i386 as well, but + * it's so painful recognizing both the new and the old numbers.. + * + * The same applies for for the MIPS ABI; in fact even the macros + * from Linux/Alpha fit almost perfectly. + */ + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 13 +#define _IOC_DIRBITS 3 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * We to additionally limit parameters to a maximum 255 bytes. + */ +#define _IOC_SLMASK 0xff + +/* + * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. + * And this turns out useful to catch old ioctl numbers in header + * files for us. + */ +#define _IOC_NONE 1U +#define _IOC_READ 2U +#define _IOC_WRITE 4U + +/* + * The following are included for compatibility + */ +#define _IOC_VOID 0x20000000 +#define _IOC_OUT 0x40000000 +#define _IOC_IN 0x80000000 +#define _IOC_INOUT (IOC_IN|IOC_OUT) + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + (((size) & _IOC_SLMASK) << _IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode them.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* ...and for the drivers/sound files... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* __ASM_MIPS_IOCTL_H */ diff --git a/include/asm-mips/ioctls.h b/include/asm-mips/ioctls.h new file mode 100644 index 000000000..9ec2c0215 --- /dev/null +++ b/include/asm-mips/ioctls.h @@ -0,0 +1,112 @@ +/* + * ioctls for Linux/MIPS. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_IOCTLS_H +#define __ASM_MIPS_IOCTLS_H + +#include <asm/ioctl.h> + +#if defined(__USE_MISC) || defined (__KERNEL__) +#define tIOC ('t' << 8) +#endif + +#define TCGETA 0x5401 +#define TCSETA 0x5402 +#define TCSETAW 0x5403 +#define TCSETAF 0x5404 + +#define TCSBRK 0x5405 +#define TCXONC 0x5406 +#define TCFLSH 0x5407 + +#define TCGETS 0x540d +#define TCSETS 0x540e +#define TCSETSW 0x540f +#define TCSETSF 0x5410 + +#define TIOCEXCL 0x740d /* set exclusive use of tty */ +#define TIOCNXCL 0x740e /* reset exclusive use of tty */ +#define TIOCOUTQ 0x7472 /* output queue size */ +#define TIOCSTI 0x5472 /* simulate terminal input */ +#define TIOCMGET 0x741d /* get all modem bits */ +#define TIOCMBIS 0x741b /* bis modem bits */ +#define TIOCMBIC 0x741c /* bic modem bits */ +#define TIOCMSET 0x741a /* set all modem bits */ +#define TIOCPKT 0x5470 /* pty: set/clear packet mode */ +#define TIOCPKT_DATA 0x00 /* data packet */ +#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */ +#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ +#define TIOCPKT_STOP 0x04 /* stop output */ +#define TIOCPKT_START 0x08 /* start output */ +#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ +#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ +#if 0 +#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */ +#endif +#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */ +#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */ +#define TIOCNOTTY 0x5471 /* void tty association */ +#define TIOCSETD (tIOC | 1) +#define TIOCGETD (tIOC | 0) + +#define FIOCLEX 0x6601 +#define FIONCLEX 0x6602 /* these numbers need to be adjusted. */ +#define FIOASYNC 0x667d +#define FIONBIO 0x667e + +#if defined(__USE_MISC) || defined (__KERNEL__) +#define TIOCGLTC (tIOC | 116) /* get special local chars */ +#define TIOCSLTC (tIOC | 117) /* set special local chars */ +#endif +#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */ +#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */ +#define TIOCCONS _IOW('t', 120, int) /* become virtual console */ + +#define FIONREAD 0x467f +#define TIOCINQ FIONREAD + +#if defined(__USE_MISC) || defined (__KERNEL__) +#define TIOCGETP (tIOC | 8) +#define TIOCSETP (tIOC | 9) +#define TIOCSETN (tIOC | 10) /* TIOCSETP wo flush */ +#endif + +#if 0 +#define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */ +#define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */ +#define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */ +#define TIOCGETD _IOR('t', 26, int) /* get line discipline */ +#define TIOCSETD _IOW('t', 27, int) /* set line discipline */ + /* 127-124 compat */ +#endif + +/* I hope the range from 0x5480 on is free ... */ +#define TIOCSCTTY 0x5480 /* become controlling tty */ +#define TIOCGSOFTCAR 0x5481 +#define TIOCSSOFTCAR 0x5482 +#define TIOCLINUX 0x5483 +#define TIOCGSERIAL 0x5484 +#define TIOCSSERIAL 0x5485 + +#define TCSBRKP 0x5486 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5487 /* For debugging only */ + +#define TIOCSERCONFIG 0x5488 +#define TIOCSERGWILD 0x5489 +#define TIOCSERSWILD 0x548a +#define TIOCGLCKTRMIOS 0x548b +#define TIOCSLCKTRMIOS 0x548c +#define TIOCSERGSTRUCT 0x548d /* For debugging only */ +#define TIOCSERGETLSR 0x548e /* Get line status register */ +#define TIOCSERGETMULTI 0x548f /* Get multiport config */ +#define TIOCSERSETMULTI 0x5490 /* Set multiport config */ +#define TIOCMIWAIT 0x5491 /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x5492 /* read serial port inline interrupt counts */ + +#endif /* __ASM_MIPS_IOCTLS_H */ diff --git a/include/asm-mips/ipc.h b/include/asm-mips/ipc.h new file mode 100644 index 000000000..3288c1e28 --- /dev/null +++ b/include/asm-mips/ipc.h @@ -0,0 +1,29 @@ +#ifndef __ASM_MIPS_IPC_H +#define __ASM_MIPS_IPC_H + +/* + * These are used to wrap system calls on MIPS. + * + * See arch/mips/kernel/sysmips.c for ugly details.. + * FIXME: split up into ordinary syscalls ... + */ +struct ipc_kludge { + struct msgbuf *msgp; + long msgtyp; +}; + +#define SEMOP 1 +#define SEMGET 2 +#define SEMCTL 3 +#define MSGSND 11 +#define MSGRCV 12 +#define MSGGET 13 +#define MSGCTL 14 +#define SHMAT 21 +#define SHMDT 22 +#define SHMGET 23 +#define SHMCTL 24 + +#define IPCCALL(version,op) ((version)<<16 | (op)) + +#endif /* __ASM_MIPS_IPC_H */ diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h index 4c5191fef..e6bc9ae3c 100644 --- a/include/asm-mips/irq.h +++ b/include/asm-mips/irq.h @@ -12,6 +12,15 @@ #ifndef __ASM_MIPS_IRQ_H #define __ASM_MIPS_IRQ_H +/* + * Actually this is a lie but we hide the local device's interrupts ... + */ +#define NR_IRQS 16 + +#define TIMER_IRQ 0 + +struct irqaction; +extern int setup_x86_irq(int irq, struct irqaction * new); extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); diff --git a/include/asm-mips/jazz.h b/include/asm-mips/jazz.h index 2e6a3cc2d..9a3dbccf0 100644 --- a/include/asm-mips/jazz.h +++ b/include/asm-mips/jazz.h @@ -9,7 +9,6 @@ * * This file is a mess. It really needs some reorganisation! */ - #ifndef __ASM_MIPS_JAZZ_H #define __ASM_MIPS_JAZZ_H @@ -53,7 +52,7 @@ * Some characters for the LED control registers * The original Mips machines seem to have a LED display * with integrated decoder while the Acer machines can - * control each of the seven segments and the dot independend. + * control each of the seven segments and the dot independently. * It's only a toy, anyway... */ #define LED_DOT 0x01 @@ -87,6 +86,16 @@ extern __inline__ void pica_set_led(unsigned int bits) #endif /* + * Base address of the Sonic Ethernet adapter in Jazz machines. + */ +#define JAZZ_ETHERNET_BASE 0xe0001000 + +/* + * Base address of the 53C94 SCSI hostadapter in Jazz machines. + */ +#define JAZZ_SCSI_BASE 0xe0002000 + +/* * i8042 keyboard controller for JAZZ and PICA chipsets. * This address is just a guess and seems to differ from * other mips machines such as RC3xxx... @@ -126,7 +135,6 @@ typedef struct { /* * Serial and parallel ports (WD 16C552) on the Mips JAZZ */ - #define JAZZ_SERIAL1_BASE (unsigned int)0xe0006000 #define JAZZ_SERIAL2_BASE (unsigned int)0xe0007000 #define JAZZ_PARALLEL_BASE (unsigned int)0xe0008000 @@ -134,7 +142,6 @@ typedef struct { /* * Dummy Device Address. Used in jazzdma.c */ - #define JAZZ_DUMMY_DEVICE 0xe000d000 /* @@ -196,10 +203,9 @@ typedef struct { /* * JAZZ Interrupt Level definitions */ - #define JAZZ_TIMER_IRQ 0 #define JAZZ_KEYBOARD_IRQ 1 -#define JAZZ_ETHERNET_IRQ 2 /* 15 */ +#define JAZZ_ETHERNET_IRQ 13 #define JAZZ_SERIAL1_IRQ 3 #define JAZZ_SERIAL2_IRQ 4 #define JAZZ_PARALLEL_IRQ 5 @@ -211,7 +217,6 @@ typedef struct { * Note: Channels 4...7 are not used with respect to the Acer PICA-61 * chipset which does not provide these DMA channels. */ - #define JAZZ_SCSI_DMA 0 /* SCSI */ #define JAZZ_FLOPPY_DMA 1 /* FLOPPY */ #define JAZZ_AUDIOL_DMA 2 /* AUDIO L */ @@ -221,7 +226,6 @@ typedef struct { * JAZZ R4030 MCT_ADR chip (DMA controller) * Note: Virtual Addresses ! */ - #define JAZZ_R4030_CONFIG 0xE0000000 /* R4030 config register */ #define JAZZ_R4030_REVISION 0xE0000008 /* same as PICA_ASIC_REVISION */ #define JAZZ_R4030_INV_ADDR 0xE0000010 /* Invalid Address register */ @@ -232,7 +236,7 @@ typedef struct { #define JAZZ_R4030_CACHE_MTNC 0xE0000030 /* Cache Maintenance */ #define JAZZ_R4030_R_FAIL_ADDR 0xE0000038 /* Remote Failed Address */ -#define JAZZ_R4030_M_FAIL_ADDR 0xE0000040 /* Memory Failed Adresss */ +#define JAZZ_R4030_M_FAIL_ADDR 0xE0000040 /* Memory Failed Address */ #define JAZZ_R4030_CACHE_PTAG 0xE0000048 /* I/O Cache Physical Tag */ #define JAZZ_R4030_CACHE_LTAG 0xE0000050 /* I/O Cache Logical Tag */ @@ -247,68 +251,64 @@ typedef struct { * 8: parallel, 9: NVRAM, 10: CPU, 11: PROM, * 12: reserved, 13: free, 14: 7seg LED, 15: ??? */ - #define JAZZ_R4030_REM_SPEED 0xE0000070 /* 16 Remote Speed Registers */ /* 0xE0000070,78,80... 0xE00000E8 */ #define JAZZ_R4030_IRQ_ENABLE 0xE00000E8 /* Internal Interrupt Enable */ - -#define JAZZ_R4030_IRQ_SOURCE 0xE0000200 /* Interrupt Source Reg */ +#define JAZZ_R4030_INVAL_ADDR 0xE0000010 /* Invalid address Register */ +#define JAZZ_R4030_IRQ_SOURCE 0xE0000200 /* Interrupt Source Register */ #define JAZZ_R4030_I386_ERROR 0xE0000208 /* i386/EISA Bus Error */ +/* + * Virtual (E)ISA controller address + */ +#define JAZZ_EISA_IRQ_ACK 0xE0000238 /* EISA interrupt acknowledge */ /* * Access the R4030 DMA and I/O Controller */ - #ifndef __LANGUAGE_ASSEMBLY__ -extern inline unsigned short r4030_read_reg16(unsigned addr) { +extern inline void r4030_delay(void) +{ +__asm__ __volatile__( + ".set\tnoreorder\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\treorder"); +} + +extern inline unsigned short r4030_read_reg16(unsigned addr) +{ unsigned short ret = *((volatile unsigned short *)addr); - __asm__ __volatile__( - ".set\tnoreorder\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - ".set\treorder"); + r4030_delay(); return ret; } -extern inline unsigned int r4030_read_reg32(unsigned addr) { +extern inline unsigned int r4030_read_reg32(unsigned addr) +{ unsigned int ret = *((volatile unsigned int *)addr); - __asm__ __volatile__( - ".set\tnoreorder\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - ".set\treorder"); + r4030_delay(); return ret; } -extern inline void r4030_write_reg16(unsigned addr, unsigned val) { +extern inline void r4030_write_reg16(unsigned addr, unsigned val) +{ *((volatile unsigned short *)addr) = val; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - ".set\treorder"); + r4030_delay(); } -extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val) { +extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val) +{ *((volatile unsigned int *)addr) = val; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - ".set\treorder"); + r4030_delay(); } #endif /* !LANGUAGE_ASSEMBLY__ */ - +#define JAZZ_FDC_BASE 0xe0003000 + +#define JAZZ_RTC_BASE 0xe0004000 + #endif /* __ASM_MIPS_JAZZ_H */ diff --git a/include/asm-mips/jazzdma.h b/include/asm-mips/jazzdma.h index 292a16177..c7f1730cf 100644 --- a/include/asm-mips/jazzdma.h +++ b/include/asm-mips/jazzdma.h @@ -1,14 +1,12 @@ /* * Helpfile for jazzdma.c -- Mips Jazz R4030 DMA controller support */ - -#ifndef __ASM_JAZZDMA_H -#define __ASM_JAZZDMA_H +#ifndef __ASM_MIPS_JAZZDMA_H +#define __ASM_MIPS_JAZZDMA_H /* * Prototypes and macros */ - unsigned long vdma_init(unsigned long memory_start, unsigned long memory_end); unsigned long vdma_alloc(unsigned long paddr, unsigned long size); int vdma_free(unsigned long laddr); @@ -27,7 +25,6 @@ int vdma_get_residue(int channel); /* * some definitions used by the driver functions */ - #define VDMA_PAGESIZE 4096 #define VDMA_PGTBL_ENTRIES 4096 #define VDMA_PGTBL_SIZE (sizeof(VDMA_PGTBL_ENTRY) * VDMA_PGTBL_ENTRIES) @@ -44,13 +41,11 @@ int vdma_get_residue(int channel); * error code returned by vdma_alloc() * (See also arch/mips/kernel/jazzdma.c) */ - #define VDMA_ERROR 0xffffffff /* * VDMA pagetable entry description */ - typedef volatile struct VDMA_PGTBL_ENTRY { unsigned int frame; /* physical frame no. */ @@ -62,7 +57,6 @@ typedef volatile struct VDMA_PGTBL_ENTRY * DMA channel control registers * in the R4030 MCT_ADR chip */ - #define JAZZ_R4030_CHNL_MODE 0xE0000100 /* 8 DMA Channel Mode Registers, */ /* 0xE0000100,120,140... */ #define JAZZ_R4030_CHNL_ENABLE 0xE0000108 /* 8 DMA Channel Enable Regs, */ @@ -80,8 +74,9 @@ typedef volatile struct VDMA_PGTBL_ENTRY #define R4030_MEM_INTR (1<<9) #define R4030_ADDR_INTR (1<<10) -/* channel mode register bits */ - +/* + * Channel mode register bits + */ #define R4030_MODE_ATIME_40 (0) /* device access time on remote bus */ #define R4030_MODE_ATIME_80 (1) #define R4030_MODE_ATIME_120 (2) @@ -97,4 +92,4 @@ typedef volatile struct VDMA_PGTBL_ENTRY #define R4030_MODE_BURST (1<<6) /* Rev. 2 only */ #define R4030_MODE_FAST_ACK (1<<7) /* Rev. 2 only */ -#endif /* __ASM_JAZZDMA_H */ +#endif /* __ASM_MIPS_JAZZDMA_H */ diff --git a/include/asm-mips/keyboard.h b/include/asm-mips/keyboard.h new file mode 100644 index 000000000..3c5c7ce65 --- /dev/null +++ b/include/asm-mips/keyboard.h @@ -0,0 +1,309 @@ +/* + * CPU specific parts of the keyboard driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef __ASM_MIPS_KEYBOARD_H +#define __ASM_MIPS_KEYBOARD_H + +#include <linux/config.h> + +/* + * The default IO slowdown is doing 'inb()'s from 0x61, which should be + * safe. But as that is the keyboard controller chip address, we do our + * slowdowns here by doing short jumps: the keyboard controller should + * be able to keep up + */ +#define REALLY_SLOW_IO +#define SLOW_IO_BY_JUMPING +#include <asm/io.h> +#include <asm/bootinfo.h> +#include <asm/jazz.h> + +/* + * Not true for Jazz machines, we cheat a bit for 'em. + */ +#define KEYBOARD_IRQ 1 + +static int initialize_kbd(void); + +int (*kbd_inb_p)(unsigned short port); +int (*kbd_inb)(unsigned short port); +void (*kbd_outb_p)(unsigned char data, unsigned short port); +void (*kbd_outb)(unsigned char data, unsigned short port); + +#ifdef CONFIG_MIPS_JAZZ +/* + * We want the full initialization for the keyboard controller. + */ +#define INIT_KBD + +static volatile keyboard_hardware *kh = (void *) JAZZ_KEYBOARD_ADDRESS; + +static int +jazz_kbd_inb_p(unsigned short port) +{ + int result; + + if(port == KBD_DATA_REG) + result = kh->data; + else /* Must be KBD_STATUS_REG */ + result = kh->command; + inb(0x80); + + return result; +} + +static int +jazz_kbd_inb(unsigned short port) +{ + int result; + + if(port == KBD_DATA_REG) + result = kh->data; + else /* Must be KBD_STATUS_REG */ + result = kh->command; + + return result; +} + +static void +jazz_kbd_outb_p(unsigned char data, unsigned short port) +{ + if(port == KBD_DATA_REG) + kh->data = data; + else if(port == KBD_CNTL_REG) + kh->command = data; + inb(0x80); +} + +static void +jazz_kbd_outb(unsigned char data, unsigned short port) +{ + if(port == KBD_DATA_REG) + kh->data = data; + else if(port == KBD_CNTL_REG) + kh->command = data; +} +#endif /* CONFIG_MIPS_JAZZ */ + +/* + * Most other MIPS machines access the keyboard controller via + * ordinary I/O ports. + */ +static int +port_kbd_inb_p(unsigned short port) +{ + return inb_p(port); +} + +static int +port_kbd_inb(unsigned short port) +{ + return inb(port); +} + +static void +port_kbd_outb_p(unsigned char data, unsigned short port) +{ + return outb_p(data, port); +} + +static void +port_kbd_outb(unsigned char data, unsigned short port) +{ + return outb(data, port); +} + +#ifdef INIT_KBD +static int +kbd_wait_for_input(void) +{ + int n; + int status, data; + + n = TIMEOUT_CONST; + do { + status = kbd_inb(KBD_STATUS_REG); + /* + * Wait for input data to become available. This bit will + * then be cleared by the following read of the DATA + * register. + */ + + if (!(status & KBD_OBF)) + continue; + + data = kbd_inb(KBD_DATA_REG); + + /* + * Check to see if a timeout error has occurred. This means + * that transmission was started but did not complete in the + * normal time cycle. PERR is set when a parity error occurred + * in the last transmission. + */ + if (status & (KBD_GTO | KBD_PERR)) { + continue; + } + return (data & 0xff); + } while (--n); + return (-1); /* timed-out if fell through to here... */ +} + +static void kbd_write(int address, int data) +{ + int status; + + do { + status = kbd_inb(KBD_STATUS_REG); /* spin until input buffer empty*/ + } while (status & KBD_IBF); + kbd_outb(data, address); /* write out the data*/ +} + +static int initialize_kbd(void) +{ + unsigned long flags; + + save_flags(flags); cli(); + + /* Flush any pending input. */ + while (kbd_wait_for_input() != -1) + continue; + + /* + * Test the keyboard interface. + * This seems to be the only way to get it going. + * If the test is successful a x55 is placed in the input buffer. + */ + kbd_write(KBD_CNTL_REG, KBD_SELF_TEST); + if (kbd_wait_for_input() != 0x55) { + printk(KERN_WARNING "initialize_kbd: " + "keyboard failed self test.\n"); + restore_flags(flags); + return(-1); + } + + /* + * Perform a keyboard interface test. This causes the controller + * to test the keyboard clock and data lines. The results of the + * test are placed in the input buffer. + */ + kbd_write(KBD_CNTL_REG, KBD_SELF_TEST2); + if (kbd_wait_for_input() != 0x00) { + printk(KERN_WARNING "initialize_kbd: " + "keyboard failed self test 2.\n"); + restore_flags(flags); + return(-1); + } + + /* Enable the keyboard by allowing the keyboard clock to run. */ + kbd_write(KBD_CNTL_REG, KBD_CNTL_ENABLE); + + /* + * Reset keyboard. If the read times out + * then the assumption is that no keyboard is + * plugged into the machine. + * This defaults the keyboard to scan-code set 2. + */ + kbd_write(KBD_DATA_REG, KBD_RESET); + if (kbd_wait_for_input() != KBD_ACK) { + printk(KERN_WARNING "initialize_kbd: " + "reset kbd failed, no ACK.\n"); + restore_flags(flags); + return(-1); + } + + /* + * Give the keyboard some time to breathe ... + * ... or it fucks up the floppy controller, too. Wiered. + */ + udelay(20); + + if (kbd_wait_for_input() != KBD_POR) { + printk(KERN_WARNING "initialize_kbd: " + "reset kbd failed, not POR.\n"); + restore_flags(flags); + return(-1); + } + + /* + * now do a DEFAULTS_DISABLE always + */ + kbd_write(KBD_DATA_REG, KBD_DISABLE); + if (kbd_wait_for_input() != KBD_ACK) { + printk(KERN_WARNING "initialize_kbd: " + "disable kbd failed, no ACK.\n"); + restore_flags(flags); + return(-1); + } + + /* + * Enable keyboard interrupt, operate in "sys" mode, + * enable keyboard (by clearing the disable keyboard bit), + * disable mouse, do conversion of keycodes. + */ + kbd_write(KBD_CNTL_REG, KBD_WRITE_MODE); + kbd_write(KBD_DATA_REG, KBD_EKI|KBD_SYS|KBD_DMS|KBD_KCC); + + /* + * now ENABLE the keyboard to set it scanning... + */ + kbd_write(KBD_DATA_REG, KBD_ENABLE); + if (kbd_wait_for_input() != KBD_ACK) { + printk(KERN_WARNING "initialize_kbd: " + "keyboard enable failed.\n"); + restore_flags(flags); + return(-1); + } + + restore_flags(flags); + + return (1); +} +#endif + +extern __inline__ void +keyboard_setup(void) +{ +#ifdef CONFIG_MIPS_JAZZ + if (mips_machgroup == MACH_GROUP_JAZZ) { + kbd_inb_p = jazz_kbd_inb_p; + kbd_inb = jazz_kbd_inb; + kbd_outb_p = jazz_kbd_outb_p; + kbd_outb = jazz_kbd_outb; + /* + * Enable keyboard interrupts. + */ + *((volatile u16 *)JAZZ_IO_IRQ_ENABLE) |= JAZZ_IE_KEYBOARD; + set_cp0_status(IE_IRQ1, IE_IRQ1); + initialize_kbd(); + } else +#endif + if (mips_machgroup == MACH_GROUP_ARC || /* this is for Deskstation */ + (mips_machgroup == MACH_GROUP_SNI_RM + && mips_machtype == MACH_SNI_RM200_PCI)) { + /* + * These machines address their keyboard via the normal + * port address range. + * + * Also enable Scan Mode 2. + */ + kbd_inb_p = port_kbd_inb_p; + kbd_inb = port_kbd_inb; + kbd_outb_p = port_kbd_outb_p; + kbd_outb = port_kbd_outb; + request_region(0x60,16,"keyboard"); + + kb_wait(); + kbd_outb(0x60, 0x64); /* 60 == PS/2 MODE ?? */ + kb_wait(); + kbd_outb(0x41, 0x60); /* 4d:same as freebsd, 41:KCC+EKI */ + kb_wait(); + if (!send_data(0xf0) || !send_data(0x02)) + printk("Scanmode 2 change failed\n"); + } +} + +#endif /* __ASM_MIPS_KEYBOARD_H */ diff --git a/include/asm-mips/mc146818rtc.h b/include/asm-mips/mc146818rtc.h new file mode 100644 index 000000000..0e2700526 --- /dev/null +++ b/include/asm-mips/mc146818rtc.h @@ -0,0 +1,26 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef __ASM_MIPS_MC146818RTC_H +#define __ASM_MIPS_MC146818RTC_H + +#include <asm/io.h> +#include <asm/vector.h> + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 0 /* RTC operates in binary mode */ +#endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#define CMOS_READ(addr) ({ \ +feature->rtc_read_data(addr); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +feature->rtc_write_data(val, addr); \ +}) + +#endif /* __ASM_MIPS_MC146818RTC_H */ diff --git a/include/asm-mips/mipsconfig.h b/include/asm-mips/mipsconfig.h index 1648f7c7e..01316c11b 100644 --- a/include/asm-mips/mipsconfig.h +++ b/include/asm-mips/mipsconfig.h @@ -5,9 +5,12 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995 by Waldorf Electronics - * written by Ralf Baechle + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle + * + * This file contains constant definitions and some MIPS specific debug and + * other compile time switches. */ + #ifndef __ASM_MIPS_MIPSCONFIG_H #define __ASM_MIPS_MIPSCONFIG_H @@ -15,13 +18,23 @@ * This is the virtual address to which all ports are being mapped. * Must be a value that can be load with a lui instruction. */ +#define PORT_BASE_SNI 0xb4000000 +#define PORT_BASE_RPC44 0xe2000000 +#define PORT_BASE_TYNE 0xe2000000 +#define PORT_BASE_JAZZ 0xe2000000 #ifndef PORT_BASE -#define PORT_BASE 0xe2000000 +#if !defined (__LANGUAGE_ASSEMBLY__) +extern unsigned long port_base; +#endif +#define PORT_BASE port_base #endif /* * Pagetables are 4MB mapped at 0xe4000000 * Must be a value that can be loaded with a single instruction. + * The xtlb exception handler assumes that bit 30 and 31 of TLBMAP + * are the same. This is true for all KSEG2 and KSEG3 addresses and + * will therefore not a problem. */ #define TLBMAP 0xe4000000 @@ -35,15 +48,4 @@ */ #define TLB_ROOT 0xe4390000 -/* - * Use this to activate extra TLB error checking - */ -#define CONFIG_DEBUG_TLB - -/* - * Use this to activate extra TLB profiling code - * (currently not implemented) - */ -#undef CONFIG_PROFILE_TLB - #endif /* __ASM_MIPS_MIPSCONFIG_H */ diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 466c8b12b..12666127e 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -5,17 +5,18 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995 by Ralf Baechle + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle + * Modified for further R[236]000 support by Paul M. Antoine, 1996. */ - #ifndef __ASM_MIPS_MIPSREGS_H #define __ASM_MIPS_MIPSREGS_H +#include <linux/linkage.h> + /* * The following macros are especially useful for __asm__ * inline assembler. */ - #ifndef __STR #define __STR(x) #x #endif @@ -24,15 +25,21 @@ #endif /* - * On the R2000/3000 load instructions are not interlocked - - * we therefore sometimes need to fill load delay slots with a nop - * which would be useless for ISA >= 2. + * Assigned values for the product ID register. In order to detect a + * certain CPU type exactly eventually additional registers may need to + * be examined. */ -#if !defined (__R4000__) -#define FILL_LDS nop -#else -#define FILL_LDS -#endif +#define PRID_R3000A 0x02 +#define PRID_R4000 0x04 +#define PRID_R4400 0x04 +#define PRID_R4300 0x0b +#define PRID_R4600 0x20 +#define PRID_R4700 0x21 +#define PRID_R4640 0x22 +#define PRID_R4650 0x22 +#define PRID_R5000 0x23 +#define PRID_SONIC 0x24 +#define PRID_R10000 0x09 /* * Coprocessor 0 register names @@ -67,9 +74,22 @@ #define CP0_ERROREPC $30 /* - * Coprocessor 1 (FPU) register names + * R4640/R4650 cp0 register names. These registers are listed + * here only for completeness; without MMU these CPUs are not useable + * by Linux. A future ELKS port might take make Linux run on them + * though ... */ +#define CP0_IBASE $0 +#define CP0_IBOUND $1 +#define CP0_DBASE $2 +#define CP0_DBOUND $3 +#define CP0_CALG $17 +#define CP0_IWATCH $18 +#define CP0_DWATCH $19 +/* + * Coprocessor 1 (FPU) register names + */ #define CP1_REVISION $0 #define CP1_STATUS $31 @@ -177,9 +197,14 @@ BUILD_SET_CP0(cause,CP0_CAUSE) /* * Inline code for use of the ll and sc instructions * - * FIXME: This instruction is only available on MIPS ISA >=3. + * FIXME: This instruction is only available on MIPS ISA >=2. * Since these operations are only being used for atomic operations * the easiest workaround for the R[23]00 is to disable interrupts. + * This fails for R3000 SMP machines which use that many different + * technologies as replacement that it is difficult to create even + * just a hook for for all machines to hook into. The only good + * thing is that there is currently no R3000 SMP machine on the + * Linux/MIPS target list ... */ #define load_linked(addr) \ ({ \ @@ -188,7 +213,7 @@ BUILD_SET_CP0(cause,CP0_CAUSE) __asm__ __volatile__( \ "ll\t%0,(%1)" \ : "=r" (__res) \ - : "r" ((unsigned int) (addr))); \ + : "r" ((unsigned long) (addr))); \ \ __res; \ }) @@ -206,10 +231,7 @@ BUILD_SET_CP0(cause,CP0_CAUSE) }) /* - * Bitfields in the cp0 status register - * - * Refer to the MIPS R4xx0 manuals, chapter 5 for explanation. - * FIXME: This doesn't cover all R4xx0 processors. + * Bitfields in the R4xx0 cp0 status register */ #define ST0_IE (1 << 0) #define ST0_EXL (1 << 1) @@ -221,6 +243,28 @@ BUILD_SET_CP0(cause,CP0_CAUSE) #define ST0_UX (1 << 5) #define ST0_SX (1 << 6) #define ST0_KX (1 << 7) + +/* + * Bitfields in the R[23]000 cp0 status register. + */ +#define ST0_IEC (1 << 0) +#define ST0_KUC (1 << 1) +#define ST0_IEP (1 << 2) +#define ST0_KUP (1 << 3) +#define ST0_IEO (1 << 4) +#define ST0_KUO (1 << 5) +/* bits 6 & 7 are reserved on R[23]000 */ + +/* + * Bits specific to the R4640/R4650 + */ +#define ST0_UM <1 << 4) +#define ST0_IL (1 << 23) +#define ST0_DL (1 << 24) + +/* + * Status register bits available in all MIPS CPUs. + */ #define ST0_IM (255 << 8) #define ST0_DE (1 << 16) #define ST0_CE (1 << 17) @@ -234,6 +278,7 @@ BUILD_SET_CP0(cause,CP0_CAUSE) #define ST0_CU1 (1 << 29) #define ST0_CU2 (1 << 30) #define ST0_CU3 (1 << 31) +#define ST0_XX (1 << 31) /* MIPS IV naming */ /* * Bitfields and bit numbers in the coprocessor 0 cause register. @@ -265,4 +310,77 @@ BUILD_SET_CP0(cause,CP0_CAUSE) #define CAUSEB_BD 31 #define CAUSEF_BD (1 << 31) +/* + * Bits in the coprozessor 0 config register. + */ +#define CONFIG_DB (1<<4) +#define CONFIG_IB (1<<5) +#define CONFIG_SC (1<<17) + +/* + * R10000 performance counter definitions. + * + * FIXME: The R10000 performance counter opens a nice way to implement CPU + * time accounting with a precission of one cycle. I don't have + * R10000 silicon but just a manual, so ... + */ + +/* + * Events counted by counter #0 + */ +#define CE0_CYCLES 0 +#define CE0_INSN_ISSUED 1 +#define CE0_LPSC_ISSUED 2 +#define CE0_S_ISSUED 3 +#define CE0_SC_ISSUED 4 +#define CE0_SC_FAILED 5 +#define CE0_BRANCH_DECODED 6 +#define CE0_QW_WB_SECONDARY 7 +#define CE0_CORRECTED_ECC_ERRORS 8 +#define CE0_ICACHE_MISSES 9 +#define CE0_SCACHE_I_MISSES 10 +#define CE0_SCACHE_I_WAY_MISSPREDICTED 11 +#define CE0_EXT_INTERVENTIONS_REQ 12 +#define CE0_EXT_INVALIDATE_REQ 13 +#define CE0_VIRTUAL_COHERENCY_COND 14 +#define CE0_INSN_GRADUATED 15 + +/* + * Events counted by counter #1 + */ +#define CE1_CYCLES 0 +#define CE1_INSN_GRADUATED 1 +#define CE1_LPSC_GRADUATED 2 +#define CE1_S_GRADUATED 3 +#define CE1_SC_GRADUATED 4 +#define CE1_FP_INSN_GRADUATED 5 +#define CE1_QW_WB_PRIMARY 6 +#define CE1_TLB_REFILL 7 +#define CE1_BRANCH_MISSPREDICTED 8 +#define CE1_DCACHE_MISS 9 +#define CE1_SCACHE_D_MISSES 10 +#define CE1_SCACHE_D_WAY_MISSPREDICTED 11 +#define CE1_EXT_INTERVENTION_HITS 12 +#define CE1_EXT_INVALIDATE_REQ 13 +#define CE1_SP_HINT_TO_CEXCL_SC_BLOCKS 14 +#define CE1_SP_HINT_TO_SHARED_SC_BLOCKS 15 + +/* + * These flags define in which priviledge mode the counters count events + */ +#define CEB_USER 8 /* Count events in user mode, EXL = ERL = 0 */ +#define CEB_SUPERVISOR 4 /* Count events in supvervisor mode EXL = ERL = 0 */ +#define CEB_KERNEL 2 /* Count events in kernel mode EXL = ERL = 0 */ +#define CEB_EXL 1 /* Count events with EXL = 1, ERL = 0 */ + +#ifndef __LANGUAGE_ASSEMBLY__ +/* + * Functions to access the performance counter and control registers + */ +extern asmlinkage unsigned int read_perf_cntr(unsigned int counter); +extern asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val); +extern asmlinkage unsigned int read_perf_cntl(unsigned int counter); +extern asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val); +#endif + #endif /* __ASM_MIPS_MIPSREGS_H */ diff --git a/include/asm-mips/mman.h b/include/asm-mips/mman.h new file mode 100644 index 000000000..f95aec1e6 --- /dev/null +++ b/include/asm-mips/mman.h @@ -0,0 +1,63 @@ +/* + * Linux/MIPS memory manager definitions + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MMAN_H +#define __ASM_MIPS_MMAN_H + +/* + * Protections are chosen from these bits, OR'd together. The + * implementation does not necessarily support PROT_EXEC or PROT_WRITE + * without PROT_READ. The only guarantees are that no writing will be + * allowed without PROT_WRITE and no access will be allowed for PROT_NONE. + */ +#define PROT_NONE 0x0 /* page can not be accessed */ +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ + +/* + * Flags for mmap + */ +#define MAP_SHARED 0x001 /* Share changes */ +#define MAP_PRIVATE 0x002 /* Changes are private */ +#define MAP_TYPE 0x00f /* Mask for type of mapping */ +#define MAP_FIXED 0x010 /* Interpret addr exactly */ + +/* not used by linux, but here to make sure we don't clash with ABI defines */ +#define MAP_RENAME 0x020 /* Assign page to file */ +#define MAP_AUTOGROW 0x040 /* File may grow by writing */ +#define MAP_LOCAL 0x080 /* Copy on fork/sproc */ +#define MAP_AUTORSRV 0x100 /* Logical swap reserved on demand */ + +/* These are linux-specific */ +#define MAP_NORESERVE 0x0400 /* don't check for reservations */ +#define MAP_ANONYMOUS 0x0800 /* don't use a file */ +#define MAP_GROWSDOWN 0x1000 /* stack-like segment */ +#define MAP_DENYWRITE 0x2000 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x4000 /* mark it as an executable */ +#define MAP_LOCKED 0x8000 /* pages are locked */ + +/* + * Flags for msync + */ +#define MS_SYNC 0 /* synchronous memory sync */ +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate mappings & caches */ + +/* + * Flags for mlockall + */ +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __ASM_MIPS_MMAN_H */ diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h new file mode 100644 index 000000000..5a61279da --- /dev/null +++ b/include/asm-mips/mmu_context.h @@ -0,0 +1,22 @@ +/* + * Switch a MMU context. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MMU_CONTEXT_H +#define __ASM_MIPS_MMU_CONTEXT_H + +/* + * Get a new mmu context. For MIPS we use resume() to change the + * PID (R3000)/ASID (R4000). Well, we will ... + */ +extern __inline__ void +get_mmu_context(struct task_struct *p) +{ +} + +#endif /* __ASM_MIPS_MMU_CONTEXT_H */ diff --git a/include/asm-mips/ncr53c94.h b/include/asm-mips/ncr53c94.h new file mode 100644 index 000000000..bf5c072f4 --- /dev/null +++ b/include/asm-mips/ncr53c94.h @@ -0,0 +1,121 @@ +/* + * Makefile for MIPS Linux main source directory + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ + +/* + * As far as I know there are some MIPS boxes which have their NCRs + * mapped with pad bytes. For these NCR_PAD will have to be redefined. + */ +#define NCR_PAD(name) +struct ncr53c94 { + NCR_PAD(pad0); + volatile unsigned char count_lo; + NCR_PAD(pad1); + volatile unsigned char count_hi; + NCR_PAD(pad2); + volatile unsigned char fifo; + NCR_PAD(pad3); + volatile unsigned char command; + NCR_PAD(pad4); + union { + volatile unsigned char status; + volatile unsigned char dest_id; + } s_d; + NCR_PAD(pad5); + union { + volatile unsigned char interrupts; + volatile unsigned char timeout; + } i_t; + NCR_PAD(pad6); + union { + volatile unsigned char seqn_step; + volatile unsigned char sync_period; + } s_p; + NCR_PAD(pad7); + union { + volatile unsigned char fifo_flags; + volatile unsigned char sync_offset; + } f_o; + NCR_PAD(pad8); + volatile unsigned char config1; + NCR_PAD(pad9); + volatile unsigned char clk_conv; + NCR_PAD(pad10); + volatile unsigned char test; + NCR_PAD(pad11); + volatile unsigned char config2; + NCR_PAD(pad12); + volatile unsigned char config3; + NCR_PAD(pad13); + volatile unsigned char unused; + NCR_PAD(pad14); + volatile unsigned char count_xhi; + NCR_PAD(pad15); + volatile unsigned char fifo_b; +}; + +/* + * Clock conversion factors + */ +#define CCV_10MHZ 0x2 /* 10 Mhz */ +#define CCV_15MHZ 0x3 /* 10.01 - 15 Mhz */ +#define CCV_20MHZ 0x4 /* 15.01 - 20 Mhz */ +#define CCV_25MHZ 0x5 /* 20.01 - 25 Mhz */ +#define CCV_30MHZ 0x6 /* 25.01 - 30 Mhz */ +#define CCV_35MHZ 0x7 /* 30.01 - 35 Mhz */ +#define CCV_40MHZ 0x0 /* 35.01 - 40 Mhz */ + +/* + * Set this additional to enable DMA for a command. + */ +#define NCR_DMA 0x80 + +/* + * Miscellaneous commands + */ +#define NCR_NOP 0x00 +#define NCR_FLUSH_FIFO 0x01 +#define NCR_RESET_NCR 0x02 +#define NCR_RESET_SCSI 0x03 + +/* + * Disconnected state commands + */ +#define NCR_SELECT_NO_ATN 0x41 +#define NCR_SELECT_ATN 0x42 +#define NCR_SELECT_ATN_STOP 0x43 +#define NCR_ENABLE_RESEL 0x44 +#define NCR_DISABLE_RESEL 0x45 +#define NCR_SELECT_ATN3 0x46 + +/* + * Initiator state commands + */ +#define NCR_TRANSFER 0x10 +#define NCR_CMD_CMP 0x11 +#define NCR_MSG_OK 0x12 +#define NCR_TRANSFER_PAD 0x18 +#define NCR_SET_ATN 0x1a +#define NCR_RESET_ATN 0x1b + +/* + * Target state commands + */ +#define NCR_SEND_MSG 0x20 +#define NCR_SEND_STATUS 0x21 +#define NCR_SEND_DATA 0x22 +#define NCR_DISC_SEQN 0x23 +#define NCR_TERM_SEQN 0x24 +#define NCR_CMD_COMP_SEQN 0x25 +#define NCR_DISC 0x27 +#define NCR_REC_MSG 0x28 +#define NCR_REC_CMD 0x29 +#define NCR_REC_DATA 0x2a +#define NCR_REC_CMD_SEQN 0x2b +#define NCR_ABORT_DMA 0x04 diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index 4ea742d84..6339c0373 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -1,3 +1,12 @@ +/* + * Definitions for page handling + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle + */ #ifndef __ASM_MIPS_PAGE_H #define __ASM_MIPS_PAGE_H @@ -8,13 +17,14 @@ #ifdef __KERNEL__ -#define CONFIG_STRICT_MM_TYPECHECKS +#define STRICT_MM_TYPECHECKS -#ifndef __LANGUAGE_ASSEMBLY__ +extern void (*clear_page)(unsigned long page); +extern void (*copy_page)(unsigned long to, unsigned long from); -#include <asm/cachectl.h> +#ifndef __LANGUAGE_ASSEMBLY__ -#ifdef CONFIG_STRICT_MM_TYPECHECKS +#ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ @@ -33,7 +43,7 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -#else /* !defined (CONFIG_STRICT_MM_TYPECHECKS) */ +#else /* !defined (STRICT_MM_TYPECHECKS) */ /* * .. while these make it easier on the compiler */ @@ -52,18 +62,7 @@ typedef unsigned long pgprot_t; #define __pgd(x) (x) #define __pgprot(x) (x) -#endif /* !defined (CONFIG_STRICT_MM_TYPECHECKS) */ - -#include <linux/linkage.h> - -extern asmlinkage void tlbflush(void); -#define invalidate() ({sys_cacheflush(0, ~0, BCACHE);tlbflush();}) - -#if __mips == 3 -typedef unsigned int mem_map_t; -#else -typedef unsigned short mem_map_t; -#endif +#endif /* !defined (STRICT_MM_TYPECHECKS) */ #endif /* __LANGUAGE_ASSEMBLY__ */ @@ -71,32 +70,36 @@ typedef unsigned short mem_map_t; #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) /* This handles the memory map */ -#if __mips == 3 +#if 0 /* + * Kernel with 64 bit address space. * We handle pages at XKPHYS + 0x1800000000000000 (cachable, noncoherent) * Pagetables are at XKPHYS + 0x1000000000000000 (uncached) */ #define PAGE_OFFSET 0x9800000000000000UL #define PT_OFFSET 0x9000000000000000UL #define MAP_MASK 0x07ffffffffffffffUL -#define MAP_PAGE_RESERVED (1<<31) -#else +#else /* !defined (__mips64) */ /* + * Kernel with 32 bit address space. * We handle pages at KSEG0 (cachable, noncoherent) * Pagetables are at KSEG1 (uncached) */ -#define PAGE_OFFSET 0x80000000 -#define PT_OFFSET 0xa0000000 -#define MAP_MASK 0x1fffffff -#define MAP_PAGE_RESERVED (1<<15) -#endif +#define PAGE_OFFSET 0x80000000UL +#define PT_OFFSET 0xa0000000UL +#define MAP_MASK 0x1fffffffUL +#endif /* !defined (__mips64) */ + +/* + * __pa breaks when applied to a pagetable pointer on >= R4000. + */ +#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) #define MAP_NR(addr) ((((unsigned long)(addr)) & MAP_MASK) >> PAGE_SHIFT) #ifndef __LANGUAGE_ASSEMBLY__ -#define copy_page(from,to) __copy_page((unsigned long)from, (unsigned long)to) - extern unsigned long page_colour_mask; extern inline unsigned long @@ -105,21 +108,6 @@ page_colour(unsigned long page) return page & page_colour_mask; } -#if 0 -extern inline void __copy_page(unsigned long from, unsigned long to) -{ -printk("__copy_page(%08lx, %08lx)\n", from, to); - sys_cacheflush(0, ~0, DCACHE); - sync_mem(); - from += (PT_OFFSET - PAGE_OFFSET); - to += (PT_OFFSET - PAGE_OFFSET); - memcpy((void *) to, (void *) from, PAGE_SIZE); - sys_cacheflush(0, ~0, ICACHE); -} -#else -extern void __copy_page(unsigned long from, unsigned long to); -#endif - #endif /* defined (__LANGUAGE_ASSEMBLY__) */ #endif /* defined (__KERNEL__) */ diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index e2fb67cbe..2744d5c24 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h @@ -1,7 +1,56 @@ +/* + * Linux/MIPS pagetables + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996 by Ralf Baechle + */ #ifndef __ASM_MIPS_PGTABLE_H #define __ASM_MIPS_PGTABLE_H -#include <asm/cachectl.h> +#include <asm/addrspace.h> +#include <asm/mipsconfig.h> + +#ifndef __LANGUAGE_ASSEMBLY__ + +#include <linux/linkage.h> +#include <asm/cache.h> + +extern inline void +flush_cache_all(void) +{ + cacheflush(0, ~0UL, CF_DCACHE|CF_VIRTUAL); +} + +extern inline void +flush_cache_mm(struct mm_struct *mm) +{ + cacheflush(0, ~0UL, CF_BCACHE|CF_VIRTUAL); +} + +extern inline void +flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) +{ + cacheflush(start, end - start, CF_DCACHE|CF_VIRTUAL); +} + +extern inline void +flush_cache_page(struct vm_area_struct * vma, unsigned long vmaddr) +{ + unsigned int flags; + + flags = (vma->vm_flags & VM_EXEC) ? CF_BCACHE|CF_VIRTUAL + : CF_DCACHE|CF_VIRTUAL; + cacheflush(vmaddr, PAGE_SIZE, flags); +} + +extern inline void +flush_page_to_ram(unsigned long page) +{ + cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL); +} /* * The Linux memory management assumes a three-level page table setup. In @@ -10,8 +59,58 @@ * i386 mmu expects. The 64 bit version uses a three level setup. * * This file contains the functions and defines necessary to modify and use - * the MIPS page table tree. + * the MIPS page table tree. Note the frequent conversion between addresses + * in KSEG0 and KSEG1. + * + * This is required due to the cache aliasing problem of the R4xx0 series. + * Sometimes doing uncached accesses also to improve the cache performance + * slightly. The R10000 caching mode "uncached accelerated" will help even + * further. + */ + +/* + * TLB invalidation: + * + * - flush_tlb() flushes the current mm struct TLB entries + * - flush_tlb_all() flushes all processes TLB entries + * - flush_tlb_mm(mm) flushes the specified mm context TLB entries + * - flush_tlb_page(mm, vmaddr) flushes a single page + * - flush_tlb_range(mm, start, end) flushes a range of pages + * + * FIXME: MIPS has full control of all TLB activity in the CPU. Though + * we just stick with complete flushing of TLBs for now. + * Currently this code only supports only R4000 and newer. Support + * for R3000 is in the works. The R6000 uses a 2x8 entry TLB slice + * and the R6000A an 16 entry TLB slice which is quite different + * from the memory management concepts of the other R-series CPUs. + * Only a few machines with this CPU still exist and I don't have one + * so chances for complete R6000 support are relativly low. */ +extern asmlinkage void tlbflush(void); +extern asmlinkage void tlbflush_page(unsigned long addr); +#define flush_tlb() tlbflush() +#define flush_tlb_all() flush_tlb() + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->mm) + flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + if (vma->vm_mm == current->mm) + tlbflush_page(addr); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + if (mm == current->mm) + flush_tlb(); +} +#endif /* !defined (__LANGUAGE_ASSEMBLY__) */ /* PMD_SHIFT determines the size of the area a second-level page table can map */ #define PMD_SHIFT 22 @@ -40,16 +139,16 @@ * physical address by a single 'and' operation and gain 6 additional * bits for storing information which isn't present in a normal * MIPS page table. - * Since the Mips has choosen some quite missleading names for the + * Since the Mips has chosen some quite misleading names for the * valid and dirty bits they're defined here but only their synonyms * will be used. */ #define _PAGE_PRESENT (1<<0) /* implemented in software */ -#define _PAGE_COW (1<<1) /* implemented in software */ -#define _PAGE_READ (1<<2) /* implemented in software */ -#define _PAGE_WRITE (1<<3) /* implemented in software */ -#define _PAGE_ACCESSED (1<<4) /* implemented in software */ -#define _PAGE_MODIFIED (1<<5) /* implemented in software */ +#define _PAGE_READ (1<<1) /* implemented in software */ +#define _PAGE_WRITE (1<<2) /* implemented in software */ +#define _PAGE_ACCESSED (1<<3) /* implemented in software */ +#define _PAGE_MODIFIED (1<<4) /* implemented in software */ +#define _PAGE_UNUSED1 (1<<5) #define _PAGE_GLOBAL (1<<6) #define _PAGE_VALID (1<<7) #define _PAGE_SILENT_READ (1<<7) /* synonym */ @@ -75,7 +174,7 @@ #define PAGE_NONE __pgprot(_PAGE_PRESENT | __READABLE | _CACHE_UNCACHED) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_WRITE | \ _PAGE_ACCESSED | _CACHE_CACHABLE_NONCOHERENT) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_COW | \ +#define PAGE_COPY __pgprot(_PAGE_PRESENT | __READABLE | \ _CACHE_CACHABLE_NONCOHERENT) #define PAGE_READONLY __pgprot(_PAGE_PRESENT | __READABLE | \ _CACHE_CACHABLE_NONCOHERENT) @@ -107,8 +206,8 @@ #if !defined (__LANGUAGE_ASSEMBLY__) -/* page table for 0-4MB for everybody */ -extern unsigned long pg0[1024]; +/* zero page used for uninitialized stuff */ +extern unsigned long empty_zero_page[1024]; /* * BAD_PAGETABLE is used when we need a bogus page-table, while @@ -124,7 +223,7 @@ extern unsigned long __zero_page(void); #define BAD_PAGETABLE __bad_pagetable() #define BAD_PAGE __bad_page() -#define ZERO_PAGE __zero_page() +#define ZERO_PAGE ((unsigned long)empty_zero_page) /* number of bits that fit into a memory pointer */ #define BITS_PER_PTR (8*sizeof(unsigned long)) @@ -133,9 +232,9 @@ extern unsigned long __zero_page(void); #define PTR_MASK (~(sizeof(void*)-1)) /* - * sizeof(void*)==1<<SIZEOF_PTR_LOG2 + * sizeof(void*) == (1 << SIZEOF_PTR_LOG2) */ -#if __mips == 3 +#ifdef 0 /* __mips64 */ #define SIZEOF_PTR_LOG2 3 #else #define SIZEOF_PTR_LOG2 2 @@ -145,18 +244,28 @@ extern unsigned long __zero_page(void); #define PAGE_PTR(address) \ ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) +extern void load_pgd(unsigned long pg_dir); + /* to set the page-dir */ #define SET_PAGE_DIR(tsk,pgdir) \ do { \ (tsk)->tss.pg_dir = ((unsigned long) (pgdir)) - PT_OFFSET; \ if ((tsk) == current) \ - invalidate(); \ + load_pgd((tsk)->tss.pg_dir); \ } while (0) -extern unsigned long high_memory; extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)]; /* + * Convert a page address to a page table pointer and vice versa. + * Due to the wiered virtual caches in the r-series we might run into + * problems with cache aliasing. We solve this problem by accessing + * the pagetables uncached. + */ +#define page_to_ptp(x) ((__typeof__(x))(((unsigned long) (x)) + (PT_OFFSET - PAGE_OFFSET))) +#define ptp_to_page(x) ((__typeof__(x))(((unsigned long) (x)) - (PT_OFFSET - PAGE_OFFSET))) + +/* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ @@ -171,29 +280,32 @@ extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) extern inline int pte_none(pte_t pte) { return !pte_val(pte); } extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } -extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; } -extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } -extern inline void pte_reuse(pte_t * ptep) + +/* + * Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +extern inline void set_pte(pte_t *ptep, pte_t pteval) { - if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(ptep)]++; + *ptep = pteval; +} + +extern inline void pte_clear(pte_t *ptep) +{ + pte_t pte; + + pte_val(pte) = 0; + set_pte(ptep, pte); } /* * Empty pgd/pmd entries point to the invalid_pte_table. */ extern inline int pmd_none(pmd_t pmd) { return (pmd_val(pmd) & PAGE_MASK) == ((unsigned long) invalid_pte_table - PAGE_OFFSET); } - -extern inline int pmd_bad(pmd_t pmd) -{ - return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || - pmd_page(pmd) > high_memory || - pmd_page(pmd) < PAGE_OFFSET; -} +extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE; } extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; } -extern inline int pmd_inuse(pmd_t *pmdp) { return 0; } -extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = ((unsigned long) invalid_pte_table - PAGE_OFFSET); } -extern inline void pmd_reuse(pmd_t * pmdp) { } +extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = ((unsigned long) invalid_pte_table - PAGE_OFFSET) | _PAGE_TABLE; } /* * The "pgd_xxx()" functions here are trivial for a folded two-level @@ -203,13 +315,7 @@ extern inline void pmd_reuse(pmd_t * pmdp) { } extern inline int pgd_none(pgd_t pgd) { return 0; } extern inline int pgd_bad(pgd_t pgd) { return 0; } extern inline int pgd_present(pgd_t pgd) { return 1; } -extern inline int pgd_inuse(pgd_t * pgdp) { return mem_map[MAP_NR(pgdp)] != 1; } extern inline void pgd_clear(pgd_t * pgdp) { } -extern inline void pgd_reuse(pgd_t * pgdp) -{ - if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(pgdp)]++; -} /* * The following only work if pte_present() is true. @@ -220,7 +326,6 @@ extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_READ; } extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -extern inline int pte_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; } extern inline pte_t pte_wrprotect(pte_t pte) { @@ -237,7 +342,6 @@ extern inline pte_t pte_exprotect(pte_t pte) } extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); return pte; } extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ|_PAGE_SILENT_WRITE); return pte; } -extern inline pte_t pte_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; } extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; @@ -277,11 +381,6 @@ extern inline pte_t pte_mkyoung(pte_t pte) } return pte; } -extern inline pte_t pte_mkcow(pte_t pte) -{ - pte_val(pte) |= _PAGE_COW; - return pte; -} /* * Conversion functions: convert a page and protection to a page entry, @@ -290,14 +389,16 @@ extern inline pte_t pte_mkcow(pte_t pte) extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) { pte_t pte; pte_val(pte) = (page - PAGE_OFFSET) | pgprot_val(pgprot); return pte; } +extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) +{ pte_t pte; pte_val(pte) = physpage | pgprot_val(pgprot); return pte; } + extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } /* to find an entry in a page-table-directory */ -extern inline pgd_t * pgd_offset(struct task_struct * tsk, unsigned long address) +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) { - return (pgd_t *) (tsk->tss.pg_dir + PT_OFFSET) + - (address >> PGDIR_SHIFT); + return mm->pgd + (address >> PGDIR_SHIFT); } /* Find an entry in the second-level page table.. */ @@ -309,40 +410,40 @@ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) /* Find an entry in the third-level page table.. */ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) { - return (pte_t *) (pmd_page(*dir) + (PT_OFFSET - PAGE_OFFSET)) + + return (pte_t *) (page_to_ptp(pmd_page(*dir))) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); } /* * Allocate and free page tables. The xxx_kernel() versions are * used to allocate a kernel page table - this turns on ASN bits - * if any, and marks the page tables reserved. + * if any. */ extern inline void pte_free_kernel(pte_t * pte) { unsigned long page = (unsigned long) pte; - mem_map[MAP_NR(pte)] = 1; if(!page) return; - page -= (PT_OFFSET - PAGE_OFFSET); - free_page(page); + /* + * Flush complete cache - we don't know the virtual address. + */ + cacheflush(0, ~0, CF_DCACHE|CF_VIRTUAL); + free_page(ptp_to_page(page)); } extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); if (pmd_none(*pmd)) { - unsigned long page = __get_free_page(GFP_KERNEL); + unsigned long page = get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (page) { - mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED; - sys_cacheflush((void *)page, PAGE_SIZE, DCACHE); + cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL); sync_mem(); - page += (PT_OFFSET - PAGE_OFFSET); - memset((void *) page, 0, PAGE_SIZE); + page = page_to_ptp(page); pmd_set(pmd, (pte_t *)page); - return ((pte_t *)page) + address; + return (pte_t *)page + address; } pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; @@ -354,7 +455,7 @@ extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; } - return (pte_t *) (pmd_page(*pmd) + (PT_OFFSET - PAGE_OFFSET)) + address; + return (pte_t *) page_to_ptp(pmd_page(*pmd)) + address; } /* @@ -376,23 +477,25 @@ extern inline void pte_free(pte_t * pte) if(!page) return; - page -= (PT_OFFSET - PAGE_OFFSET); - free_page(page); + /* + * Flush complete cache - we don't know the virtual address. + */ + cacheflush(0, ~0UL, CF_DCACHE|CF_VIRTUAL); + free_page(ptp_to_page(page)); } extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); if (pmd_none(*pmd)) { - unsigned long page = __get_free_page(GFP_KERNEL); + unsigned long page = get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (page) { - sys_cacheflush((void *)page, PAGE_SIZE, DCACHE); + cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL); sync_mem(); - page += (PT_OFFSET - PAGE_OFFSET); - memset((void *) page, 0, PAGE_SIZE); + page = page_to_ptp(page); pmd_set(pmd, (pte_t *)page); - return ((pte_t *)page) + address; + return (pte_t *)page + address; } pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; @@ -404,7 +507,7 @@ extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; } - return (pte_t *) (pmd_page(*pmd) + (PT_OFFSET - PAGE_OFFSET)) + address; + return (pte_t *) page_to_ptp(pmd_page(*pmd)) + address; } /* @@ -426,59 +529,17 @@ extern inline void pgd_free(pgd_t * pgd) if(!page) return; - page -= (PT_OFFSET - PAGE_OFFSET); - free_page(page); + /* + * Flush complete cache - we don't know the virtual address. + */ + cacheflush(0, ~0UL, CF_DCACHE|CF_VIRTUAL); + free_page(ptp_to_page(page)); } /* * Initialize new page directory with pointers to invalid ptes */ -extern inline void pgd_init(unsigned long page) -{ - unsigned long dummy1, dummy2; - - page += (PT_OFFSET - PAGE_OFFSET); -#ifdef __R4000__ - /* - * Ich will Spass - ich geb Gas ich geb Gas... - */ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "dsll32\t$1,%2,0\n\t" - "dsrl32\t%2,$1,0\n\t" - "or\t%2,$1\n" - "1:\tsd\t%2,(%0)\n\t" - "subu\t%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,8\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), - "=r" (dummy2) - :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) | - _PAGE_TABLE), - "0" (page), - "1" (PAGE_SIZE/(sizeof(pmd_t)*2)) - :"$1"); -#else - __asm__ __volatile__( - ".set\tnoreorder\n" - "1:\tsw\t%2,(%0)\n\t" - "subu\t%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,4\n\t" - ".set\treorder" - :"=r" (dummy1), - "=r" (dummy2) - :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) | - _PAGE_TABLE), - "0" (page), - "1" (PAGE_SIZE/sizeof(pmd_t))); -#endif -} +extern void (*pgd_init)(unsigned long page); extern inline pgd_t * pgd_alloc(void) { @@ -486,33 +547,37 @@ extern inline pgd_t * pgd_alloc(void) if(!(page = __get_free_page(GFP_KERNEL))) return NULL; - - sys_cacheflush((void *)page, PAGE_SIZE, DCACHE); - sync_mem(); pgd_init(page); - return (pgd_t *) (page + (PT_OFFSET - PAGE_OFFSET)); + return (pgd_t *) page_to_ptp(page); } extern pgd_t swapper_pg_dir[1024]; -/* - * MIPS doesn't need any external MMU info: the kernel page - * tables contain all the necessary information. - */ extern inline void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte) { + tlbflush_page(address); + /* + * FIXME: We should also reload a new entry into the TLB to + * avoid unnecessary exceptions. + */ } -#if __mips >= 3 +#if 0 /* defined(__mips64) */ +/* + * For true 64 bit kernel + */ #define SWP_TYPE(entry) (((entry) >> 32) & 0xff) #define SWP_OFFSET(entry) ((entry) >> 40) #define SWP_ENTRY(type,offset) pte_val(mk_swap_pte((type),(offset))) #else +/* + * Kernel with 32 bit address space + */ #define SWP_TYPE(entry) (((entry) >> 1) & 0x7f) #define SWP_OFFSET(entry) ((entry) >> 8) #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8)) diff --git a/include/asm-mips/pica.h b/include/asm-mips/pica.h deleted file mode 100644 index 799dcf4a0..000000000 --- a/include/asm-mips/pica.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Hardware info about Acer PICA 61 and similar - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1995 by Andreas Busse and Ralf Baechle - */ -#ifndef __ASM_MIPS_PICA_H -#define __ASM_MIPS_PICA_H - -/* - * The addresses below are virtual address. The mappings are - * created on startup via wired entries in the tlb. The Mips - * Magnum R3000 and R4000 machines are similar in many aspects, - * but many hardware register are accessible at 0xb9000000 in - * instead of 0xe0000000. - */ - -/* - * Revision numbers in PICA_ASIC_REVISION - * - * 0xf0000000 - Rev1 - * 0xf0000001 - Rev2 - * 0xf0000002 - Rev3 - */ -#define PICA_ASIC_REVISION 0xe0000008 - -/* - * The segments of the seven segment LED are mapped - * to the control bits as follows: - * - * (7) - * --------- - * | | - * (2) | | (6) - * | (1) | - * --------- - * | | - * (3) | | (5) - * | (4) | - * --------- . (0) - */ -#define PICA_LED 0xe000f000 - -/* - * Some characters for the LED control registers - * The original Mips machines seem to have a LED display - * with integrated decoder while the Acer machines can - * control each of the seven segments and the dot independend. - * It only a toy, anyway... - */ -#define LED_DOT 0x01 -#define LED_SPACE 0x00 -#define LED_0 0xfc -#define LED_1 0x60 -#define LED_2 0xda -#define LED_3 0xf2 -#define LED_4 0x66 -#define LED_5 0xb6 -#define LED_6 0xbe -#define LED_7 0xe0 -#define LED_8 0xfe -#define LED_9 0xf6 -#define LED_A 0xee -#define LED_b 0x3e -#define LED_C 0x9c -#define LED_d 0x7a -#define LED_E 0x9e -#define LED_F 0x8e - -#ifndef __LANGUAGE_ASSEMBLY__ - -extern __inline__ void pica_set_led(unsigned int bits) -{ - volatile unsigned int *led_register = (unsigned int *) PICA_LED; - - *led_register = bits; -} - -#endif - -/* - * i8042 keyboard controller for PICA chipset. - * This address is just a guess and seems to differ - * from the other mips machines... - */ -#define PICA_KEYBOARD_ADDRESS 0xe0005000 -#define PICA_KEYBOARD_DATA 0xe0005000 -#define PICA_KEYBOARD_COMMAND 0xe0005001 - -#ifndef __LANGUAGE_ASSEMBLY__ - -typedef struct { - unsigned char data; - unsigned char command; -} pica_keyboard_hardware; - -typedef struct { - unsigned char pad0[3]; - unsigned char data; - unsigned char pad1[3]; - unsigned char command; -} mips_keyboard_hardware; - -/* - * For now - */ -#define keyboard_hardware pica_keyboard_hardware - -#endif - -/* - * i8042 keyboard controller for most other Mips machines. - */ -#define MIPS_KEYBOARD_ADDRESS 0xb9005000 -#define MIPS_KEYBOARD_DATA 0xb9005003 -#define MIPS_KEYBOARD_COMMAND 0xb9005007 - -#ifndef __LANGUAGE_ASSEMBLY__ - -#endif - -/* - * PICA timer registers and interrupt no. - * Note that the hardware timer interrupt is actually on - * cpu level 6, but to keep compatibility with PC stuff - * it is remapped to vector 0. See arch/mips/kernel/entry.S. - */ -#define PICA_TIMER_INTERVAL 0xe0000228 -#define PICA_TIMER_REGISTER 0xe0000230 - -/* - * DRAM configuration register - */ -#ifndef __LANGUAGE_ASSEMBLY__ -#ifdef __MIPSEL__ -typedef struct { - unsigned int bank2 : 3; - unsigned int bank1 : 3; - unsigned int mem_bus_width : 1; - unsigned int reserved2 : 1; - unsigned int page_mode : 1; - unsigned int reserved1 : 23; -} dram_configuration; -#else /* defined (__MIPSEB__) */ -typedef struct { - unsigned int reserved1 : 23; - unsigned int page_mode : 1; - unsigned int reserved2 : 1; - unsigned int mem_bus_width : 1; - unsigned int bank1 : 3; - unsigned int bank2 : 3; -} dram_configuration; -#endif -#endif /* __LANGUAGE_ASSEMBLY__ */ - -#define PICA_DRAM_CONFIG 0xe00fffe0 - -/* - * PICA interrupt control registers - */ -#define PICA_IO_IRQ_SOURCE 0xe0100000 -#define PICA_IO_IRQ_ENABLE 0xe0100002 - -/* - * Pica interrupt enable bits - */ -#define PIE_PARALLEL (1<<0) -#define PIE_FLOPPY (1<<1) -#define PIE_SOUND (1<<2) -#define PIE_VIDEO (1<<3) -#define PIE_ETHERNET (1<<4) -#define PIE_SCSI (1<<5) -#define PIE_KEYBOARD (1<<6) -#define PIE_MOUSE (1<<7) -#define PIE_SERIAL1 (1<<8) -#define PIE_SERIAL2 (1<<9) - -#endif /* __ASM_MIPS_PICA_H */ diff --git a/include/asm-mips/posix_types.h b/include/asm-mips/posix_types.h new file mode 100644 index 000000000..21217ebae --- /dev/null +++ b/include/asm-mips/posix_types.h @@ -0,0 +1,117 @@ +/* + * POSIX types + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ +#ifndef __ARCH_MIPS_POSIX_TYPES_H +#define __ARCH_MIPS_POSIX_TYPES_H + +#define __need_size_t +#define __need_ptrdiff_t +#include <stddef.h> + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned long __kernel_mode_t; +typedef unsigned long __kernel_nlink_t; +typedef long __kernel_off_t; +typedef long __kernel_pid_t; +typedef long __kernel_ipc_pid_t; +typedef long __kernel_uid_t; +typedef long __kernel_gid_t; +typedef __SIZE_TYPE__ __kernel_size_t; +typedef __SSIZE_TYPE__ __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_clock_t; +typedef long __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned long __kernel_sigset_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + long val[2]; +} __kernel_fsid_t; + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + __fdsetp->fds_bits[__tmp] |= (1UL<<__rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + __fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem); +} + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set *__p) +{ + unsigned long *__tmp = __p->fds_bits; + int __i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 16: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + __tmp[ 4] = 0; __tmp[ 5] = 0; + __tmp[ 6] = 0; __tmp[ 7] = 0; + __tmp[ 8] = 0; __tmp[ 9] = 0; + __tmp[10] = 0; __tmp[11] = 0; + __tmp[12] = 0; __tmp[13] = 0; + __tmp[14] = 0; __tmp[15] = 0; + return; + + case 8: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + __tmp[ 4] = 0; __tmp[ 5] = 0; + __tmp[ 6] = 0; __tmp[ 7] = 0; + return; + + case 4: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + return; + } + } + __i = __FDSET_LONGS; + while (__i) { + __i--; + *__tmp = 0; + __tmp++; + } +} + +#endif /* __ARCH_MIPS_POSIX_TYPES_H */ diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 8e3e00267..be6d26a61 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -1,15 +1,18 @@ /* * include/asm-mips/processor.h * - * Copyright (C) 1994 Waldorf Electronics - * written by Ralf Baechle + * Copyright (C) 1994, 1995 by Waldorf Electronics + * Copyright (C) 1995, 1996 by Ralf Baechle + * Modified further for R[236]000 compatibility by Paul M. Antoine */ - #ifndef __ASM_MIPS_PROCESSOR_H #define __ASM_MIPS_PROCESSOR_H +#include <asm/sgidefs.h> + #if !defined (__LANGUAGE_ASSEMBLY__) -#include <asm/cachectl.h> +#include <asm/mipsregs.h> +#include <asm/reg.h> #include <asm/system.h> /* @@ -22,24 +25,19 @@ extern unsigned long event; /* * Bus types (default is ISA, but people can check others with these..) - * MCA_bus hardcoded to 0 for now. + * There are no Microchannel MIPS machines. * * This needs to be extended since MIPS systems are being delivered with * numerous different types of bus systems. */ extern int EISA_bus; #define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - -/* - * MIPS has no problems with write protection - */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ /* * User space process size: 2GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. + * so don't change it unless you know what you are doing. TASK_SIZE + * for a 64 bit kernel is expandable to 8192PB, of which the current MIPS + * implementations will "only" be able to use 1TB ... */ #define TASK_SIZE (0x80000000UL) @@ -78,24 +76,28 @@ struct thread_struct { /* * saved main processor registers */ - unsigned long reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; - unsigned long reg28, reg29, reg30, reg31; + __register_t reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; + __register_t reg28, reg29, reg30, reg31; /* * saved cp0 stuff */ - unsigned long cp0_status; + unsigned int cp0_status; /* * saved fpu/fpu emulator stuff */ union mips_fpu_union fpu; /* - * Other stuff associated with the process + * Other stuff associated with the thread */ - unsigned long cp0_badvaddr; + long cp0_badvaddr; unsigned long error_code; unsigned long trap_no; - unsigned long ksp; /* Top of kernel stack */ - unsigned long pg_dir; /* L1 page table pointer */ + long ksp; /* Top of kernel stack */ + long pg_dir; /* L1 page table pointer */ +#define MF_FIXADE 1 /* Fix address errors in software */ +#define MF_LOGADE 2 /* Log address errors to syslog */ + unsigned long mflags; + unsigned long segment; }; #endif /* !defined (__LANGUAGE_ASSEMBLY__) */ @@ -104,31 +106,32 @@ struct thread_struct { * If you change the #defines remember to change thread_struct above too! */ #define TOFF_REG16 0 -#define TOFF_REG17 (TOFF_REG16+4) -#define TOFF_REG18 (TOFF_REG17+4) -#define TOFF_REG19 (TOFF_REG18+4) -#define TOFF_REG20 (TOFF_REG19+4) -#define TOFF_REG21 (TOFF_REG20+4) -#define TOFF_REG22 (TOFF_REG21+4) -#define TOFF_REG23 (TOFF_REG22+4) -#define TOFF_REG28 (TOFF_REG23+4) -#define TOFF_REG29 (TOFF_REG28+4) -#define TOFF_REG30 (TOFF_REG29+4) -#define TOFF_REG31 (TOFF_REG30+4) -#define TOFF_CP0_STATUS (TOFF_REG31+4) +#define TOFF_REG17 (TOFF_REG16+SZREG) +#define TOFF_REG18 (TOFF_REG17+SZREG) +#define TOFF_REG19 (TOFF_REG18+SZREG) +#define TOFF_REG20 (TOFF_REG19+SZREG) +#define TOFF_REG21 (TOFF_REG20+SZREG) +#define TOFF_REG22 (TOFF_REG21+SZREG) +#define TOFF_REG23 (TOFF_REG22+SZREG) +#define TOFF_REG28 (TOFF_REG23+SZREG) +#define TOFF_REG29 (TOFF_REG28+SZREG) +#define TOFF_REG30 (TOFF_REG29+SZREG) +#define TOFF_REG31 (TOFF_REG30+SZREG) +#define TOFF_CP0_STATUS (TOFF_REG31+SZREG) /* * Pad for 8 byte boundary! */ -#define TOFF_FPU (((TOFF_CP0_STATUS+4)+(8-1))&~(8-1)) +#define TOFF_FPU (((TOFF_CP0_STATUS+SZREG)+(8-1))&~(8-1)) #define TOFF_CP0_BADVADDR (TOFF_FPU+264) #define TOFF_ERROR_CODE (TOFF_CP0_BADVADDR+4) #define TOFF_TRAP_NO (TOFF_ERROR_CODE+4) #define TOFF_KSP (TOFF_TRAP_NO+4) #define TOFF_PG_DIR (TOFF_KSP+4) +#define TOFF_MFLAGS (TOFF_PG_DIR+4) +#define TOFF_EX (TOFF_PG_MFLAGS+4) -#if !defined (__LANGUAGE_ASSEMBLY__) - -#define INIT_MMAP { &init_task, 0, 0x40000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } +#define INIT_MMAP { &init_mm, KSEG0, KSEG1, PAGE_SHARED, \ + VM_READ | VM_WRITE | VM_EXEC } #define INIT_TSS { \ /* \ @@ -145,54 +148,73 @@ struct thread_struct { */ \ INIT_FPU, \ /* \ - * Other stuff associated with the process\ + * Other stuff associated with the process \ */ \ 0, 0, 0, sizeof(init_kernel_stack) + (unsigned long)init_kernel_stack - 8, \ - (unsigned long) swapper_pg_dir - PT_OFFSET \ + (unsigned long) swapper_pg_dir - PT_OFFSET, \ + /* \ + * For now the default is to fix address errors \ + */ \ + MF_FIXADE, \ + KERNEL_DS \ } /* - * Do necessary setup to start up a newly executed thread. + * Paul, please check if 4kb stack are sufficient for the R3000. With 4kb + * I never had a stack overflows on 32 bit R4000 kernels but the almost + * completly 64bit R4000 kernels from 1.3.63 on need more stack even in + * trivial situations. */ -static __inline__ -void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) -{ - sys_cacheflush(0, ~0, BCACHE); - sync_mem(); - regs->cp0_epc = pc; - /* - * New thread looses kernel priviledges - */ - regs->cp0_status = (regs->cp0_status & ~ST0_KSU) | KSU_USER; - regs->reg29 = sp; -} +#define KERNEL_STACK_SIZE 8192 -#ifdef __KERNEL__ +#if !defined (__LANGUAGE_ASSEMBLY__) +extern unsigned long alloc_kernel_stack(void); +extern void free_kernel_stack(unsigned long stack); /* - * switch_to(n) should switch tasks to task nr n, first - * checking that n isn't the current task, in which case it does nothing. + * Return saved PC of a blocked thread. */ -asmlinkage void resume(struct task_struct *tsk, int offset); +extern unsigned long (*thread_saved_pc)(struct thread_struct *t); -#define switch_to(n) \ - resume(n, ((int)(&((struct task_struct *)0)->tss))) +/* + * Do necessary setup to start up a newly executed thread. + */ +extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); /* * Does the process account for user or for system time? */ -#if defined (__R4000__) - -#define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x18)) - -#else /* !defined (__R4000__) */ - +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) #define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x4)) +#endif +#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS5) +#define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x18)) +#endif -#endif /* !defined (__R4000__) */ - -#endif /* __KERNEL__ */ - +/* + * Return_address is a replacement for __builtin_return_address(count) + * which on certain architectures cannot reasonably be implemented in GCC + * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * Note that __builtin_return_address(x>=1) is forbidden because GCC + * aborts compilation on some CPUs. It's simply not possible to unwind + * some CPU's stackframes. + */ +#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) +/* + * __builtin_return_address works only for non-leaf functions. We avoid the + * overhead of a function call by forcing the compiler to save the return + * address register on the stack. + */ +#define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);}) +#else +/* + * __builtin_return_address is not implemented at all. Calling it + * will return senseless values. Return NULL which at least is an obviously + * senseless value. + */ +#define return_address() NULL +#endif #endif /* !defined (__LANGUAGE_ASSEMBLY__) */ #endif /* __ASM_MIPS_PROCESSOR_H */ diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index 18cdb8387..ade150d90 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h @@ -5,8 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995 by Waldorf GMBH - * written by Ralf Baechle + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle * * Machine dependent structs and defines to help the user use * the ptrace system call. @@ -14,101 +13,72 @@ #ifndef __ASM_MIPS_PTRACE_H #define __ASM_MIPS_PTRACE_H +#include <asm/sgidefs.h> +#include <asm/register.h> + /* - * This defines/structures correspond to the register layout on stack - - * if the order here is changed, it needs to be updated in - * include/asm-mips/stackframe.h - */ -#define IN_REG1 5 -#define IN_REG2 6 -#define IN_REG3 7 -#define IN_REG4 8 -#define IN_REG5 9 -#define IN_REG6 10 -#define IN_REG7 11 -#define IN_REG8 12 -#define IN_REG9 13 -#define IN_REG10 14 -#define IN_REG11 15 -#define IN_REG12 16 -#define IN_REG13 17 -#define IN_REG14 18 -#define IN_REG15 19 -#define IN_REG16 20 -#define IN_REG17 21 -#define IN_REG18 22 -#define IN_REG19 23 -#define IN_REG20 24 -#define IN_REG21 25 -#define IN_REG22 26 -#define IN_REG23 27 -#define IN_REG24 28 -#define IN_REG25 29 -/* - * k0/k1 unsaved + * General purpose registers. */ -#define IN_REG28 30 -#define IN_REG29 31 -#define IN_REG30 32 -#define IN_REG31 33 +#define GPR_BASE 0 +#define NGP_REGS 32 /* - * Saved special registers + * Floating point registers. */ -#define IN_LO 34 -#define IN_HI 35 +#define FPR_BASE (GPR_BASE + NGP_REGS) +#define NFP_REGS 32 /* - * saved cp0 registers + * Signal handlers */ -#define IN_CP0_STATUS 36 -#define IN_CP0_EPC 37 -#define IN_CP0_CAUSE 38 +#define SIG_BASE (FPR_BASE + NFP_REGS) +#define NSIG_HNDLRS 32 /* - * Some goodies + * Special registers. */ -#define IN_INTERRUPT 39 -#define IN_ORIG_REG2 40 +#define SPEC_BASE (SIG_BASE + NSIG_HNDLRS) +#define NSPEC_REGS 7 +#define PC SPEC_BASE +#define CAUSE (PC + 1) +#define BADVADDR (CAUSE + 1) +#define MMHI (BADVADDR + 1) +#define MMLO (MMHI + 1) +#define FPC_CSR (MMLO + 1) +#define FPC_EIR (FPC_CSR + 1) +#define NPTRC_REGS (FPC_EIR + 1) /* * This struct defines the way the registers are stored on the stack during a - * system call/exception. As usual the registers k0/k1 aren't being saved. + * system call/exception. As usual the registers zero/k0/k1 aren't being saved. */ struct pt_regs { /* * Pad bytes for argument save space on the stack * 20/40 Bytes for 32/64 bit code */ - unsigned long pad0[5]; + __register_t pad0[6]; /* extra word for alignment */ /* - * saved main processor registers + * Saved main processor registers */ - long reg1, reg2, reg3, reg4, reg5, reg6, reg7; - long reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15; - long reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; - long reg24, reg25, reg28, reg29, reg30, reg31; + __register_t regs[32]; /* - * Saved special registers + * Other saved registers */ - long lo; - long hi; + __register_t lo; + __register_t hi; + __register_t orig_reg2; + __register_t orig_reg7; /* * saved cp0 registers */ - unsigned long cp0_status; - unsigned long cp0_epc; - unsigned long cp0_cause; - - /* - * Some goodies... - */ - unsigned long interrupt; - long orig_reg2; - long pad1; + __register_t cp0_epc; + __register_t cp0_badvaddr; + unsigned int cp0_status; + unsigned int cp0_cause; }; #ifdef __KERNEL__ @@ -116,16 +86,15 @@ struct pt_regs { /* * Does the process account for user or for system time? */ -#if defined (__R4000__) - -#define user_mode(regs) ((regs)->cp0_status & 0x10) - -#else /* !defined (__R4000__) */ - +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) #define user_mode(regs) (!((regs)->cp0_status & 0x8)) +#endif +#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS5) +#define user_mode(regs) ((regs)->cp0_status & 0x10) +#endif -#endif /* !defined (__R4000__) */ - +#define instruction_pointer(regs) ((regs)->cp0_epc) extern void show_regs(struct pt_regs *); #endif diff --git a/include/asm-mips/reg.h b/include/asm-mips/reg.h new file mode 100644 index 000000000..196a1a133 --- /dev/null +++ b/include/asm-mips/reg.h @@ -0,0 +1,81 @@ +/* + * Makefile for MIPS Linux main source directory + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + */ +#ifndef __ASM_MIPS_REG_H +#define __ASM_MIPS_REG_H + +/* + * This defines/structures correspond to the register layout on stack - + * if the order here is changed, it needs to be updated in + * include/asm-mips/stackframe.h + */ +#define EF_REG1 5 +#define EF_REG2 6 +#define EF_REG3 7 +#define EF_REG4 8 +#define EF_REG5 9 +#define EF_REG6 10 +#define EF_REG7 11 +#define EF_REG8 12 +#define EF_REG9 13 +#define EF_REG10 14 +#define EF_REG11 15 +#define EF_REG12 16 +#define EF_REG13 17 +#define EF_REG14 18 +#define EF_REG15 19 +#define EF_REG16 20 +#define EF_REG17 21 +#define EF_REG18 22 +#define EF_REG19 23 +#define EF_REG20 24 +#define EF_REG21 25 +#define EF_REG22 26 +#define EF_REG23 27 +#define EF_REG24 28 +#define EF_REG25 29 +/* + * k0/k1 unsaved + */ +#define EF_REG28 30 +#define EF_REG29 31 +#define EF_REG30 32 +#define EF_REG31 33 + +/* + * Saved special registers + */ +#define EF_LO 34 +#define EF_HI 35 +#define EF_ORIG_REG2 36 + +#if 0 +/* + * saved cp0 registers + */ +#define EF_CP0_EPC 37 +#define EF_CP0_STATUS 36 +#define EF_CP0_CAUSE 38 +#endif + +#ifdef __mips64 +#define EF_SIZE 304 +#else +#define EF_SIZE 160 +#endif + +#if 0 +/* + * Map register number into core file offset. + */ +#define CORE_REG(reg, ubase) \ + (((unsigned long *)((unsigned long)(ubase)))[reg]) +#endif + +#endif /* __ASM_MIPS_REG_H */ diff --git a/include/asm-mips/regdef.h b/include/asm-mips/regdef.h index ec455790e..691d047b6 100644 --- a/include/asm-mips/regdef.h +++ b/include/asm-mips/regdef.h @@ -12,7 +12,7 @@ #define __ASM_MIPS_REGDEF_H /* - * Symbolic register names + * Symbolic register names for 32 bit ABI */ #define zero $0 /* wired zero */ #define AT $1 /* assembler temp - uppercase because of ".set at" */ @@ -40,11 +40,13 @@ #define s7 $23 #define t8 $24 /* caller saved */ #define t9 $25 +#define jp $25 /* PIC jump register */ #define k0 $26 /* kernel scratch */ #define k1 $27 #define gp $28 /* global pointer */ #define sp $29 /* stack pointer */ #define fp $30 /* frame pointer */ +#define s8 $30 /* same like fp! */ #define ra $31 /* return address */ #endif /* __ASM_MIPS_REGDEF_H */ diff --git a/include/asm-mips/register.h b/include/asm-mips/register.h new file mode 100644 index 000000000..9a19187e0 --- /dev/null +++ b/include/asm-mips/register.h @@ -0,0 +1,34 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_REGISTER_H +#define __ASM_MIPS_REGISTER_H + +/* + * Types to represent a register + */ +#ifdef __mips64 +/* + * The R4000 port makes use of the 64 bit wide registers + */ +#ifndef __LANGUAGE_ASSEMBLY__ +typedef long long __register_t; +typedef unsigned long long __uregister_t; +#endif + +#else + +/* + * Good 'ole R3000 has only 32 bit wide registers + */ +#ifndef __LANGUAGE_ASSEMBLY__ +typedef long __register_t; +typedef unsigned long __uregister_t; +#endif +#endif + +#endif /* __ASM_MIPS_REGISTER_H */ diff --git a/include/asm-mips/resource.h b/include/asm-mips/resource.h index 001f92435..16c83544d 100644 --- a/include/asm-mips/resource.h +++ b/include/asm-mips/resource.h @@ -1,25 +1,47 @@ +/* + * Process resource limits + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996 by Ralf Baechle + */ #ifndef __ASM_MIPS_RESOURCE_H #define __ASM_MIPS_RESOURCE_H /* * Resource limits */ +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_NOFILE 5 /* max number of open files */ +#define RLIMIT_AS 6 /* mapped memory */ +#define RLIMIT_RSS 7 /* max resident set size */ +#define RLIMIT_NPROC 8 /* max number of processes */ +#define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */ + +#define RLIM_NLIMITS 10 /* Number of limit flavors. */ -#define RLIMIT_CPU 0 /* CPU time in ms */ -#define RLIMIT_FSIZE 1 /* Maximum filesize */ -#define RLIMIT_DATA 2 /* max data size */ -#define RLIMIT_STACK 3 /* max stack size */ -#define RLIMIT_CORE 4 /* max core file size */ -#define RLIMIT_NOFILE 5 /* max number of open files */ -#define RLIMIT_VMEM 6 /* mapped memory */ -#define RLIMIT_AS RLIMIT_VMEM -#define RLIMIT_RSS 7 /* max resident set size */ -#define RLIMIT_NPROC 8 /* max number of processes */ +#ifdef __KERNEL__ -#ifdef notdef -#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space*/ -#endif +#define INIT_RLIMITS \ +{ \ + {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, \ + {_STK_LIM, _STK_LIM}, \ + { 0, LONG_MAX}, \ + {NR_OPEN, NR_OPEN}, \ + {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, \ + {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, \ + { LONG_MAX, LONG_MAX }, \ +} -#define RLIM_NLIMITS 9 +#endif /* __KERNEL__ */ #endif /* __ASM_MIPS_RESOURCE_H */ diff --git a/include/asm-mips/segment.h b/include/asm-mips/segment.h index 73c0de45f..c6a684e8d 100644 --- a/include/asm-mips/segment.h +++ b/include/asm-mips/segment.h @@ -1,197 +1,6 @@ -/* - * include/asm-mips/segment.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1994, 1995 by Ralf Baechle - * - */ -#ifndef __ASM_MIPS_SEGMENT_H -#define __ASM_MIPS_SEGMENT_H +#ifndef __MIPS_SEGMENT_H +#define __MIPS_SEGMENT_H -#ifndef __LANGUAGE_ASSEMBLY__ -/* - * Uh, these should become the main single-value transfer routines.. - * They automatically use the right size if we just have the right - * pointer type.. - */ -#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))) -#define get_user(ptr) __get_user((ptr),sizeof(*(ptr))) +/* Only here because we have some old header files that expect it.. */ -/* - * This is a silly but good way to make sure that - * the __put_user function is indeed always optimized, - * and that we use the correct sizes.. - */ -extern int bad_user_access_length(void); - -/* I should make this use unaligned transfers etc.. */ -static inline void __put_user(unsigned long x, void * y, int size) -{ - switch (size) { - case 1: - *(char *) y = x; - break; - case 2: - *(short *) y = x; - break; - case 4: - *(int *) y = x; - break; - case 8: - *(long *) y = x; - break; - default: - bad_user_access_length(); - } -} - -/* I should make this use unaligned transfers etc.. */ -static inline unsigned long __get_user(void * y, int size) -{ - switch (size) { - case 1: - return *(unsigned char *) y; - case 2: - return *(unsigned short *) y; - case 4: - return *(unsigned int *) y; - case 8: - return *(unsigned long *) y; - default: - return bad_user_access_length(); - } -} -#endif /* __LANGUAGE_ASSEMBLY__ */ - -/* - * Memory segments (32bit kernel mode addresses) - */ -#define KUSEG 0x00000000 -#define KSEG0 0x80000000 -#define KSEG1 0xa0000000 -#define KSEG2 0xc0000000 -#define KSEG3 0xe0000000 - -/* - * Returns the kernel segment base of a given address - */ -#define KSEGX(a) (a & 0xe0000000) - -/* - * Returns the physical address of a KSEG0/KSEG1 address - */ - -#define PHYSADDR(a) ((unsigned long)a & 0x1fffffff) - -/* - * Map an address to a certain kernel segment - */ - -#define KSEG0ADDR(a) (((unsigned long)a & 0x1fffffff) | KSEG0) -#define KSEG1ADDR(a) (((unsigned long)a & 0x1fffffff) | KSEG1) -#define KSEG2ADDR(a) (((unsigned long)a & 0x1fffffff) | KSEG2) -#define KSEG3ADDR(a) (((unsigned long)a & 0x1fffffff) | KSEG3) - - -/* - * Memory segments (64bit kernel mode addresses) - */ -#define XKUSEG 0x0000 0000 0000 0000 -#define XKSSEG 0x4000 0000 0000 0000 -#define XKPHYS 0x8000 0000 0000 0000 -#define XKSEG 0xc000 0000 0000 0000 -#define CKSEG0 0xffff ffff 8000 0000 -#define CKSEG1 0xffff ffff a000 0000 -#define CKSSEG 0xffff ffff c000 0000 -#define CKSEG3 0xffff ffff e000 0000 - -#ifndef __LANGUAGE_ASSEMBLY__ -/* - * These are deprecated - */ - -#define get_fs_byte(addr) get_user_byte((char *)(addr)) -static inline unsigned char get_user_byte(const char *addr) -{ - return *addr; -} - -/* - * Beware: the xxx_fs_word functions work on 16bit words! - */ -#define get_fs_word(addr) get_user_word((short *)(addr)) -static inline unsigned short get_user_word(const short *addr) -{ - return *addr; -} - -#define get_fs_long(addr) get_user_long((int *)(addr)) -static inline unsigned long get_user_long(const int *addr) -{ - return *addr; -} - -#define get_fs_dlong(addr) get_user_dlong((long long *)(addr)) -static inline unsigned long get_user_dlong(const long long *addr) -{ - return *addr; -} - -#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) -static inline void put_user_byte(char val,char *addr) -{ - *addr = val; -} - -#define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) -static inline void put_user_word(short val,short * addr) -{ - *addr = val; -} - -#define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) -static inline void put_user_long(unsigned long val,int * addr) -{ - *addr = val; -} - -#define put_fs_dlong(x,addr) put_user_dlong((x),(int *)(addr)) -static inline void put_user_dlong(unsigned long val,long long * addr) -{ - *addr = val; -} - -#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n)) - -#define memcpy_tofs(to, from, n) memcpy((to),(from),(n)) - -/* - * For segmented architectures, these are used to specify which segment - * to use for the above functions. - * - * MIPS is not segmented, so these are just dummies. - */ - -#define KERNEL_DS 0 -#define USER_DS 1 - -static inline unsigned long get_fs(void) -{ - return 0; -} - -static inline unsigned long get_ds(void) -{ - return 0; -} - -static inline void set_fs(unsigned long val) -{ -} - -#endif /* !__LANGUAGE_ASSEMBLY__ */ - -#endif /* __ASM_MIPS_SEGMENT_H */ +#endif /* __MIPS_SEGMENT_H */ diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h new file mode 100644 index 000000000..f093fe519 --- /dev/null +++ b/include/asm-mips/semaphore.h @@ -0,0 +1,46 @@ +/* + * SMP- and interrupt-safe semaphores.. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * (C) Copyright 1996 Linus Torvalds, Ralf Baechle + */ +#ifndef __ASM_MIPS_SEMAPHORE_H +#define __ASM_MIPS_SEMAPHORE_H + +#include <asm/atomic.h> + +struct semaphore { + atomic_t count; + atomic_t waiting; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { 1, 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) + +extern void __down(struct semaphore * sem); +extern void __up(struct semaphore * sem); + +extern inline void down(struct semaphore * sem) +{ + while (1) { + if (atomic_dec_return(&sem->count) >= 0) + break; + __down(sem); + } +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + */ +extern inline void up(struct semaphore * sem) +{ + if (atomic_inc_return(&sem->count) <= 0) + __up(sem); +} + +#endif /* __ASM_MIPS_SEMAPHORE_H */ diff --git a/include/asm-mips/sgidefs.h b/include/asm-mips/sgidefs.h new file mode 100644 index 000000000..23dc0447f --- /dev/null +++ b/include/asm-mips/sgidefs.h @@ -0,0 +1,82 @@ +/* + * Makefile for MIPS Linux main source directory + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + * + * Definitions commonly used in SGI style code. + */ +#ifndef __ASM_SGIDEFS_H +#define __ASM_SGIDEFS_H + +/* + * There are compilers out there that don't define _MIPS_ISA, _MIPS_SIM, + * _MIPS_SZINT, _MIPS_SZLONG, _MIPS_SZPTR. So we notify the user about this + * problem. The kernel sources are aware of this problem, so we don't warn + * when compiling the kernel. + */ +#if (!defined(_MIPS_ISA) || \ + !defined(_MIPS_SIM) || \ + !defined(_MIPS_SZINT) || \ + !defined(_MIPS_SZLONG) || \ + !defined(_MIPS_SZPTR)) && !defined(__KERNEL__) +#warning "Please update your GCC to GCC 2.7.2-3 or newer" +#endif + +/* + * Now lets try our best to supply some reasonable default values for + * whatever defines GCC didn't supply. This cannot be done correct for + * all possible combinations of options, so be careful with your options + * to GCC. Best bet is to keep your fingers off the a.out GCC and use + * ELF GCC 2.7.2-3 where possible. + */ +#ifndef _MIPS_ISA +#if __mips == 1 +#define _MIPS_ISA _MIPS_ISA_MIPS1 +/* It is impossible to handle the -mips2 case correct. */ +#elif __mips == 3 +#define _MIPS_ISA _MIPS_ISA_MIPS3 +#elif __mips == 4 +#define _MIPS_ISA _MIPS_ISA_MIPS4 +#else /* __mips must be 5 */ +#define _MIPS_ISA _MIPS_ISA_MIPS5 +#endif +#endif +#ifndef _MIPS_SIM +#define _MIPS_SIM _MIPS_SIM_ABI32 +#endif +#ifndef _MIPS_SZINT +#define _MIPS_SZINT 32 +#endif +#ifndef _MIPS_SZLONG +#define _MIPS_SZLONG 32 +#endif +#ifndef _MIPS_SZPTR +#define _MIPS_SZPTR 32 +#endif + +/* + * Definitions for the ISA level + */ +#define _MIPS_ISA_MIPS1 1 +#define _MIPS_ISA_MIPS2 2 +#define _MIPS_ISA_MIPS3 3 +#define _MIPS_ISA_MIPS4 4 +#define _MIPS_ISA_MIPS5 5 + +/* + * Subprogram calling convention + * + * At the moment only _MIPS_SIM_ABI32 is in use. This will change rsn. + * Until GCC 2.8.0 is released don't rely on this definitions because the + * 64bit code is essentially using the 32bit interface model just with + * 64bit registers. + */ +#define _MIPS_SIM_ABI32 1 +#define _MIPS_SIM_NABI32 2 +#define _MIPS_SIM_ABI64 3 + +#endif /* __ASM_SGIDEFS_H */ diff --git a/include/asm-mips/shmparam.h b/include/asm-mips/shmparam.h new file mode 100644 index 000000000..9c5a38a40 --- /dev/null +++ b/include/asm-mips/shmparam.h @@ -0,0 +1,47 @@ +#ifndef __ASM_MIPS_SHMPARAM_H +#define __ASM_MIPS_SHMPARAM_H + +/* address range for shared memory attaches if no address passed to shmat() */ +#define SHM_RANGE_START 0x50000000 +#define SHM_RANGE_END 0x60000000 + +/* + * Format of a swap-entry for shared memory pages currently out in + * swap space (see also mm/swap.c). + * + * SWP_TYPE = SHM_SWP_TYPE + * SWP_OFFSET is used as follows: + * + * bits 0..6 : id of shared memory segment page belongs to (SHM_ID) + * bits 7..21: index of page within shared memory segment (SHM_IDX) + * (actually fewer bits get used since SHMMAX is so low) + */ + +/* + * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and + * there is a static array of size SHMMNI. + */ +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +/* + * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and + * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). + */ + +#define SHMMAX 0x1000000 /* max shared seg size (bytes) */ +#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ +#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ +#define SHMALL /* max shm system wide (pages) */ \ + (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) +/* + * This constant is very large but the ABI in its wisdom says ... + */ +#define SHMLBA 0x40000 /* attach addr a multiple of this */ +#define SHMSEG SHMMNI /* max shared segs per process */ + +#endif /* __ASM_MIPS_SHMPARAM_H */ diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h new file mode 100644 index 000000000..135d83df6 --- /dev/null +++ b/include/asm-mips/sigcontext.h @@ -0,0 +1,48 @@ +#ifndef __ASM_MIPS_SIGCONTEXT_H +#define __ASM_MIPS_SIGCONTEXT_H + +#ifdef __LANGUAGE_ASSEMBLY__ + +#define SC_REGMASK 0 +#define SC_STATUS 4 +#define SC_PC 8 +#define SC_REGS 16 +#define SC_FPREGS 272 +#define SC_OWNEDFP 528 +#define SC_FPC_CSR 532 +#define SC_FPC_EIR 536 +#define SC_SSFLAGS 540 +#define SC_MDHI 544 +#define SC_MDLO 552 + +#endif + +#if defined(__LANGUAGE_C__) || \ + defined(__LANGUAGE_C_PLUS_PLUS__) || \ + defined(__LANGUAGE_OBJECTIVE_C__) + +/* + * Whenever this structure is changed you must update the offsets in + * arch/mips/mips<isa>/fp-context.S. + */ +struct sigcontext { + unsigned int sc_regmask; /* Unused */ + unsigned int sc_status; + unsigned long long sc_pc; + unsigned long long sc_regs[32]; + unsigned long long sc_fpregs[32]; /* Unused */ + unsigned int sc_ownedfp; + unsigned int sc_fpc_csr; /* Unused */ + unsigned int sc_fpc_eir; /* Unused */ + unsigned int sc_ssflags; /* Unused */ + unsigned long long sc_mdhi; + unsigned long long sc_mdlo; + + unsigned int sc_cause; /* Unused */ + unsigned int sc_badvaddr; /* Unused */ + + sigset_t sc_sigset; +}; +#endif + +#endif /* __ASM_MIPS_SIGCONTEXT_H */ diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h index 998d95c14..ced9ee9e3 100644 --- a/include/asm-mips/signal.h +++ b/include/asm-mips/signal.h @@ -1,63 +1,89 @@ +/* + * Linux/MIPS specific definitions for signals. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996 by Ralf Baechle + */ #ifndef __ASM_MIPS_SIGNAL_H -#define __ASM_MIPS_SIGNAL_H -#if 0 -/* The Linux/i386 definition */ -typedef unsigned long sigset_t; /* at least 32 bits */ +#include <asm/sgidefs.h> + +/* Any one of these symbols __need_* means that GNU libc + wants us just to define one data type. So don't define + the symbols that indicate this file's entire job has been done. */ +#if !defined(__need_signums) && !defined(__need_fake_sigfuns) && \ + !defined(__need__nsig) +#define __ASM_MIPS_SIGNAL_H #endif -#if 1 -/* For now ... */ -#include <asm/types.h> -typedef __u64 sigset_t; -#else -/* This is what we should really use ... */ +#ifdef __ASM_MIPS_SIGNAL_H +/* + * This is what we should really use but the kernel can't handle + * a non-scalar type yet. Since we use 64 signals only anyway we + * just use __u64 and pad another 64 bits in the kernel for now ... + */ typedef struct { - unsigned int sigbits[4]; + unsigned int __sigbits[4]; } sigset_t; -#endif +#endif /* __ASM_MIPS_SIGNAL_H */ +#if !defined (___nsig_defined) && \ + (defined (__ASM_MIPS_SIGNAL_H) || defined (__need__nsig)) +#define ___nsig_defined #define _NSIG 65 +#endif +#undef __need__nsig +#ifdef __KERNEL__ #define NSIG _NSIG +#endif +#if !defined (__signums_defined) && \ + (defined (__ASM_MIPS_SIGNAL_H) || defined (__need_signums)) +#define __signums_defined /* * For 1.3.0 Linux/MIPS changed the signal numbers to be compatible the ABI. */ -#define SIGHUP 1 -#define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGIOT 6 -#define SIGABRT SIGIOT +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define SIGABRT SIGIOT /* Abort (ANSI). */ #define SIGEMT 7 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGBUS 10 -#define SIGSEGV 11 +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGBUS 10 /* BUS error (4.2 BSD). */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ #define SIGSYS 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGTERM 15 -#define SIGUSR1 16 -#define SIGUSR2 17 -#define SIGCHLD 18 -#define SIGCLD SIGCHLD -#define SIGPWR 19 -#define SIGWINCH 20 -#define SIGURG 21 -#define SIGIO 22 -#define SIGPOLL SIGIO -#define SIGSTOP 23 -#define SIGTSTP 24 -#define SIGCONT 25 -#define SIGTTIN 26 -#define SIGTTOU 27 -#define SIGVTALRM 28 -#define SIGPROF 29 -#define SIGXCPU 30 -#define SIGXFSZ 31 +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */ +#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */ +#define SIGCHLD 18 /* Child status has changed (POSIX). */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGPWR 19 /* Power failure restart (System V). */ +#define SIGWINCH 20 /* Window size change (4.3 BSD, Sun). */ +#define SIGURG 21 /* Urgent condition on socket (4.2 BSD). */ +#define SIGIO 22 /* I/O now possible (4.2 BSD). */ +#define SIGPOLL SIGIO /* Pollable event occurred (System V). */ +#define SIGSTOP 23 /* Stop, unblockable (POSIX). */ +#define SIGTSTP 24 /* Keyboard stop (POSIX). */ +#define SIGCONT 25 /* Continue (POSIX). */ +#define SIGTTIN 26 /* Background read from tty (POSIX). */ +#define SIGTTOU 27 /* Background write to tty (POSIX). */ +#define SIGVTALRM 28 /* Virtual alarm clock (4.2 BSD). */ +#define SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */ +#define SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */ +#define SIGXFSZ 31 /* File size limit exceeded (4.2 BSD). */ +#endif /* need signums */ +#undef __need_signums +#ifdef __ASM_MIPS_SIGNAL_H /* * sa_flags values: SA_STACK is not currently supported, but will allow the * usage of signal stacks by using the (now obsolete) sa_restorer field in @@ -65,6 +91,7 @@ typedef struct { * the changes in signal handling. LBT 010493. * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. */ #define SA_STACK 0x1 #define SA_ONSTACK SA_STACK @@ -74,51 +101,124 @@ typedef struct { #define SA_INTERRUPT 0x01000000 #define SA_NOMASK 0x02000000 #define SA_ONESHOT 0x04000000 +#define SA_SHIRQ 0x08000000 + +#ifdef __KERNEL__ +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#endif /* __KERNEL__ */ -#define SIG_BLOCK 1 /* for blocking signals */ -#define SIG_UNBLOCK 2 /* for unblocking signals */ -#define SIG_SETMASK 3 /* for setting the signal mask */ +#define SIG_BLOCK 1 /* for blocking signals */ +#define SIG_UNBLOCK 2 /* for unblocking signals */ +#define SIG_SETMASK 3 /* for setting the signal mask */ +#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility: + set only the low 32 bit of the sigset. */ +#ifndef __sighandler_t_defined +#define __sighandler_t_defined /* Type of a signal handler. */ typedef void (*__sighandler_t)(int); +#endif +#endif +#if !defined (__fake_sigfuns_defined) && \ + (defined (__ASM_MIPS_SIGNAL_H) || defined (__need_fake_sigfuns)) +#define __fake_sigfuns_defined +/* Fake signal functions */ #define SIG_DFL ((__sighandler_t)0) /* default signal handling */ #define SIG_IGN ((__sighandler_t)1) /* ignore signal */ #define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ +#endif +#undef __need_fake_sigfuns +#ifdef __ASM_MIPS_SIGNAL_H struct sigaction { unsigned int sa_flags; __sighandler_t sa_handler; sigset_t sa_mask; + + /* Abi says here follows reserved int[2] */ void (*sa_restorer)(void); -#if __mips <= 3 +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) /* * For 32 bit code we have to pad struct sigaction to get * constant size for the ABI */ - int pad0[2]; /* reserved */ + int pad0[1]; /* reserved */ #endif }; #ifdef __KERNEL__ +#include <asm/sigcontext.h> +/* + * This type is used by the kernel internal for it's sigsets. + */ +typedef unsigned long k_sigset_t; + +extern __inline__ k_sigset_t * +to_k_sigset_t(sigset_t *set) +{ + return (k_sigset_t *) set->__sigbits; +} + +#define copy_sigbits32(set, bits) ((set)->__sigbits[0] = (bits)) + +/* + * Clear a userland sigset_t. + */ +extern __inline__ void +u_sigemptyset (sigset_t *set) +{ + set->__sigbits[0] = set->__sigbits[1] = + set->__sigbits[2] = set->__sigbits[3] = 0; +} /* - * This struct isn't in the ABI, so we continue to use the old - * pre 1.3 definition. Needs to be changed for 64 bit kernels, - * but it's 4am ... + * Add/delete sigbits from a k_sigset_t. */ -struct sigcontext_struct { - unsigned long sc_at, sc_v0, sc_v1, sc_a0, sc_a1, sc_a2, sc_a3; - unsigned long sc_t0, sc_t1, sc_t2, sc_t3, sc_t4, sc_t5, sc_t6, sc_t7; - unsigned long sc_s0, sc_s1, sc_s2, sc_s3, sc_s4, sc_s5, sc_s6, sc_s7; - unsigned long sc_t8, sc_t9, sc_gp, sc_sp, sc_fp, sc_ra; +#define __KSSMASK(nr) (1 << ((nr) - 1)) - unsigned long sc_epc; - unsigned long sc_cause; +extern __inline__ void +k_sigaddset (k_sigset_t *set, int sig) +{ + *set |= __KSSMASK (sig); +} - unsigned long oldmask; -}; +extern __inline__ void +k_sigdelset (k_sigset_t *set, int sig) +{ + *set &= ~__KSSMASK (sig); +} -#endif +#endif /* __KERNEL__ */ -#endif /* __ASM_MIPS_SIGNAL_H */ +#if defined (__KERNEL__) || defined (__USE_MISC) +/* + * The following break codes are or were in use for specific purposes in + * other MIPS operating systems. Linux/MIPS doesn't use all of them. The + * unused ones are here as placeholders; we might encounter them in + * non-Linux/MIPS object files or make use of them in the future. + */ +#define BRK_USERBP 0 /* User bp (used by debuggers) */ +#define BRK_KERNELBP 1 /* Break in the kernel */ +#define BRK_ABORT 2 /* Sometimes used by abort(3) to SIGIOT */ +#define BRK_BD_TAKEN 3 /* For bd slot emulation - not implemented */ +#define BRK_BD_NOTTAKEN 4 /* For bd slot emulation - not implemented */ +#define BRK_SSTEPBP 5 /* User bp (used by debuggers) */ +#define BRK_OVERFLOW 6 /* Overflow check */ +#define BRK_DIVZERO 7 /* Divide by zero check */ +#define BRK_RANGE 8 /* Range error check */ +#define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */ +#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */ +#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ +#define BRK_MULOVF 1023 /* Multiply overflow */ +#endif /* defined (__KERNEL__) || defined (__USE_MISC) */ +#endif /* defined (__ASM_MIPS_SIGNAL_H) */ + +#endif /* !defined (__ASM_MIPS_SIGNAL_H) */ diff --git a/include/asm-mips/slots.h b/include/asm-mips/slots.h index 4b9eb358c..387802333 100644 --- a/include/asm-mips/slots.h +++ b/include/asm-mips/slots.h @@ -7,11 +7,17 @@ #ifndef __ASM_MIPS_SLOTS_H #define __ASM_MIPS_SLOTS_H +#include <linux/config.h> + /* * SLOTSPACE is the address to which the physical address 0 * of the Slotspace is mapped by the chipset in the main CPU's * address space. */ +#ifdef CONFIG_DESKSTATION_RPC44 +#define SLOTSPACE 0xa0000000 +#else #define SLOTSPACE 0xe1000000 +#endif #endif /* __ASM_MIPS_SLOTS_H */ diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h new file mode 100644 index 000000000..acf771ead --- /dev/null +++ b/include/asm-mips/smp.h @@ -0,0 +1,9 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 Ralf Baechle + * + * Linux/MIPS SMP support. Just a dummy to make building possible. + */ diff --git a/include/asm-mips/smp_lock.h b/include/asm-mips/smp_lock.h new file mode 100644 index 000000000..acf771ead --- /dev/null +++ b/include/asm-mips/smp_lock.h @@ -0,0 +1,9 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 Ralf Baechle + * + * Linux/MIPS SMP support. Just a dummy to make building possible. + */ diff --git a/include/asm-mips/socket.h b/include/asm-mips/socket.h new file mode 100644 index 000000000..e5ddb6a17 --- /dev/null +++ b/include/asm-mips/socket.h @@ -0,0 +1,68 @@ +#ifndef __ASM_MIPS_SOCKET_H +#define __ASM_MIPS_SOCKET_H + +#include <linux/types.h> +#include <asm/sockios.h> + +/* + * For setsockoptions(2) + * + * This defines are ABI conformant as far as Linux supports these ... + */ +#define SOL_SOCKET 0xffff + +enum +{ + SO_DEBUG = 0x0001, /* Record debugging information. */ + SO_REUSEADDR = 0x0004, /* Allow reuse of local addresses. */ + SO_KEEPALIVE = 0x0008, /* Keep connections alive and send + SIGPIPE when they die. */ + SO_DONTROUTE = 0x0010, /* Don't do local routing. */ + SO_BROADCAST = 0x0020, /* Allow transmission of + broadcast messages. */ + SO_LINGER = 0x0080, /* Block on close of a reliable + socket to transmit pending data. */ + SO_OOBINLINE = 0x0100, /* Receive out-of-band data in-band. */ +#if 0 +To add: SO_REUSEPORT = 0x0200, /* Allow local address and port reuse. */ +#endif + + SO_TYPE = 0x1008, /* Compatible name for SO_STYLE. */ + SO_STYLE = SO_TYPE, /* Synonym */ + SO_ERROR = 0x1007, /* get error status and clear */ + SO_SNDBUF = 0x1001, /* Send buffer size. */ + SO_RCVBUF = 0x1002, /* Receive buffer. */ + SO_SNDLOWAT = 0x1003, /* send low-water mark */ + SO_RCVLOWAT = 0x1004, /* receive low-water mark */ + SO_SNDTIMEO = 0x1005, /* send timeout */ + SO_RCVTIMEO = 0x1006, /* receive timeout */ + +/* linux-specific, might as well be the same as on i386 */ + SO_NO_CHECK = 11, + SO_PRIORITY = 12, + SO_BSDCOMPAT = 14, +}; + +/* + * Weird. The existing SVr4 port to MIPS use two different definitions for + * SOCK_STREAM and SOCK_DGRAM with swapped values. I choose to be compatible + * with the newer definitions though that looks wrong ... + */ + +/* Types of sockets. */ +enum __socket_type +{ + SOCK_DGRAM = 1, /* Connectionless, unreliable datagrams + of fixed maximum length. */ + SOCK_STREAM = 2, /* Sequenced, reliable, connection-based + byte streams. */ + SOCK_RAW = 3, /* Raw protocol interface. */ + SOCK_RDM = 4, /* Reliably-delivered messages. */ + SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based, + datagrams of fixed maximum length. */ + SOCK_PACKET = 10, /* linux specific way of getting packets at + the dev level. For writing rarp and + other similar things on the user level. */ +}; + +#endif /* __ASM_MIPS_SOCKET_H */ diff --git a/include/asm-mips/sockios.h b/include/asm-mips/sockios.h new file mode 100644 index 000000000..18ca5f9a4 --- /dev/null +++ b/include/asm-mips/sockios.h @@ -0,0 +1,25 @@ +/* + * Socket-level I/O control calls. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + */ +#ifndef __ASM_MIPS_SOCKIOS_H +#define __ASM_MIPS_SOCKIOS_H + +#include <asm/ioctl.h> + +/* Socket-level I/O control calls. */ +#define FIOGETOWN _IOR('f', 123, int) +#define FIOSETOWN _IOW('f', 124, int) + +#define SIOCATMARK _IOR('s', 7, int) +#define SIOCSPGRP _IOW('s', 8, pid_t) +#define SIOCGPGRP _IOR('s', 9, pid_t) + +#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */ + +#endif /* __ASM_MIPS_SOCKIOS_H */ diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index b3b69f3c6..3cdbb61ef 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -1,109 +1,141 @@ /* - * include/asm-mips/stackframe.h + * Makefile for MIPS Linux main source directory * - * Copyright (C) 1994, 1995 Waldorf Electronics - * written by Ralf Baechle + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Paul M. Antoine. + * Additional R3000 support by Didier Frick <dfrick@dial.eunet.ch> + * for ACN S.A, Copyright (C) 1996 by ACN S.A */ - #ifndef __ASM_MIPS_STACKFRAME_H #define __ASM_MIPS_STACKFRAME_H +#include <asm/sgidefs.h> +#include <asm/asm.h> + /* * Stack layout for all exceptions: * * ptrace needs to have all regs on the stack. If the order here is changed, * it needs to be updated in include/asm-mips/ptrace.h * - * The first PTRSIZE*5 bytes are argument save space for C subroutines. + * The first PTRSIZE*6 bytes are argument save space for C subroutines. + * zero doesn't get saved; it's just a placeholder. */ -#define FR_REG1 (PTRSIZE*5) -#define FR_REG2 ((FR_REG1) + 4) -#define FR_REG3 ((FR_REG2) + 4) -#define FR_REG4 ((FR_REG3) + 4) -#define FR_REG5 ((FR_REG4) + 4) -#define FR_REG6 ((FR_REG5) + 4) -#define FR_REG7 ((FR_REG6) + 4) -#define FR_REG8 ((FR_REG7) + 4) -#define FR_REG9 ((FR_REG8) + 4) -#define FR_REG10 ((FR_REG9) + 4) -#define FR_REG11 ((FR_REG10) + 4) -#define FR_REG12 ((FR_REG11) + 4) -#define FR_REG13 ((FR_REG12) + 4) -#define FR_REG14 ((FR_REG13) + 4) -#define FR_REG15 ((FR_REG14) + 4) -#define FR_REG16 ((FR_REG15) + 4) -#define FR_REG17 ((FR_REG16) + 4) -#define FR_REG18 ((FR_REG17) + 4) -#define FR_REG19 ((FR_REG18) + 4) -#define FR_REG20 ((FR_REG19) + 4) -#define FR_REG21 ((FR_REG20) + 4) -#define FR_REG22 ((FR_REG21) + 4) -#define FR_REG23 ((FR_REG22) + 4) -#define FR_REG24 ((FR_REG23) + 4) -#define FR_REG25 ((FR_REG24) + 4) +#define FR_REG0 (SZREG*6) +#define FR_REG1 ((FR_REG0) + SZREG) +#define FR_REG2 ((FR_REG1) + SZREG) +#define FR_REG3 ((FR_REG2) + SZREG) +#define FR_REG4 ((FR_REG3) + SZREG) +#define FR_REG5 ((FR_REG4) + SZREG) +#define FR_REG6 ((FR_REG5) + SZREG) +#define FR_REG7 ((FR_REG6) + SZREG) +#define FR_REG8 ((FR_REG7) + SZREG) +#define FR_REG9 ((FR_REG8) + SZREG) +#define FR_REG10 ((FR_REG9) + SZREG) +#define FR_REG11 ((FR_REG10) + SZREG) +#define FR_REG12 ((FR_REG11) + SZREG) +#define FR_REG13 ((FR_REG12) + SZREG) +#define FR_REG14 ((FR_REG13) + SZREG) +#define FR_REG15 ((FR_REG14) + SZREG) +#define FR_REG16 ((FR_REG15) + SZREG) +#define FR_REG17 ((FR_REG16) + SZREG) +#define FR_REG18 ((FR_REG17) + SZREG) +#define FR_REG19 ((FR_REG18) + SZREG) +#define FR_REG20 ((FR_REG19) + SZREG) +#define FR_REG21 ((FR_REG20) + SZREG) +#define FR_REG22 ((FR_REG21) + SZREG) +#define FR_REG23 ((FR_REG22) + SZREG) +#define FR_REG24 ((FR_REG23) + SZREG) +#define FR_REG25 ((FR_REG24) + SZREG) /* - * $26 (k0) and $27 (k1) not saved + * $26 (k0) and $27 (k1) not saved - just placeholders */ -#define FR_REG28 ((FR_REG25) + 4) -#define FR_REG29 ((FR_REG28) + 4) -#define FR_REG30 ((FR_REG29) + 4) -#define FR_REG31 ((FR_REG30) + 4) +#define FR_REG26 ((FR_REG25) + SZREG) +#define FR_REG27 ((FR_REG26) + SZREG) + +#define FR_REG28 ((FR_REG27) + SZREG) +#define FR_REG29 ((FR_REG28) + SZREG) +#define FR_REG30 ((FR_REG29) + SZREG) +#define FR_REG31 ((FR_REG30) + SZREG) /* * Saved special registers */ -#define FR_LO ((FR_REG31) + 4) -#define FR_HI ((FR_LO) + 4) +#define FR_LO ((FR_REG31) + SZREG) +#define FR_HI ((FR_LO) + SZREG) +#define FR_ORIG_REG2 ((FR_HI) + SZREG) +#define FR_ORIG_REG7 ((FR_ORIG_REG2) + SZREG) /* * Saved cp0 registers follow */ -#define FR_STATUS ((FR_HI) + 4) -#define FR_EPC ((FR_STATUS) + 4) -#define FR_CAUSE ((FR_EPC) + 4) +#define FR_EPC ((FR_ORIG_REG7) + SZREG) +#define FR_BADVADDR ((FR_EPC) + SZREG) +#define FR_STATUS ((FR_BADVADDR) + SZREG) +#define FR_CAUSE ((FR_STATUS) + 4) /* - * Some goodies... + * Size of stack frame, word/double word alignment */ -#define FR_INTERRUPT ((FR_CAUSE) + 4) -#define FR_ORIG_REG2 ((FR_INTERRUPT) + 4) -#define FR_PAD1 ((FR_ORIG_REG2) + 4) +#define FR_SIZE (((FR_CAUSE + 4) + ALSZ) & ALMASK) /* - * Size of stack frame, word/double word alignment + * Load the global pointer. Only for ELF executables global pointer + * optimization is possible, so we only load the global pointer for + * ELF kernels. */ -#define FR_SIZE ((((FR_PAD1) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1)) +#if 0 +#define LOAD_GP la gp,_gp +#else +#define LOAD_GP +#endif -#ifdef __R4000__ +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) #define SAVE_ALL \ mfc0 k0,CP0_STATUS; \ - sll k0,3; /* extract cu0 bit */ \ - bltz k0,8f; \ + li k1,ST0_CU0; \ + and k0,k1; \ + bnez k0,8f; \ move k1,sp; \ + nop; \ /* \ * Called from user mode, new stack \ */ \ - lui k1,%hi(kernelsp); \ - lw k1,%lo(kernelsp)(k1); \ + lw k1,kernelsp; \ 8: move k0,sp; \ subu sp,k1,FR_SIZE; \ sw k0,FR_REG29(sp); \ - sw $2,FR_REG2(sp); \ - sw $2,FR_ORIG_REG2(sp); \ - mfc0 v0,CP0_STATUS; \ - sw v0,FR_STATUS(sp); \ - mfc0 v0,CP0_CAUSE; \ - sw v0,FR_CAUSE(sp); \ - mfc0 v0,CP0_EPC; \ - sw v0,FR_EPC(sp); \ - mfhi v0; \ - sw v0,FR_HI(sp); \ - mflo v0; \ - sw v0,FR_LO(sp); \ - sw $1,FR_REG1(sp); \ sw $3,FR_REG3(sp); \ + mfc0 $3,CP0_STATUS; \ + nop; \ + sw $3,FR_STATUS(sp); \ + li k1,ST0_CU0; \ + or k1,$3; \ + mtc0 k1,CP0_STATUS; \ + nop; \ + mfc0 $3,CP0_ENTRYHI; \ + nop; \ + sw $3,FR_ENTRYHI(sp); \ + mfc0 $3,CP0_CAUSE; \ + nop; \ + sw $3,FR_CAUSE(sp); \ + mfc0 $3,CP0_EPC; \ + nop; \ + sw $3,FR_EPC(sp); \ + mfc0 $3,CP0_BADVADDR; \ + nop; \ + sw $3,FR_BADVADDR(sp); \ + mfhi $3; \ + sw $3,FR_HI(sp); \ + mflo $3; \ + sw $3,FR_LO(sp); \ + sw $1,FR_REG1(sp); \ + sw $2,FR_REG2(sp); \ sw $4,FR_REG4(sp); \ sw $5,FR_REG5(sp); \ sw $6,FR_REG6(sp); \ @@ -128,24 +160,25 @@ sw $25,FR_REG25(sp); \ sw $28,FR_REG28(sp); \ sw $30,FR_REG30(sp); \ - sw $31,FR_REG31(sp) + sw $31,FR_REG31(sp); \ + LOAD_GP /* * Note that we restore the IE flags from stack. This means * that a modified IE mask will be nullified. */ -#define RESTORE_ALL \ - .set mips3; \ +/* + * FIXME: Don't need to clear these bits on R[236]000's?? + * mfc0 t0,CP0_STATUS; \ ori t0,0x1f; \ xori t0,0x1f; \ mtc0 t0,CP0_STATUS; \ - \ - lw v0,FR_STATUS(sp); \ + */ +#define RESTORE_ALL \ lw v1,FR_LO(sp); \ - mtc0 v0,CP0_STATUS; \ - mtlo v1; \ lw v0,FR_HI(sp); \ + mtlo v1; \ lw v1,FR_EPC(sp); \ mthi v0; \ mtc0 v1,CP0_EPC; \ @@ -177,13 +210,169 @@ lw $3,FR_REG3(sp); \ lw $2,FR_REG2(sp); \ lw $1,FR_REG1(sp); \ - lw sp,FR_REG29(sp); /* Deallocate stack */ \ - .set mips0 + lw k1,FR_STATUS(sp); \ + lw sp,FR_REG29(sp); \ + ori k1,3; \ + xori k1,3; \ + mtc0 k1,CP0_STATUS; \ + nop + +/* + * We disable interrupts when restoring the status register because: + * 1) the ret_from_syscall routine uses k0/k1 to preserve values around + * the RESTORE_ALL + * 2) the rfe instruction will restore the IE and KU flags to their + * previous value. + */ + +#define CLI \ + mfc0 t1,$12; \ + li t0,ST0_CU0|1; \ + or t1,t1,t0; \ + xori t1,1; \ + mtc0 t1,$12; \ + nop; \ + nop + +#define STI \ + mfc0 t1,$12; \ + li t0,ST0_CU0|1; \ + or t1,t1,t0; \ + mtc0 t1,$12; \ + nop; \ + nop + +#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) */ -#else /* !defined (__R4000__) */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS5) -#error "Implement SAVE_ALL and RESTORE_ALL!" +#define SAVE_ALL \ + mfc0 k0,CP0_STATUS; \ + sll k0,3; /* extract cu0 bit */ \ + bltz k0,8f; \ + move k1,sp; \ + /* \ + * Called from user mode, new stack \ + */ \ + lw k1,kernelsp; \ +8: move k0,sp; \ + subu sp,k1,FR_SIZE; \ + sd k0,FR_REG29(sp); \ + sd $3,FR_REG3(sp); \ + mfc0 $3,CP0_STATUS; \ + sw $3,FR_STATUS(sp); \ + mfc0 $3,CP0_CAUSE; \ + sw $3,FR_CAUSE(sp); \ + dmfc0 $3,CP0_EPC; \ + sd $3,FR_EPC(sp); \ + mfhi $3; \ + sd $3,FR_HI(sp); \ + mflo $3; \ + sd $3,FR_LO(sp); \ + sd $1,FR_REG1(sp); \ + sd $2,FR_REG2(sp); \ + sd $4,FR_REG4(sp); \ + sd $5,FR_REG5(sp); \ + sd $6,FR_REG6(sp); \ + sd $7,FR_REG7(sp); \ + sd $8,FR_REG8(sp); \ + sd $9,FR_REG9(sp); \ + sd $10,FR_REG10(sp); \ + sd $11,FR_REG11(sp); \ + sd $12,FR_REG12(sp); \ + sd $13,FR_REG13(sp); \ + sd $14,FR_REG14(sp); \ + sd $15,FR_REG15(sp); \ + sd $16,FR_REG16(sp); \ + sd $17,FR_REG17(sp); \ + sd $18,FR_REG18(sp); \ + sd $19,FR_REG19(sp); \ + sd $20,FR_REG20(sp); \ + sd $21,FR_REG21(sp); \ + sd $22,FR_REG22(sp); \ + sd $23,FR_REG23(sp); \ + sd $24,FR_REG24(sp); \ + sd $25,FR_REG25(sp); \ + sd $28,FR_REG28(sp); \ + sd $30,FR_REG30(sp); \ + sd $31,FR_REG31(sp); \ + LOAD_GP + +/* + * Note that we restore the IE flags from stack. This means + * that a modified IE mask will be nullified. + */ +#define RESTORE_ALL \ + mfc0 t0,CP0_STATUS; \ + ori t0,0x1f; \ + xori t0,0x1f; \ + mtc0 t0,CP0_STATUS; \ + \ + lw v0,FR_STATUS(sp); \ + ld v1,FR_LO(sp); \ + mtc0 v0,CP0_STATUS; \ + mtlo v1; \ + ld v0,FR_HI(sp); \ + ld v1,FR_EPC(sp); \ + mthi v0; \ + dmtc0 v1,CP0_EPC; \ + ld $31,FR_REG31(sp); \ + ld $30,FR_REG30(sp); \ + ld $28,FR_REG28(sp); \ + ld $25,FR_REG25(sp); \ + ld $24,FR_REG24(sp); \ + ld $23,FR_REG23(sp); \ + ld $22,FR_REG22(sp); \ + ld $21,FR_REG21(sp); \ + ld $20,FR_REG20(sp); \ + ld $19,FR_REG19(sp); \ + ld $18,FR_REG18(sp); \ + ld $17,FR_REG17(sp); \ + ld $16,FR_REG16(sp); \ + ld $15,FR_REG15(sp); \ + ld $14,FR_REG14(sp); \ + ld $13,FR_REG13(sp); \ + ld $12,FR_REG12(sp); \ + ld $11,FR_REG11(sp); \ + ld $10,FR_REG10(sp); \ + ld $9,FR_REG9(sp); \ + ld $8,FR_REG8(sp); \ + ld $7,FR_REG7(sp); \ + ld $6,FR_REG6(sp); \ + ld $5,FR_REG5(sp); \ + ld $4,FR_REG4(sp); \ + ld $3,FR_REG3(sp); \ + ld $2,FR_REG2(sp); \ + ld $1,FR_REG1(sp); \ + ld sp,FR_REG29(sp) /* Deallocate stack */ \ + +/* + * Move to kernel mode and disable interrupts. + * Set cp0 enable bit as sign that we're running on the kernel stack + */ +#define CLI \ + mfc0 t0,CP0_STATUS; \ + li t1,ST0_CU0|0x1f; \ + or t0,t1; \ + xori t0,0x1f; \ + mtc0 t0,CP0_STATUS + +/* + * Move to kernel mode and enable interrupts. + * Set cp0 enable bit as sign that we're running on the kernel stack + * + * Note that the mtc0 will be effective on R4000 pipeline stage 7. This + * means that another three instructions will be executed with interrupts + * disabled. Arch/mips/mips3/r4xx0.S makes use of this fact. + */ +#define STI \ + mfc0 t0,CP0_STATUS; \ + li t1,ST0_CU0|0x1f; \ + or t0,t1; \ + xori t0,0x1e; \ + mtc0 t0,CP0_STATUS -#endif /* !defined (__R4000__) */ +#endif /* _MIPS_ISA >= MIPS3 */ #endif /* __ASM_MIPS_STACKFRAME_H */ diff --git a/include/asm-mips/stat.h b/include/asm-mips/stat.h index ffae5bbcf..9b2f48ed9 100644 --- a/include/asm-mips/stat.h +++ b/include/asm-mips/stat.h @@ -1,9 +1,9 @@ #ifndef __ASM_MIPS_STAT_H #define __ASM_MIPS_STAT_H -#include <asm/types.h> +#include <linux/types.h> -struct old_stat { +struct __old_kernel_stat { unsigned int st_dev; unsigned int st_ino; unsigned int st_mode; @@ -15,13 +15,13 @@ struct old_stat { unsigned int st_atime, st_res1; unsigned int st_mtime, st_res2; unsigned int st_ctime, st_res3; - unsigned int st_blkize; + unsigned int st_blksize; int st_blocks; unsigned int st_flags; unsigned int st_gen; }; -struct new_stat { +struct stat { dev_t st_dev; long st_pad1[3]; /* Reserved for network id */ ino_t st_ino; diff --git a/include/asm-mips/statfs.h b/include/asm-mips/statfs.h index 3cae73206..500f6f1b6 100644 --- a/include/asm-mips/statfs.h +++ b/include/asm-mips/statfs.h @@ -1,25 +1,40 @@ +/* + * Definitions for the statfs(2) call. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + */ #ifndef __ASM_MIPS_STATFS_H #define __ASM_MIPS_STATFS_H -typedef struct { - long val[2]; -} fsid_t; +#include <linux/posix_types.h> + +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif struct statfs { - long f_type; + long f_type; #define f_fstyp f_type - long f_bsize; - long f_frsize; /* Fragment size - unsupported */ - long f_blocks; - long f_bfree; - long f_files; - long f_ffree; + long f_bsize; + long f_frsize; /* Fragment size - unsupported */ + long f_blocks; + long f_bfree; + long f_files; + long f_ffree; /* Linux specials */ long f_bavail; - fsid_t f_fsid; - long f_namelen; - long f_spare[6]; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_spare[6]; }; #endif /* __ASM_MIPS_STATFS_H */ diff --git a/include/asm-mips/string.h b/include/asm-mips/string.h index 1142eaf30..1773abd81 100644 --- a/include/asm-mips/string.h +++ b/include/asm-mips/string.h @@ -5,15 +5,20 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1994, 1995 Waldorf Electronics - * written by Ralf Baechle + * Copyright (c) 1994, 1995, 1996 by Ralf Baechle */ #ifndef __ASM_MIPS_STRING_H #define __ASM_MIPS_STRING_H -extern __inline__ char * strcpy(char * dest, const char *src) +#ifdef __KERNEL__ + +#include <linux/linkage.h> +#include <asm/sgidefs.h> + +#define __HAVE_ARCH_STRCPY +extern __inline__ char *strcpy(char *__dest, __const__ char *__src) { - char *xdest = dest; + char *__xdest = __dest; __asm__ __volatile__( ".set\tnoreorder\n\t" @@ -25,41 +30,43 @@ extern __inline__ char * strcpy(char * dest, const char *src) "addiu\t%0,1\n\t" ".set\tat\n\t" ".set\treorder" - : "=r" (dest), "=r" (src) - : "0" (dest), "1" (src) + : "=r" (__dest), "=r" (__src) + : "0" (__dest), "1" (__src) : "$1","memory"); - return xdest; + return __xdest; } -extern __inline__ char * strncpy(char *dest, const char *src, size_t n) +#define __HAVE_ARCH_STRNCPY +extern __inline__ char *strncpy(char *__dest, __const__ char *__src, size_t __n) { - char *xdest = dest; + char *__xdest = __dest; - if (n == 0) - return xdest; + if (__n == 0) + return __xdest; __asm__ __volatile__( ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t$1,(%1)\n\t" - "subu\t%2,%2,1\n\t" + "subu\t%2,1\n\t" "sb\t$1,(%0)\n\t" "beqz\t$1,2f\n\t" - "addiu\t%0,%0,1\n\t" + "addiu\t%0,1\n\t" "bnez\t%2,1b\n\t" - "addiu\t%1,%1,1\n" + "addiu\t%1,1\n" "2:\n\t" ".set\tat\n\t" - ".set\treorder\n\t" - : "=r" (dest), "=r" (src), "=r" (n) - : "0" (dest), "1" (src), "2" (n) + ".set\treorder" + : "=r" (__dest), "=r" (__src), "=r" (__n) + : "0" (__dest), "1" (__src), "2" (__n) : "$1","memory"); - return dest; + return __dest; } -extern __inline__ int strcmp(const char * cs, const char * ct) +#define __HAVE_ARCH_STRCMP +extern __inline__ int strcmp(__const__ char *__cs, __const__ char *__ct) { int __res; @@ -73,21 +80,22 @@ extern __inline__ int strcmp(const char * cs, const char * ct) "addiu\t%1,1\n\t" "bnez\t%2,1b\n\t" "lbu\t%2,(%0)\n\t" -#ifndef __R4000__ +#if _MIPS_ISA == _MIPS_ISA_MIPS1 "nop\n\t" #endif "move\t%2,$1\n" "2:\tsubu\t%2,$1\n" "3:\t.set\tat\n\t" ".set\treorder" - : "=d" (cs), "=d" (ct), "=d" (__res) - : "0" (cs), "1" (ct) + : "=r" (__cs), "=r" (__ct), "=r" (__res) + : "0" (__cs), "1" (__ct) : "$1"); return __res; } -extern __inline__ int strncmp(const char * cs, const char * ct, size_t count) +#define __HAVE_ARCH_STRNCMP +extern __inline__ int strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count) { char __res; @@ -106,114 +114,350 @@ extern __inline__ int strncmp(const char * cs, const char * ct, size_t count) "3:\tsubu\t%3,$1\n\t" ".set\tat\n\t" ".set\treorder" - : "=d" (cs), "=d" (ct), "=d" (count), "=d" (__res) - : "0" (cs), "1" (ct), "2" (count) + : "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res) + : "0" (__cs), "1" (__ct), "2" (__count) : "$1"); return __res; } -extern __inline__ void * memset(void * s, int c, size_t count) +#define __HAVE_ARCH_MEMSET +/* + * Ok, this definately looks braindead. I tried several other variants + * some of which GCC wasn't able to optimize or which made GCC consume + * extreme amounts of memory. + * This code attempts never to generate address errors which require + * expensive software emulation. For this purpose GCC's __alignof__ + * seems to be perfect. Unfortunately GCC 2.7.2 complains about + * __alignof__(*p) when p is a pointer to void. For now I ignore these + * warnings. + */ + +extern void __generic_memset_b(void *__s, int __c, size_t __count); +extern void __generic_memset_dw(void *__s, unsigned long long __c, + size_t __count); + +/* + * The constant c handling looks wired but it combines minimal code + * size with fast execution. + */ +#define __generic_memset(s, c, count, const_c) \ +({if(const_c) { \ + unsigned long long __dwc; \ +\ + __dwc = c & 0xff; \ + __dwc = (__dwc << 8) | __dwc; \ + __dwc = (__dwc << 16) | __dwc; \ + __dwc = (__dwc << 32) | __dwc; \ + __generic_memset_dw(s, __dwc, count); \ + } \ +else \ + __generic_memset_b(s, c, count); \ +}) + +extern __inline__ void __const_count_memset1(void *__s, int __c, size_t __count, + int __const_c) { - void *xs = s; + switch(__count) { + case 0: return; + case 1: *(0+(char *)__s) = __c; + return; + case 2: *(0+(char *)__s) = __c; + *(1+(char *)__s) = __c; + return; + case 3: *(0+(char *)__s) = __c; + *(1+(char *)__s) = __c; + *(2+(char *)__s) = __c; + return; + case 4: *(0+(char *)__s) = __c; + *(1+(char *)__s) = __c; + *(2+(char *)__s) = __c; + *(3+(char *)__s) = __c; + return; + case 5: *(0+(char *)__s) = __c; + *(1+(char *)__s) = __c; + *(2+(char *)__s) = __c; + *(3+(char *)__s) = __c; + *(4+(char *)__s) = __c; + return; + case 6: *(0+(char *)__s) = __c; + *(1+(char *)__s) = __c; + *(2+(char *)__s) = __c; + *(3+(char *)__s) = __c; + *(4+(char *)__s) = __c; + *(5+(char *)__s) = __c; + return; + case 7: *(0+(char *)__s) = __c; + *(1+(char *)__s) = __c; + *(2+(char *)__s) = __c; + *(3+(char *)__s) = __c; + *(4+(char *)__s) = __c; + *(5+(char *)__s) = __c; + *(6+(char *)__s) = __c; + return; + case 8: *(0+(char *)__s) = __c; + *(1+(char *)__s) = __c; + *(2+(char *)__s) = __c; + *(3+(char *)__s) = __c; + *(4+(char *)__s) = __c; + *(5+(char *)__s) = __c; + *(6+(char *)__s) = __c; + *(7+(char *)__s) = __c; + return; + } + __generic_memset(__s, __c, __count, __const_c); + return; +} - if (!count) - return xs; - __asm__ __volatile__( - ".set\tnoreorder\n" - "1:\tsb\t%3,(%0)\n\t" - "bne\t%0,%1,1b\n\t" - "addiu\t%0,%0,1\n\t" - ".set\treorder" - : "=r" (s), "=r" (count) - : "0" (s), "r" (c), "1" (s + count - 1) - : "memory"); +extern __inline__ void __const_count_memset2(void *__s, int __c, size_t __count, + int __const_c) +{ + switch(__count) { + case 0: return; + case 2: *(0+(short *)__s) = 0x0101 * __c; + return; + case 4: *(0+(short *)__s) = 0x0101 * __c; + *(1+(short *)__s) = 0x0101 * __c; + return; + case 6: *(0+(short *)__s) = 0x0101 * __c; + *(1+(short *)__s) = 0x0101 * __c; + *(2+(short *)__s) = 0x0101 * __c; + return; + case 8: *(0+(short *)__s) = 0x0101 * __c; + *(1+(short *)__s) = 0x0101 * __c; + *(2+(short *)__s) = 0x0101 * __c; + *(3+(short *)__s) = 0x0101 * __c; + return; + case 10:*(0+(short *)__s) = 0x0101 * __c; + *(1+(short *)__s) = 0x0101 * __c; + *(2+(short *)__s) = 0x0101 * __c; + *(3+(short *)__s) = 0x0101 * __c; + *(4+(short *)__s) = 0x0101 * __c; + return; + case 12:*(0+(short *)__s) = 0x0101 * __c; + *(1+(short *)__s) = 0x0101 * __c; + *(2+(short *)__s) = 0x0101 * __c; + *(3+(short *)__s) = 0x0101 * __c; + *(4+(short *)__s) = 0x0101 * __c; + *(5+(short *)__s) = 0x0101 * __c; + return; + case 14:*(0+(short *)__s) = 0x0101 * __c; + *(1+(short *)__s) = 0x0101 * __c; + *(2+(short *)__s) = 0x0101 * __c; + *(3+(short *)__s) = 0x0101 * __c; + *(4+(short *)__s) = 0x0101 * __c; + *(5+(short *)__s) = 0x0101 * __c; + *(6+(short *)__s) = 0x0101 * __c; + return; + case 16:*(0+(short *)__s) = 0x0101 * __c; + *(1+(short *)__s) = 0x0101 * __c; + *(2+(short *)__s) = 0x0101 * __c; + *(3+(short *)__s) = 0x0101 * __c; + *(4+(short *)__s) = 0x0101 * __c; + *(5+(short *)__s) = 0x0101 * __c; + *(6+(short *)__s) = 0x0101 * __c; + *(7+(short *)__s) = 0x0101 * __c; + return; + } + __generic_memset(__s, __c, __count, __const_c); + return; +} - return xs; +extern __inline__ void __const_count_memset4(void *__s, int __c, size_t __count, + int __const_c) +{ + switch(__count) { + case 0: return; + case 4: *(0+(int *)__s) = 0x01010101 * __c; + return; + case 8: *(0+(int *)__s) = 0x01010101 * __c; + *(1+(int *)__s) = 0x01010101 * __c; + return; + case 12:*(0+(int *)__s) = 0x01010101 * __c; + *(1+(int *)__s) = 0x01010101 * __c; + *(2+(int *)__s) = 0x01010101 * __c; + return; + case 16:*(0+(int *)__s) = 0x01010101 * __c; + *(1+(int *)__s) = 0x01010101 * __c; + *(2+(int *)__s) = 0x01010101 * __c; + *(3+(int *)__s) = 0x01010101 * __c; + return; + case 20:*(0+(int *)__s) = 0x01010101 * __c; + *(1+(int *)__s) = 0x01010101 * __c; + *(2+(int *)__s) = 0x01010101 * __c; + *(3+(int *)__s) = 0x01010101 * __c; + *(4+(int *)__s) = 0x01010101 * __c; + return; + case 24:*(0+(int *)__s) = 0x01010101 * __c; + *(1+(int *)__s) = 0x01010101 * __c; + *(2+(int *)__s) = 0x01010101 * __c; + *(3+(int *)__s) = 0x01010101 * __c; + *(4+(int *)__s) = 0x01010101 * __c; + *(5+(int *)__s) = 0x01010101 * __c; + return; + case 28:*(0+(int *)__s) = 0x01010101 * __c; + *(1+(int *)__s) = 0x01010101 * __c; + *(2+(int *)__s) = 0x01010101 * __c; + *(3+(int *)__s) = 0x01010101 * __c; + *(4+(int *)__s) = 0x01010101 * __c; + *(5+(int *)__s) = 0x01010101 * __c; + *(6+(int *)__s) = 0x01010101 * __c; + return; + case 32:*(0+(int *)__s) = 0x01010101 * __c; + *(1+(int *)__s) = 0x01010101 * __c; + *(2+(int *)__s) = 0x01010101 * __c; + *(3+(int *)__s) = 0x01010101 * __c; + *(4+(int *)__s) = 0x01010101 * __c; + *(5+(int *)__s) = 0x01010101 * __c; + *(6+(int *)__s) = 0x01010101 * __c; + *(7+(int *)__s) = 0x01010101 * __c; + return; + } + __generic_memset(__s, __c, __count, __const_c); + return; } -extern __inline__ void * memcpy(void * to, const void * from, size_t n) +extern __inline__ void __const_count_memset8(void *__s, int __c, size_t __count, + int __const_c) { - void *xto = to; + unsigned long long __dwc; - if (!n) - return xto; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%1,1\n\t" - "sb\t$1,(%0)\n\t" - "subu\t%2,1\n\t" - "bnez\t%2,1b\n\t" - "addiu\t%0,1\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (to), "=r" (from), "=r" (n) - : "0" (to), "1" (from), "2" (n) - : "$1","memory" ); - return xto; + __dwc = __c & 0xff; + __dwc = (__dwc << 8) | __dwc; + __dwc = (__dwc << 16) | __dwc; + __dwc = (__dwc << 32) | __dwc; + switch(__count) { + case 0: return; + case 8: *(0+(long long *)__s) = __dwc; + return; + case 16:*(0+(long long *)__s) = __dwc; + *(1+(long long *)__s) = __dwc; + return; + case 24:*(0+(long long *)__s) = __dwc; + *(1+(long long *)__s) = __dwc; + *(2+(long long *)__s) = __dwc; + return; + case 32:*(0+(long long *)__s) = __dwc; + *(1+(long long *)__s) = __dwc; + *(2+(long long *)__s) = __dwc; + *(3+(long long *)__s) = __dwc; + return; + case 40:*(0+(long long *)__s) = __dwc; + *(1+(long long *)__s) = __dwc; + *(2+(long long *)__s) = __dwc; + *(3+(long long *)__s) = __dwc; + *(4+(long long *)__s) = __dwc; + return; + case 48:*(0+(long long *)__s) = __dwc; + *(1+(long long *)__s) = __dwc; + *(2+(long long *)__s) = __dwc; + *(3+(long long *)__s) = __dwc; + *(4+(long long *)__s) = __dwc; + *(5+(long long *)__s) = __dwc; + return; + case 56:*(0+(long long *)__s) = __dwc; + *(1+(long long *)__s) = __dwc; + *(2+(long long *)__s) = __dwc; + *(3+(long long *)__s) = __dwc; + *(4+(long long *)__s) = __dwc; + *(5+(long long *)__s) = __dwc; + *(6+(long long *)__s) = __dwc; + return; + case 64:*(0+(long long *)__s) = __dwc; + *(1+(long long *)__s) = __dwc; + *(2+(long long *)__s) = __dwc; + *(3+(long long *)__s) = __dwc; + *(4+(long long *)__s) = __dwc; + *(5+(long long *)__s) = __dwc; + *(6+(long long *)__s) = __dwc; + *(7+(long long *)__s) = __dwc; + return; + } + __generic_memset(__s, __c, __count, __const_c); + return; } -extern __inline__ void * memmove(void * dest,const void * src, size_t n) +extern __inline__ void * __const_count_memset(void *__s, int __c, + size_t __count, int __align, + int __const_c) { - void *xdest = dest; + switch(__align) { + /* + * We only want this for the 64 bit CPUs; this gets + * too bloated on 32 bit. + */ + case 1: __const_count_memset1(__s, __c, __count, __const_c); + return __s; + case 2: __const_count_memset2(__s, __c, __count, __const_c); + return __s; + case 4: __const_count_memset4(__s, __c, __count, __const_c); + return __s; +#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS5) + case 8: __const_count_memset8(__s, __c, __count, __const_c); + return __s; +#endif + } + __generic_memset(__s, __c, __count, __const_c); + return __s; +} - if (!n) - return xdest; +#define memset(s, c, count) \ +(__builtin_constant_p(count) ? \ + __const_count_memset((s),(c),(count),__alignof__(*(s)), \ + __builtin_constant_p(c)) : \ + __generic_memset((s),(c),(count),__builtin_constant_p(c))) - if (dest < src) - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%1,1\n\t" - "sb\t$1,(%0)\n\t" - "subu\t%2,1\n\t" - "bnez\t%2,1b\n\t" - "addiu\t%0,1\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (dest), "=r" (src), "=r" (n) - : "0" (dest), "1" (src), "2" (n) - : "$1","memory" ); - else - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tlbu\t$1,-1(%1)\n\t" - "subu\t%1,1\n\t" - "sb\t$1,-1(%0)\n\t" - "subu\t%2,1\n\t" - "bnez\t%2,1b\n\t" - "subu\t%0,1\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (dest), "=r" (src), "=r" (n) - : "0" (dest+n), "1" (src+n), "2" (n) - : "$1","memory" ); - return xdest; +#define __HAVE_ARCH_MEMCPY +extern void __memcpy(void *__to, __const__ void *__from, size_t __n); +extern __inline__ void *memcpy(void *__to, __const__ void *__from, size_t __n) +{ + __memcpy(__to, __from, __n); + + return __to; +} + +#define __HAVE_ARCH_MEMMOVE +extern void __memmove(void *__dest, __const__ void *__src, size_t __n); +extern __inline__ void *memmove(void *__dest, __const__ void *__src, size_t __n) +{ + __memmove(__dest, __src, __n); + + return __dest; } -extern __inline__ void * memscan(void * addr, int c, size_t size) +#define __HAVE_ARCH_BCOPY +extern __inline__ char *bcopy(__const__ char *__src, char *__dest, size_t __count) { - if (!size) - return addr; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tbeqz\t%1,2f\n\t" - "lbu\t$1,(%0)\n\t" - "subu\t%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,1\n\t" + __memmove(__dest, __src, __count); + + return __dest; +} + +#define __HAVE_ARCH_MEMSCAN +extern __inline__ void *memscan(void *__addr, int __c, size_t __size) +{ + char *__end = (char *)__addr + __size; + + if (!__size) + return __addr; + __asm__(".set\tnoat\n" + "1:\tlbu\t$1,(%0)\n\t" + ".set\tnoreorder\n\t" + "beq\t$1,%3,2f\n\t" + "addiu\t%0,1\t\t\t# delay slot\n\t" + ".set\treorder\n\t" ".set\tat\n\t" - ".set\treorder\n" - "2:" - : "=r" (addr), "=r" (size) - : "0" (addr), "1" (size), "r" (c) + "bne\t%0,%2,1b\n\t" + "2:\n" + : "=r" (__addr) + : "0" (__addr), "1" (__end), "r" (__c) : "$1"); - return addr; + return __addr; } +#endif /* __KERNEL__ */ + #endif /* __ASM_MIPS_STRING_H */ diff --git a/include/asm-mips/sysmips.h b/include/asm-mips/sysmips.h new file mode 100644 index 000000000..f0d13cfd5 --- /dev/null +++ b/include/asm-mips/sysmips.h @@ -0,0 +1,25 @@ +/* + * Definitions for the MIPS sysmips(2) call + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 by Ralf Baechle + */ +#ifndef __ASM_MIPS_SYSMIPS_H +#define __ASM_MIPS_SYSMIPS_H + +/* + * Commands for the sysmips(2) call + * + * sysmips(2) is deprecated - though some existing software uses it. + * We only support the following commands. + */ +#define SETNAME 1 /* set hostname */ +#define FLUSH_CACHE 3 /* writeback and invalidate caches */ +#define MIPS_FIXADE 7 /* control address error fixing */ +#define MIPS_RDNVRAM 10 /* read NVRAM */ +#define MIPS_ATOMIC_SET 2001 /* atomically set variable */ + +#endif /* __ASM_MIPS_SYSMIPS_H */ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index ef8c51b21..5489dd87a 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -5,108 +5,136 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995 by Ralf Baechle + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle, Paul M. Antoine */ #ifndef __ASM_MIPS_SYSTEM_H #define __ASM_MIPS_SYSTEM_H -#if defined (__R4000__) -#define sti() \ -__asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t$1,$12\n\t" \ - "ori\t$1,0x1f\n\t" \ - "xori\t$1,0x1e\n\t" \ - "mtc0\t$1,$12\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - : /* no outputs */ \ - : /* no inputs */ \ - : "$1") +#include <linux/linkage.h> +#include <asm/sgidefs.h> -#define cli() \ -__asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t$1,$12\n\t" \ - "ori\t$1,1\n\t" \ - "xori\t$1,1\n\t" \ - "mtc0\t$1,$12\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - : /* no outputs */ \ - : /* no inputs */ \ - : "$1") +/* + * sti/cli/save_flags use a memory clobber to make shure GCC doesn't + * move memory references around calls to these functions. + */ +extern __inline__ void +sti(void) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "mfc0\t$1,$12\n\t" + "ori\t$1,1\n\t" + "mtc0\t$1,$12\n\t" + ".set\tat\n\t" + ".set\treorder" + : /* no outputs */ + : /* no inputs */ + : "$1","memory"); +} -#else /* !defined (__R4000__) */ /* - * Untested goodies for the R3000 based DECstation et al. + * For cli() we have to make shure that the new c0_status value has + * really arrived in the status register at the end of the inline + * function using worst case scheduling. The worst case is the R4000 + * which needs three nops. */ -#define sti() \ -__asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t$1,$12\n\t" \ - "ori\t$1,0x01\n\t" \ - "mtc0\t$1,$12\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - : /* no outputs */ \ - : /* no inputs */ \ - : "$1") +extern __inline__ void +cli(void) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "mfc0\t$1,$12\n\t" + "ori\t$1,1\n\t" + "xori\t$1,1\n\t" + "mtc0\t$1,$12\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\tat\n\t" + ".set\treorder" + : /* no outputs */ + : /* no inputs */ + : "$1","memory"); +} -#define cli() \ +#define save_flags(x) \ __asm__ __volatile__( \ ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t$1,$12\n\t" \ - "ori\t$1,1\n\t" \ - "xori\t$1,1\n\t" \ - "mtc0\t$1,$12\n\t" \ - ".set\tat\n\t" \ + "mfc0\t%0,$12\n\t" \ ".set\treorder" \ - : /* no outputs */ \ + : "=r" (x) \ : /* no inputs */ \ - : "$1") -#endif /* !defined (__R4000__) */ + : "memory") -#define nop() __asm__ __volatile__ ("nop") +extern void __inline__ +restore_flags(int flags) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + "mtc0\t%0,$12\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\treorder" + : /* no output */ + : "r" (flags) + : "memory"); +} -#define save_flags(x) \ +#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) +#define sync_mem() \ __asm__ __volatile__( \ ".set\tnoreorder\n\t" \ - "mfc0\t%0,$12\n\t" \ + "sync\n\t" \ ".set\treorder" \ - : "=r" (x)) \ - -#define restore_flags(x) \ + : /* no output */ \ + : /* no input */ \ + : "memory") +#else +/* + * FIXME: Don't really know what to do here for the R[236]000's. + * Should probably bfc0 until write buffer is empty? - PMA + * Not shure if wb flushing is really required but sounds reasonable. + * The code below does this for R2000/R3000. - Ralf + */ +#define sync_mem() \ __asm__ __volatile__( \ ".set\tnoreorder\n\t" \ - "mtc0\t%0,$12\n\t" \ + "nop;nop;nop;nop;\n" \ + "1:\tbc0f\t1b\n\t" \ + "nop\n\t" \ ".set\treorder" \ - : /* no output */ \ - : "r" (x)) \ + : /* no output */ \ + : /* no input */ \ + : "memory") +#endif -#define sync_mem() \ -__asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - "sync\n\t" \ - ".set\treorder") \ +/* + * switch_to(n) should switch tasks to task nr n, first + * checking that n isn't the current task, in which case it does nothing. + */ +struct task_struct; +asmlinkage void resume(struct task_struct *tsk, int offset); + +/* + * FIXME: resume() assumes current == prev + */ +#define switch_to(prev,next) \ + resume(next, ((int)(&((struct task_struct *)0)->tss))); /* * The 8 and 16 bit variants have to disable interrupts temporarily. * Both are currently unused. */ -extern inline unsigned long xchg_u8(char * m, unsigned long val) +extern __inline__ unsigned long xchg_u8(volatile char * m, unsigned long val) { unsigned long flags, retval; save_flags(flags); - sti(); + cli(); retval = *m; *m = val; restore_flags(flags); @@ -114,12 +142,12 @@ extern inline unsigned long xchg_u8(char * m, unsigned long val) return retval; } -extern inline unsigned long xchg_u16(short * m, unsigned long val) +extern __inline__ unsigned long xchg_u16(volatile short * m, unsigned long val) { unsigned long flags, retval; save_flags(flags); - sti(); + cli(); retval = *m; *m = val; restore_flags(flags); @@ -131,8 +159,10 @@ extern inline unsigned long xchg_u16(short * m, unsigned long val) * For 32 and 64 bit operands we can take advantage of ll and sc. * FIXME: This doesn't work for R3000 machines. */ -extern inline unsigned long xchg_u32(int * m, unsigned long val) +extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) { +#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) unsigned long dummy; __asm__ __volatile__( @@ -147,14 +177,23 @@ extern inline unsigned long xchg_u32(int * m, unsigned long val) ".set\treorder" : "=r" (val), "=r" (m), "=r" (dummy) : "1" (m), "2" (val)); +#else /* FIXME: Brain-dead approach, but then again, I AM hacking - PMA */ + unsigned long flags, retval; + save_flags(flags); + cli(); + retval = *m; + *m = val; + restore_flags(flags); + +#endif /* Processor-dependent optimization */ return val; } /* * Only used for 64 bit kernel. */ -extern inline unsigned long xchg_u64(long * m, unsigned long val) +extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val) { unsigned long dummy; @@ -174,13 +213,33 @@ extern inline unsigned long xchg_u64(long * m, unsigned long val) return val; } -extern inline void * xchg_ptr(void * m, void * val) +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) + +/* + * This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid xchg(). + * + * This only works if the compiler isn't horribly bad at optimizing. + * gcc-2.5.8 reportedly can't handle this, but I define that one to + * be dead anyway. + */ +extern void __xchg_called_with_bad_pointer(void); + +static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size) { -#if __mips == 3 - return (void *) xchg_u64(m, (unsigned long) val); -#else - return (void *) xchg_u32(m, (unsigned long) val); -#endif + switch (size) { + case 1: + return xchg_u8(ptr, x); + case 2: + return xchg_u16(ptr, x); + case 4: + return xchg_u32(ptr, x); + case 8: + return xchg_u64(ptr, x); + } + __xchg_called_with_bad_pointer(); + return x; } extern unsigned long IRQ_vectors[16]; @@ -192,4 +251,9 @@ extern unsigned long exception_handlers[32]; #define set_except_vector(n,addr) \ exception_handlers[n] = (unsigned long) (addr) +/* + * Reset the machine. + */ +extern void (*hard_reset_now)(void); + #endif /* __ASM_MIPS_SYSTEM_H */ diff --git a/include/asm-mips/termbits.h b/include/asm-mips/termbits.h new file mode 100644 index 000000000..336915bce --- /dev/null +++ b/include/asm-mips/termbits.h @@ -0,0 +1,217 @@ +/* + * termbits stuff for Linux/MIPS. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_TERMBITS_H +#define __ASM_MIPS_TERMBITS_H + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned long speed_t; +typedef unsigned long tcflag_t; + +/* + * The ABI says nothing about NCC but seems to use NCCS as + * replacement for it in struct termio + */ +#define NCCS 23 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + /* + * Seems nonexistent in the ABI, but Linux assumes existence ... + */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 /* Interrupt character [ISIG]. */ +#define VQUIT 1 /* Quit character [ISIG]. */ +#define VERASE 2 /* Erase character [ICANON]. */ +#define VKILL 3 /* Kill-line character [ICANON]. */ +#define VEOF 4 /* End-of-file character [ICANON]. */ +#define VMIN VEOF /* Minimum number of bytes read at once [!ICANON]. */ +#define VEOL 5 /* End-of-line character [ICANON]. */ +#define VTIME VEOL /* Time-out value (tenths of a second) [!ICANON]. */ +#if defined (__USE_BSD) || defined (__KERNEL__) +#define VEOL2 6 /* Second EOL character [ICANON]. */ +/* The next two are guesses ... */ +#define VSWTC 7 /* ??? */ +#endif +#define VSWTCH VSWTC +#define VSTART 8 /* Start (X-ON) character [IXON, IXOFF]. */ +#define VSTOP 9 /* Stop (X-OFF) character [IXON, IXOFF]. */ +#define VSUSP 10 /* Suspend character [ISIG]. */ +#if 0 +/* + * VDSUSP is not supported + */ +#if defined (__USE_BSD) || defined (__KERNEL__) +#define VDSUSP 11 /* Delayed suspend character [ISIG]. */ +#endif +#endif +#if defined (__USE_BSD) || defined (__KERNEL__) +#define VREPRINT 12 /* Reprint-line character [ICANON]. */ +#endif +#if defined (__USE_BSD) || defined (__KERNEL__) +#define VDISCARD 13 /* Discard character [IEXTEN]. */ +#define VWERASE 14 /* Word-erase character [ICANON]. */ +#define VLNEXT 15 /* Literal-next character [IEXTEN]. */ +#endif +/* + * 17 - 19 are reserved + */ + +/* c_iflag bits */ +#define IGNBRK 0000001 /* Ignore break condition. */ +#define BRKINT 0000002 /* Signal interrupt on break. */ +#define IGNPAR 0000004 /* Ignore characters with parity errors. */ +#define PARMRK 0000010 /* Mark parity and framing errors. */ +#define INPCK 0000020 /* Enable input parity check. */ +#define ISTRIP 0000040 /* Strip 8th bit off characters. */ +#define INLCR 0000100 /* Map NL to CR on input. */ +#define IGNCR 0000200 /* Ignore CR. */ +#define ICRNL 0000400 /* Map CR to NL on input. */ +#if defined (__USE_BSD) || defined (__KERNEL__) +#define IUCLC 0001000 /* Map upper case to lower case on input. */ +#endif +#define IXON 0002000 /* Enable start/stop output control. */ +#if defined (__USE_BSD) || defined (__KERNEL__) +#define IXANY 0004000 /* Any character will restart after stop. */ +#endif +#define IXOFF 0010000 /* Enable start/stop input control. */ +#if defined (__USE_BSD) || defined (__KERNEL__) +#define IMAXBEL 0020000 /* Ring bell when input queue is full. */ +#endif + +/* c_oflag bits */ +#define OPOST 0000001 /* Perform output processing. */ +#if defined (__USE_BSD) || defined (__KERNEL__) +#define OLCUC 0000002 /* Map lower case to upper case on output. */ +#define ONLCR 0000004 /* Map NL to CR-NL on output. */ +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 +/* +#define PAGEOUT ??? +#define WRAP ??? + */ +#endif + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 /* Number of bits per byte (mask). */ +#define CS5 0000000 /* 5 bits per byte. */ +#define CS6 0000020 /* 6 bits per byte. */ +#define CS7 0000040 /* 7 bits per byte. */ +#define CS8 0000060 /* 8 bits per byte. */ +#define CSTOPB 0000100 /* Two stop bits instead of one. */ +#define CREAD 0000200 /* Enable receiver. */ +#define PARENB 0000400 /* Parity enable. */ +#define PARODD 0001000 /* Odd parity instead of even. */ +#define HUPCL 0002000 /* Hang up on last close. */ +#define CLOCAL 0004000 /* Ignore modem status lines. */ +#if defined (__USE_BSD) || defined (__KERNEL__) +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CRTSCTS 020000000000 /* flow control */ +#endif + +/* c_lflag bits */ +#define ISIG 0000001 /* Enable signals. */ +#define ICANON 0000002 /* Do erase and kill processing. */ +#define XCASE 0000004 +#define ECHO 0000010 /* Enable echo. */ +#define ECHOE 0000020 /* Visual erase for ERASE. */ +#define ECHOK 0000040 /* Echo NL after KILL. */ +#define ECHONL 0000100 /* Echo NL even if ECHO is off. */ +#define NOFLSH 0000200 /* Disable flush after interrupt. */ +#define IEXTEN 0000400 /* Enable DISCARD and LNEXT. */ +#if defined (__USE_BSD) || defined (__KERNEL__) +#define ECHOCTL 0001000 /* Echo control characters as ^X. */ +#define ECHOPRT 0002000 /* Hardcopy visual erase. */ +#define ECHOKE 0004000 /* Visual erase for KILL. */ +#endif +#define FLUSHO 0020000 +#if defined (__USE_BSD) || defined (__KERNEL__) +#define PENDIN 0040000 /* Retype pending input (state). */ +#endif +#define TOSTOP 0100000 /* Send SIGTTOU for background output. */ +#define ITOSTOP TOSTOP + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 /* Suspend output. */ +#define TCOON 1 /* Restart suspended output. */ +#define TCIOFF 2 /* Send a STOP character. */ +#define TCION 3 /* Send a START character. */ + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 /* Discard data received but not yet read. */ +#define TCOFLUSH 1 /* Discard data written but not yet sent. */ +#define TCIOFLUSH 2 /* Discard all pending data. */ + +/* tcsetattr uses these */ +#define TCSANOW 0x540e /* Same as TCSETS; change immediately. */ +#define TCSADRAIN 0x540f /* Same as TCSETSW; change when pending output is written. */ +#define TCSAFLUSH 0x5410 /* Same as TCSETSF; flush pending input before changing. */ + +#endif /* __ASM_MIPS_TERMBITS_H */ diff --git a/include/asm-mips/termios.h b/include/asm-mips/termios.h new file mode 100644 index 000000000..57fcbeef7 --- /dev/null +++ b/include/asm-mips/termios.h @@ -0,0 +1,127 @@ +/* + * ioctls for Linux/MIPS. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_TERMIOS_H + +#include <asm/termbits.h> +#include <asm/ioctls.h> + +struct sgttyb { + char sg_ispeed; + char sg_ospeed; + char sg_erase; + char sg_kill; + int sg_flags; /* SGI special - int, not short */ +}; + +struct tchars { + char t_intrc; + char t_quitc; + char t_startc; + char t_stopc; + char t_eofc; + char t_brkc; +}; + +struct ltchars { + char t_suspc; /* stop process signal */ + char t_dsuspc; /* delayed stop process signal */ + char t_rprntc; /* reprint line */ + char t_flushc; /* flush output (toggles) */ + char t_werasc; /* word erase */ + char t_lnextc; /* literal next character */ +}; + +/* TIOCGSIZE, TIOCSSIZE not defined yet. Only needed for SunOS source + compatibility anyway ... */ + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + char c_line; /* line discipline */ + unsigned char c_cc[NCCS]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* + * intr=^C quit=^\ erase=del kill=^U + * eof=^D eol=time=\0 eol2=\0 swtc=\0 + * start=^Q stop=^S susp=^Z vdsusp= + * reprint=^R discard=^U werase=^W lnext=^V + */ +#define INIT_C_CC "\003\034\177\025\004\0\0\0\021\023\032\0\022\017\027\026" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 /* line enable */ +#define TIOCM_DTR 0x002 /* data terminal ready */ +#define TIOCM_RTS 0x004 /* request to send */ +#define TIOCM_ST 0x010 /* secondary transmit */ +#define TIOCM_SR 0x020 /* secondary receive */ +#define TIOCM_CTS 0x040 /* clear to send */ +#define TIOCM_CAR 0x100 /* carrier detect */ +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RNG 0x200 /* ring */ +#define TIOCM_RI TIOCM_RNG +#define TIOCM_DSR 0x400 /* data set ready */ + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 + +#ifdef __KERNEL__ + +#include <linux/string.h> + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +extern inline void trans_from_termio(struct termio * termio, + struct termios * termios) +{ +#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y)) + SET_LOW_BITS(termios->c_iflag, termio->c_iflag); + SET_LOW_BITS(termios->c_oflag, termio->c_oflag); + SET_LOW_BITS(termios->c_cflag, termio->c_cflag); + SET_LOW_BITS(termios->c_lflag, termio->c_lflag); +#undef SET_LOW_BITS + memcpy(termios->c_cc, termio->c_cc, NCC); +} + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +extern inline void trans_to_termio(struct termios * termios, + struct termio * termio) +{ + termio->c_iflag = termios->c_iflag; + termio->c_oflag = termios->c_oflag; + termio->c_cflag = termios->c_cflag; + termio->c_lflag = termios->c_lflag; + termio->c_line = termios->c_line; + memcpy(termio->c_cc, termios->c_cc, NCC); +} + +#endif /* defined(__KERNEL__) */ + +#endif /* __ASM_MIPS_TERMIOS_H */ diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h index da0310a02..4d27f768b 100644 --- a/include/asm-mips/types.h +++ b/include/asm-mips/types.h @@ -5,36 +5,12 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995 by Waldorf GMBH - * written by Ralf Baechle + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle */ #ifndef __ASM_MIPS_TYPES_H #define __ASM_MIPS_TYPES_H -#ifndef _SIZE_T -#define _SIZE_T -typedef __SIZE_TYPE__ size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __SSIZE_TYPE__ ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef __PTRDIFF_TYPE__ ptrdiff_t; -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef long time_t; -#endif - -#ifndef _CLOCK_T -#define _CLOCK_T -typedef long clock_t; -#endif +typedef unsigned long umode_t; /* * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the @@ -94,33 +70,4 @@ typedef unsigned long u64; #endif /* __KERNEL__ */ -typedef __s32 pid_t; -typedef __s32 uid_t; -typedef __s32 gid_t; -typedef __u32 dev_t; -typedef __u32 ino_t; -typedef __u32 mode_t; -typedef __u32 umode_t; -typedef __u32 nlink_t; -typedef long daddr_t; -typedef long off_t; - -#if 0 -/* - * These definitions double the definitions from <gnu/types.h>. - */ -#undef __FDELT -#define __FDELT(d) ((d) / __NFDBITS) -#undef __FDMASK -#define __FDMASK(d) (1 << ((d) % __NFDBITS)) -#undef __FD_SET -#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) -#undef __FD_CLR -#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) -#undef __FD_ISSET -#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) -#undef __FD_ZERO -#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) -#endif - #endif /* __ASM_MIPS_TYPES_H */ diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h new file mode 100644 index 000000000..48a205077 --- /dev/null +++ b/include/asm-mips/uaccess.h @@ -0,0 +1,314 @@ +/* + * include/asm-mips/uaccess.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_UACCESS_H +#define __ASM_MIPS_UACCESS_H + +#include <linux/errno.h> +#include <linux/sched.h> +#include <asm/asm.h> + +#define STR(x) __STR(x) +#define __STR(x) #x + +/* + * 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 KERNEL_DS 0 +#define USER_DS 1 + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define get_fs() (current->tss.segment) +#define set_fs(x) (current->tss.segment=(x)) + +static inline unsigned long get_ds(void) +{ + return KERNEL_DS; +} + +/* + * Is a address valid? This does a straighforward calculation rather + * than tests. + * + * Address valid if: + * - "addr" doesn't have any high-bits set + * - AND "size" doesn't have any high-bits set + * - AND "addr+size" doesn't have any high-bits set + * - OR we are in kernel mode. + */ +#define __access_ok(addr,size,mask) \ + (((__signed__ long)((mask)&(addr | size | (addr+size)))) >= 0) +#define __access_mask (-(long)get_fs()) + +#define access_ok(type,addr,size) \ +__access_ok(((unsigned long)(addr)),(size),__access_mask) + +extern inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size) ? 0 : -EFAULT; +} + +/* + * Uh, these should become the main single-value transfer routines ... + * They automatically use the right size if we just have the right + * pointer type ... + * + * As MIPS uses the same address space for kernel and user data, we + * can just do these as direct assignments. + * + * Careful to not + * (a) re-use the arguments for side effects (sizeof is ok) + * (b) require any knowledge of processes at this stage + */ +#define put_user(x,ptr) __put_user_check((x),(ptr),sizeof(*(ptr)),__access_mask) +#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr)),__access_mask) + +/* + * The "__xxx" versions do not do address space checking, useful when + * doing multiple accesses to the same area (the user has to do the + * checks by hand with "access_ok()") + */ +#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr))) +#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr))) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) (*(struct __large_struct *)(x)) + +#define copy_to_user(to,from,n) __copy_tofrom_user((to),(from),(n),__cu_to) +#define copy_from_user(to,from,n) __copy_tofrom_user((to),(from),(n),__cu_from) + +extern size_t __copy_user(void *__to, const void *__from, size_t __n); + +#define __copy_tofrom_user(to,from,n,v) ({ \ + void * __cu_to; \ + const void * __cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + if (__access_ok(((unsigned long)(v)),__cu_len,__access_mask)) \ + __cu_len = __copy_user(__cu_to, __cu_from, __cu_len); \ + __cu_len; \ +}) + +#define __get_user_nocheck(x,ptr,size) ({ \ +long __gu_err; \ +long __gu_val; \ +long __gu_addr; \ +__asm__("":"=r" (__gu_val)); \ +__gu_addr = (long) (ptr); \ +__gu_err = 0; \ +switch (size) { \ +case 1: __get_user_nocheck_asm("lb"); break; \ +case 2: __get_user_nocheck_asm("lh"); break; \ +case 4: __get_user_nocheck_asm("lw"); break; \ +case 8: __get_user_nocheck_asm("ld"); break; \ +default: __get_user_unknown(); break; \ +} x = (__typeof__(*(ptr))) __gu_val; __gu_err; }) + +#define __get_user_nocheck_asm(insn) \ +({ \ +__asm__ __volatile__( \ + "1:\t" insn "\t%1,%3\n" \ + "2:\n\t" \ + ".section\t.fixup,\"ax\"\n" \ + "3:\t.set\tnoat\n\t" \ + "la\t$1,2b\n\t" \ + "li\t%0,%4\n\t" \ + "jr\t$1\n\t" \ + ".set\tat\n\t" \ + ".section\t__ex_table,\"a\"\n\t" \ + STR(PTR)"\t1b,3b\n\t" \ + ".text" \ + :"=r" (__gu_err), "=r" (__gu_val) \ + :"0" (__gu_err), "o" (__m(__gu_addr)), "i" (-EFAULT) \ + :"$1"); }) + +#define __get_user_check(x,ptr,size,mask) ({ \ +long __gu_err; \ +long __gu_val; \ +long __gu_addr; \ +__asm__("":"=r" (__gu_val)); \ +__gu_addr = (long) (ptr); \ +__gu_err = -EFAULT; \ +if (__access_ok(__gu_addr,size,mask)) { \ +switch (size) { \ +case 1: __get_user_check_asm("lb"); break; \ +case 2: __get_user_check_asm("lh"); break; \ +case 4: __get_user_check_asm("lw"); break; \ +case 8: __get_user_check_asm("ld"); break; \ +default: __get_user_unknown(); break; \ +} } x = (__typeof__(*(ptr))) __gu_val; __gu_err; }) + +#define __get_user_check_asm(insn) \ +({ \ +__asm__ __volatile__( \ + "1:\t" insn "\t%1,%2\n\t" \ + "move\t%0,$0\n" \ + "2:\n\t" \ + ".section\t.fixup,\"ax\"\n" \ + "3:\t.set\tnoat\n\t" \ + "la\t$1,2b\n\t" \ + "jr\t$1\n\t" \ + ".set\tat\n\t" \ + ".section\t__ex_table,\"a\"\n\t" \ + STR(PTR)"\t1b,3b\n\t" \ + ".text" \ + :"=r" (__gu_err), "=r" (__gu_val) \ + :"o" (__m(__gu_addr)) \ + :"$1"); }) + +extern void __get_user_unknown(void); + +#define __put_user_nocheck(x,ptr,size) ({ \ +long __pu_err; \ +__typeof__(*(ptr)) __pu_val; \ +long __pu_addr; \ +__pu_val = (x); \ +__pu_addr = (long) (ptr); \ +__pu_err = 0; \ +switch (size) { \ +case 1: __put_user_nocheck_asm("sb"); break; \ +case 2: __put_user_nocheck_asm("sh"); break; \ +case 4: __put_user_nocheck_asm("sw"); break; \ +case 8: __put_user_nocheck_asm("sd"); break; \ +default: __put_user_unknown(); break; \ +} __pu_err; }) + +#define __put_user_nocheck_asm(insn) \ +({ \ +__asm__ __volatile__( \ + "1:\t" insn "\t%1,%2\n" \ + "2:\n\t" \ + ".section\t.fixup,\"ax\"\n" \ + "3:\t.set\tnoat\n\t" \ + "la\t$1,2b\n\t" \ + "li\t%0,%3\n\t" \ + "jr\t$1\n\t" \ + ".set\tat\n\t" \ + ".section\t__ex_table,\"a\"\n\t" \ + STR(PTR)"\t1b,3b\n\t" \ + ".text" \ + :"=r" (__pu_err) \ + :"r" (__pu_val), "o" (__m(__pu_addr)), "i" (-EFAULT) \ + :"$1"); }) + +#define __put_user_check(x,ptr,size,mask) ({ \ +long __pu_err; \ +__typeof__(*(ptr)) __pu_val; \ +long __pu_addr; \ +__pu_val = (x); \ +__pu_addr = (long) (ptr); \ +__pu_err = -EFAULT; \ +if (__access_ok(__pu_addr,size,mask)) { \ +switch (size) { \ +case 1: __put_user_check_asm("sb"); break; \ +case 2: __put_user_check_asm("sh"); break; \ +case 4: __put_user_check_asm("sw"); break; \ +case 8: __put_user_check_asm("sd"); break; \ +default: __put_user_unknown(); break; \ +} } __pu_err; }) + +#define __put_user_check_asm(insn) \ +({ \ +__asm__ __volatile__( \ + "1:\t" insn "\t%1,%2\n\t" \ + "move\t%0,$0\n" \ + "2:\n\t" \ + ".section\t.fixup,\"ax\"\n" \ + "3:\t.set\tnoat\n\t" \ + "la\t$1,2b\n\t" \ + "jr\t$1\n\t" \ + ".set\tat\n\t" \ + ".section\t__ex_table,\"a\"\n\t" \ + STR(PTR)"\t1b,3b\n\t" \ + ".text" \ + :"=r" (__pu_err) \ + :"r" (__pu_val), "o" (__m(__pu_addr)) \ + :"$1"); }) + +extern void __put_user_unknown(void); + +#define __clear_user(addr,size) \ +({ \ + void *__cu_end; \ + __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + "1:\tsb\t$0,(%0)\n\t" \ + "bne\t%0,%1,1b\n\t" \ + "addiu\t%0,1\n" \ + "2:\t.set\treorder\n\t" \ + ".section\t.fixup,\"ax\"\n" \ + "3:\t.set\tnoat\n\t" \ + "la\t$1,2b\n\t" \ + "jr\t$1\n\t" \ + ".set\tat\n\t" \ + ".section\t__ex_table,\"a\"\n\t" \ + STR(PTR)"\t1b,3b\n\t" \ + ".text" \ + :"=r" (addr), "=r" (__cu_end) \ + :"0" (addr), "1" (addr + size - 1), "i" (-EFAULT) \ + :"$1","memory"); \ + size = __cu_end - (addr) - 1; \ +}) + +#define clear_user(addr,n) ({ \ +void * __cl_addr = (addr); \ +unsigned long __cl_size = (n); \ +if (__cl_size && __access_ok(VERIFY_WRITE, ((unsigned long)(__cl_addr)), __cl_size)) \ +__clear_user(__cl_addr, __cl_size); \ +__cl_size; }) + +/* + * Returns: -EFAULT if exception before terminator, N if the entire + * buffer filled, else strlen. + */ +extern long __strncpy_from_user(char *__to, const char *__from, long __to_len); + +#define strncpy_from_user(dest,src,count) ({ \ + const void * __sc_src = (src); \ + long __sc_res = -EFAULT; \ + if (access_ok(VERIFY_READ, __sc_src, 0)) { \ + __sc_res = __strncpy_from_user(dest, __sc_src, count); \ +} __sc_res; }) + +/* Returns: 0 if bad, string length+1 (memory size) of string if ok */ +extern long __strlen_user(const char *); + +extern inline long strlen_user(const char *str) +{ + long len = __strlen_user(str); + if (!access_ok(VERIFY_READ, str, len)) + len = 0; + return len; +} + +struct exception_table_entry +{ + unsigned long insn; + unsigned long nextinsn; +}; + +/* Returns 0 if exception not found and fixup.unit otherwise. */ +extern unsigned long search_exception_table(unsigned long addr); + +/* Returns the new pc */ +#define fixup_exception(map_reg, fixup_unit, pc) \ +({ \ + fixup_unit; \ +}) + +#endif /* __ASM_MIPS_UACCESS_H */ diff --git a/include/asm-mips/unaligned.h b/include/asm-mips/unaligned.h new file mode 100644 index 000000000..95eb47f55 --- /dev/null +++ b/include/asm-mips/unaligned.h @@ -0,0 +1,176 @@ +/* + * Inline functions to do unaligned accesses. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ +#ifndef __ASM_MIPS_UNALIGNED_H +#define __ASM_MIPS_UNALIGNED_H + +#if 0 +/* + * The following macros are the portable and efficient versions of + * get_unaligned()/put_unaligned(). They work but due to some lackings in the + * MIPS machine description of GCC generate only good code only for accessing + * word sized data. We only use get_unaligned() for accessing unaligned ints + * and then GCC makes full score anyway ... + */ +#define get_unaligned(ptr) \ + ({ \ + struct __unal { \ + __typeof__(*(ptr)) __x __attribute__((packed)); \ + }; \ + \ + ((struct __unal *)(ptr))->__x; \ + }) + +#define put_unaligned(ptr,val) \ + ({ \ + struct __unal { \ + __typeof__(*(ptr)) __x __attribute__((packed)); \ + }; \ + \ + ((struct __unal *)(ptr))->__x = (val); \ + }) +#else + +/* + * The main single-value unaligned transfer routines. + */ +#define get_unaligned(ptr) \ + ((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr)))) +#define put_unaligned(x,ptr) \ + __put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr))) + +/* + * This is a silly but good way to make sure that + * the get/put functions are indeed always optimized, + * and that we use the correct sizes. + */ +extern void bad_unaligned_access_length(void); + +/* + * Load unaligned doubleword. + */ +extern __inline__ unsigned long __uld(const unsigned long long * __addr) +{ + unsigned long long __res; + + __asm__("uld\t%0,(%1)" + :"=&r" (__res) + :"r" (__addr)); + + return __res; +} + +/* + * Load unaligned word. + */ +extern __inline__ unsigned long __ulw(const unsigned int * __addr) +{ + unsigned long __res; + + __asm__("ulw\t%0,(%1)" + :"=&r" (__res) + :"r" (__addr)); + + return __res; +} + +/* + * Load unaligned halfword. + */ +extern __inline__ unsigned long __ulh(const unsigned short * __addr) +{ + unsigned long __res; + + __asm__("ulh\t%0,(%1)" + :"=&r" (__res) + :"r" (__addr)); + + return __res; +} + +/* + * Store unaligned doubleword. + */ +extern __inline__ void __usd(unsigned long __val, unsigned long long * __addr) +{ + __asm__ __volatile__( + "usd\t%0,(%1)" + : /* No results */ + :"r" (__val), + "r" (__addr)); +} + +/* + * Store unaligned word. + */ +extern __inline__ void __usw(unsigned long __val, unsigned int * __addr) +{ + __asm__ __volatile__( + "usw\t%0,(%1)" + : /* No results */ + :"r" (__val), + "r" (__addr)); +} + +/* + * Store unaligned halfword. + */ +extern __inline__ void __ush(unsigned long __val, unsigned short * __addr) +{ + __asm__ __volatile__( + "ush\t%0,(%1)" + : /* No results */ + :"r" (__val), + "r" (__addr)); +} + +extern inline unsigned long __get_unaligned(const void *ptr, size_t size) +{ + unsigned long val; + switch (size) { + case 1: + val = *(const unsigned char *)ptr; + break; + case 2: + val = __ulh((const unsigned short *)ptr); + break; + case 4: + val = __ulw((const unsigned int *)ptr); + break; + case 8: + val = __uld((const unsigned long long *)ptr); + break; + default: + bad_unaligned_access_length(); + } + return val; +} + +extern inline void __put_unaligned(unsigned long val, void *ptr, size_t size) +{ + switch (size) { + case 1: + *(unsigned char *)ptr = (val); + break; + case 2: + __ush(val, (unsigned short *)ptr); + break; + case 4: + __usw(val, (unsigned int *)ptr); + break; + case 8: + __usd(val, (unsigned long long *)ptr); + break; + default: + bad_unaligned_access_length(); + } +} +#endif + +#endif /* __ASM_MIPS_UNALIGNED_H */ diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 94878e595..8db0d3cee 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -1,32 +1,1222 @@ +/* + * This file contains the system call numbers. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996 by Ralf Baechle + * + * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto + * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A + */ #ifndef __ASM_MIPS_UNISTD_H #define __ASM_MIPS_UNISTD_H +/* + * The syscalls 0 - 3999 are reserved for a down to the root syscall + * compatibility with RISC/os and IRIX. None of these syscalls has yet been + * implemented. We'll see how to deal with the various "real" BSD variants + * like Ultrix, NetBSD ... + */ + +/* + * SVR4 syscalls are in the range from 1 to 999 + */ +#define __NR_SVR4 0 +#define __NR_SVR4_syscall (__NR_SVR4 + 0) +#define __NR_SVR4_exit (__NR_SVR4 + 1) +#define __NR_SVR4_fork (__NR_SVR4 + 2) +#define __NR_SVR4_read (__NR_SVR4 + 3) +#define __NR_SVR4_write (__NR_SVR4 + 4) +#define __NR_SVR4_open (__NR_SVR4 + 5) +#define __NR_SVR4_close (__NR_SVR4 + 6) +#define __NR_SVR4_wait (__NR_SVR4 + 7) +#define __NR_SVR4_creat (__NR_SVR4 + 8) +#define __NR_SVR4_link (__NR_SVR4 + 9) +#define __NR_SVR4_unlink (__NR_SVR4 + 10) +#define __NR_SVR4_exec (__NR_SVR4 + 11) +#define __NR_SVR4_chdir (__NR_SVR4 + 12) +#define __NR_SVR4_gtime (__NR_SVR4 + 13) +#define __NR_SVR4_mknod (__NR_SVR4 + 14) +#define __NR_SVR4_chmod (__NR_SVR4 + 15) +#define __NR_SVR4_chown (__NR_SVR4 + 16) +#define __NR_SVR4_sbreak (__NR_SVR4 + 17) +#define __NR_SVR4_stat (__NR_SVR4 + 18) +#define __NR_SVR4_lseek (__NR_SVR4 + 19) +#define __NR_SVR4_getpid (__NR_SVR4 + 20) +#define __NR_SVR4_mount (__NR_SVR4 + 21) +#define __NR_SVR4_umount (__NR_SVR4 + 22) +#define __NR_SVR4_setuid (__NR_SVR4 + 23) +#define __NR_SVR4_getuid (__NR_SVR4 + 24) +#define __NR_SVR4_stime (__NR_SVR4 + 25) +#define __NR_SVR4_ptrace (__NR_SVR4 + 26) +#define __NR_SVR4_alarm (__NR_SVR4 + 27) +#define __NR_SVR4_fstat (__NR_SVR4 + 28) +#define __NR_SVR4_pause (__NR_SVR4 + 29) +#define __NR_SVR4_utime (__NR_SVR4 + 30) +#define __NR_SVR4_stty (__NR_SVR4 + 31) +#define __NR_SVR4_gtty (__NR_SVR4 + 32) +#define __NR_SVR4_access (__NR_SVR4 + 33) +#define __NR_SVR4_nice (__NR_SVR4 + 34) +#define __NR_SVR4_statfs (__NR_SVR4 + 35) +#define __NR_SVR4_sync (__NR_SVR4 + 36) +#define __NR_SVR4_kill (__NR_SVR4 + 37) +#define __NR_SVR4_fstatfs (__NR_SVR4 + 38) +#define __NR_SVR4_setpgrp (__NR_SVR4 + 39) +#define __NR_SVR4_cxenix (__NR_SVR4 + 40) +#define __NR_SVR4_dup (__NR_SVR4 + 41) +#define __NR_SVR4_pipe (__NR_SVR4 + 42) +#define __NR_SVR4_times (__NR_SVR4 + 43) +#define __NR_SVR4_profil (__NR_SVR4 + 44) +#define __NR_SVR4_plock (__NR_SVR4 + 45) +#define __NR_SVR4_setgid (__NR_SVR4 + 46) +#define __NR_SVR4_getgid (__NR_SVR4 + 47) +#define __NR_SVR4_sig (__NR_SVR4 + 48) +#define __NR_SVR4_msgsys (__NR_SVR4 + 49) +#define __NR_SVR4_sysmips (__NR_SVR4 + 50) +#define __NR_SVR4_sysacct (__NR_SVR4 + 51) +#define __NR_SVR4_shmsys (__NR_SVR4 + 52) +#define __NR_SVR4_semsys (__NR_SVR4 + 53) +#define __NR_SVR4_ioctl (__NR_SVR4 + 54) +#define __NR_SVR4_uadmin (__NR_SVR4 + 55) +#define __NR_SVR4_exch (__NR_SVR4 + 56) +#define __NR_SVR4_utssys (__NR_SVR4 + 57) +#define __NR_SVR4_fsync (__NR_SVR4 + 58) +#define __NR_SVR4_exece (__NR_SVR4 + 59) +#define __NR_SVR4_umask (__NR_SVR4 + 60) +#define __NR_SVR4_chroot (__NR_SVR4 + 61) +#define __NR_SVR4_fcntl (__NR_SVR4 + 62) +#define __NR_SVR4_ulimit (__NR_SVR4 + 63) +#define __NR_SVR4_reserved1 (__NR_SVR4 + 64) +#define __NR_SVR4_reserved2 (__NR_SVR4 + 65) +#define __NR_SVR4_reserved3 (__NR_SVR4 + 66) +#define __NR_SVR4_reserved4 (__NR_SVR4 + 67) +#define __NR_SVR4_reserved5 (__NR_SVR4 + 68) +#define __NR_SVR4_reserved6 (__NR_SVR4 + 69) +#define __NR_SVR4_advfs (__NR_SVR4 + 70) +#define __NR_SVR4_unadvfs (__NR_SVR4 + 71) +#define __NR_SVR4_unused1 (__NR_SVR4 + 72) +#define __NR_SVR4_unused2 (__NR_SVR4 + 73) +#define __NR_SVR4_rfstart (__NR_SVR4 + 74) +#define __NR_SVR4_unused3 (__NR_SVR4 + 75) +#define __NR_SVR4_rdebug (__NR_SVR4 + 76) +#define __NR_SVR4_rfstop (__NR_SVR4 + 77) +#define __NR_SVR4_rfsys (__NR_SVR4 + 78) +#define __NR_SVR4_rmdir (__NR_SVR4 + 79) +#define __NR_SVR4_mkdir (__NR_SVR4 + 80) +#define __NR_SVR4_getdents (__NR_SVR4 + 81) +#define __NR_SVR4_libattach (__NR_SVR4 + 82) +#define __NR_SVR4_libdetach (__NR_SVR4 + 83) +#define __NR_SVR4_sysfs (__NR_SVR4 + 84) +#define __NR_SVR4_getmsg (__NR_SVR4 + 85) +#define __NR_SVR4_putmsg (__NR_SVR4 + 86) +#define __NR_SVR4_poll (__NR_SVR4 + 87) +#define __NR_SVR4_lstat (__NR_SVR4 + 88) +#define __NR_SVR4_symlink (__NR_SVR4 + 89) +#define __NR_SVR4_readlink (__NR_SVR4 + 90) +#define __NR_SVR4_setgroups (__NR_SVR4 + 91) +#define __NR_SVR4_getgroups (__NR_SVR4 + 92) +#define __NR_SVR4_fchmod (__NR_SVR4 + 93) +#define __NR_SVR4_fchown (__NR_SVR4 + 94) +#define __NR_SVR4_sigprocmask (__NR_SVR4 + 95) +#define __NR_SVR4_sigsuspend (__NR_SVR4 + 96) +#define __NR_SVR4_sigaltstack (__NR_SVR4 + 97) +#define __NR_SVR4_sigaction (__NR_SVR4 + 98) +#define __NR_SVR4_sigpending (__NR_SVR4 + 99) +#define __NR_SVR4_setcontext (__NR_SVR4 + 100) +#define __NR_SVR4_evsys (__NR_SVR4 + 101) +#define __NR_SVR4_evtrapret (__NR_SVR4 + 102) +#define __NR_SVR4_statvfs (__NR_SVR4 + 103) +#define __NR_SVR4_fstatvfs (__NR_SVR4 + 104) +#define __NR_SVR4_reserved7 (__NR_SVR4 + 105) +#define __NR_SVR4_nfssys (__NR_SVR4 + 106) +#define __NR_SVR4_waitid (__NR_SVR4 + 107) +#define __NR_SVR4_sigsendset (__NR_SVR4 + 108) +#define __NR_SVR4_hrtsys (__NR_SVR4 + 109) +#define __NR_SVR4_acancel (__NR_SVR4 + 110) +#define __NR_SVR4_async (__NR_SVR4 + 111) +#define __NR_SVR4_priocntlset (__NR_SVR4 + 112) +#define __NR_SVR4_pathconf (__NR_SVR4 + 113) +#define __NR_SVR4_mincore (__NR_SVR4 + 114) +#define __NR_SVR4_mmap (__NR_SVR4 + 115) +#define __NR_SVR4_mprotect (__NR_SVR4 + 116) +#define __NR_SVR4_munmap (__NR_SVR4 + 117) +#define __NR_SVR4_fpathconf (__NR_SVR4 + 118) +#define __NR_SVR4_vfork (__NR_SVR4 + 119) +#define __NR_SVR4_fchdir (__NR_SVR4 + 120) +#define __NR_SVR4_readv (__NR_SVR4 + 121) +#define __NR_SVR4_writev (__NR_SVR4 + 122) +#define __NR_SVR4_xstat (__NR_SVR4 + 123) +#define __NR_SVR4_lxstat (__NR_SVR4 + 124) +#define __NR_SVR4_fxstat (__NR_SVR4 + 125) +#define __NR_SVR4_xmknod (__NR_SVR4 + 126) +#define __NR_SVR4_clocal (__NR_SVR4 + 127) +#define __NR_SVR4_setrlimit (__NR_SVR4 + 128) +#define __NR_SVR4_getrlimit (__NR_SVR4 + 129) +#define __NR_SVR4_lchown (__NR_SVR4 + 130) +#define __NR_SVR4_memcntl (__NR_SVR4 + 131) +#define __NR_SVR4_getpmsg (__NR_SVR4 + 132) +#define __NR_SVR4_putpmsg (__NR_SVR4 + 133) +#define __NR_SVR4_rename (__NR_SVR4 + 134) +#define __NR_SVR4_nuname (__NR_SVR4 + 135) +#define __NR_SVR4_setegid (__NR_SVR4 + 136) +#define __NR_SVR4_sysconf (__NR_SVR4 + 137) +#define __NR_SVR4_adjtime (__NR_SVR4 + 138) +#define __NR_SVR4_sysinfo (__NR_SVR4 + 139) +#define __NR_SVR4_reserved8 (__NR_SVR4 + 140) +#define __NR_SVR4_seteuid (__NR_SVR4 + 141) +#define __NR_SVR4_PYRAMID_statis (__NR_SVR4 + 142) +#define __NR_SVR4_PYRAMID_tuning (__NR_SVR4 + 143) +#define __NR_SVR4_PYRAMID_forcerr (__NR_SVR4 + 144) +#define __NR_SVR4_PYRAMID_mpcntl (__NR_SVR4 + 145) +#define __NR_SVR4_reserved9 (__NR_SVR4 + 146) +#define __NR_SVR4_reserved10 (__NR_SVR4 + 147) +#define __NR_SVR4_reserved11 (__NR_SVR4 + 148) +#define __NR_SVR4_reserved12 (__NR_SVR4 + 149) +#define __NR_SVR4_reserved13 (__NR_SVR4 + 150) +#define __NR_SVR4_reserved14 (__NR_SVR4 + 151) +#define __NR_SVR4_reserved15 (__NR_SVR4 + 152) +#define __NR_SVR4_reserved16 (__NR_SVR4 + 153) +#define __NR_SVR4_reserved17 (__NR_SVR4 + 154) +#define __NR_SVR4_reserved18 (__NR_SVR4 + 155) +#define __NR_SVR4_reserved19 (__NR_SVR4 + 156) +#define __NR_SVR4_reserved20 (__NR_SVR4 + 157) +#define __NR_SVR4_reserved21 (__NR_SVR4 + 158) +#define __NR_SVR4_reserved22 (__NR_SVR4 + 159) +#define __NR_SVR4_reserved23 (__NR_SVR4 + 160) +#define __NR_SVR4_reserved24 (__NR_SVR4 + 161) +#define __NR_SVR4_reserved25 (__NR_SVR4 + 162) +#define __NR_SVR4_reserved26 (__NR_SVR4 + 163) +#define __NR_SVR4_reserved27 (__NR_SVR4 + 164) +#define __NR_SVR4_reserved28 (__NR_SVR4 + 165) +#define __NR_SVR4_reserved29 (__NR_SVR4 + 166) +#define __NR_SVR4_reserved30 (__NR_SVR4 + 167) +#define __NR_SVR4_reserved31 (__NR_SVR4 + 168) +#define __NR_SVR4_reserved32 (__NR_SVR4 + 169) +#define __NR_SVR4_reserved33 (__NR_SVR4 + 170) +#define __NR_SVR4_reserved34 (__NR_SVR4 + 171) +#define __NR_SVR4_reserved35 (__NR_SVR4 + 172) +#define __NR_SVR4_reserved36 (__NR_SVR4 + 173) +#define __NR_SVR4_reserved37 (__NR_SVR4 + 174) +#define __NR_SVR4_reserved38 (__NR_SVR4 + 175) +#define __NR_SVR4_reserved39 (__NR_SVR4 + 176) +#define __NR_SVR4_reserved40 (__NR_SVR4 + 177) +#define __NR_SVR4_reserved41 (__NR_SVR4 + 178) +#define __NR_SVR4_reserved42 (__NR_SVR4 + 179) +#define __NR_SVR4_reserved43 (__NR_SVR4 + 180) +#define __NR_SVR4_reserved44 (__NR_SVR4 + 181) +#define __NR_SVR4_reserved45 (__NR_SVR4 + 182) +#define __NR_SVR4_reserved46 (__NR_SVR4 + 183) +#define __NR_SVR4_reserved47 (__NR_SVR4 + 184) +#define __NR_SVR4_reserved48 (__NR_SVR4 + 185) +#define __NR_SVR4_reserved49 (__NR_SVR4 + 186) +#define __NR_SVR4_reserved50 (__NR_SVR4 + 187) +#define __NR_SVR4_reserved51 (__NR_SVR4 + 188) +#define __NR_SVR4_reserved52 (__NR_SVR4 + 189) +#define __NR_SVR4_reserved53 (__NR_SVR4 + 190) +#define __NR_SVR4_reserved54 (__NR_SVR4 + 191) +#define __NR_SVR4_reserved55 (__NR_SVR4 + 192) +#define __NR_SVR4_reserved56 (__NR_SVR4 + 193) +#define __NR_SVR4_reserved57 (__NR_SVR4 + 194) +#define __NR_SVR4_reserved58 (__NR_SVR4 + 195) +#define __NR_SVR4_reserved59 (__NR_SVR4 + 196) +#define __NR_SVR4_reserved60 (__NR_SVR4 + 197) +#define __NR_SVR4_reserved61 (__NR_SVR4 + 198) +#define __NR_SVR4_reserved62 (__NR_SVR4 + 199) +#define __NR_SVR4_reserved63 (__NR_SVR4 + 200) +#define __NR_SVR4_aread (__NR_SVR4 + 201) +#define __NR_SVR4_awrite (__NR_SVR4 + 202) +#define __NR_SVR4_listio (__NR_SVR4 + 203) +#define __NR_SVR4_mips_acancel (__NR_SVR4 + 204) +#define __NR_SVR4_astatus (__NR_SVR4 + 205) +#define __NR_SVR4_await (__NR_SVR4 + 206) +#define __NR_SVR4_areadv (__NR_SVR4 + 207) +#define __NR_SVR4_awritev (__NR_SVR4 + 208) +#define __NR_SVR4_MIPS_reserved1 (__NR_SVR4 + 209) +#define __NR_SVR4_MIPS_reserved2 (__NR_SVR4 + 210) +#define __NR_SVR4_MIPS_reserved3 (__NR_SVR4 + 211) +#define __NR_SVR4_MIPS_reserved4 (__NR_SVR4 + 212) +#define __NR_SVR4_MIPS_reserved5 (__NR_SVR4 + 213) +#define __NR_SVR4_MIPS_reserved6 (__NR_SVR4 + 214) +#define __NR_SVR4_MIPS_reserved7 (__NR_SVR4 + 215) +#define __NR_SVR4_MIPS_reserved8 (__NR_SVR4 + 216) +#define __NR_SVR4_MIPS_reserved9 (__NR_SVR4 + 217) +#define __NR_SVR4_MIPS_reserved10 (__NR_SVR4 + 218) +#define __NR_SVR4_MIPS_reserved11 (__NR_SVR4 + 219) +#define __NR_SVR4_MIPS_reserved12 (__NR_SVR4 + 220) +#define __NR_SVR4_CDC_reserved1 (__NR_SVR4 + 221) +#define __NR_SVR4_CDC_reserved2 (__NR_SVR4 + 222) +#define __NR_SVR4_CDC_reserved3 (__NR_SVR4 + 223) +#define __NR_SVR4_CDC_reserved4 (__NR_SVR4 + 224) +#define __NR_SVR4_CDC_reserved5 (__NR_SVR4 + 225) +#define __NR_SVR4_CDC_reserved6 (__NR_SVR4 + 226) +#define __NR_SVR4_CDC_reserved7 (__NR_SVR4 + 227) +#define __NR_SVR4_CDC_reserved8 (__NR_SVR4 + 228) +#define __NR_SVR4_CDC_reserved9 (__NR_SVR4 + 229) +#define __NR_SVR4_CDC_reserved10 (__NR_SVR4 + 230) +#define __NR_SVR4_CDC_reserved11 (__NR_SVR4 + 231) +#define __NR_SVR4_CDC_reserved12 (__NR_SVR4 + 232) +#define __NR_SVR4_CDC_reserved13 (__NR_SVR4 + 233) +#define __NR_SVR4_CDC_reserved14 (__NR_SVR4 + 234) +#define __NR_SVR4_CDC_reserved15 (__NR_SVR4 + 235) +#define __NR_SVR4_CDC_reserved16 (__NR_SVR4 + 236) +#define __NR_SVR4_CDC_reserved17 (__NR_SVR4 + 237) +#define __NR_SVR4_CDC_reserved18 (__NR_SVR4 + 238) +#define __NR_SVR4_CDC_reserved19 (__NR_SVR4 + 239) +#define __NR_SVR4_CDC_reserved20 (__NR_SVR4 + 240) + +/* + * SYS V syscalls are in the range from 1000 to 1999 + */ +#define __NR_SYSV 1000 +#define __NR_SYSV_syscall (__NR_SYSV + 0) +#define __NR_SYSV_exit (__NR_SYSV + 1) +#define __NR_SYSV_fork (__NR_SYSV + 2) +#define __NR_SYSV_read (__NR_SYSV + 3) +#define __NR_SYSV_write (__NR_SYSV + 4) +#define __NR_SYSV_open (__NR_SYSV + 5) +#define __NR_SYSV_close (__NR_SYSV + 6) +#define __NR_SYSV_wait (__NR_SYSV + 7) +#define __NR_SYSV_creat (__NR_SYSV + 8) +#define __NR_SYSV_link (__NR_SYSV + 9) +#define __NR_SYSV_unlink (__NR_SYSV + 10) +#define __NR_SYSV_execv (__NR_SYSV + 11) +#define __NR_SYSV_chdir (__NR_SYSV + 12) +#define __NR_SYSV_time (__NR_SYSV + 13) +#define __NR_SYSV_mknod (__NR_SYSV + 14) +#define __NR_SYSV_chmod (__NR_SYSV + 15) +#define __NR_SYSV_chown (__NR_SYSV + 16) +#define __NR_SYSV_brk (__NR_SYSV + 17) +#define __NR_SYSV_stat (__NR_SYSV + 18) +#define __NR_SYSV_lseek (__NR_SYSV + 19) +#define __NR_SYSV_getpid (__NR_SYSV + 20) +#define __NR_SYSV_mount (__NR_SYSV + 21) +#define __NR_SYSV_umount (__NR_SYSV + 22) +#define __NR_SYSV_setuid (__NR_SYSV + 23) +#define __NR_SYSV_getuid (__NR_SYSV + 24) +#define __NR_SYSV_stime (__NR_SYSV + 25) +#define __NR_SYSV_ptrace (__NR_SYSV + 26) +#define __NR_SYSV_alarm (__NR_SYSV + 27) +#define __NR_SYSV_fstat (__NR_SYSV + 28) +#define __NR_SYSV_pause (__NR_SYSV + 29) +#define __NR_SYSV_utime (__NR_SYSV + 30) +#define __NR_SYSV_stty (__NR_SYSV + 31) +#define __NR_SYSV_gtty (__NR_SYSV + 32) +#define __NR_SYSV_access (__NR_SYSV + 33) +#define __NR_SYSV_nice (__NR_SYSV + 34) +#define __NR_SYSV_statfs (__NR_SYSV + 35) +#define __NR_SYSV_sync (__NR_SYSV + 36) +#define __NR_SYSV_kill (__NR_SYSV + 37) +#define __NR_SYSV_fstatfs (__NR_SYSV + 38) +#define __NR_SYSV_setpgrp (__NR_SYSV + 39) +#define __NR_SYSV_syssgi (__NR_SYSV + 40) +#define __NR_SYSV_dup (__NR_SYSV + 41) +#define __NR_SYSV_pipe (__NR_SYSV + 42) +#define __NR_SYSV_times (__NR_SYSV + 43) +#define __NR_SYSV_profil (__NR_SYSV + 44) +#define __NR_SYSV_plock (__NR_SYSV + 45) +#define __NR_SYSV_setgid (__NR_SYSV + 46) +#define __NR_SYSV_getgid (__NR_SYSV + 47) +#define __NR_SYSV_sig (__NR_SYSV + 48) +#define __NR_SYSV_msgsys (__NR_SYSV + 49) +#define __NR_SYSV_sysmips (__NR_SYSV + 50) +#define __NR_SYSV_acct (__NR_SYSV + 51) +#define __NR_SYSV_shmsys (__NR_SYSV + 52) +#define __NR_SYSV_semsys (__NR_SYSV + 53) +#define __NR_SYSV_ioctl (__NR_SYSV + 54) +#define __NR_SYSV_uadmin (__NR_SYSV + 55) +#define __NR_SYSV_sysmp (__NR_SYSV + 56) +#define __NR_SYSV_utssys (__NR_SYSV + 57) +#define __NR_SYSV_USG_reserved1 (__NR_SYSV + 58) +#define __NR_SYSV_execve (__NR_SYSV + 59) +#define __NR_SYSV_umask (__NR_SYSV + 60) +#define __NR_SYSV_chroot (__NR_SYSV + 61) +#define __NR_SYSV_fcntl (__NR_SYSV + 62) +#define __NR_SYSV_ulimit (__NR_SYSV + 63) +#define __NR_SYSV_SAFARI4_reserved1 (__NR_SYSV + 64) +#define __NR_SYSV_SAFARI4_reserved2 (__NR_SYSV + 65) +#define __NR_SYSV_SAFARI4_reserved3 (__NR_SYSV + 66) +#define __NR_SYSV_SAFARI4_reserved4 (__NR_SYSV + 67) +#define __NR_SYSV_SAFARI4_reserved5 (__NR_SYSV + 68) +#define __NR_SYSV_SAFARI4_reserved6 (__NR_SYSV + 69) +#define __NR_SYSV_advfs (__NR_SYSV + 70) +#define __NR_SYSV_unadvfs (__NR_SYSV + 71) +#define __NR_SYSV_rmount (__NR_SYSV + 72) +#define __NR_SYSV_rumount (__NR_SYSV + 73) +#define __NR_SYSV_rfstart (__NR_SYSV + 74) +#define __NR_SYSV_getrlimit64 (__NR_SYSV + 75) +#define __NR_SYSV_setrlimit64 (__NR_SYSV + 76) +#define __NR_SYSV_nanosleep (__NR_SYSV + 77) +#define __NR_SYSV_lseek64 (__NR_SYSV + 78) +#define __NR_SYSV_rmdir (__NR_SYSV + 79) +#define __NR_SYSV_mkdir (__NR_SYSV + 80) +#define __NR_SYSV_getdents (__NR_SYSV + 81) +#define __NR_SYSV_sginap (__NR_SYSV + 82) +#define __NR_SYSV_sgikopt (__NR_SYSV + 83) +#define __NR_SYSV_sysfs (__NR_SYSV + 84) +#define __NR_SYSV_getmsg (__NR_SYSV + 85) +#define __NR_SYSV_putmsg (__NR_SYSV + 86) +#define __NR_SYSV_poll (__NR_SYSV + 87) +#define __NR_SYSV_sigreturn (__NR_SYSV + 88) +#define __NR_SYSV_accept (__NR_SYSV + 89) +#define __NR_SYSV_bind (__NR_SYSV + 90) +#define __NR_SYSV_connect (__NR_SYSV + 91) +#define __NR_SYSV_gethostid (__NR_SYSV + 92) +#define __NR_SYSV_getpeername (__NR_SYSV + 93) +#define __NR_SYSV_getsockname (__NR_SYSV + 94) +#define __NR_SYSV_getsockopt (__NR_SYSV + 95) +#define __NR_SYSV_listen (__NR_SYSV + 96) +#define __NR_SYSV_recv (__NR_SYSV + 97) +#define __NR_SYSV_recvfrom (__NR_SYSV + 98) +#define __NR_SYSV_recvmsg (__NR_SYSV + 99) +#define __NR_SYSV_select (__NR_SYSV + 100) +#define __NR_SYSV_send (__NR_SYSV + 101) +#define __NR_SYSV_sendmsg (__NR_SYSV + 102) +#define __NR_SYSV_sendto (__NR_SYSV + 103) +#define __NR_SYSV_sethostid (__NR_SYSV + 104) +#define __NR_SYSV_setsockopt (__NR_SYSV + 105) +#define __NR_SYSV_shutdown (__NR_SYSV + 106) +#define __NR_SYSV_socket (__NR_SYSV + 107) +#define __NR_SYSV_gethostname (__NR_SYSV + 108) +#define __NR_SYSV_sethostname (__NR_SYSV + 109) +#define __NR_SYSV_getdomainname (__NR_SYSV + 110) +#define __NR_SYSV_setdomainname (__NR_SYSV + 111) +#define __NR_SYSV_truncate (__NR_SYSV + 112) +#define __NR_SYSV_ftruncate (__NR_SYSV + 113) +#define __NR_SYSV_rename (__NR_SYSV + 114) +#define __NR_SYSV_symlink (__NR_SYSV + 115) +#define __NR_SYSV_readlink (__NR_SYSV + 116) +#define __NR_SYSV_lstat (__NR_SYSV + 117) +#define __NR_SYSV_nfsmount (__NR_SYSV + 118) +#define __NR_SYSV_nfssvc (__NR_SYSV + 119) +#define __NR_SYSV_getfh (__NR_SYSV + 120) +#define __NR_SYSV_async_daemon (__NR_SYSV + 121) +#define __NR_SYSV_exportfs (__NR_SYSV + 122) +#define __NR_SYSV_setregid (__NR_SYSV + 123) +#define __NR_SYSV_setreuid (__NR_SYSV + 124) +#define __NR_SYSV_getitimer (__NR_SYSV + 125) +#define __NR_SYSV_setitimer (__NR_SYSV + 126) +#define __NR_SYSV_adjtime (__NR_SYSV + 127) +#define __NR_SYSV_BSD_getime (__NR_SYSV + 128) +#define __NR_SYSV_sproc (__NR_SYSV + 129) +#define __NR_SYSV_prctl (__NR_SYSV + 130) +#define __NR_SYSV_procblk (__NR_SYSV + 131) +#define __NR_SYSV_sprocsp (__NR_SYSV + 132) +#define __NR_SYSV_sgigsc (__NR_SYSV + 133) +#define __NR_SYSV_mmap (__NR_SYSV + 134) +#define __NR_SYSV_munmap (__NR_SYSV + 135) +#define __NR_SYSV_mprotect (__NR_SYSV + 136) +#define __NR_SYSV_msync (__NR_SYSV + 137) +#define __NR_SYSV_madvise (__NR_SYSV + 138) +#define __NR_SYSV_pagelock (__NR_SYSV + 139) +#define __NR_SYSV_getpagesize (__NR_SYSV + 140) +#define __NR_SYSV_quotactl (__NR_SYSV + 141) +#define __NR_SYSV_libdetach (__NR_SYSV + 142) +#define __NR_SYSV_BSDgetpgrp (__NR_SYSV + 143) +#define __NR_SYSV_BSDsetpgrp (__NR_SYSV + 144) +#define __NR_SYSV_vhangup (__NR_SYSV + 145) +#define __NR_SYSV_fsync (__NR_SYSV + 146) +#define __NR_SYSV_fchdir (__NR_SYSV + 147) +#define __NR_SYSV_getrlimit (__NR_SYSV + 148) +#define __NR_SYSV_setrlimit (__NR_SYSV + 149) +#define __NR_SYSV_cacheflush (__NR_SYSV + 150) +#define __NR_SYSV_cachectl (__NR_SYSV + 151) +#define __NR_SYSV_fchown (__NR_SYSV + 152) +#define __NR_SYSV_fchmod (__NR_SYSV + 153) +#define __NR_SYSV_wait3 (__NR_SYSV + 154) +#define __NR_SYSV_socketpair (__NR_SYSV + 155) +#define __NR_SYSV_sysinfo (__NR_SYSV + 156) +#define __NR_SYSV_nuname (__NR_SYSV + 157) +#define __NR_SYSV_xstat (__NR_SYSV + 158) +#define __NR_SYSV_lxstat (__NR_SYSV + 159) +#define __NR_SYSV_fxstat (__NR_SYSV + 160) +#define __NR_SYSV_xmknod (__NR_SYSV + 161) +#define __NR_SYSV_ksigaction (__NR_SYSV + 162) +#define __NR_SYSV_sigpending (__NR_SYSV + 163) +#define __NR_SYSV_sigprocmask (__NR_SYSV + 164) +#define __NR_SYSV_sigsuspend (__NR_SYSV + 165) +#define __NR_SYSV_sigpoll (__NR_SYSV + 166) +#define __NR_SYSV_swapctl (__NR_SYSV + 167) +#define __NR_SYSV_getcontext (__NR_SYSV + 168) +#define __NR_SYSV_setcontext (__NR_SYSV + 169) +#define __NR_SYSV_waitsys (__NR_SYSV + 170) +#define __NR_SYSV_sigstack (__NR_SYSV + 171) +#define __NR_SYSV_sigaltstack (__NR_SYSV + 172) +#define __NR_SYSV_sigsendset (__NR_SYSV + 173) +#define __NR_SYSV_statvfs (__NR_SYSV + 174) +#define __NR_SYSV_fstatvfs (__NR_SYSV + 175) +#define __NR_SYSV_getpmsg (__NR_SYSV + 176) +#define __NR_SYSV_putpmsg (__NR_SYSV + 177) +#define __NR_SYSV_lchown (__NR_SYSV + 178) +#define __NR_SYSV_priocntl (__NR_SYSV + 179) +#define __NR_SYSV_ksigqueue (__NR_SYSV + 180) +#define __NR_SYSV_readv (__NR_SYSV + 181) +#define __NR_SYSV_writev (__NR_SYSV + 182) +#define __NR_SYSV_truncate64 (__NR_SYSV + 183) +#define __NR_SYSV_ftruncate64 (__NR_SYSV + 184) +#define __NR_SYSV_mmap64 (__NR_SYSV + 185) +#define __NR_SYSV_dmi (__NR_SYSV + 186) +#define __NR_SYSV_pread (__NR_SYSV + 187) +#define __NR_SYSV_pwrite (__NR_SYSV + 188) + +/* + * BSD 4.3 syscalls are in the range from 2000 to 2999 + */ +#define __NR_BSD43 2000 +#define __NR_BSD43_syscall (__NR_BSD43 + 0) +#define __NR_BSD43_exit (__NR_BSD43 + 1) +#define __NR_BSD43_fork (__NR_BSD43 + 2) +#define __NR_BSD43_read (__NR_BSD43 + 3) +#define __NR_BSD43_write (__NR_BSD43 + 4) +#define __NR_BSD43_open (__NR_BSD43 + 5) +#define __NR_BSD43_close (__NR_BSD43 + 6) +#define __NR_BSD43_wait (__NR_BSD43 + 7) +#define __NR_BSD43_creat (__NR_BSD43 + 8) +#define __NR_BSD43_link (__NR_BSD43 + 9) +#define __NR_BSD43_unlink (__NR_BSD43 + 10) +#define __NR_BSD43_exec (__NR_BSD43 + 11) +#define __NR_BSD43_chdir (__NR_BSD43 + 12) +#define __NR_BSD43_time (__NR_BSD43 + 13) +#define __NR_BSD43_mknod (__NR_BSD43 + 14) +#define __NR_BSD43_chmod (__NR_BSD43 + 15) +#define __NR_BSD43_chown (__NR_BSD43 + 16) +#define __NR_BSD43_sbreak (__NR_BSD43 + 17) +#define __NR_BSD43_oldstat (__NR_BSD43 + 18) +#define __NR_BSD43_lseek (__NR_BSD43 + 19) +#define __NR_BSD43_getpid (__NR_BSD43 + 20) +#define __NR_BSD43_oldmount (__NR_BSD43 + 21) +#define __NR_BSD43_umount (__NR_BSD43 + 22) +#define __NR_BSD43_setuid (__NR_BSD43 + 23) +#define __NR_BSD43_getuid (__NR_BSD43 + 24) +#define __NR_BSD43_stime (__NR_BSD43 + 25) +#define __NR_BSD43_ptrace (__NR_BSD43 + 26) +#define __NR_BSD43_alarm (__NR_BSD43 + 27) +#define __NR_BSD43_oldfstat (__NR_BSD43 + 28) +#define __NR_BSD43_pause (__NR_BSD43 + 29) +#define __NR_BSD43_utime (__NR_BSD43 + 30) +#define __NR_BSD43_stty (__NR_BSD43 + 31) +#define __NR_BSD43_gtty (__NR_BSD43 + 32) +#define __NR_BSD43_access (__NR_BSD43 + 33) +#define __NR_BSD43_nice (__NR_BSD43 + 34) +#define __NR_BSD43_ftime (__NR_BSD43 + 35) +#define __NR_BSD43_sync (__NR_BSD43 + 36) +#define __NR_BSD43_kill (__NR_BSD43 + 37) +#define __NR_BSD43_stat (__NR_BSD43 + 38) +#define __NR_BSD43_oldsetpgrp (__NR_BSD43 + 39) +#define __NR_BSD43_lstat (__NR_BSD43 + 40) +#define __NR_BSD43_dup (__NR_BSD43 + 41) +#define __NR_BSD43_pipe (__NR_BSD43 + 42) +#define __NR_BSD43_times (__NR_BSD43 + 43) +#define __NR_BSD43_profil (__NR_BSD43 + 44) +#define __NR_BSD43_msgsys (__NR_BSD43 + 45) +#define __NR_BSD43_setgid (__NR_BSD43 + 46) +#define __NR_BSD43_getgid (__NR_BSD43 + 47) +#define __NR_BSD43_ssig (__NR_BSD43 + 48) +#define __NR_BSD43_reserved1 (__NR_BSD43 + 49) +#define __NR_BSD43_reserved2 (__NR_BSD43 + 50) +#define __NR_BSD43_sysacct (__NR_BSD43 + 51) +#define __NR_BSD43_phys (__NR_BSD43 + 52) +#define __NR_BSD43_lock (__NR_BSD43 + 53) +#define __NR_BSD43_ioctl (__NR_BSD43 + 54) +#define __NR_BSD43_reboot (__NR_BSD43 + 55) +#define __NR_BSD43_mpxchan (__NR_BSD43 + 56) +#define __NR_BSD43_symlink (__NR_BSD43 + 57) +#define __NR_BSD43_readlink (__NR_BSD43 + 58) +#define __NR_BSD43_execve (__NR_BSD43 + 59) +#define __NR_BSD43_umask (__NR_BSD43 + 60) +#define __NR_BSD43_chroot (__NR_BSD43 + 61) +#define __NR_BSD43_fstat (__NR_BSD43 + 62) +#define __NR_BSD43_reserved3 (__NR_BSD43 + 63) +#define __NR_BSD43_getpagesize (__NR_BSD43 + 64) +#define __NR_BSD43_mremap (__NR_BSD43 + 65) +#define __NR_BSD43_vfork (__NR_BSD43 + 66) +#define __NR_BSD43_vread (__NR_BSD43 + 67) +#define __NR_BSD43_vwrite (__NR_BSD43 + 68) +#define __NR_BSD43_sbrk (__NR_BSD43 + 69) +#define __NR_BSD43_sstk (__NR_BSD43 + 70) +#define __NR_BSD43_mmap (__NR_BSD43 + 71) +#define __NR_BSD43_vadvise (__NR_BSD43 + 72) +#define __NR_BSD43_munmap (__NR_BSD43 + 73) +#define __NR_BSD43_mprotect (__NR_BSD43 + 74) +#define __NR_BSD43_madvise (__NR_BSD43 + 75) +#define __NR_BSD43_vhangup (__NR_BSD43 + 76) +#define __NR_BSD43_vlimit (__NR_BSD43 + 77) +#define __NR_BSD43_mincore (__NR_BSD43 + 78) +#define __NR_BSD43_getgroups (__NR_BSD43 + 79) +#define __NR_BSD43_setgroups (__NR_BSD43 + 80) +#define __NR_BSD43_getpgrp (__NR_BSD43 + 81) +#define __NR_BSD43_setpgrp (__NR_BSD43 + 82) +#define __NR_BSD43_setitimer (__NR_BSD43 + 83) +#define __NR_BSD43_wait3 (__NR_BSD43 + 84) +#define __NR_BSD43_swapon (__NR_BSD43 + 85) +#define __NR_BSD43_getitimer (__NR_BSD43 + 86) +#define __NR_BSD43_gethostname (__NR_BSD43 + 87) +#define __NR_BSD43_sethostname (__NR_BSD43 + 88) +#define __NR_BSD43_getdtablesize (__NR_BSD43 + 89) +#define __NR_BSD43_dup2 (__NR_BSD43 + 90) +#define __NR_BSD43_getdopt (__NR_BSD43 + 91) +#define __NR_BSD43_fcntl (__NR_BSD43 + 92) +#define __NR_BSD43_select (__NR_BSD43 + 93) +#define __NR_BSD43_setdopt (__NR_BSD43 + 94) +#define __NR_BSD43_fsync (__NR_BSD43 + 95) +#define __NR_BSD43_setpriority (__NR_BSD43 + 96) +#define __NR_BSD43_socket (__NR_BSD43 + 97) +#define __NR_BSD43_connect (__NR_BSD43 + 98) +#define __NR_BSD43_oldaccept (__NR_BSD43 + 99) +#define __NR_BSD43_getpriority (__NR_BSD43 + 100) +#define __NR_BSD43_send (__NR_BSD43 + 101) +#define __NR_BSD43_recv (__NR_BSD43 + 102) +#define __NR_BSD43_sigreturn (__NR_BSD43 + 103) +#define __NR_BSD43_bind (__NR_BSD43 + 104) +#define __NR_BSD43_setsockopt (__NR_BSD43 + 105) +#define __NR_BSD43_listen (__NR_BSD43 + 106) +#define __NR_BSD43_vtimes (__NR_BSD43 + 107) +#define __NR_BSD43_sigvec (__NR_BSD43 + 108) +#define __NR_BSD43_sigblock (__NR_BSD43 + 109) +#define __NR_BSD43_sigsetmask (__NR_BSD43 + 110) +#define __NR_BSD43_sigpause (__NR_BSD43 + 111) +#define __NR_BSD43_sigstack (__NR_BSD43 + 112) +#define __NR_BSD43_oldrecvmsg (__NR_BSD43 + 113) +#define __NR_BSD43_oldsendmsg (__NR_BSD43 + 114) +#define __NR_BSD43_vtrace (__NR_BSD43 + 115) +#define __NR_BSD43_gettimeofday (__NR_BSD43 + 116) +#define __NR_BSD43_getrusage (__NR_BSD43 + 117) +#define __NR_BSD43_getsockopt (__NR_BSD43 + 118) +#define __NR_BSD43_reserved4 (__NR_BSD43 + 119) +#define __NR_BSD43_readv (__NR_BSD43 + 120) +#define __NR_BSD43_writev (__NR_BSD43 + 121) +#define __NR_BSD43_settimeofday (__NR_BSD43 + 122) +#define __NR_BSD43_fchown (__NR_BSD43 + 123) +#define __NR_BSD43_fchmod (__NR_BSD43 + 124) +#define __NR_BSD43_oldrecvfrom (__NR_BSD43 + 125) +#define __NR_BSD43_setreuid (__NR_BSD43 + 126) +#define __NR_BSD43_setregid (__NR_BSD43 + 127) +#define __NR_BSD43_rename (__NR_BSD43 + 128) +#define __NR_BSD43_truncate (__NR_BSD43 + 129) +#define __NR_BSD43_ftruncate (__NR_BSD43 + 130) +#define __NR_BSD43_flock (__NR_BSD43 + 131) +#define __NR_BSD43_semsys (__NR_BSD43 + 132) +#define __NR_BSD43_sendto (__NR_BSD43 + 133) +#define __NR_BSD43_shutdown (__NR_BSD43 + 134) +#define __NR_BSD43_socketpair (__NR_BSD43 + 135) +#define __NR_BSD43_mkdir (__NR_BSD43 + 136) +#define __NR_BSD43_rmdir (__NR_BSD43 + 137) +#define __NR_BSD43_utimes (__NR_BSD43 + 138) +#define __NR_BSD43_sigcleanup (__NR_BSD43 + 139) +#define __NR_BSD43_adjtime (__NR_BSD43 + 140) +#define __NR_BSD43_oldgetpeername (__NR_BSD43 + 141) +#define __NR_BSD43_gethostid (__NR_BSD43 + 142) +#define __NR_BSD43_sethostid (__NR_BSD43 + 143) +#define __NR_BSD43_getrlimit (__NR_BSD43 + 144) +#define __NR_BSD43_setrlimit (__NR_BSD43 + 145) +#define __NR_BSD43_killpg (__NR_BSD43 + 146) +#define __NR_BSD43_shmsys (__NR_BSD43 + 147) +#define __NR_BSD43_quota (__NR_BSD43 + 148) +#define __NR_BSD43_qquota (__NR_BSD43 + 149) +#define __NR_BSD43_oldgetsockname (__NR_BSD43 + 150) +#define __NR_BSD43_sysmips (__NR_BSD43 + 151) +#define __NR_BSD43_cacheflush (__NR_BSD43 + 152) +#define __NR_BSD43_cachectl (__NR_BSD43 + 153) +#define __NR_BSD43_debug (__NR_BSD43 + 154) +#define __NR_BSD43_reserved5 (__NR_BSD43 + 155) +#define __NR_BSD43_reserved6 (__NR_BSD43 + 156) +#define __NR_BSD43_nfs_mount (__NR_BSD43 + 157) +#define __NR_BSD43_nfs_svc (__NR_BSD43 + 158) +#define __NR_BSD43_getdirentries (__NR_BSD43 + 159) +#define __NR_BSD43_statfs (__NR_BSD43 + 160) +#define __NR_BSD43_fstatfs (__NR_BSD43 + 161) +#define __NR_BSD43_unmount (__NR_BSD43 + 162) +#define __NR_BSD43_async_daemon (__NR_BSD43 + 163) +#define __NR_BSD43_nfs_getfh (__NR_BSD43 + 164) +#define __NR_BSD43_getdomainname (__NR_BSD43 + 165) +#define __NR_BSD43_setdomainname (__NR_BSD43 + 166) +#define __NR_BSD43_pcfs_mount (__NR_BSD43 + 167) +#define __NR_BSD43_quotactl (__NR_BSD43 + 168) +#define __NR_BSD43_oldexportfs (__NR_BSD43 + 169) +#define __NR_BSD43_smount (__NR_BSD43 + 170) +#define __NR_BSD43_mipshwconf (__NR_BSD43 + 171) +#define __NR_BSD43_exportfs (__NR_BSD43 + 172) +#define __NR_BSD43_nfsfh_open (__NR_BSD43 + 173) +#define __NR_BSD43_libattach (__NR_BSD43 + 174) +#define __NR_BSD43_libdetach (__NR_BSD43 + 175) +#define __NR_BSD43_accept (__NR_BSD43 + 176) +#define __NR_BSD43_reserved7 (__NR_BSD43 + 177) +#define __NR_BSD43_reserved8 (__NR_BSD43 + 178) +#define __NR_BSD43_recvmsg (__NR_BSD43 + 179) +#define __NR_BSD43_recvfrom (__NR_BSD43 + 180) +#define __NR_BSD43_sendmsg (__NR_BSD43 + 181) +#define __NR_BSD43_getpeername (__NR_BSD43 + 182) +#define __NR_BSD43_getsockname (__NR_BSD43 + 183) +#define __NR_BSD43_aread (__NR_BSD43 + 184) +#define __NR_BSD43_awrite (__NR_BSD43 + 185) +#define __NR_BSD43_listio (__NR_BSD43 + 186) +#define __NR_BSD43_acancel (__NR_BSD43 + 187) +#define __NR_BSD43_astatus (__NR_BSD43 + 188) +#define __NR_BSD43_await (__NR_BSD43 + 189) +#define __NR_BSD43_areadv (__NR_BSD43 + 190) +#define __NR_BSD43_awritev (__NR_BSD43 + 191) + +/* + * POSIX syscalls are in the range from 3000 to 3999 + */ +#define __NR_POSIX 3000 +#define __NR_POSIX_syscall (__NR_POSIX + 0) +#define __NR_POSIX_exit (__NR_POSIX + 1) +#define __NR_POSIX_fork (__NR_POSIX + 2) +#define __NR_POSIX_read (__NR_POSIX + 3) +#define __NR_POSIX_write (__NR_POSIX + 4) +#define __NR_POSIX_open (__NR_POSIX + 5) +#define __NR_POSIX_close (__NR_POSIX + 6) +#define __NR_POSIX_wait (__NR_POSIX + 7) +#define __NR_POSIX_creat (__NR_POSIX + 8) +#define __NR_POSIX_link (__NR_POSIX + 9) +#define __NR_POSIX_unlink (__NR_POSIX + 10) +#define __NR_POSIX_exec (__NR_POSIX + 11) +#define __NR_POSIX_chdir (__NR_POSIX + 12) +#define __NR_POSIX_gtime (__NR_POSIX + 13) +#define __NR_POSIX_mknod (__NR_POSIX + 14) +#define __NR_POSIX_chmod (__NR_POSIX + 15) +#define __NR_POSIX_chown (__NR_POSIX + 16) +#define __NR_POSIX_sbreak (__NR_POSIX + 17) +#define __NR_POSIX_stat (__NR_POSIX + 18) +#define __NR_POSIX_lseek (__NR_POSIX + 19) +#define __NR_POSIX_getpid (__NR_POSIX + 20) +#define __NR_POSIX_mount (__NR_POSIX + 21) +#define __NR_POSIX_umount (__NR_POSIX + 22) +#define __NR_POSIX_setuid (__NR_POSIX + 23) +#define __NR_POSIX_getuid (__NR_POSIX + 24) +#define __NR_POSIX_stime (__NR_POSIX + 25) +#define __NR_POSIX_ptrace (__NR_POSIX + 26) +#define __NR_POSIX_alarm (__NR_POSIX + 27) +#define __NR_POSIX_fstat (__NR_POSIX + 28) +#define __NR_POSIX_pause (__NR_POSIX + 29) +#define __NR_POSIX_utime (__NR_POSIX + 30) +#define __NR_POSIX_stty (__NR_POSIX + 31) +#define __NR_POSIX_gtty (__NR_POSIX + 32) +#define __NR_POSIX_access (__NR_POSIX + 33) +#define __NR_POSIX_nice (__NR_POSIX + 34) +#define __NR_POSIX_statfs (__NR_POSIX + 35) +#define __NR_POSIX_sync (__NR_POSIX + 36) +#define __NR_POSIX_kill (__NR_POSIX + 37) +#define __NR_POSIX_fstatfs (__NR_POSIX + 38) +#define __NR_POSIX_getpgrp (__NR_POSIX + 39) +#define __NR_POSIX_syssgi (__NR_POSIX + 40) +#define __NR_POSIX_dup (__NR_POSIX + 41) +#define __NR_POSIX_pipe (__NR_POSIX + 42) +#define __NR_POSIX_times (__NR_POSIX + 43) +#define __NR_POSIX_profil (__NR_POSIX + 44) +#define __NR_POSIX_lock (__NR_POSIX + 45) +#define __NR_POSIX_setgid (__NR_POSIX + 46) +#define __NR_POSIX_getgid (__NR_POSIX + 47) +#define __NR_POSIX_sig (__NR_POSIX + 48) +#define __NR_POSIX_msgsys (__NR_POSIX + 49) +#define __NR_POSIX_sysmips (__NR_POSIX + 50) +#define __NR_POSIX_sysacct (__NR_POSIX + 51) +#define __NR_POSIX_shmsys (__NR_POSIX + 52) +#define __NR_POSIX_semsys (__NR_POSIX + 53) +#define __NR_POSIX_ioctl (__NR_POSIX + 54) +#define __NR_POSIX_uadmin (__NR_POSIX + 55) +#define __NR_POSIX_exch (__NR_POSIX + 56) +#define __NR_POSIX_utssys (__NR_POSIX + 57) +#define __NR_POSIX_USG_reserved1 (__NR_POSIX + 58) +#define __NR_POSIX_exece (__NR_POSIX + 59) +#define __NR_POSIX_umask (__NR_POSIX + 60) +#define __NR_POSIX_chroot (__NR_POSIX + 61) +#define __NR_POSIX_fcntl (__NR_POSIX + 62) +#define __NR_POSIX_ulimit (__NR_POSIX + 63) +#define __NR_POSIX_SAFARI4_reserved1 (__NR_POSIX + 64) +#define __NR_POSIX_SAFARI4_reserved2 (__NR_POSIX + 65) +#define __NR_POSIX_SAFARI4_reserved3 (__NR_POSIX + 66) +#define __NR_POSIX_SAFARI4_reserved4 (__NR_POSIX + 67) +#define __NR_POSIX_SAFARI4_reserved5 (__NR_POSIX + 68) +#define __NR_POSIX_SAFARI4_reserved6 (__NR_POSIX + 69) +#define __NR_POSIX_advfs (__NR_POSIX + 70) +#define __NR_POSIX_unadvfs (__NR_POSIX + 71) +#define __NR_POSIX_rmount (__NR_POSIX + 72) +#define __NR_POSIX_rumount (__NR_POSIX + 73) +#define __NR_POSIX_rfstart (__NR_POSIX + 74) +#define __NR_POSIX_reserved1 (__NR_POSIX + 75) +#define __NR_POSIX_rdebug (__NR_POSIX + 76) +#define __NR_POSIX_rfstop (__NR_POSIX + 77) +#define __NR_POSIX_rfsys (__NR_POSIX + 78) +#define __NR_POSIX_rmdir (__NR_POSIX + 79) +#define __NR_POSIX_mkdir (__NR_POSIX + 80) +#define __NR_POSIX_getdents (__NR_POSIX + 81) +#define __NR_POSIX_sginap (__NR_POSIX + 82) +#define __NR_POSIX_sgikopt (__NR_POSIX + 83) +#define __NR_POSIX_sysfs (__NR_POSIX + 84) +#define __NR_POSIX_getmsg (__NR_POSIX + 85) +#define __NR_POSIX_putmsg (__NR_POSIX + 86) +#define __NR_POSIX_poll (__NR_POSIX + 87) +#define __NR_POSIX_sigreturn (__NR_POSIX + 88) +#define __NR_POSIX_accept (__NR_POSIX + 89) +#define __NR_POSIX_bind (__NR_POSIX + 90) +#define __NR_POSIX_connect (__NR_POSIX + 91) +#define __NR_POSIX_gethostid (__NR_POSIX + 92) +#define __NR_POSIX_getpeername (__NR_POSIX + 93) +#define __NR_POSIX_getsockname (__NR_POSIX + 94) +#define __NR_POSIX_getsockopt (__NR_POSIX + 95) +#define __NR_POSIX_listen (__NR_POSIX + 96) +#define __NR_POSIX_recv (__NR_POSIX + 97) +#define __NR_POSIX_recvfrom (__NR_POSIX + 98) +#define __NR_POSIX_recvmsg (__NR_POSIX + 99) +#define __NR_POSIX_select (__NR_POSIX + 100) +#define __NR_POSIX_send (__NR_POSIX + 101) +#define __NR_POSIX_sendmsg (__NR_POSIX + 102) +#define __NR_POSIX_sendto (__NR_POSIX + 103) +#define __NR_POSIX_sethostid (__NR_POSIX + 104) +#define __NR_POSIX_setsockopt (__NR_POSIX + 105) +#define __NR_POSIX_shutdown (__NR_POSIX + 106) +#define __NR_POSIX_socket (__NR_POSIX + 107) +#define __NR_POSIX_gethostname (__NR_POSIX + 108) +#define __NR_POSIX_sethostname (__NR_POSIX + 109) +#define __NR_POSIX_getdomainname (__NR_POSIX + 110) +#define __NR_POSIX_setdomainname (__NR_POSIX + 111) +#define __NR_POSIX_truncate (__NR_POSIX + 112) +#define __NR_POSIX_ftruncate (__NR_POSIX + 113) +#define __NR_POSIX_rename (__NR_POSIX + 114) +#define __NR_POSIX_symlink (__NR_POSIX + 115) +#define __NR_POSIX_readlink (__NR_POSIX + 116) +#define __NR_POSIX_lstat (__NR_POSIX + 117) +#define __NR_POSIX_nfs_mount (__NR_POSIX + 118) +#define __NR_POSIX_nfs_svc (__NR_POSIX + 119) +#define __NR_POSIX_nfs_getfh (__NR_POSIX + 120) +#define __NR_POSIX_async_daemon (__NR_POSIX + 121) +#define __NR_POSIX_exportfs (__NR_POSIX + 122) +#define __NR_POSIX_SGI_setregid (__NR_POSIX + 123) +#define __NR_POSIX_SGI_setreuid (__NR_POSIX + 124) +#define __NR_POSIX_getitimer (__NR_POSIX + 125) +#define __NR_POSIX_setitimer (__NR_POSIX + 126) +#define __NR_POSIX_adjtime (__NR_POSIX + 127) +#define __NR_POSIX_SGI_bsdgettime (__NR_POSIX + 128) +#define __NR_POSIX_SGI_sproc (__NR_POSIX + 129) +#define __NR_POSIX_SGI_prctl (__NR_POSIX + 130) +#define __NR_POSIX_SGI_blkproc (__NR_POSIX + 131) +#define __NR_POSIX_SGI_reserved1 (__NR_POSIX + 132) +#define __NR_POSIX_SGI_sgigsc (__NR_POSIX + 133) +#define __NR_POSIX_SGI_mmap (__NR_POSIX + 134) +#define __NR_POSIX_SGI_munmap (__NR_POSIX + 135) +#define __NR_POSIX_SGI_mprotect (__NR_POSIX + 136) +#define __NR_POSIX_SGI_msync (__NR_POSIX + 137) +#define __NR_POSIX_SGI_madvise (__NR_POSIX + 138) +#define __NR_POSIX_SGI_mpin (__NR_POSIX + 139) +#define __NR_POSIX_SGI_getpagesize (__NR_POSIX + 140) +#define __NR_POSIX_SGI_libattach (__NR_POSIX + 141) +#define __NR_POSIX_SGI_libdetach (__NR_POSIX + 142) +#define __NR_POSIX_SGI_getpgrp (__NR_POSIX + 143) +#define __NR_POSIX_SGI_setpgrp (__NR_POSIX + 144) +#define __NR_POSIX_SGI_reserved2 (__NR_POSIX + 145) +#define __NR_POSIX_SGI_reserved3 (__NR_POSIX + 146) +#define __NR_POSIX_SGI_reserved4 (__NR_POSIX + 147) +#define __NR_POSIX_SGI_reserved5 (__NR_POSIX + 148) +#define __NR_POSIX_SGI_reserved6 (__NR_POSIX + 149) +#define __NR_POSIX_cacheflush (__NR_POSIX + 150) +#define __NR_POSIX_cachectl (__NR_POSIX + 151) +#define __NR_POSIX_fchown (__NR_POSIX + 152) +#define __NR_POSIX_fchmod (__NR_POSIX + 153) +#define __NR_POSIX_wait3 (__NR_POSIX + 154) +#define __NR_POSIX_mmap (__NR_POSIX + 155) +#define __NR_POSIX_munmap (__NR_POSIX + 156) +#define __NR_POSIX_madvise (__NR_POSIX + 157) +#define __NR_POSIX_BSD_getpagesize (__NR_POSIX + 158) +#define __NR_POSIX_setreuid (__NR_POSIX + 159) +#define __NR_POSIX_setregid (__NR_POSIX + 160) +#define __NR_POSIX_setpgid (__NR_POSIX + 161) +#define __NR_POSIX_getgroups (__NR_POSIX + 162) +#define __NR_POSIX_setgroups (__NR_POSIX + 163) +#define __NR_POSIX_gettimeofday (__NR_POSIX + 164) +#define __NR_POSIX_getrusage (__NR_POSIX + 165) +#define __NR_POSIX_getrlimit (__NR_POSIX + 166) +#define __NR_POSIX_setrlimit (__NR_POSIX + 167) +#define __NR_POSIX_waitpid (__NR_POSIX + 168) +#define __NR_POSIX_dup2 (__NR_POSIX + 169) +#define __NR_POSIX_reserved2 (__NR_POSIX + 170) +#define __NR_POSIX_reserved3 (__NR_POSIX + 171) +#define __NR_POSIX_reserved4 (__NR_POSIX + 172) +#define __NR_POSIX_reserved5 (__NR_POSIX + 173) +#define __NR_POSIX_reserved6 (__NR_POSIX + 174) +#define __NR_POSIX_reserved7 (__NR_POSIX + 175) +#define __NR_POSIX_reserved8 (__NR_POSIX + 176) +#define __NR_POSIX_reserved9 (__NR_POSIX + 177) +#define __NR_POSIX_reserved10 (__NR_POSIX + 178) +#define __NR_POSIX_reserved11 (__NR_POSIX + 179) +#define __NR_POSIX_reserved12 (__NR_POSIX + 180) +#define __NR_POSIX_reserved13 (__NR_POSIX + 181) +#define __NR_POSIX_reserved14 (__NR_POSIX + 182) +#define __NR_POSIX_reserved15 (__NR_POSIX + 183) +#define __NR_POSIX_reserved16 (__NR_POSIX + 184) +#define __NR_POSIX_reserved17 (__NR_POSIX + 185) +#define __NR_POSIX_reserved18 (__NR_POSIX + 186) +#define __NR_POSIX_reserved19 (__NR_POSIX + 187) +#define __NR_POSIX_reserved20 (__NR_POSIX + 188) +#define __NR_POSIX_reserved21 (__NR_POSIX + 189) +#define __NR_POSIX_reserved22 (__NR_POSIX + 190) +#define __NR_POSIX_reserved23 (__NR_POSIX + 191) +#define __NR_POSIX_reserved24 (__NR_POSIX + 192) +#define __NR_POSIX_reserved25 (__NR_POSIX + 193) +#define __NR_POSIX_reserved26 (__NR_POSIX + 194) +#define __NR_POSIX_reserved27 (__NR_POSIX + 195) +#define __NR_POSIX_reserved28 (__NR_POSIX + 196) +#define __NR_POSIX_reserved29 (__NR_POSIX + 197) +#define __NR_POSIX_reserved30 (__NR_POSIX + 198) +#define __NR_POSIX_reserved31 (__NR_POSIX + 199) +#define __NR_POSIX_reserved32 (__NR_POSIX + 200) +#define __NR_POSIX_reserved33 (__NR_POSIX + 201) +#define __NR_POSIX_reserved34 (__NR_POSIX + 202) +#define __NR_POSIX_reserved35 (__NR_POSIX + 203) +#define __NR_POSIX_reserved36 (__NR_POSIX + 204) +#define __NR_POSIX_reserved37 (__NR_POSIX + 205) +#define __NR_POSIX_reserved38 (__NR_POSIX + 206) +#define __NR_POSIX_reserved39 (__NR_POSIX + 207) +#define __NR_POSIX_reserved40 (__NR_POSIX + 208) +#define __NR_POSIX_reserved41 (__NR_POSIX + 209) +#define __NR_POSIX_reserved42 (__NR_POSIX + 210) +#define __NR_POSIX_reserved43 (__NR_POSIX + 211) +#define __NR_POSIX_reserved44 (__NR_POSIX + 212) +#define __NR_POSIX_reserved45 (__NR_POSIX + 213) +#define __NR_POSIX_reserved46 (__NR_POSIX + 214) +#define __NR_POSIX_reserved47 (__NR_POSIX + 215) +#define __NR_POSIX_reserved48 (__NR_POSIX + 216) +#define __NR_POSIX_reserved49 (__NR_POSIX + 217) +#define __NR_POSIX_reserved50 (__NR_POSIX + 218) +#define __NR_POSIX_reserved51 (__NR_POSIX + 219) +#define __NR_POSIX_reserved52 (__NR_POSIX + 220) +#define __NR_POSIX_reserved53 (__NR_POSIX + 221) +#define __NR_POSIX_reserved54 (__NR_POSIX + 222) +#define __NR_POSIX_reserved55 (__NR_POSIX + 223) +#define __NR_POSIX_reserved56 (__NR_POSIX + 224) +#define __NR_POSIX_reserved57 (__NR_POSIX + 225) +#define __NR_POSIX_reserved58 (__NR_POSIX + 226) +#define __NR_POSIX_reserved59 (__NR_POSIX + 227) +#define __NR_POSIX_reserved60 (__NR_POSIX + 228) +#define __NR_POSIX_reserved61 (__NR_POSIX + 229) +#define __NR_POSIX_reserved62 (__NR_POSIX + 230) +#define __NR_POSIX_reserved63 (__NR_POSIX + 231) +#define __NR_POSIX_reserved64 (__NR_POSIX + 232) +#define __NR_POSIX_reserved65 (__NR_POSIX + 233) +#define __NR_POSIX_reserved66 (__NR_POSIX + 234) +#define __NR_POSIX_reserved67 (__NR_POSIX + 235) +#define __NR_POSIX_reserved68 (__NR_POSIX + 236) +#define __NR_POSIX_reserved69 (__NR_POSIX + 237) +#define __NR_POSIX_reserved70 (__NR_POSIX + 238) +#define __NR_POSIX_reserved71 (__NR_POSIX + 239) +#define __NR_POSIX_reserved72 (__NR_POSIX + 240) +#define __NR_POSIX_reserved73 (__NR_POSIX + 241) +#define __NR_POSIX_reserved74 (__NR_POSIX + 242) +#define __NR_POSIX_reserved75 (__NR_POSIX + 243) +#define __NR_POSIX_reserved76 (__NR_POSIX + 244) +#define __NR_POSIX_reserved77 (__NR_POSIX + 245) +#define __NR_POSIX_reserved78 (__NR_POSIX + 246) +#define __NR_POSIX_reserved79 (__NR_POSIX + 247) +#define __NR_POSIX_reserved80 (__NR_POSIX + 248) +#define __NR_POSIX_reserved81 (__NR_POSIX + 249) +#define __NR_POSIX_reserved82 (__NR_POSIX + 250) +#define __NR_POSIX_reserved83 (__NR_POSIX + 251) +#define __NR_POSIX_reserved84 (__NR_POSIX + 252) +#define __NR_POSIX_reserved85 (__NR_POSIX + 253) +#define __NR_POSIX_reserved86 (__NR_POSIX + 254) +#define __NR_POSIX_reserved87 (__NR_POSIX + 255) +#define __NR_POSIX_reserved88 (__NR_POSIX + 256) +#define __NR_POSIX_reserved89 (__NR_POSIX + 257) +#define __NR_POSIX_reserved90 (__NR_POSIX + 258) +#define __NR_POSIX_reserved91 (__NR_POSIX + 259) +#define __NR_POSIX_netboot (__NR_POSIX + 260) +#define __NR_POSIX_netunboot (__NR_POSIX + 261) +#define __NR_POSIX_rdump (__NR_POSIX + 262) +#define __NR_POSIX_setsid (__NR_POSIX + 263) +#define __NR_POSIX_getmaxsig (__NR_POSIX + 264) +#define __NR_POSIX_sigpending (__NR_POSIX + 265) +#define __NR_POSIX_sigprocmask (__NR_POSIX + 266) +#define __NR_POSIX_sigsuspend (__NR_POSIX + 267) +#define __NR_POSIX_sigaction (__NR_POSIX + 268) +#define __NR_POSIX_MIPS_reserved1 (__NR_POSIX + 269) +#define __NR_POSIX_MIPS_reserved2 (__NR_POSIX + 270) +#define __NR_POSIX_MIPS_reserved3 (__NR_POSIX + 271) +#define __NR_POSIX_MIPS_reserved4 (__NR_POSIX + 272) +#define __NR_POSIX_MIPS_reserved5 (__NR_POSIX + 273) +#define __NR_POSIX_MIPS_reserved6 (__NR_POSIX + 274) +#define __NR_POSIX_MIPS_reserved7 (__NR_POSIX + 275) +#define __NR_POSIX_MIPS_reserved8 (__NR_POSIX + 276) +#define __NR_POSIX_MIPS_reserved9 (__NR_POSIX + 277) +#define __NR_POSIX_MIPS_reserved10 (__NR_POSIX + 278) +#define __NR_POSIX_MIPS_reserved11 (__NR_POSIX + 279) +#define __NR_POSIX_TANDEM_reserved1 (__NR_POSIX + 280) +#define __NR_POSIX_TANDEM_reserved2 (__NR_POSIX + 281) +#define __NR_POSIX_TANDEM_reserved3 (__NR_POSIX + 282) +#define __NR_POSIX_TANDEM_reserved4 (__NR_POSIX + 283) +#define __NR_POSIX_TANDEM_reserved5 (__NR_POSIX + 284) +#define __NR_POSIX_TANDEM_reserved6 (__NR_POSIX + 285) +#define __NR_POSIX_TANDEM_reserved7 (__NR_POSIX + 286) +#define __NR_POSIX_TANDEM_reserved8 (__NR_POSIX + 287) +#define __NR_POSIX_TANDEM_reserved9 (__NR_POSIX + 288) +#define __NR_POSIX_TANDEM_reserved10 (__NR_POSIX + 289) +#define __NR_POSIX_TANDEM_reserved11 (__NR_POSIX + 290) +#define __NR_POSIX_TANDEM_reserved12 (__NR_POSIX + 291) +#define __NR_POSIX_TANDEM_reserved13 (__NR_POSIX + 292) +#define __NR_POSIX_TANDEM_reserved14 (__NR_POSIX + 293) +#define __NR_POSIX_TANDEM_reserved15 (__NR_POSIX + 294) +#define __NR_POSIX_TANDEM_reserved16 (__NR_POSIX + 295) +#define __NR_POSIX_TANDEM_reserved17 (__NR_POSIX + 296) +#define __NR_POSIX_TANDEM_reserved18 (__NR_POSIX + 297) +#define __NR_POSIX_TANDEM_reserved19 (__NR_POSIX + 298) +#define __NR_POSIX_TANDEM_reserved20 (__NR_POSIX + 299) +#define __NR_POSIX_SGI_reserved7 (__NR_POSIX + 300) +#define __NR_POSIX_SGI_reserved8 (__NR_POSIX + 301) +#define __NR_POSIX_SGI_reserved9 (__NR_POSIX + 302) +#define __NR_POSIX_SGI_reserved10 (__NR_POSIX + 303) +#define __NR_POSIX_SGI_reserved11 (__NR_POSIX + 304) +#define __NR_POSIX_SGI_reserved12 (__NR_POSIX + 305) +#define __NR_POSIX_SGI_reserved13 (__NR_POSIX + 306) +#define __NR_POSIX_SGI_reserved14 (__NR_POSIX + 307) +#define __NR_POSIX_SGI_reserved15 (__NR_POSIX + 308) +#define __NR_POSIX_SGI_reserved16 (__NR_POSIX + 309) +#define __NR_POSIX_SGI_reserved17 (__NR_POSIX + 310) +#define __NR_POSIX_SGI_reserved18 (__NR_POSIX + 311) +#define __NR_POSIX_SGI_reserved19 (__NR_POSIX + 312) +#define __NR_POSIX_SGI_reserved20 (__NR_POSIX + 313) +#define __NR_POSIX_SGI_reserved21 (__NR_POSIX + 314) +#define __NR_POSIX_SGI_reserved22 (__NR_POSIX + 315) +#define __NR_POSIX_SGI_reserved23 (__NR_POSIX + 316) +#define __NR_POSIX_SGI_reserved24 (__NR_POSIX + 317) +#define __NR_POSIX_SGI_reserved25 (__NR_POSIX + 318) +#define __NR_POSIX_SGI_reserved26 (__NR_POSIX + 319) + +/* + * Linux syscalls are in the range from 4000 to 4999 + * Hopefully these syscall numbers are unused ... If not everyone using + * statically linked binaries is pretty upsh*t. You've been warned. + */ +#define __NR_Linux 4000 +#define __NR_syscall (__NR_Linux + 0) +#define __NR_exit (__NR_Linux + 1) +#define __NR_fork (__NR_Linux + 2) +#define __NR_read (__NR_Linux + 3) +#define __NR_write (__NR_Linux + 4) +#define __NR_open (__NR_Linux + 5) +#define __NR_close (__NR_Linux + 6) +#define __NR_waitpid (__NR_Linux + 7) +#define __NR_creat (__NR_Linux + 8) +#define __NR_link (__NR_Linux + 9) +#define __NR_unlink (__NR_Linux + 10) +#define __NR_execve (__NR_Linux + 11) +#define __NR_chdir (__NR_Linux + 12) +#define __NR_time (__NR_Linux + 13) +#define __NR_mknod (__NR_Linux + 14) +#define __NR_chmod (__NR_Linux + 15) +#define __NR_chown (__NR_Linux + 16) +#define __NR_break (__NR_Linux + 17) +#define __NR_oldstat (__NR_Linux + 18) +#define __NR_lseek (__NR_Linux + 19) +#define __NR_getpid (__NR_Linux + 20) +#define __NR_mount (__NR_Linux + 21) +#define __NR_umount (__NR_Linux + 22) +#define __NR_setuid (__NR_Linux + 23) +#define __NR_getuid (__NR_Linux + 24) +#define __NR_stime (__NR_Linux + 25) +#define __NR_ptrace (__NR_Linux + 26) +#define __NR_alarm (__NR_Linux + 27) +#define __NR_oldfstat (__NR_Linux + 28) +#define __NR_pause (__NR_Linux + 29) +#define __NR_utime (__NR_Linux + 30) +#define __NR_stty (__NR_Linux + 31) +#define __NR_gtty (__NR_Linux + 32) +#define __NR_access (__NR_Linux + 33) +#define __NR_nice (__NR_Linux + 34) +#define __NR_ftime (__NR_Linux + 35) +#define __NR_sync (__NR_Linux + 36) +#define __NR_kill (__NR_Linux + 37) +#define __NR_rename (__NR_Linux + 38) +#define __NR_mkdir (__NR_Linux + 39) +#define __NR_rmdir (__NR_Linux + 40) +#define __NR_dup (__NR_Linux + 41) +#define __NR_pipe (__NR_Linux + 42) +#define __NR_times (__NR_Linux + 43) +#define __NR_prof (__NR_Linux + 44) +#define __NR_brk (__NR_Linux + 45) +#define __NR_setgid (__NR_Linux + 46) +#define __NR_getgid (__NR_Linux + 47) +#define __NR_signal (__NR_Linux + 48) +#define __NR_geteuid (__NR_Linux + 49) +#define __NR_getegid (__NR_Linux + 50) +#define __NR_acct (__NR_Linux + 51) +#define __NR_phys (__NR_Linux + 52) +#define __NR_lock (__NR_Linux + 53) +#define __NR_ioctl (__NR_Linux + 54) +#define __NR_fcntl (__NR_Linux + 55) +#define __NR_mpx (__NR_Linux + 56) +#define __NR_setpgid (__NR_Linux + 57) +#define __NR_ulimit (__NR_Linux + 58) +#define __NR_oldolduname (__NR_Linux + 59) +#define __NR_umask (__NR_Linux + 60) +#define __NR_chroot (__NR_Linux + 61) +#define __NR_ustat (__NR_Linux + 62) +#define __NR_dup2 (__NR_Linux + 63) +#define __NR_getppid (__NR_Linux + 64) +#define __NR_getpgrp (__NR_Linux + 65) +#define __NR_setsid (__NR_Linux + 66) +#define __NR_sigaction (__NR_Linux + 67) +#define __NR_sgetmask (__NR_Linux + 68) +#define __NR_ssetmask (__NR_Linux + 69) +#define __NR_setreuid (__NR_Linux + 70) +#define __NR_setregid (__NR_Linux + 71) +#define __NR_sigsuspend (__NR_Linux + 72) +#define __NR_sigpending (__NR_Linux + 73) +#define __NR_sethostname (__NR_Linux + 74) +#define __NR_setrlimit (__NR_Linux + 75) +#define __NR_getrlimit (__NR_Linux + 76) +#define __NR_getrusage (__NR_Linux + 77) +#define __NR_gettimeofday (__NR_Linux + 78) +#define __NR_settimeofday (__NR_Linux + 79) +#define __NR_getgroups (__NR_Linux + 80) +#define __NR_setgroups (__NR_Linux + 81) +#define __NR_reserved82 (__NR_Linux + 82) +#define __NR_symlink (__NR_Linux + 83) +#define __NR_oldlstat (__NR_Linux + 84) +#define __NR_readlink (__NR_Linux + 85) +#define __NR_uselib (__NR_Linux + 86) +#define __NR_swapon (__NR_Linux + 87) +#define __NR_reboot (__NR_Linux + 88) +#define __NR_readdir (__NR_Linux + 89) +#define __NR_mmap (__NR_Linux + 90) +#define __NR_munmap (__NR_Linux + 91) +#define __NR_truncate (__NR_Linux + 92) +#define __NR_ftruncate (__NR_Linux + 93) +#define __NR_fchmod (__NR_Linux + 94) +#define __NR_fchown (__NR_Linux + 95) +#define __NR_getpriority (__NR_Linux + 96) +#define __NR_setpriority (__NR_Linux + 97) +#define __NR_profil (__NR_Linux + 98) +#define __NR_statfs (__NR_Linux + 99) +#define __NR_fstatfs (__NR_Linux + 100) +#define __NR_ioperm (__NR_Linux + 101) +#define __NR_socketcall (__NR_Linux + 102) +#define __NR_syslog (__NR_Linux + 103) +#define __NR_setitimer (__NR_Linux + 104) +#define __NR_getitimer (__NR_Linux + 105) +#define __NR_stat (__NR_Linux + 106) +#define __NR_lstat (__NR_Linux + 107) +#define __NR_fstat (__NR_Linux + 108) +#define __NR_olduname (__NR_Linux + 109) +#define __NR_iopl (__NR_Linux + 110) +#define __NR_vhangup (__NR_Linux + 111) +#define __NR_idle (__NR_Linux + 112) +#define __NR_vm86 (__NR_Linux + 113) +#define __NR_wait4 (__NR_Linux + 114) +#define __NR_swapoff (__NR_Linux + 115) +#define __NR_sysinfo (__NR_Linux + 116) +#define __NR_ipc (__NR_Linux + 117) +#define __NR_fsync (__NR_Linux + 118) +#define __NR_sigreturn (__NR_Linux + 119) +#define __NR_clone (__NR_Linux + 120) +#define __NR_setdomainname (__NR_Linux + 121) +#define __NR_uname (__NR_Linux + 122) +#define __NR_modify_ldt (__NR_Linux + 123) +#define __NR_adjtimex (__NR_Linux + 124) +#define __NR_mprotect (__NR_Linux + 125) +#define __NR_sigprocmask (__NR_Linux + 126) +#define __NR_create_module (__NR_Linux + 127) +#define __NR_init_module (__NR_Linux + 128) +#define __NR_delete_module (__NR_Linux + 129) +#define __NR_get_kernel_syms (__NR_Linux + 130) +#define __NR_quotactl (__NR_Linux + 131) +#define __NR_getpgid (__NR_Linux + 132) +#define __NR_fchdir (__NR_Linux + 133) +#define __NR_bdflush (__NR_Linux + 134) +#define __NR_sysfs (__NR_Linux + 135) +#define __NR_personality (__NR_Linux + 136) +#define __NR_afs_syscall (__NR_Linux + 137) /* Syscall for Andrew File System */ +#define __NR_setfsuid (__NR_Linux + 138) +#define __NR_setfsgid (__NR_Linux + 139) +#define __NR__llseek (__NR_Linux + 140) +#define __NR_getdents (__NR_Linux + 141) +#define __NR__newselect (__NR_Linux + 142) +#define __NR_flock (__NR_Linux + 143) +#define __NR_msync (__NR_Linux + 144) +#define __NR_readv (__NR_Linux + 145) +#define __NR_writev (__NR_Linux + 146) +#define __NR_cacheflush (__NR_Linux + 147) +#define __NR_cachectl (__NR_Linux + 148) +#define __NR_sysmips (__NR_Linux + 149) +#define __NR_setup (__NR_Linux + 150) /* used only by init, to get system going */ +#define __NR_getsid (__NR_Linux + 151) +#define __NR_fdatasync (__NR_Linux + 152) +#define __NR__sysctl (__NR_Linux + 153) +#define __NR_mlock (__NR_Linux + 154) +#define __NR_munlock (__NR_Linux + 155) +#define __NR_mlockall (__NR_Linux + 156) +#define __NR_munlockall (__NR_Linux + 157) +#define __NR_sched_setparam (__NR_Linux + 158) +#define __NR_sched_getparam (__NR_Linux + 159) +#define __NR_sched_setscheduler (__NR_Linux + 160) +#define __NR_sched_getscheduler (__NR_Linux + 161) +#define __NR_sched_yield (__NR_Linux + 162) +#define __NR_sched_get_priority_max (__NR_Linux + 163) +#define __NR_sched_get_priority_min (__NR_Linux + 164) +#define __NR_sched_rr_get_interval (__NR_Linux + 165) +#define __NR_nanosleep (__NR_Linux + 166) +#define __NR_mremap (__NR_Linux + 167) +#define __NR_accept (__NR_Linux + 168) +#define __NR_bind (__NR_Linux + 169) +#define __NR_connect (__NR_Linux + 170) +#define __NR_getpeername (__NR_Linux + 171) +#define __NR_getsockname (__NR_Linux + 172) +#define __NR_getsockopt (__NR_Linux + 173) +#define __NR_listen (__NR_Linux + 174) +#define __NR_recv (__NR_Linux + 175) +#define __NR_recvfrom (__NR_Linux + 176) +#define __NR_recvmsg (__NR_Linux + 177) +#define __NR_send (__NR_Linux + 178) +#define __NR_sendmsg (__NR_Linux + 179) +#define __NR_sendto (__NR_Linux + 180) +#define __NR_setsockopt (__NR_Linux + 181) +#define __NR_shutdown (__NR_Linux + 182) +#define __NR_socket (__NR_Linux + 183) +#define __NR_socketpair (__NR_Linux + 184) +#define __NR_setresuid (__NR_Linux + 185) +#define __NR_getresuid (__NR_Linux + 186) + +/* + * Offset of the last Linux flavoured syscall + */ +#define __NR_Linux_syscalls 186 + +#ifndef __LANGUAGE_ASSEMBLY__ + /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ type name(void) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile ("syscall" \ - : "=r" (__res) \ - : "0" (__NR_##name)); \ -if (__res >= 0) \ +register long __err __asm__ ("$7"); \ +__asm__ volatile ("li\t$2,%2\n\t" \ + "syscall" \ + : "=r" (__res), "=r" (__err) \ + : "i" (__NR_##name)); \ +if (__err == 0) \ return (type) __res; \ -errno = -__res; \ +errno = __res; \ return -1; \ } +/* + * DANGER: This macro isn't usable for the pipe(2) call + * which has a unusual return convention. + */ #define _syscall1(type,name,atype,a) \ type name(atype a) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile ("move\t$4,%2\n\t" \ +register long __err __asm__ ("$7"); \ +__asm__ volatile ("move\t$4,%3\n\t" \ + "li\t$2,%2\n\t" \ "syscall" \ - : "=r" (__res) \ - : "0" (__NR_##name),"r" ((long)(a)) \ + : "=r" (__res), "=r" (__err) \ + : "i" (__NR_##name),"r" ((long)(a)) \ : "$4"); \ -if (__res >= 0) \ +if (__err == 0) \ return (type) __res; \ -errno = -__res; \ +errno = __res; \ return -1; \ } @@ -34,16 +1224,18 @@ return -1; \ type name(atype a,btype b) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile ("move\t$4,%2\n\t" \ - "move\t$5,%3\n\t" \ +register long __err __asm__ ("$7"); \ +__asm__ volatile ("move\t$4,%3\n\t" \ + "move\t$5,%4\n\t" \ + "li\t$2,%2\n\t" \ "syscall" \ - : "=r" (__res) \ - : "0" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b))); \ + : "=r" (__res), "=r" (__err) \ + : "i" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b)) \ : "$4","$5"); \ -if (__res >= 0) \ +if (__err == 0) \ return (type) __res; \ -errno = -__res; \ +errno = __res; \ return -1; \ } @@ -51,18 +1243,20 @@ return -1; \ type name (atype a, btype b, ctype c) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile ("move\t$4,%2\n\t" \ - "move\t$5,%3\n\t" \ - "move\t$6,%4\n\t" \ +register long __err __asm__ ("$7"); \ +__asm__ volatile ("move\t$4,%3\n\t" \ + "move\t$5,%4\n\t" \ + "move\t$6,%5\n\t" \ + "li\t$2,%2\n\t" \ "syscall" \ - : "=r" (__res) \ - : "0" (__NR_##name),"r" ((long)(a)), \ + : "=r" (__res), "=r" (__err) \ + : "i" (__NR_##name),"r" ((long)(a)), \ "r" ((long)(b)), \ "r" ((long)(c)) \ : "$4","$5","$6"); \ -if (__res>=0) \ +if (__err == 0) \ return (type) __res; \ -errno=-__res; \ +errno = __res; \ return -1; \ } @@ -70,20 +1264,22 @@ return -1; \ type name (atype a, btype b, ctype c, dtype d) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile ("move\t$4,%2\n\t" \ - "move\t$5,%3\n\t" \ - "move\t$6,%4\n\t" \ - "move\t$7,%5\n\t" \ +register long __err __asm__ ("$7"); \ +__asm__ volatile ("move\t$4,%3\n\t" \ + "move\t$5,%4\n\t" \ + "move\t$6,%5\n\t" \ + "move\t$7,%6\n\t" \ + "li\t$2,%2\n\t" \ "syscall" \ - : "=r" (__res) \ - : "0" (__NR_##name),"r" ((long)(a)), \ + : "=r" (__res), "=r" (__err) \ + : "i" (__NR_##name),"r" ((long)(a)), \ "r" ((long)(b)), \ "r" ((long)(c)), \ "r" ((long)(d)) \ - : "$4","$5","$6","$7"); \ -if (__res>=0) \ + : "$4","$5","$6"); \ +if (__err == 0) \ return (type) __res; \ -errno=-__res; \ +errno = __res; \ return -1; \ } @@ -91,22 +1287,92 @@ return -1; \ type name (atype a,btype b,ctype c,dtype d,etype e) \ { \ register long __res __asm__ ("$2"); \ -__asm__ volatile ("move\t$4,%2\n\t" \ - "move\t$5,%3\n\t" \ - "move\t$6,%4\n\t" \ - "move\t$7,%5\n\t" \ - "move\t$3,%6\n\t" \ - "syscall" \ - : "=r" (__res) \ - : "0" (__NR_##name),"r" ((long)(a)), \ +register long __err __asm__ ("$7"); \ +__asm__ volatile ("move\t$4,%3\n\t" \ + "move\t$5,%4\n\t" \ + "move\t$6,%5\n\t" \ + "lw\t$2,%7\n\t" \ + "move\t$7,%6\n\t" \ + "subu\t$29,24\n\t" \ + "sw\t$2,16($29)\n\t" \ + "li\t$2,%2\n\t" \ + "syscall\n\t" \ + "addiu\t$29,24" \ + : "=r" (__res), "=r" (__err) \ + : "i" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b)), \ + "r" ((long)(c)), \ + "r" ((long)(d)), \ + "m" ((long)(e)) \ + : "$2","$4","$5","$6","$7"); \ +if (__err == 0) \ + return (type) __res; \ +errno = __res; \ +return -1; \ +} + +#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \ +type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ +{ \ +register long __res __asm__ ("$2"); \ +register long __err __asm__ ("$7"); \ +__asm__ volatile ("move\t$4,%3\n\t" \ + "move\t$5,%4\n\t" \ + "move\t$6,%5\n\t" \ + "lw\t$2,%7\n\t" \ + "lw\t$3,%8\n\t" \ + "move\t$7,%6\n\t" \ + "subu\t$29,24\n\t" \ + "sw\t$2,16($29)\n\t" \ + "sw\t$3,20($29)\n\t" \ + "li\t$2,%2\n\t" \ + "syscall\n\t" \ + "addiu\t$29,24" \ + : "=r" (__res), "=r" (__err) \ + : "i" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b)), \ + "r" ((long)(c)), \ + "r" ((long)(d)), \ + "m" ((long)(e)), \ + "m" ((long)(f)) \ + : "$2","$3","$4","$5","$6","$7"); \ +if (__err == 0) \ + return (type) __res; \ +errno = __res; \ +return -1; \ +} + +#define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \ +type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \ +{ \ +register long __res __asm__ ("$2"); \ +register long __err __asm__ ("$7"); \ +__asm__ volatile ("move\t$4,%3\n\t" \ + "move\t$5,%4\n\t" \ + "move\t$6,%5\n\t" \ + "lw\t$2,%7\n\t" \ + "lw\t$3,%8\n\t" \ + "move\t$7,%6\n\t" \ + "subu\t$29,32\n\t" \ + "sw\t$2,16($29)\n\t" \ + "lw\t$2,%9\n\t" \ + "sw\t$3,20($29)\n\t" \ + "sw\t$2,24($29)\n\t" \ + "li\t$2,%2\n\t" \ + "syscall\n\t" \ + "addiu\t$29,32" \ + : "=r" (__res), "=r" (__err) \ + : "i" (__NR_##name),"r" ((long)(a)), \ "r" ((long)(b)), \ "r" ((long)(c)), \ "r" ((long)(d)), \ - "r" ((long)(e)) \ - : "$3","$4","$5","$6","$7"); \ -if (__res>=0) \ + "m" ((long)(e)), \ + "m" ((long)(f)), \ + "m" ((long)(g)) \ + : "$2","$3","$4","$5","$6","$7"); \ +if (__err == 0) \ return (type) __res; \ -errno=-__res; \ +errno = __res; \ return -1; \ } @@ -127,6 +1393,7 @@ return -1; \ #define __NR__exit __NR_exit static inline _syscall0(int,idle) static inline _syscall0(int,fork) +static inline _syscall2(int,clone,unsigned long,flags,char *,esp) static inline _syscall0(int,pause) static inline _syscall0(int,setup) static inline _syscall0(int,sync) @@ -144,6 +1411,49 @@ static inline pid_t wait(int * wait_stat) return waitpid(-1,wait_stat,0); } -#endif +/* + * This is the mechanism for creating a new kernel thread. + * + * NOTE! Only a kernel-only process(ie the swapper or direct descendants + * who haven't done an "execve()") should use this: it will work within + * a system call from a "real" process, but the process memory space will + * not be free'd until both the parent and the child have exited. + */ +static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + long retval; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + "move\t$8,$sp\n\t" + "move\t$4,%5\n\t" + "li\t$2,%1\n\t" + "syscall\n\t" + "beq\t$8,$sp,1f\n\t" + "subu\t$sp,32\n\t" /* delay slot */ + "jalr\t%4\n\t" + "move\t$4,%3\n\t" /* delay slot */ + "move\t$4,$2\n\t" + "li\t$2,%2\n\t" + "syscall\n" + "1:\taddiu\t$sp,32\n\t" + "move\t%0,$2\n\t" + ".set\treorder" + :"=r" (retval) + :"i" (__NR_clone), "i" (__NR_exit), + "r" (arg), "r" (fn), + "r" (flags | CLONE_VM) + /* + * The called subroutine might have destroyed any of the + * at, result, argument or temporary registers ... + */ + :"$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$9","$10","$11","$12","$13","$14","$15","$24","$25"); + + return retval; +} + +#endif /* !defined (__KERNEL_SYSCALLS__) */ +#endif /* !defined (__LANGUAGE_ASSEMBLY__) */ #endif /* __ASM_MIPS_UNISTD_H */ diff --git a/include/asm-mips/user.h b/include/asm-mips/user.h new file mode 100644 index 000000000..64069dd60 --- /dev/null +++ b/include/asm-mips/user.h @@ -0,0 +1,52 @@ +#ifndef __ASM_MIPS_USER_H +#define __ASM_MIPS_USER_H + +#include <linux/ptrace.h> + +#include <asm/page.h> +#include <asm/reg.h> + +/* + * Core file format: The core file is written in such a way that gdb + * can understand it and provide useful information to the user (under + * linux we use the `trad-core' bfd, NOT the osf-core). The file contents + * are as follows: + * + * upage: 1 page consisting of a user struct that tells gdb + * what is present in the file. Directly after this is a + * copy of the task_struct, which is currently not used by gdb, + * but it may come in handy at some point. All of the registers + * are stored as part of the upage. The upage should always be + * only one page long. + * data: The data segment follows next. We use current->end_text to + * current->brk to pick up all of the user variables, plus any memory + * that may have been sbrk'ed. No attempt is made to determine if a + * page is demand-zero or if a page is totally unused, we just cover + * the entire range. All of the addresses are rounded in such a way + * that an integral number of pages is written. + * stack: We need the stack information in order to get a meaningful + * backtrace. We need to write the data from usp to + * current->start_stack, so we round each of these in order to be able + * to write an integer number of pages. + */ +struct user { + unsigned long regs[EF_SIZE/8+32]; /* integer and fp regs */ + size_t u_tsize; /* text size (pages) */ + size_t u_dsize; /* data size (pages) */ + size_t u_ssize; /* stack size (pages) */ + unsigned long start_code; /* text starting address */ + unsigned long start_data; /* data starting address */ + unsigned long start_stack; /* stack starting address */ + long int signal; /* signal causing core dump */ + struct regs * u_ar0; /* help gdb find registers */ + unsigned long magic; /* identifies a core file */ + char u_comm[32]; /* user command name */ +}; + +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_DATA_START_ADDR (u.start_data) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif /* __ASM_MIPS_USER_H */ diff --git a/include/asm-mips/vector.h b/include/asm-mips/vector.h index bc0d85e3b..23c5b8385 100644 --- a/include/asm-mips/vector.h +++ b/include/asm-mips/vector.h @@ -5,28 +5,50 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995 by Ralf Baechle + * Copyright (C) 1995, 1996 by Ralf Baechle */ +#ifndef __ASM_MIPS_VECTOR_H +#define __ASM_MIPS_VECTOR_H /* - * This structure defines how to access various features of - * different machine types and how to access them. - * - * FIXME: More things need to be accessed via this vector. + * These vector structures are not very good to maintain - they'd probably + * grow to at leat three times the size - so I'll remove 'em and replace + * the with lots of ordinary variables. */ -struct feature { - void (*handle_int)(void); -}; +extern void (*irq_setup)(void); +extern asmlinkage void (*fd_cacheflush)(const void *addr, size_t size); /* - * Similar to the above this is a structure that describes various - * CPU dependend features. - * - * FIXME: This vector isn't being used yet + * This structure defines how to access various features of + * different machine types and how to access them. */ -struct cpu { - int dummy; /* keep GCC from complaining */ +struct feature { + /* + * How to access the floppy controller's ports. + */ + unsigned char (*fd_inb)(unsigned int port); + void (*fd_outb)(unsigned char value, unsigned int port); + /* + * How to access the floppy DMA functions. + */ + void (*fd_enable_dma)(void); + void (*fd_disable_dma)(void); + int (*fd_request_dma)(void); + void (*fd_free_dma)(void); + void (*fd_clear_dma_ff)(void); + void (*fd_set_dma_mode)(char mode); + void (*fd_set_dma_addr)(unsigned int a); + void (*fd_set_dma_count)(unsigned int count); + int (*fd_get_dma_residue)(void); + void (*fd_enable_irq)(void); + void (*fd_disable_irq)(void); + /* + * How to access the RTC register of the DS1287? + */ + unsigned char (*rtc_read_data)(unsigned long addr); + void (*rtc_write_data)(unsigned char data, unsigned long addr); }; extern struct feature *feature; -extern struct cpu *cpu; + +#endif /* __ASM_MIPS_VECTOR_H */ diff --git a/include/asm-mips/watch.h b/include/asm-mips/watch.h new file mode 100644 index 000000000..9c44856ef --- /dev/null +++ b/include/asm-mips/watch.h @@ -0,0 +1,38 @@ +/* + * Functions to use the watch register debugging functionality. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + */ +#ifndef __ASM_WATCH_H +#define __ASM_WATCH_H + +#include <linux/linkage.h> + +/* + * Types of reference for watch_set() + */ +enum wref_type { + wr_save = 1, + wr_load = 2 +}; + +extern asmlinkage unsigned int watch_available; +extern asmlinkage __watch_set(unsigned long addr, enum wref_type ref); +extern asmlinkage __watch_clear(void); +extern asmlinkage __watch_reenable(void); + +#define watch_set(addr, ref) \ + if (watch_available) \ + __watch_set(addr, ref) +#define watch_clear() \ + if (watch_available) \ + __watch_clear() +#define watch_reenable() \ + if (watch_available) \ + __watch_reenable() + +#endif __ASM_WATCH_H diff --git a/include/asm-ppc/a.out.h b/include/asm-ppc/a.out.h new file mode 100644 index 000000000..eef6a92dd --- /dev/null +++ b/include/asm-ppc/a.out.h @@ -0,0 +1,26 @@ +#ifndef __PPC_A_OUT_H__ +#define __PPC_A_OUT_H__ + +/* grabbed from the intel stuff */ +#define STACK_TOP TASK_SIZE + + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + + +#endif diff --git a/include/asm-ppc/atomic.h b/include/asm-ppc/atomic.h new file mode 100644 index 000000000..a54e6af42 --- /dev/null +++ b/include/asm-ppc/atomic.h @@ -0,0 +1,10 @@ +/* + * PowerPC atomic operations + */ + +#ifndef _ASM_PPC_ATOMIC_H_ +#define _ASM_PPC_ATOMIC_H_ + +typedef int atomic_t; +#endif + diff --git a/include/asm-ppc/bitops.h b/include/asm-ppc/bitops.h new file mode 100644 index 000000000..5e0407abd --- /dev/null +++ b/include/asm-ppc/bitops.h @@ -0,0 +1,130 @@ +#ifndef _ASM_PPC_BITOPS_H_ +#define _ASM_PPC_BITOPS_H_ + +/* + * For the benefit of those who are trying to port Linux to another + * architecture, here are some C-language equivalents. You should + * recode these in the native assembly language, if at all possible. + * To guarantee atomicity, these routines call cli() and sti() to + * disable interrupts while they operate. (You have to provide inline + * routines to cli() and sti().) + * + * Also note, these routines assume that you have 32 bit integers. + * You will have to change this if you are trying to port Linux to the + * Alpha architecture or to a Cray. :-) + * + * C language equivalents written by Theodore Ts'o, 9/26/92 + */ + +#include "asm/system.h" /* For cli/sti declaration */ + +#define BIT(n) 1<<(n&0x1F) +typedef unsigned long BITFIELD; + +extern __inline__ int set_bit(int nr, void * add) +{ + int mask, oldbit; + BITFIELD *addr = add; + + int s = _disable_interrupts(); + addr += nr >> 5; + mask = BIT(nr); + oldbit = (mask & *addr) != 0; + *addr |= mask; + _enable_interrupts(s); + + + return oldbit; +} + +extern __inline__ int change_bit(int nr, void *add) +{ + BITFIELD *addr = add; + int mask, retval; + int s = _disable_interrupts(); + addr += nr >> 5; + mask = BIT(nr); + retval = (mask & *addr) != 0; + *addr ^= mask; + _enable_interrupts(s); + return retval; +} + +extern __inline__ int clear_bit(int nr, void *add) +{ + BITFIELD *addr = add; + int mask, retval; + int s = _disable_interrupts(); + addr += nr >> 5; + mask = BIT(nr); + retval = (mask & *addr) != 0; + *addr &= ~mask; + _enable_interrupts(s); + return retval; +} + +extern __inline__ int test_bit(int nr, void *add) +{ + int mask; + BITFIELD *addr = add; + + addr += nr >> 5; + mask = BIT(nr); + return ((mask & *addr) != 0); +} +#if 0 +extern __inline__ int find_first_zero_bit(void *add, int len) +{ + int mask, nr, i; + BITFIELD *addr = add; + nr = 0; + while (len) + { + if (~*addr != 0) + { /* Contains at least one zero */ + for (i = 0; i < 32; i++, nr++) + { + mask = BIT(nr); + if ((mask & *addr) == 0) + { + return (nr); + } + } + } + len -= 32; + addr++; + nr += 32; + } + return (0); /* Shouldn't happen */ +} + +extern __inline__ int find_next_zero_bit(void *add, int len, int nr) +{ + int mask, i; + BITFIELD *addr = add; + addr += nr >> 5; + len -= nr; + while (len) + { + if (*addr != 0xFFFFFFFF) + { /* Contains at least one zero */ + for (i = 0; i < 32; i++, nr++) + { + mask = BIT(nr); + if ((mask & *addr) == 0) + { +printk("Bit: %d(%d), Pat: %x\n", nr, nr&0x1F, *addr); + return (nr); + } + } + } + len -= 32; + addr++; + nr += 32; + } + return (0); /* Shouldn't happen */ +} +#endif +#endif /* _ASM_PPC_BITOPS_H */ + + diff --git a/include/asm-ppc/bugs.h b/include/asm-ppc/bugs.h new file mode 100644 index 000000000..202f9ab06 --- /dev/null +++ b/include/asm-ppc/bugs.h @@ -0,0 +1,8 @@ +/* + * This file is included by 'init/main.c' + */ + +void +check_bugs(void) +{ +} diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h new file mode 100644 index 000000000..240e7401a --- /dev/null +++ b/include/asm-ppc/byteorder.h @@ -0,0 +1,93 @@ +#ifndef _PPC_BYTEORDER_H +#define _PPC_BYTEORDER_H + +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN +#endif + +#ifndef __BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN_BITFIELD +#endif + +#if 0 /* Assume PowerPC is Big-Endian! */ +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +extern unsigned long int ntohl(unsigned long int); +extern unsigned short int ntohs(unsigned short int); +extern unsigned long int htonl(unsigned long int); +extern unsigned short int htons(unsigned short int); + +extern unsigned long int __ntohl(unsigned long int); +extern unsigned short int __ntohs(unsigned short int); +extern unsigned long int __constant_ntohl(unsigned long int); +extern unsigned short int __constant_ntohs(unsigned short int); + +extern __inline__ unsigned long int +__ntohl(unsigned long int x) +{ + return (((x & 0x000000ffU) << 24) | + ((x & 0x0000ff00U) << 8) | + ((x & 0x00ff0000U) >> 8) | + ((x & 0xff000000U) >> 24)); +} + +extern __inline__ unsigned long int +__constant_ntohl(unsigned long int x) +{ + return (((x & 0x000000ffU) << 24) | + ((x & 0x0000ff00U) << 8) | + ((x & 0x00ff0000U) >> 8) | + ((x & 0xff000000U) >> 24)); +} + +extern __inline__ unsigned short int +__ntohs(unsigned short int x) +{ + return (((x & 0x00ff) << 8) | + ((x & 0xff00) >> 8)); +} + +extern __inline__ unsigned short int +__constant_ntohs(unsigned short int x) +{ + return (((x & 0x00ff) << 8) | + ((x & 0xff00) >> 8)); +} + +#define __htonl(x) __ntohl(x) +#define __htons(x) __ntohs(x) +#define __constant_htonl(x) __constant_ntohl(x) +#define __constant_htons(x) __constant_ntohs(x) + +#ifdef __OPTIMIZE__ +# define ntohl(x) \ +(__builtin_constant_p((long)(x)) ? \ + __constant_ntohl((x)) : \ + __ntohl((x))) +# define ntohs(x) \ +(__builtin_constant_p((short)(x)) ? \ + __constant_ntohs((x)) : \ + __ntohs((x))) +# define htonl(x) \ +(__builtin_constant_p((long)(x)) ? \ + __constant_htonl((x)) : \ + __htonl((x))) +# define htons(x) \ +(__builtin_constant_p((short)(x)) ? \ + __constant_htons((x)) : \ + __htons((x))) +#endif + +#else + +#define ntohl(x) (x) +#define ntohs(x) (x) +#define htonl(x) (x) +#define htons(x) (x) + +#endif + +#endif /* !(_PPC_BYTEORDER_H) */ diff --git a/include/asm-ppc/checksum.h b/include/asm-ppc/checksum.h new file mode 100644 index 000000000..99dbed2e3 --- /dev/null +++ b/include/asm-ppc/checksum.h @@ -0,0 +1,58 @@ +#ifndef _PPC_CHECKSUM_H +#define _PPC_CHECKSUM_H + + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl); + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +extern unsigned short int csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum); + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum); + +/* + * the same as csum_partial, but copies from user space (but on the alpha + * we have just one address space, so this is identical to the above) + */ +#define csum_partial_copy_fromuser csum_partial_copy + + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c +A */ + +extern unsigned short ip_compute_csum(unsigned char * buff, int len); + +#endif diff --git a/include/asm-ppc/delay.h b/include/asm-ppc/delay.h new file mode 100644 index 000000000..68f1a4da7 --- /dev/null +++ b/include/asm-ppc/delay.h @@ -0,0 +1,15 @@ +#ifndef _PPC_DELAY_H +#define _PPC_DELAY_H + + +extern __inline__ void __delay(unsigned long ); +extern __inline__ void __udelay(unsigned long ); + + +extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) +{ + return (a*b)/c; +} + +#endif /* defined(_PPC_DELAY_H) */ + diff --git a/include/asm-ppc/dma.h b/include/asm-ppc/dma.h new file mode 100644 index 000000000..9e6608d54 --- /dev/null +++ b/include/asm-ppc/dma.h @@ -0,0 +1,299 @@ +/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen + * and John Boyd, Nov. 1992. + */ + +/* + * Note: Adapted for PowerPC by Gary Thomas + * + * There may be some comments or restrictions made here which are + * not valid for the PowerPC (PreP) platform. Take what you read + * with a grain of salt. + */ + + +#ifndef _ASM_DMA_H +#define _ASM_DMA_H + +#include <asm/io.h> /* need byte IO */ + + +#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER +#define dma_outb outb_p +#else +#define dma_outb outb +#endif + +#define dma_inb inb + +/* + * NOTES about DMA transfers: + * + * controller 1: channels 0-3, byte operations, ports 00-1F + * controller 2: channels 4-7, word operations, ports C0-DF + * + * - ALL registers are 8 bits only, regardless of transfer size + * - channel 4 is not used - cascades 1 into 2. + * - channels 0-3 are byte - addresses/counts are for physical bytes + * - channels 5-7 are word - addresses/counts are for physical words + * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries + * - transfer count loaded to registers is 1 less than actual count + * - controller 2 offsets are all even (2x offsets for controller 1) + * - page registers for 5-7 don't use data bit 0, represent 128K pages + * - page registers for 0-3 use bit 0, represent 64K pages + * + * DMA transfers are limited to the lower 16MB of _physical_ memory. + * Note that addresses loaded into registers must be _physical_ addresses, + * not logical addresses (which may differ if paging is active). + * + * Address mapping for channels 0-3: + * + * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * P7 ... P0 A7 ... A0 A7 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Address mapping for channels 5-7: + * + * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) + * | ... | \ \ ... \ \ \ ... \ \ + * | ... | \ \ ... \ \ \ ... \ (not used) + * | ... | \ \ ... \ \ \ ... \ + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses + * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at + * the hardware level, so odd-byte transfers aren't possible). + * + * Transfer count (_not # bytes_) is limited to 64K, represented as actual + * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, + * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * + */ + +#define MAX_DMA_CHANNELS 8 + +/* The maximum address that we can perform a DMA transfer to on this platform */ +/* Doesn't really apply... */ +#define MAX_DMA_ADDRESS 0xFFFFFFFF + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG 0x08 /* command register (w) */ +#define DMA1_STAT_REG 0x08 /* status register (r) */ +#define DMA1_REQ_REG 0x09 /* request register (w) */ +#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ +#define DMA1_MODE_REG 0x0B /* mode register (w) */ +#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ +#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ +#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ + +#define DMA2_CMD_REG 0xD0 /* command register (w) */ +#define DMA2_STAT_REG 0xD0 /* status register (r) */ +#define DMA2_REQ_REG 0xD2 /* request register (w) */ +#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ +#define DMA2_MODE_REG 0xD6 /* mode register (w) */ +#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ +#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ +#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ + +#define DMA_ADDR_0 0x00 /* DMA address registers */ +#define DMA_ADDR_1 0x02 +#define DMA_ADDR_2 0x04 +#define DMA_ADDR_3 0x06 +#define DMA_ADDR_4 0xC0 +#define DMA_ADDR_5 0xC4 +#define DMA_ADDR_6 0xC8 +#define DMA_ADDR_7 0xCC + +#define DMA_CNT_0 0x01 /* DMA count registers */ +#define DMA_CNT_1 0x03 +#define DMA_CNT_2 0x05 +#define DMA_CNT_3 0x07 +#define DMA_CNT_4 0xC2 +#define DMA_CNT_5 0xC6 +#define DMA_CNT_6 0xCA +#define DMA_CNT_7 0xCE + +#define DMA_LO_PAGE_0 0x87 /* DMA page registers */ +#define DMA_LO_PAGE_1 0x83 +#define DMA_LO_PAGE_2 0x81 +#define DMA_LO_PAGE_3 0x82 +#define DMA_LO_PAGE_5 0x8B +#define DMA_LO_PAGE_6 0x89 +#define DMA_LO_PAGE_7 0x8A + +#define DMA_HI_PAGE_0 0x487 /* DMA page registers */ +#define DMA_HI_PAGE_1 0x483 +#define DMA_HI_PAGE_2 0x481 +#define DMA_HI_PAGE_3 0x482 +#define DMA_HI_PAGE_5 0x48B +#define DMA_HI_PAGE_6 0x489 +#define DMA_HI_PAGE_7 0x48A + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (dmanr != 4) + { + dma_outb(0, DMA2_MASK_REG); /* This may not be enabled */ + dma_outb(0, DMA2_CMD_REG); /* Enable group */ + } + if (dmanr<=3) + { + dma_outb(dmanr, DMA1_MASK_REG); + dma_outb(0, DMA1_CMD_REG); /* Enable group */ + } else + { + dma_outb(dmanr & 3, DMA2_MASK_REG); + } +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr | 4, DMA1_MASK_REG); + else + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(0, DMA1_CLEAR_FF_REG); + else + dma_outb(0, DMA2_CLEAR_FF_REG); +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + dma_outb(mode | dmanr, DMA1_MODE_REG); + else + dma_outb(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, int pagenr) +{ + switch(dmanr) { + case 0: + dma_outb(pagenr, DMA_LO_PAGE_0); + break; + case 1: + dma_outb(pagenr, DMA_LO_PAGE_1); + break; + case 2: + dma_outb(pagenr, DMA_LO_PAGE_2); + dma_outb(pagenr>>8, DMA_HI_PAGE_2); + break; + case 3: + dma_outb(pagenr, DMA_LO_PAGE_3); + break; + case 5: + dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5); + break; + case 6: + dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6); + break; + case 7: + dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7); + break; + } +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys) +{ + if (dmanr <= 3) { + dma_outb( phys & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + dma_outb( (phys>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + dma_outb( (phys>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + dma_outb( (phys>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } + set_dma_page(dmanr, phys>>16); +} + + +/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + + count = 1 + dma_inb(io_port); + count += dma_inb(io_port) << 8; + + return (dmanr<=3)? count : (count<<1); +} + + +/* These are in kernel/dma.c: */ +/*extern int request_dma(unsigned int dmanr, char * device_id);*/ /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + + +#endif /* _ASM_DMA_H */ diff --git a/include/asm-ppc/elf.h b/include/asm-ppc/elf.h new file mode 100644 index 000000000..875064189 --- /dev/null +++ b/include/asm-ppc/elf.h @@ -0,0 +1,30 @@ +#ifndef __PPC_ELF_H +#define __PPC_ELF_H + +/* + * ELF register definitions.. + */ + +#define ELF_NGREG 32 +#define ELF_NFPREG 32 + +typedef unsigned long elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +#define elf_check_arch(x) ((x) == EM_PPC) + +/* + * These are used to set parameters in the core dumps. + * FIXME(eric) I don't know what the correct endianness to use is. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB; +#define ELF_ARCH EM_PPC + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +#endif diff --git a/include/asm-ppc/errno.h b/include/asm-ppc/errno.h new file mode 100644 index 000000000..1b5d9f387 --- /dev/null +++ b/include/asm-ppc/errno.h @@ -0,0 +1,133 @@ +#ifndef _PPC_ERRNO_H +#define _PPC_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ +#define EDEADLOCK 58 /* File locking deadlock error */ +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +/* Should never be seen by user programs */ +#define ERESTARTSYS 512 +#define ERESTARTNOINTR 513 +#define ERESTARTNOHAND 514 /* restart if no handler.. */ +#define ENOIOCTLCMD 515 /* No ioctl command */ + +#endif diff --git a/include/asm-ppc/fcntl.h b/include/asm-ppc/fcntl.h new file mode 100644 index 000000000..9b0f41c73 --- /dev/null +++ b/include/asm-ppc/fcntl.h @@ -0,0 +1,59 @@ +#ifndef _PPC_FCNTL_H +#define _PPC_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#define O_SYNC 010000 +#define FASYNC 020000 /* fcntl, for BSD compatibility */ + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get f_flags */ +#define F_SETFD 2 /* set f_flags */ +#define F_GETFL 3 /* more flags (cloexec) */ +#define F_SETFL 4 +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +#endif diff --git a/include/asm-ppc/floppy.h b/include/asm-ppc/floppy.h new file mode 100644 index 000000000..eb52f4611 --- /dev/null +++ b/include/asm-ppc/floppy.h @@ -0,0 +1,54 @@ +/* + * Architecture specific parts of the Floppy driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995 + */ +#ifndef __ASM_PPC_FLOPPY_H +#define __ASM_PPC_FLOPPY_H + +#define fd_inb(port) inb_p(port) +#define fd_outb(port,value) outb_p(port,value) + +#define fd_enable_dma() enable_dma(FLOPPY_DMA) +#define fd_disable_dma() disable_dma(FLOPPY_DMA) +#define fd_request_dma() request_dma(FLOPPY_DMA,"floppy") +#define fd_free_dma() free_dma(FLOPPY_DMA) +#define fd_clear_dma_ff() clear_dma_ff(FLOPPY_DMA) +#define fd_set_dma_mode(mode) set_dma_mode(FLOPPY_DMA,mode) +#define fd_set_dma_addr(addr) set_dma_addr(FLOPPY_DMA,virt_to_bus(addr)) +#define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA,count) +#define fd_enable_irq() enable_irq(FLOPPY_IRQ) +#define fd_disable_irq() disable_irq(FLOPPY_IRQ) +#define fd_cacheflush(addr,size) /* nothing */ +#define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \ + SA_INTERRUPT|SA_SAMPLE_RANDOM, \ + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL); + +__inline__ void virtual_dma_init(void) +{ + /* Nothing to do on PowerPC */ +} + +static int FDC1 = 0x3f0; +static int FDC2 = -1; + +/* + * Again, the CMOS information not available + */ +#define FLOPPY0_TYPE 6 +#define FLOPPY1_TYPE 0 + +#define N_FDC 2 /* Don't change this! */ +#define N_DRIVE 8 + +/* + * The PowerPC has no problems with floppy DMA crossing 64k borders. + */ +#define CROSS_64KB(a,s) (0) + +#endif /* __ASM_PPC_FLOPPY_H */ diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h new file mode 100644 index 000000000..35cd7e2f2 --- /dev/null +++ b/include/asm-ppc/io.h @@ -0,0 +1,86 @@ +#ifndef _PPC_IO_H +#define _PPC_IO_H + +/* Define the particulars of outb/outw/outl "instructions" */ + +#define SLOW_DOWN_IO + +#ifndef PCI_DRAM_OFFSET +#define PCI_DRAM_OFFSET 0x80000000 +#endif +#ifndef KERNELBASE +#define KERNELBASE 0x90000000 +#endif + +/* + * The PCI bus is inherently Little-Endian. The PowerPC is being + * run Big-Endian. Thus all values which cross the [PCI] barrier + * must be endian-adjusted. Also, the local DRAM has a different + * address from the PCI point of view, thus buffer addresses also + * have to be modified [mapped] appropriately. + */ +extern inline unsigned long virt_to_bus(volatile void * address) +{ + if (address == (void *)0) return 0; + return ((unsigned long)((long)address - KERNELBASE + PCI_DRAM_OFFSET)); +} + +extern inline void * bus_to_virt(unsigned long address) +{ + if (address == 0) return 0; + return ((void *)(address - PCI_DRAM_OFFSET + KERNELBASE)); +} +/* #define virt_to_bus(a) ((unsigned long)(((char *)a==(char *) 0) ? ((char *)0) \ + : ((char *)((long)a - KERNELBASE + PCI_DRAM_OFFSET)))) +#define bus_to_virt(a) ((void *) (((char *)a==(char *)0) ? ((char *)0) \ + : ((char *)((long)a - PCI_DRAM_OFFSET + KERNELBASE)))) +*/ + +#define readb(addr) (*(volatile unsigned char *) (addr)) +#define readw(addr) (*(volatile unsigned short *) (addr)) +#define readl(addr) (*(volatile unsigned int *) (addr)) + +#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b)) +#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b)) +#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b)) + +/* + * Change virtual addresses to physical addresses and vv. + * These are trivial on the 1:1 Linux/i386 mapping (but if we ever + * make the kernel segment mapped at 0, we need to do translation + * on the i386 as well) + */ +extern inline unsigned long virt_to_phys(volatile void * address) +{ + return (unsigned long) address; +} + +extern inline void * phys_to_virt(unsigned long address) +{ + return (void *) address; +} + +/* from arch/ppc/kernel/port_io.c + * -- Cort + */ +unsigned char inb(int port); +unsigned short inw(int port); +unsigned long inl(int port); +unsigned char outb(unsigned char val,int port); +unsigned short outw(unsigned short val,int port); +unsigned long outl(unsigned long val,int port); +void outsl(int port, long *ptr, int len); + +static inline unsigned char inb_p(int port) {return (inb(port)); } +static inline unsigned short inw_p(int port) {return (inw(port)); } +static inline unsigned long inl_p(int port) {return (inl(port)); } + + + +static inline unsigned char outb_p(unsigned char val,int port) { return (outb(val,port)); } +static inline unsigned short outw_p(unsigned short val,int port) { return (outw(val,port)); } +static inline unsigned long outl_p(unsigned long val,int port) { return (outl(val,port)); } + + + +#endif diff --git a/include/asm-ppc/ioctl.h b/include/asm-ppc/ioctl.h new file mode 100644 index 000000000..efef8c9f2 --- /dev/null +++ b/include/asm-ppc/ioctl.h @@ -0,0 +1,52 @@ +#ifndef _PPC_IOCTL_H +#define _PPC_IOCTL_H + + +/* + * this was copied from the alpha as it's a bit cleaner there. + * -- Cort + */ + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 13 +#define _IOC_DIRBITS 3 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. + * And this turns out useful to catch old ioctl numbers in header + * files for us. + */ +#define _IOC_NONE 1U +#define _IOC_READ 2U +#define _IOC_WRITE 4U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode them.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +#endif diff --git a/include/asm-ppc/ioctls.h b/include/asm-ppc/ioctls.h new file mode 100644 index 000000000..52a3d45bd --- /dev/null +++ b/include/asm-ppc/ioctls.h @@ -0,0 +1,102 @@ +#ifndef _ASM_PPC_IOCTLS_H +#define _ASM_PPC_IOCTLS_H + +#include <asm/ioctl.h> + +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD + +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCSETP _IOW('t', 9, struct sgttyb) +#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ + +#define TIOCSETC _IOW('t', 17, struct tchars) +#define TIOCGETC _IOR('t', 18, struct tchars) +#define TCGETS _IOR('t', 19, struct termios) +#define TCSETS _IOW('t', 20, struct termios) +#define TCSETSW _IOW('t', 21, struct termios) +#define TCSETSF _IOW('t', 22, struct termios) + +#define TCGETA _IOR('t', 23, struct termio) +#define TCSETA _IOW('t', 24, struct termio) +#define TCSETAW _IOW('t', 25, struct termio) +#define TCSETAF _IOW('t', 28, struct termio) + +#define TCSBRK _IO('t', 29) +#define TCXONC _IO('t', 30) +#define TCFLSH _IO('t', 31) + +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ + +#define TIOCGLTC _IOR('t', 116, struct ltchars) +#define TIOCSLTC _IOW('t', 117, struct ltchars) +#define TIOCSPGRP _IOW('t', 118, int) +#define TIOCGPGRP _IOR('t', 119, int) + +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E + +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +# define TIOCM_LE 0x001 +# define TIOCM_DTR 0x002 +# define TIOCM_RTS 0x004 +# define TIOCM_ST 0x008 +# define TIOCM_SR 0x010 +# define TIOCM_CTS 0x020 +# define TIOCM_CAR 0x040 +# define TIOCM_RNG 0x080 +# define TIOCM_DSR 0x100 +# define TIOCM_CD TIOCM_CAR +# define TIOCM_RI TIOCM_RNG + +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +# define TIOCPKT_DATA 0 +# define TIOCPKT_FLUSHREAD 1 +# define TIOCPKT_FLUSHWRITE 2 +# define TIOCPKT_STOP 4 +# define TIOCPKT_START 8 +# define TIOCPKT_NOSTOP 16 +# define TIOCPKT_DOSTOP 32 + + +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ + +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ + /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +#endif /* _ASM_PPC_IOCTLS_H */ diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h new file mode 100644 index 000000000..f457f82c3 --- /dev/null +++ b/include/asm-ppc/irq.h @@ -0,0 +1,9 @@ +#ifndef _ASM_IRQ_H +#define _ASM_IRQ_H + +#define NR_IRQS 32 + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +#endif diff --git a/include/asm-ppc/mc146818rtc.h b/include/asm-ppc/mc146818rtc.h new file mode 100644 index 000000000..78cf56e00 --- /dev/null +++ b/include/asm-ppc/mc146818rtc.h @@ -0,0 +1,109 @@ +/* mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM + * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993 + * derived from Data Sheet, Copyright Motorola 1984 (!). + * It was written to be part of the Linux operating system. + */ +/* permission is hereby granted to copy, modify and redistribute this code + * in terms of the GNU Library General Public License, Version 2 or later, + * at your option. + */ + +#ifndef _MC146818RTC_H +#define _MC146818RTC_H +#include <asm/io.h> + +#ifndef MCRTC_PORT +#define MCRTC_PORT(x) (0x70 + (x)) +#define MCRTC_ALWAYS_BCD 1 +#endif + +#define CMOS_MCRTC_READ(addr) ({ \ +outb_p((addr),MCRTC_PORT(0)); \ +inb_p(MCRTC_PORT(1)); \ +}) +#define CMOS_MCRTC_WRITE(val, addr) ({ \ +outb_p((addr),MCRTC_PORT(0)); \ +outb_p((val),MCRTC_PORT(1)); \ +}) + +/********************************************************************** + * register summary + **********************************************************************/ +#define MCRTC_SECONDS 0 +#define MCRTC_SECONDS_ALARM 1 +#define MCRTC_MINUTES 2 +#define MCRTC_MINUTES_ALARM 3 +#define MCRTC_HOURS 4 +#define MCRTC_HOURS_ALARM 5 +/* RTC_*_alarm is always true if 2 MSBs are set */ +# define MCRTC_ALARM_DONT_CARE 0xC0 + +#define MCRTC_DAY_OF_WEEK 6 +#define MCRTC_DAY_OF_MONTH 7 +#define MCRTC_MONTH 8 +#define MCRTC_YEAR 9 + +/* control registers - Moto names + */ +#define MCRTC_REG_A 10 +#define MCRTC_REG_B 11 +#define MCRTC_REG_C 12 +#define MCRTC_REG_D 13 + +/********************************************************************** + * register details + **********************************************************************/ +#define MCRTC_FREQ_SELECT MCRTC_REG_A + +/* update-in-progress - set to "1" 244 microsecs before RTC goes off the bus, + * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete, + * totalling to a max high interval of 2.228 ms. + */ +# define MCRTC_UIP 0x80 +# define MCRTC_DIV_CTL 0x70 + /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */ +# define MCRTC_REF_CLCK_4MHZ 0x00 +# define MCRTC_REF_CLCK_1MHZ 0x10 +# define MCRTC_REF_CLCK_32KHZ 0x20 + /* 2 values for divider stage reset, others for "testing purposes only" */ +# define MCRTC_DIV_RESET1 0x60 +# define MCRTC_DIV_RESET2 0x70 + /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */ +# define MCRTC_RATE_SELECT 0x0F + +/**********************************************************************/ +#define MCRTC_CONTROL MCRTC_REG_B +# define MCRTC_SET 0x80 /* disable updates for clock setting */ +# define MCRTC_PIE 0x40 /* periodic interrupt enable */ +# define MCRTC_AIE 0x20 /* alarm interrupt enable */ +# define MCRTC_UIE 0x10 /* update-finished interrupt enable */ +# define MCRTC_SQWE 0x08 /* enable square-wave output */ +# define MCRTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ +# define MCRTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ +# define MCRTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ + +/**********************************************************************/ +#define MCRTC_INTR_FLAGS MCRTC_REG_C +/* caution - cleared by read */ +# define MCRTC_IRQF 0x80 /* any of the following 3 is active */ +# define MCRTC_PF 0x40 +# define MCRTC_AF 0x20 +# define MCRTC_UF 0x10 + +/**********************************************************************/ +#define MCRTC_VALID MCRTC_REG_D +# define MCRTC_VRT 0x80 /* valid RAM and time */ +/**********************************************************************/ + +/* example: !(CMOS_READ(MCRTC_CONTROL) & MCRTC_DM_BINARY) + * determines if the following two #defines are needed + */ +#ifndef BCD_TO_BIN +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) +#endif + +#ifndef BIN_TO_BCD +#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) +#endif + +#endif /* _MC146818RTC_H */ diff --git a/include/asm-ppc/mman.h b/include/asm-ppc/mman.h new file mode 100644 index 000000000..d377dfc62 --- /dev/null +++ b/include/asm-ppc/mman.h @@ -0,0 +1,31 @@ +#ifndef __PPC_MMAN_H__ +#define __PPC_MMAN_H__ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ +#define MCL_FUTURE 0x4000 /* lock all additions to address space */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __PPC_MMAN_H__ */ diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h new file mode 100644 index 000000000..b26b79cd6 --- /dev/null +++ b/include/asm-ppc/mmu.h @@ -0,0 +1,153 @@ +/* + * PowerPC memory management structures + */ + +#ifndef _PPC_MMU_H_ +#define _PPC_MMU_H_ + +/* Hardware Page Table Entry */ + +typedef struct _PTE + { + unsigned long v:1; /* Entry is valid */ + unsigned long vsid:24; /* Virtual segment identifier */ + unsigned long h:1; /* Hash algorithm indicator */ + unsigned long api:6; /* Abbreviated page index */ + unsigned long rpn:20; /* Real (physical) page number */ + unsigned long :3; /* Unused */ + unsigned long r:1; /* Referenced */ + unsigned long c:1; /* Changed */ + unsigned long w:1; /* Write-thru cache mode */ + unsigned long i:1; /* Cache inhibited */ + unsigned long m:1; /* Memory coherence */ + unsigned long g:1; /* Guarded */ + unsigned long :1; /* Unused */ + unsigned long pp:2; /* Page protection */ + } PTE; + +/* Values for PP (assumes Ks=0, Kp=1) */ +#define PP_RWXX 0 /* Supervisor read/write, User none */ +#define PP_RWRX 1 /* Supervisor read/write, User read */ +#define PP_RWRW 2 /* Supervisor read/write, User read/write */ +#define PP_RXRX 3 /* Supervisor read, User read */ + +/* Segment Register */ + +typedef struct _SEGREG + { + unsigned long t:1; /* Normal or I/O type */ + unsigned long ks:1; /* Supervisor 'key' (normally 0) */ + unsigned long kp:1; /* User 'key' (normally 1) */ + unsigned long n:1; /* No-execute */ + unsigned long :4; /* Unused */ + unsigned long vsid:24; /* Virtual Segment Identifier */ + } SEGREG; + +/* Block Address Translation (BAT) Registers */ + +typedef struct _BATU /* Upper part of BAT */ + { + unsigned long bepi:15; /* Effective page index (virtual address) */ + unsigned long :4; /* Unused */ + unsigned long bl:11; /* Block size mask */ + unsigned long vs:1; /* Supervisor valid */ + unsigned long vp:1; /* User valid */ + } BATU; + +typedef struct _BATL /* Lower part of BAT */ + { + unsigned long brpn:15; /* Real page index (physical address) */ + unsigned long :10; /* Unused */ + unsigned long w:1; /* Write-thru cache */ + unsigned long i:1; /* Cache inhibit */ + unsigned long m:1; /* Memory coherence */ + unsigned long g:1; /* Guarded (MBZ) */ + unsigned long :1; /* Unused */ + unsigned long pp:2; /* Page access protections */ + } BATL; + +typedef struct _BAT + { + BATU batu; /* Upper register */ + BATL batl; /* Lower register */ + } BAT; + +/* Block size masks */ +#define BL_128K 0x000 +#define BL_256K 0x001 +#define BL_512K 0x003 +#define BL_1M 0x007 +#define BL_2M 0x00F +#define BL_4M 0x01F +#define BL_8M 0x03F +#define BL_16M 0x07F +#define BL_32M 0x0FF +#define BL_64M 0x1FF +#define BL_128M 0x3FF +#define BL_256M 0x7FF + +/* BAT Access Protection */ +#define BPP_XX 0x00 /* No access */ +#define BPP_RX 0x01 /* Read only */ +#define BPP_RW 0x02 /* Read/write */ + +/* + * Simulated two-level MMU. This structure is used by the kernel + * to keep track of MMU mappings and is used to update/maintain + * the hardware HASH table which is really a cache of mappings. + * + * The simulated structures mimic the hardware available on other + * platforms, notably the 80x86 and 680x0. + */ + +typedef struct _pte + { + unsigned long page_num:20; + unsigned long flags:12; /* Page flags (with some unused bits) */ + } pte; + +#define PD_SHIFT (10+12) /* Page directory */ +#define PD_MASK 0x02FF +#define PT_SHIFT (12) /* Page Table */ +#define PT_MASK 0x02FF +#define PG_SHIFT (12) /* Page Entry */ + + +/* MMU context */ + +typedef struct _MMU_context + { + SEGREG segs[16]; /* Segment registers */ + pte **pmap; /* Two-level page-map structure */ + } MMU_context; + +#if 0 +BAT ibat[4]; /* Instruction BAT images */ +BAT dbat[4]; /* Data BAT images */ +PTE *hash_table; /* Hardware hashed page table */ +int hash_table_size; +int hash_table_mask; +unsigned long sdr; /* Hardware image of SDR */ +#endif + +/* Used to set up SDR register */ +#define HASH_TABLE_SIZE_64K 0x00010000 +#define HASH_TABLE_SIZE_128K 0x00020000 +#define HASH_TABLE_SIZE_256K 0x00040000 +#define HASH_TABLE_SIZE_512K 0x00080000 +#define HASH_TABLE_SIZE_1M 0x00100000 +#define HASH_TABLE_SIZE_2M 0x00200000 +#define HASH_TABLE_SIZE_4M 0x00400000 +#define HASH_TABLE_MASK_64K 0x000 +#define HASH_TABLE_MASK_128K 0x001 +#define HASH_TABLE_MASK_256K 0x003 +#define HASH_TABLE_MASK_512K 0x007 +#define HASH_TABLE_MASK_1M 0x00F +#define HASH_TABLE_MASK_2M 0x01F +#define HASH_TABLE_MASK_4M 0x03F + +#define MMU_PAGE_SIZE 4096 + +extern int MMU_hash_page(struct thread_struct *tss, unsigned long va, pte *pg); + +#endif diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h new file mode 100644 index 000000000..8cee7fb30 --- /dev/null +++ b/include/asm-ppc/mmu_context.h @@ -0,0 +1,10 @@ +#ifndef __PPC_MMU_CONTEXT_H +#define __PPC_MMU_CONTEXT_H + +/* + * get a new mmu context.. PowerPC's don't know about contexts [yet] + */ +#define get_mmu_context(x) do { } while (0) + +#endif + diff --git a/include/asm-ppc/nvram.h b/include/asm-ppc/nvram.h new file mode 100644 index 000000000..1d704ff6a --- /dev/null +++ b/include/asm-ppc/nvram.h @@ -0,0 +1,30 @@ +/* + * PreP compliant NVRAM access + */ + +#ifndef _PPC_NVRAM_H +#define _PPC_NVRAM_H + +#define NVRAM_AS0 0x74 +#define NVRAM_AS1 0x75 +#define NVRAM_DATA 0x77 + +/* RTC Offsets */ + +#define RTC_SECONDS 0x1FF9 +#define RTC_MINUTES 0x1FFA +#define RTC_HOURS 0x1FFB +#define RTC_DAY_OF_WEEK 0x1FFC +#define RTC_DAY_OF_MONTH 0x1FFD +#define RTC_MONTH 0x1FFE +#define RTC_YEAR 0x1FFF + +#ifndef BCD_TO_BIN +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) +#endif + +#ifndef BIN_TO_BCD +#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) +#endif + +#endif diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h new file mode 100644 index 000000000..6984b2a08 --- /dev/null +++ b/include/asm-ppc/page.h @@ -0,0 +1,90 @@ +#ifndef _PPC_PAGE_H +#define _PPC_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +void invalidate(void); + +#ifdef __KERNEL__ + +#define STRICT_MM_TYPECHECKS + +#ifdef STRICT_MM_TYPECHECKS +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#else +/* + * .. while these make it easier on the compiler + */ +typedef unsigned long pte_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) (x) +#define pgd_val(x) (x) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) (x) +#define __pgd(x) (x) +#define __pgprot(x) (x) + +#endif + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* This handles the memory map.. */ + +#define KERNELBASE 0x90000000 +#define PAGE_OFFSET KERNELBASE +#define MAP_NR(addr) ((((unsigned long)addr) - PAGE_OFFSET) >> PAGE_SHIFT) +#define MAP_PAGE_RESERVED (1<<15) + + +#if 0 /* Now defined in "mm.h" */ +/* + * This used to be an unsigned short... + * + * -- Cort + */ +/*typedef unsigned short mem_map_t;*/ + +typedef struct { + unsigned count:30, + dirty:1, + reserved:1; +} mem_map_t; +#endif + +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval)) + + +#endif /* __KERNEL__ */ + +#endif /* _PPC_PAGE_H */ diff --git a/include/asm-ppc/param.h b/include/asm-ppc/param.h new file mode 100644 index 000000000..0cdcc660e --- /dev/null +++ b/include/asm-ppc/param.h @@ -0,0 +1,20 @@ +#ifndef _ASM_PPC_PARAM_H +#define _ASM_PPC_PARAM_H + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NGROUPS +#define NGROUPS 32 +#endif + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h new file mode 100644 index 000000000..b8425f882 --- /dev/null +++ b/include/asm-ppc/pgtable.h @@ -0,0 +1,533 @@ +/* * Last edited: Nov 7 23:44 1995 (cort) */ +#ifndef _PPC_PGTABLE_H +#define _PPC_PGTABLE_H + +#include <asm/page.h> +#include <asm/mmu.h> + +/* + * Memory management on the PowerPC is a software emulation of the i386 + * MMU folded onto the PowerPC hardware MMU. The emulated version looks + * and behaves like the two-level i386 MMU. Entries from these tables + * are merged into the PowerPC hashed MMU tables, on demand, treating the + * hashed tables like a special cache. + * + * Since the PowerPC does not have separate kernel and user address spaces, + * the user virtual address space must be a [proper] subset of the kernel + * space. Thus, all tasks will have a specific virtual mapping for the + * user virtual space and a common mapping for the kernel space. The + * simplest way to split this was literally in half. Also, life is so + * much simpler for the kernel if the machine hardware resources are + * always mapped in. Thus, some additional space is given up to the + * kernel space to accommodate this. + * + * CAUTION! Some of the trade-offs make sense for the PreP platform on + * which this code was originally developed. When it migrates to other + * PowerPC environments, some of the assumptions may fail and the whole + * setup may need to be reevaluated. + * + * On the PowerPC, page translations are kept in a hashed table. There + * is exactly one of these tables [although the architecture supports + * an arbitrary number]. Page table entries move in/out of this hashed + * structure on demand, with the kernel filling in entries as they are + * needed. Just where a page table entry hits in the hashed table is a + * function of the hashing which is in turn based on the upper 4 bits + * of the logical address. These 4 bits address a "virtual segment id" + * which is unique per task/page combination for user addresses and + * fixed for the kernel addresses. Thus, the kernel space can be simply + * shared [indeed at low overhead] among all tasks. + * + * The basic virtual address space is thus: + * + * 0x0XXXXXX --+ + * 0x1XXXXXX | + * 0x2XXXXXX | User address space. + * 0x3XXXXXX | + * 0x4XXXXXX | + * 0x5XXXXXX | + * 0x6XXXXXX | + * 0x7XXXXXX --+ + * 0x8XXXXXX PCI/ISA I/O space + * 0x9XXXXXX --+ + * 0xAXXXXXX | Kernel virtual memory + * 0xBXXXXXX --+ + * 0xCXXXXXX PCI/ISA Memory space + * 0xDXXXXXX + * 0xEXXXXXX + * 0xFXXXXXX Board I/O space + * + * CAUTION! One of the real problems here is keeping the software + * managed tables coherent with the hardware hashed tables. When + * the software decides to update the table, it's normally easy to + * update the hardware table. But when the hardware tables need + * changed, e.g. as the result of a page fault, it's more difficult + * to reflect those changes back into the software entries. Currently, + * this process is quite crude, with updates causing the entire set + * of tables to become invalidated. Some performance could certainly + * be regained by improving this. + * + * The Linux memory management assumes a three-level page table setup. On + * the i386, we use that, but "fold" the mid level into the top-level page + * table, so that we physically have the same two-level page table as the + * i386 mmu expects. + * + * This file contains the functions and defines necessary to modify and use + * the i386 page table tree. + */ + +/* 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 + +/* 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. ;) + */ +#define VMALLOC_OFFSET (8*1024*1024) +#define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) + +#define _PAGE_PRESENT 0x001 +#define _PAGE_RW 0x002 +#define _PAGE_USER 0x004 +#define _PAGE_PCD 0x010 +#define _PAGE_ACCESSED 0x020 +#define _PAGE_DIRTY 0x040 +#define _PAGE_COW 0x200 /* implemented in software (one of the AVL bits) */ +#define _PAGE_NO_CACHE 0x400 + +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_COW) +#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_NO_CACHE __pgprot(_PAGE_NO_CACHE | _PAGE_PRESENT | _PAGE_RW | _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 + +/* + * TLB invalidation: + * + * - invalidate() invalidates the current mm struct TLBs + * - invalidate_all() invalidates all processes TLBs + * - invalidate_mm(mm) invalidates the specified mm context TLB's + * - invalidate_page(mm, vmaddr) invalidates one page + * - invalidate_range(mm, start, end) invalidates a range of pages + * + * FIXME: This could be done much better! + */ + +#define invalidate_all() printk("invalidate_all()\n");invalidate() +#if 0 +#define invalidate_mm(mm_struct) \ +do { if ((mm_struct) == current->mm) invalidate(); else printk("Can't invalidate_mm(%x)\n", mm_struct);} while (0) +#define invalidate_page(mm_struct,addr) \ +do { if ((mm_struct) == current->mm) invalidate(); else printk("Can't invalidate_page(%x,%x)\n", mm_struct, addr);} while (0) +#define invalidate_range(mm_struct,start,end) \ +do { if ((mm_struct) == current->mm) invalidate(); else printk("Can't invalidate_range(%x,%x,%x)\n", mm_struct, start, end);} while (0) +#endif + +/* + * 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 CONFIG_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); + +extern unsigned long __zero_page(void); + +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE __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) + +/* to set the page-dir */ +/* tsk is a task_struct and pgdir is a pte_t */ +#define SET_PAGE_DIR(tsk,pgdir) \ +do { \ + (tsk)->tss.pg_tables = (unsigned long *)(pgdir); \ + if ((tsk) == current) \ + { \ +/*_printk("Change page tables = %x\n", pgdir);*/ \ + } \ +} while (0) + +extern unsigned long high_memory; + +extern inline int pte_none(pte_t pte) { return !pte_val(pte); } +extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } +#if 0 +extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)].reserved; } +/*extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] != 1; }*/ +#endif +extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } +#if 0 +extern inline void pte_reuse(pte_t * ptep) +{ + if (!mem_map[MAP_NR(ptep)].reserved) + mem_map[MAP_NR(ptep)].count++; +} +#endif +/* + extern inline void pte_reuse(pte_t * ptep) +{ + if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED)) + mem_map[MAP_NR(ptep)]++; +} +*/ +extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); } +extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE; } +extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; } +extern inline int pmd_inuse(pmd_t *pmdp) { return 0; } +extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; } +extern inline void pmd_reuse(pmd_t * pmdp) { } + +/* + * 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) + */ +extern inline int pgd_none(pgd_t pgd) { return 0; } +extern inline int pgd_bad(pgd_t pgd) { return 0; } +extern inline int pgd_present(pgd_t pgd) { return 1; } +#if 0 +/*extern inline int pgd_inuse(pgd_t * pgdp) { return mem_map[MAP_NR(pgdp)] != 1; }*/ +extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)].reserved; } +#endif +extern inline void pgd_clear(pgd_t * pgdp) { } + +/* +extern inline void pgd_reuse(pgd_t * pgdp) +{ + if (!mem_map[MAP_NR(pgdp)].reserved) + mem_map[MAP_NR(pgdp)].count++; +} +*/ + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } +extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +extern inline int pte_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; } + +extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_RW; return pte; } +extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } +extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } +extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +extern inline pte_t pte_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; } +extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; } +extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } +extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } +extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } +extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; } + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) +{ pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; } + +extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } + +/*extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) +{ pmd_val(*pmdp) = _PAGE_TABLE | ((((unsigned long) ptep) - PAGE_OFFSET) << (32-PAGE_SHIFT)); } +*/ +extern inline unsigned long pte_page(pte_t pte) +{ return pte_val(pte) & PAGE_MASK; } + +extern inline unsigned long pmd_page(pmd_t pmd) +{ return pmd_val(pmd) & PAGE_MASK; } + + +/* to find an entry in a page-table-directory */ +extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) +{ + return mm->pgd + (address >> PGDIR_SHIFT); +} + +/* Find an entry in the second-level page table.. */ +extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) dir; +} + +/* Find an entry in the third-level page table.. */ +extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) +{ + return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); +} + + +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any, and marks the page tables reserved. + */ +extern inline void pte_free_kernel(pte_t * pte) +{ + free_page((unsigned long) pte); +} +/*extern inline void pte_free_kernel(pte_t * pte) +{ + mem_map[MAP_NR(pte)] = 1; + free_page((unsigned long) pte); +} +*/ + +/* +extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page; + mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED; + return page + address; + } + pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; + return NULL; + } + free_page((unsigned long) page); + } + if (pmd_bad(*pmd)) { + printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); + pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +}*/ +/* +extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) +{ +printk("pte_alloc_kernel pmd = %08X, address = %08X\n", pmd, address); + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); +printk("address now = %08X\n", address); + if (pmd_none(*pmd)) { + pte_t *page; +printk("pmd_none(*pmd) true\n"); + page = (pte_t *) get_free_page(GFP_KERNEL); +printk("page = %08X after get_free_page(%08X)\n",page,GFP_KERNEL); + if (pmd_none(*pmd)) { +printk("pmd_none(*pmd=%08X) still\n",*pmd); + if (page) { +printk("page true = %08X\n",page); + pmd_set(pmd, page); +printk("pmd_set(%08X,%08X)\n",pmd,page); + mem_map[MAP_NR(page)].reserved = 1; +printk("did mem_map\n",pmd,page); + return page + address; + } +printk("did pmd_set(%08X, %08X\n",pmd,BAD_PAGETABLE); + pmd_set(pmd, (pte_t *) BAD_PAGETABLE); + return NULL; + } +printk("did free_page(%08X)\n",page); + free_page((unsigned long) page); + } + if (pmd_bad(*pmd)) { + printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); + pmd_set(pmd, (pte_t *) BAD_PAGETABLE); + return NULL; + } +printk("returning pmd_page(%08X) + %08X\n",pmd_page(*pmd) , address); + + return (pte_t *) pmd_page(*pmd) + address; +} +*/ +extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { +/* pmd_set(pmd,page);*/ + pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page; + return page + address; + } +/* pmd_set(pmd, BAD_PAGETABLE);*/ + pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; + return NULL; + } + free_page((unsigned long) page); + } + if (pmd_bad(*pmd)) { + printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); +/* pmd_set(pmd, (pte_t *) BAD_PAGETABLE); */ + pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +extern inline void pmd_free_kernel(pmd_t * pmd) +{ +} + +extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +extern inline void pte_free(pte_t * pte) +{ + free_page((unsigned long) pte); +} + +extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page; + return page + address; + } + pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; + return NULL; + } + free_page((unsigned long) page); + } + if (pmd_bad(*pmd)) { + printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); + pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +extern inline void pmd_free(pmd_t * pmd) +{ +} + +extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +extern inline void pgd_free(pgd_t * pgd) +{ + free_page((unsigned long) pgd); +} + +extern inline pgd_t * pgd_alloc(void) +{ + return (pgd_t *) get_free_page(GFP_KERNEL); +} + +extern pgd_t swapper_pg_dir[1024*8]; +/*extern pgd_t *swapper_pg_dir;*/ + +/* + * Software maintained MMU tables may have changed -- update the + * hardware [aka cache] + */ +extern inline void update_mmu_cache(struct vm_area_struct * vma, + unsigned long address, pte_t _pte) +{ +#if 0 + printk("Update MMU cache - VMA: %x, Addr: %x, PTE: %x\n", vma, address, *(long *)&_pte); + _printk("Update MMU cache - VMA: %x, Addr: %x, PTE: %x\n", vma, address, *(long *)&_pte); +/* MMU_hash_page(&(vma->vm_task)->tss, address & PAGE_MASK, (pte *)&_pte);*/ +#endif + MMU_hash_page(&(current)->tss, address & PAGE_MASK, (pte *)&_pte); + +} + + +#ifdef _SCHED_INIT_ +#define INIT_MMAP { &init_task, 0, 0x40000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } + +#endif + +#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f) +#define SWP_OFFSET(entry) ((entry) >> 8) +#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8)) + +#endif /* _PPC_PAGE_H */ diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h new file mode 100644 index 000000000..0b180d795 --- /dev/null +++ b/include/asm-ppc/posix_types.h @@ -0,0 +1,98 @@ +#ifndef _PPC_POSIX_TYPES_H +#define _PPC_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned int __kernel_dev_t; +typedef unsigned int __kernel_ino_t; +typedef unsigned int __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned int __kernel_uid_t; +typedef unsigned int __kernel_gid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#ifndef __GNUC__ + +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#define __FD_ZERO(set) \ + ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set))) + +#else /* __GNUC__ */ + +/* With GNU C, use inline functions instead so args are evaluated only once: */ + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] |= (1UL<<_rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); +} + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set *p) +{ + unsigned int *tmp = p->fds_bits; + int i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 8: + tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0; + tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0; + return; + } + } + i = __FDSET_LONGS; + while (i) { + i--; + *tmp = 0; + tmp++; + } +} + +#endif /* __GNUC__ */ + +#endif /* _PPC_POSIX_TYPES_H */ diff --git a/include/asm-ppc/ppc_machine.h b/include/asm-ppc/ppc_machine.h new file mode 100644 index 000000000..2891e5a4f --- /dev/null +++ b/include/asm-ppc/ppc_machine.h @@ -0,0 +1,50 @@ +/* + * PowerPC machine specifics + */ + +#ifndef _PPC_MACHINE_H_ +#define _PPC_MACHINE_H_ + +/* Bit encodings for Machine State Register (MSR) */ +#define MSR_POW (1<<18) /* Enable Power Management */ +#define MSR_TGPR (1<<17) /* TLB Update registers in use */ +#define MSR_ILE (1<<16) /* Interrupt Little-Endian enable */ +#define MSR_EE (1<<15) /* External Interrupt enable */ +#define MSR_PR (1<<14) /* Supervisor/User privilege */ +#define MSR_FP (1<<13) /* Floating Point enable */ +#define MSR_ME (1<<12) /* Machine Check enable */ +#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */ +#define MSR_SE (1<<10) /* Single Step */ +#define MSR_BE (1<<9) /* Branch Trace */ +#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */ +#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */ +#define MSR_IR (1<<5) /* Instruction MMU enable */ +#define MSR_DR (1<<4) /* Data MMU enable */ +#define MSR_RI (1<<1) /* Recoverable Exception */ +#define MSR_LE (1<<0) /* Little-Endian enable */ + +#define MSR_ MSR_FP|MSR_FE0|MSR_FE1|MSR_ME +#define MSR_USER MSR_|MSR_PR|MSR_EE|MSR_IR|MSR_DR + +/* Bit encodings for Hardware Implementation Register (HID0) */ +#define HID0_EMCP (1<<31) /* Enable Machine Check pin */ +#define HID0_EBA (1<<29) /* Enable Bus Address Parity */ +#define HID0_EBD (1<<28) /* Enable Bus Data Parity */ +#define HID0_SBCLK (1<<27) +#define HID0_EICE (1<<26) +#define HID0_ECLK (1<<25) +#define HID0_PAR (1<<24) +#define HID0_DOZE (1<<23) +#define HID0_NAP (1<<22) +#define HID0_SLEEP (1<<21) +#define HID0_DPM (1<<20) +#define HID0_ICE (1<<15) /* Instruction Cache Enable */ +#define HID0_DCE (1<<14) /* Data Cache Enable */ +#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */ +#define HID0_DLOCK (1<<12) /* Data Cache Lock */ +#define HID0_ICFI (1<<11) /* Instruction Cache Flash Invalidate */ +#define HID0_DCI (1<<10) /* Data Cache Invalidate */ +#define HID0_SIED (1<<7) /* Serial Instruction Execution [Disable] */ +#define HID0_BHTE (1<<2) /* Branch History Table Enable */ + +#endif diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h new file mode 100644 index 000000000..e14f2b270 --- /dev/null +++ b/include/asm-ppc/processor.h @@ -0,0 +1,126 @@ +#ifndef __ASM_PPC_PROCESSOR_H +#define __ASM_PPC_PROCESSOR_H + +/* + * PowerPC machine specifics + */ + +#ifndef _PPC_MACHINE_H_ +#define _PPC_MACHINE_H_ + +/* Bit encodings for Machine State Register (MSR) */ +#define MSR_POW (1<<18) /* Enable Power Management */ +#define MSR_TGPR (1<<17) /* TLB Update registers in use */ +#define MSR_ILE (1<<16) /* Interrupt Little-Endian enable */ +#define MSR_EE (1<<15) /* External Interrupt enable */ +#define MSR_PR (1<<14) /* Supervisor/User privilege */ +#define MSR_FP (1<<13) /* Floating Point enable */ +#define MSR_ME (1<<12) /* Machine Check enable */ +#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */ +#define MSR_SE (1<<10) /* Single Step */ +#define MSR_BE (1<<9) /* Branch Trace */ +#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */ +#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */ +#define MSR_IR (1<<5) /* Instruction MMU enable */ +#define MSR_DR (1<<4) /* Data MMU enable */ +#define MSR_RI (1<<1) /* Recoverable Exception */ +#define MSR_LE (1<<0) /* Little-Endian enable */ + +#define MSR_ MSR_FP|MSR_FE0|MSR_FE1|MSR_ME +#define MSR_USER MSR_|MSR_PR|MSR_EE|MSR_IR|MSR_DR + +/* Bit encodings for Hardware Implementation Register (HID0) */ +#define HID0_EMCP (1<<31) /* Enable Machine Check pin */ +#define HID0_EBA (1<<29) /* Enable Bus Address Parity */ +#define HID0_EBD (1<<28) /* Enable Bus Data Parity */ +#define HID0_SBCLK (1<<27) +#define HID0_EICE (1<<26) +#define HID0_ECLK (1<<25) +#define HID0_PAR (1<<24) +#define HID0_DOZE (1<<23) +#define HID0_NAP (1<<22) +#define HID0_SLEEP (1<<21) +#define HID0_DPM (1<<20) +#define HID0_ICE (1<<15) /* Instruction Cache Enable */ +#define HID0_DCE (1<<14) /* Data Cache Enable */ +#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */ +#define HID0_DLOCK (1<<12) /* Data Cache Lock */ +#define HID0_ICFI (1<<11) /* Instruction Cache Flash Invalidate */ +#define HID0_DCI (1<<10) /* Data Cache Invalidate */ + +#endif + +static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp) +{ + regs->nip = eip; + regs->gpr[1] = esp; + regs->msr = MSR_USER; +} + + +/* + * Bus types + */ +#define EISA_bus 0 +#define EISA_bus__is_a_macro /* for versions in ksyms.c */ +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ + +/* + * Write Protection works right in supervisor mode on the PowerPC + */ + +#define wp_works_ok 1 +#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ + +/* + * User space process size: 2GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + * + * "this is gonna have to change to 1gig for the sparc" - David S. Miller + */ +#define TASK_SIZE (0x80000000UL) + +struct thread_struct + { + unsigned long ksp; /* Kernel stack pointer */ + unsigned long *pg_tables; /* MMU information */ + unsigned long segs[16]; /* MMU Segment registers */ + unsigned long last_pc; /* PC when last entered system */ + unsigned long user_stack; /* [User] Stack when entered kernel */ + double fpr[32]; /* Complete floating point set */ + unsigned long wchan; /* Event task is sleeping on */ + unsigned long *regs; /* Pointer to saved register state */ + }; + +#define INIT_TSS { \ + 0, 0, {0}, \ + 0, 0, {0}, \ +} + +#define INIT_MMAP { &init_mm, 0, 0x40000000, \ + PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } + +#define alloc_kernel_stack() get_free_page(GFP_KERNEL) +#define free_kernel_stack(page) free_page((page)) + +/* + * Return saved PC of a blocked thread. For now, this is the "user" PC + */ +static inline unsigned long thread_saved_pc(struct thread_struct *t) +{ + return (t->last_pc); +} + +/* + * Return_address is a replacement for __builtin_return_address(count) + * which on certain architectures cannot reasonably be implemented in GCC + * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * Note that __builtin_return_address(x>=1) is forbidden because the GCC + * aborts compilation on some CPUs. It's simply not possible to unwind + * some CPU's stackframes. + */ +#define return_address() __builtin_return_address(0) + +#endif + diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h new file mode 100644 index 000000000..c654d86b7 --- /dev/null +++ b/include/asm-ppc/ptrace.h @@ -0,0 +1,99 @@ +#ifndef _PPC_PTRACE_H +#define _PPC_PTRACE_H + + +/* + * This struct defines the way the registers are stored on the + * kernel stack during a system call or other kernel entry. + * Note: the "_overhead" and "_underhead" spaces are stack locations + * used by called routines. Because of the way the PowerPC ABI + * specifies the function prologue/epilogue, registers can be + * saved in stack locations which are below the current stack + * pointer (_underhead). If an interrupt occurs during this + * [albeit] small time interval, registers which were saved on + * the stack could be trashed by the interrupt save code. The + * "_underhead" leaves a hole just in case this happens. It also + * wastes 80 bytes of stack if it doesn't! Similarly, the called + * routine stores some information "above" the stack pointer before + * if gets adjusted. This is covered by the "_overhead" field + * and [thankfully] is not totally wasted. + * + */ + +struct pt_regs { + unsigned long _overhead[14]; /* Callee's SP,LR,params */ + unsigned long gpr[32]; + unsigned long nip; + unsigned long msr; + unsigned long ctr; + unsigned long link; + unsigned long ccr; + unsigned long xer; + unsigned long dar; /* Fault registers */ + unsigned long dsisr; + unsigned long hash1, hash2; + unsigned long imiss, dmiss; + unsigned long icmp, dcmp; + unsigned long orig_gpr3; /* Used for restarting system calls */ + unsigned long result; /* Result of a system call */ + double fpr[4]; /* Caution! Only FP0-FP3 save on interrupts */ + double fpcsr; + unsigned long trap; /* Reason for being here */ + unsigned long marker; /* Should have DEADDEAD */ + unsigned long _underhead[20]; /* Callee's register save area */ + unsigned long edx; /* for binfmt_elf.c which wants edx */ +}; + +#define instruction_pointer(regs) ((regs)->nip) +#define user_mode(regs) ((regs)->msr & 0x4000) +#ifdef KERNEL +extern void show_regs(struct pt_regs *); +#endif + +/* Offsets used by 'ptrace' system call interface */ +/* Note: these should correspond to gpr[x] */ +#define PT_R0 0 +#define PT_R1 1 +#define PT_R2 2 +#define PT_R3 3 +#define PT_R4 4 +#define PT_R5 5 +#define PT_R6 6 +#define PT_R7 7 +#define PT_R8 8 +#define PT_R9 9 +#define PT_R10 10 +#define PT_R11 11 +#define PT_R12 12 +#define PT_R13 13 +#define PT_R14 14 +#define PT_R15 15 +#define PT_R16 16 +#define PT_R17 17 +#define PT_R18 18 +#define PT_R19 19 +#define PT_R20 20 +#define PT_R21 21 +#define PT_R22 22 +#define PT_R23 23 +#define PT_R24 24 +#define PT_R25 25 +#define PT_R26 26 +#define PT_R27 27 +#define PT_R28 28 +#define PT_R29 29 +#define PT_R30 30 +#define PT_R31 31 + +#define PT_NIP 32 +#define PT_MSR 33 +#define PT_ORIG_R3 34 +#define PT_CTR 35 +#define PT_LNK 36 +#define PT_XER 37 +#define PT_CCR 38 + +#define PT_FPR0 48 + +#endif + diff --git a/include/asm-ppc/resource.h b/include/asm-ppc/resource.h new file mode 100644 index 000000000..2cffda871 --- /dev/null +++ b/include/asm-ppc/resource.h @@ -0,0 +1,37 @@ +#ifndef _PPC_RESOURCE_H +#define _PPC_RESOURCE_H + +/* + * Resource limits + */ + +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_RSS 5 /* max resident set size */ +#define RLIMIT_NPROC 6 /* max number of processes */ +#define RLIMIT_NOFILE 7 /* max number of open files */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ + +#define RLIM_NLIMITS 9 + +#ifdef __KERNEL__ + +#define INIT_RLIMITS \ +{ \ + { LONG_MAX, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ + { _STK_LIM, _STK_LIM }, \ + { 0, LONG_MAX }, \ + { LONG_MAX, LONG_MAX }, \ + { MAX_TASKS_PER_USER, MAX_TASKS_PER_USER }, \ + { NR_OPEN, NR_OPEN }, \ + { LONG_MAX, LONG_MAX }, \ +} + +#endif /* __KERNEL__ */ + +#endif diff --git a/include/asm-ppc/segment.h b/include/asm-ppc/segment.h new file mode 100644 index 000000000..ee728959c --- /dev/null +++ b/include/asm-ppc/segment.h @@ -0,0 +1,131 @@ +#ifndef _ASM_PPC_SEGMENT_H +#define _ASM_PPC_SEGMENT_H + +#include <linux/string.h> + +#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))) +#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))) + +extern int bad_user_access_length(void); + +static inline void __put_user(unsigned long x, void * y, int size) +{ + switch (size) { + case 1: + *(char *) y = x; + break; + case 2: + *(short *) y = x; + break; + case 4: + *(int *) y = x; + break; + case 8: + *(long *) y = x; + break; + default: + bad_user_access_length(); + } +} + +static inline unsigned long __get_user(const void * y, int size) +{ + switch (size) { + case 1: + return *(unsigned char *) y; + case 2: + return *(unsigned short *) y; + case 4: + return *(unsigned int *) y; + case 8: + return *(unsigned long *) y; + default: + return bad_user_access_length(); + } +} + +static inline unsigned char get_user_byte(const char * addr) +{ + return *addr; +} + +#define get_fs_byte(addr) get_user_byte((char *)(addr)) + +static inline unsigned short get_user_word(const short *addr) +{ + return *addr; +} + +#define get_fs_word(addr) get_user_word((short *)(addr)) + +static inline unsigned long get_user_long(const int *addr) +{ + return *addr; +} + +#define get_fs_long(addr) get_user_long((int *)(addr)) + +static inline unsigned long get_user_quad(const long *addr) +{ + return *addr; +} + +#define get_fs_quad(addr) get_user_quad((long *)(addr)) + +static inline void put_user_byte(char val,char *addr) +{ + *addr = val; +} + +#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) + +static inline void put_user_word(short val,short * addr) +{ + *addr = val; +} + +#define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) + +static inline void put_user_long(unsigned long val,int * addr) +{ + *addr = val; +} + +#define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) + +static inline void put_user_quad(unsigned long val,long * addr) +{ + *addr = val; +} + +#define put_fs_quad(x,addr) put_user_quad((x),(long *)(addr)) + +#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n)) + +#define memcpy_tofs(to, from, n) memcpy((to),(from),(n)) + +/* + * For segmented architectures, these are used to specify which segment + * to use for the above functions. + * + * The powerpc is not segmented, so these are just dummies. + */ + +#define KERNEL_DS 0 +#define USER_DS 1 + +static inline unsigned long get_fs(void) +{ + return 0; +} + +static inline unsigned long get_ds(void) +{ + return 0; +} + +static inline void set_fs(unsigned long val) +{ +} + +#endif /* _ASM_SEGMENT_H */ diff --git a/include/asm-ppc/shmparam.h b/include/asm-ppc/shmparam.h new file mode 100644 index 000000000..754af6979 --- /dev/null +++ b/include/asm-ppc/shmparam.h @@ -0,0 +1,44 @@ +#ifndef _PPC_SHMPARAM_H +#define _PPC_SHMPARAM_H + +/* address range for shared memory attaches if no address passed to shmat() */ +#define SHM_RANGE_START 0x50000000 +#define SHM_RANGE_END 0x60000000 + +/* + * Format of a swap-entry for shared memory pages currently out in + * swap space (see also mm/swap.c). + * + * SWP_TYPE = SHM_SWP_TYPE + * SWP_OFFSET is used as follows: + * + * bits 0..6 : id of shared memory segment page belongs to (SHM_ID) + * bits 7..21: index of page within shared memory segment (SHM_IDX) + * (actually fewer bits get used since SHMMAX is so low) + */ + +/* + * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and + * there is a static array of size SHMMNI. + */ +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +/* + * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and + * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). + */ + +#define SHMMAX 0x3fa000 /* max shared seg size (bytes) */ +#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ +#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ +#define SHMALL /* max shm system wide (pages) */ \ + (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ +#define SHMSEG SHMMNI /* max shared segs per process */ + +#endif /* _PPC_SHMPARAM_H */ diff --git a/include/asm-ppc/sigcontext.h b/include/asm-ppc/sigcontext.h new file mode 100644 index 000000000..4bd66a707 --- /dev/null +++ b/include/asm-ppc/sigcontext.h @@ -0,0 +1,15 @@ +#ifndef _ASM_PPC_SIGCONTEXT_H +#define _ASM_PPC_SIGCONTEXT_H + +#include <asm/ptrace.h> + + +struct sigcontext_struct { + unsigned long _unused[4]; + int signal; + unsigned long handler; + unsigned long oldmask; + struct pt_regs *regs; +}; + +#endif diff --git a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h new file mode 100644 index 000000000..5387400dc --- /dev/null +++ b/include/asm-ppc/signal.h @@ -0,0 +1,98 @@ +#ifndef _ASMPPC_SIGNAL_H +#define _ASMPPC_SIGNAL_H + +typedef unsigned long sigset_t; /* at least 32 bits */ + +#define _NSIG 32 +#define NSIG _NSIG + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGUNUSED 31 + +/* + * sa_flags values: SA_STACK is not currently supported, but will allow the + * usage of signal stacks by using the (now obsolete) sa_restorer field in + * the sigaction structure as a stack pointer. This is now possible due to + * the changes in signal handling. LBT 010493. + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. + */ +#define SA_NOCLDSTOP 1 +#define SA_SHIRQ 0x04000000 +#define SA_STACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_INTERRUPT 0x20000000 +#define SA_NOMASK 0x40000000 +#define SA_ONESHOT 0x80000000 + +#ifdef __KERNEL__ +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#endif + +#define SIG_BLOCK 0 /* for blocking signals */ +#define SIG_UNBLOCK 1 /* for unblocking signals */ +#define SIG_SETMASK 2 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__sighandler_t)(int); + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +struct sigaction { + __sighandler_t sa_handler; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#ifdef __KERNEL__ +#include <asm/sigcontext.h> +#endif + +#endif + + diff --git a/include/asm-ppc/socket.h b/include/asm-ppc/socket.h new file mode 100644 index 000000000..eadf15190 --- /dev/null +++ b/include/asm-ppc/socket.h @@ -0,0 +1,31 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +/* For setsockoptions(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 14 */ + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-ppc/sockios.h b/include/asm-ppc/sockios.h new file mode 100644 index 000000000..385aedc55 --- /dev/null +++ b/include/asm-ppc/sockios.h @@ -0,0 +1,17 @@ +#ifndef _ASM_PPC_SOCKIOS_H +#define _ASM_PPC_SOCKIOS_H + +#if 0 /* These are defined this way on Alpha - maybe later. */ +/* Socket-level I/O control calls. */ + +#define FIOGETOWN _IOR('f', 123, int) +#define FIOSETOWN _IOW('f', 124, int) + +#define SIOCATMARK _IOR('s', 7, int) +#define SIOCSPGRP _IOW('s', 8, pid_t) +#define SIOCGPGRP _IOR('s', 9, pid_t) + +#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */ +#endif + +#endif /* _ASM_PPC_SOCKIOS_H */ diff --git a/include/asm-ppc/stat.h b/include/asm-ppc/stat.h new file mode 100644 index 000000000..462cfa0cd --- /dev/null +++ b/include/asm-ppc/stat.h @@ -0,0 +1,41 @@ +#ifndef _PPC_STAT_H +#define _PPC_STAT_H + +#include <linux/types.h> + +struct old_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +struct new_stat { + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + off_t st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif diff --git a/include/asm-ppc/statfs.h b/include/asm-ppc/statfs.h new file mode 100644 index 000000000..b2fd73564 --- /dev/null +++ b/include/asm-ppc/statfs.h @@ -0,0 +1,28 @@ +#ifndef _PPC_STATFS_H +#define _PPC_STATFS_H + +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif + +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_spare[6]; +}; + +#endif + + + diff --git a/include/asm-ppc/string.h b/include/asm-ppc/string.h new file mode 100644 index 000000000..7d550d1ed --- /dev/null +++ b/include/asm-ppc/string.h @@ -0,0 +1,62 @@ +#ifndef _PPC_STRING_H_ +#define _PPC_STRING_H_ + + + +/* + * keep things happy, the compile became unhappy since memset is + * in include/string.h and lib/string.c with different args + * -- Cort + */ + +#define __HAVE_ARCH_MEMSET +extern inline void * memset(void * s,int c,size_t count) +{ + char *xs = (char *) s; + + while (count--) + *xs++ = c; + + return s; +} +#define __HAVE_ARCH_STRSTR +/* Return the first occurrence of NEEDLE in HAYSTACK. */ +extern inline char * +strstr(const char *haystack, const char *needle) +{ + const char *const needle_end = strchr(needle, '\0'); + const char *const haystack_end = strchr(haystack, '\0'); + const size_t needle_len = needle_end - needle; + const size_t needle_last = needle_len - 1; + const char *begin; + + if (needle_len == 0) +#ifdef __linux__ + return (char *) haystack; +#else + return (char *) haystack_end; +#endif + if ((size_t) (haystack_end - haystack) < needle_len) + return NULL; + + for (begin = &haystack[needle_last]; begin < haystack_end; ++begin) + { + register const char *n = &needle[needle_last]; + register const char *h = begin; + + do + if (*h != *n) + goto loop; /* continue for loop */ + while (--n >= needle && --h >= haystack); + + return (char *) h; + + loop:; + } + + return NULL; +} + + + +#endif diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h new file mode 100644 index 000000000..3e738d382 --- /dev/null +++ b/include/asm-ppc/system.h @@ -0,0 +1,81 @@ +#ifndef __PPC_SYSTEM_H +#define __PPC_SYSTEM_H + +#if 0 +#define mb() \ +__asm__ __volatile__("mb": : :"memory") +#endif +#define mb() __asm__ __volatile__ ("" : : :"memory") + + +extern void __save_flags(long *flags); +extern void __restore_flags(long flags); +extern void sti(void); +extern void cli(void); +extern int _disable_interrupts(void); +extern void _enable_interrupts(int); + +/*extern void memcpy(void *, void *, int);*/ +extern void bzero(void *, int); + +struct task_struct; +extern void switch_to(struct task_struct *prev, struct task_struct *next); + +#define save_flags(flags) __save_flags(&(flags)) +#define restore_flags(flags) __restore_flags(flags) + +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) + +/* this guy lives in arch/ppc/kernel */ +extern inline unsigned long *xchg_u32(void *m, unsigned long val); + +/* + * these guys don't exist. + * someone should create them. + * -- Cort + */ +extern void *xchg_u64(void *ptr, unsigned long val); +extern int xchg_u8(char *m, char val); + +/* + * This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid xchg(). + * + * This only works if the compiler isn't horribly bad at optimizing. + * gcc-2.5.8 reportedly can't handle this, but as that doesn't work + * too well on the alpha anyway.. + */ +extern void __xchg_called_with_bad_pointer(void); + +static inline unsigned long __xchg(unsigned long x, void * ptr, int size) +{ + switch (size) { + case 4: + return (unsigned long )xchg_u32(ptr, x); + case 8: + return (unsigned long )xchg_u64(ptr, x); + } + __xchg_called_with_bad_pointer(); + return x; + + +} + + + +extern inline int tas(char * m) +{ + return xchg_u8(m,1); +} + +extern inline void * xchg_ptr(void * m, void * val) +{ + return (void *) xchg_u32(m, (unsigned long) val); +} + +/* + * Reset the machine. + */ +extern void hard_reset_now(void); + +#endif diff --git a/include/asm-ppc/termbits.h b/include/asm-ppc/termbits.h new file mode 100644 index 000000000..6c19c1fef --- /dev/null +++ b/include/asm-ppc/termbits.h @@ -0,0 +1,178 @@ +#ifndef _PPC_TERMBITS_H +#define _PPC_TERMBITS_H + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#if 0 /* This is how it's done on Alpha - maybe later. */ +/* + * termios type and macro definitions. Be careful about adding stuff + * to this file since it's used in GNU libc and there are strict rules + * concerning namespace pollution. + */ + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t c_line; /* line discipline (== c_cc[19]) */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VEOF 0 +#define VEOL 1 +#define VEOL2 2 +#define VERASE 3 +#define VWERASE 4 +#define VKILL 5 +#define VREPRINT 6 +#define VSWTC 7 +#define VINTR 8 +#define VQUIT 9 +#define VSUSP 10 +#define VSTART 12 +#define VSTOP 13 +#define VLNEXT 14 +#define VDISCARD 15 +#define VMIN 16 +#define VTIME 17 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IXON 0001000 +#define IXOFF 0002000 +#if !defined(KERNEL) || defined(__USE_BSD) + /* POSIX.1 doesn't want these... */ +# define IXANY 0004000 +# define IUCLC 0010000 +# define IMAXBEL 0020000 +#endif + +/* c_oflag bits */ +#define OPOST 0000001 +#define ONLCR 0000002 +#define OLCUC 0000004 + +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 + +#define OFILL 00000100 +#define OFDEL 00000200 +#define NLDLY 00001400 +#define NL0 00000000 +#define NL1 00000400 +#define NL2 00001000 +#define NL3 00001400 +#define TABDLY 00006000 +#define TAB0 00000000 +#define TAB1 00002000 +#define TAB2 00004000 +#define TAB3 00006000 +#define CRDLY 00030000 +#define CR0 00000000 +#define CR1 00010000 +#define CR2 00020000 +#define CR3 00030000 +#define FFDLY 00040000 +#define FF0 00000000 +#define FF1 00040000 +#define BSDLY 00100000 +#define BS0 00000000 +#define BS1 00100000 +#define VTDLY 00200000 +#define VT0 00000000 +#define VT1 00200000 +#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ + +/* c_cflag bit meaning */ +#define CBAUD 0000017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CBAUDEX 0000020 +#define B57600 00020 +#define B115200 00021 +#define B230400 00022 + +#define CSIZE 00001400 +#define CS5 00000000 +#define CS6 00000400 +#define CS7 00001000 +#define CS8 00001400 + +#define CSTOPB 00002000 +#define CREAD 00004000 +#define PARENB 00010000 +#define PARODD 00020000 +#define HUPCL 00040000 + +#define CLOCAL 00100000 +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0x00000080 +#define ICANON 0x00000100 +#define XCASE 0x00004000 +#define ECHO 0x00000008 +#define ECHOE 0x00000002 +#define ECHOK 0x00000004 +#define ECHONL 0x00000010 +#define NOFLSH 0x80000000 +#define TOSTOP 0x00400000 +#define ECHOCTL 0x00000040 +#define ECHOPRT 0x00000020 +#define ECHOKE 0x00000001 +#define FLUSHO 0x00800000 +#define PENDIN 0x20000000 +#define IEXTEN 0x00000400 + +/* Values for the ACTION argument to `tcflow'. */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 +#endif + +#endif /* _PPC_TERMBITS_H */ diff --git a/include/asm-ppc/termios.h b/include/asm-ppc/termios.h new file mode 100644 index 000000000..a87c495a4 --- /dev/null +++ b/include/asm-ppc/termios.h @@ -0,0 +1,403 @@ +#ifndef _PPC_TERMIOS_H +#define _PPC_TERMIOS_H + +/* + * Liberally adapted from alpha/termios.h. In particular, the c_cc[] + * fields have been reordered so that termio & termios share the + * common subset in the same order (for brain dead programs that don't + * know or care about the differences). + */ + +#include <asm/ioctls.h> +#include <asm/termbits.h> + +struct sgttyb { + char sg_ispeed; + char sg_ospeed; + char sg_erase; + char sg_kill; + short sg_flags; +}; + +struct tchars { + char t_intrc; + char t_quitc; + char t_startc; + char t_stopc; + char t_eofc; + char t_brkc; +}; + +struct ltchars { + char t_suspc; + char t_dsuspc; + char t_rprntc; + char t_flushc; + char t_werasc; + char t_lnextc; +}; + +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD + +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCSETP _IOW('t', 9, struct sgttyb) +#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ + +#define TIOCSETC _IOW('t', 17, struct tchars) +#define TIOCGETC _IOR('t', 18, struct tchars) +#define TCGETS _IOR('t', 19, struct termios) +#define TCSETS _IOW('t', 20, struct termios) +#define TCSETSW _IOW('t', 21, struct termios) +#define TCSETSF _IOW('t', 22, struct termios) + +#define TCGETA _IOR('t', 23, struct termio) +#define TCSETA _IOW('t', 24, struct termio) +#define TCSETAW _IOW('t', 25, struct termio) +#define TCSETAF _IOW('t', 28, struct termio) + +#define TCSBRK _IO('t', 29) +#define TCXONC _IO('t', 30) +#define TCFLSH _IO('t', 31) + +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ + +#define TIOCGLTC _IOR('t', 116, struct ltchars) +#define TIOCSLTC _IOW('t', 117, struct ltchars) +#define TIOCSPGRP _IOW('t', 118, int) +#define TIOCGPGRP _IOR('t', 119, int) + +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E + +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 + +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ + +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 10 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t c_line; /* line discipline (== c_cc[19]) */ + int c_ispeed; /* input speed */ + int c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define _VINTR 0 +#define _VQUIT 1 +#define _VERASE 2 +#define _VKILL 3 +#define _VEOF 4 +#define _VMIN 5 +#define _VEOL 6 +#define _VTIME 7 +#define _VEOL2 8 +#define _VSWTC 9 + +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VMIN 5 +#define VEOL 6 +#define VTIME 7 +#define VEOL2 8 +#define VSWTC 9 + +#define VWERASE 10 +#define VREPRINT 11 +#define VSUSP 12 +#define VSTART 13 +#define VSTOP 14 +#define VLNEXT 15 +#define VDISCARD 16 + + +#ifdef __KERNEL__ +/* eof=^D eol=\0 eol2=\0 erase=del + werase=^W kill=^U reprint=^R sxtc=\0 + intr=^C quit=^\ susp=^Z <OSF/1 VDSUSP> + start=^Q stop=^S lnext=^V discard=^U + vmin=\1 vtime=\0 +#define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000" +*/ + +/* ^C ^\ del ^U ^D 1 0 0 0 0 ^W ^R ^Z ^Q ^S ^V ^U */ +#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" +#endif + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IXON 0001000 +#define IXOFF 0002000 +#define IXANY 0004000 +#define IUCLC 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define ONLCR 0000002 +#define OLCUC 0000004 + +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 + +#define OFILL 00000100 +#define OFDEL 00000200 +#define NLDLY 00001400 +#define NL0 00000000 +#define NL1 00000400 +#define NL2 00001000 +#define NL3 00001400 +#define TABDLY 00006000 +#define TAB0 00000000 +#define TAB1 00002000 +#define TAB2 00004000 +#define TAB3 00006000 +#define CRDLY 00030000 +#define CR0 00000000 +#define CR1 00010000 +#define CR2 00020000 +#define CR3 00030000 +#define FFDLY 00040000 +#define FF0 00000000 +#define FF1 00040000 +#define BSDLY 00100000 +#define BS0 00000000 +#define BS1 00100000 +#define VTDLY 00200000 +#define VT0 00000000 +#define VT1 00200000 +#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ + +/* c_cflag bit meaning */ +#define CBAUD 0000377 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CBAUDEX 0000020 +#define B57600 00020 +#define B115200 00021 +#define B230400 00022 +#define B460800 00023 + +#define CSIZE 00001400 +#define CS5 00000000 +#define CS6 00000400 +#define CS7 00001000 +#define CS8 00001400 + +#define CSTOPB 00002000 +#define CREAD 00004000 +#define PARENB 00010000 +#define PARODD 00020000 +#define HUPCL 00040000 + +#define CLOCAL 00100000 +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0x00000080 +#define ICANON 0x00000100 +#define XCASE 0x00004000 +#define ECHO 0x00000008 +#define ECHOE 0x00000002 +#define ECHOK 0x00000004 +#define ECHONL 0x00000010 +#define NOFLSH 0x80000000 +#define TOSTOP 0x00400000 +#define ECHOCTL 0x00000040 +#define ECHOPRT 0x00000020 +#define ECHOKE 0x00000001 +#define FLUSHO 0x00800000 +#define PENDIN 0x20000000 +#define IEXTEN 0x00000400 + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_AX25 5 + +#ifdef __KERNEL__ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +extern inline void trans_from_termio(struct termio * termio, + struct termios * termios) +{ +#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y)) + SET_LOW_BITS(termios->c_iflag, termio->c_iflag); + SET_LOW_BITS(termios->c_oflag, termio->c_oflag); + SET_LOW_BITS(termios->c_cflag, termio->c_cflag); + SET_LOW_BITS(termios->c_lflag, termio->c_lflag); +#undef SET_LOW_BITS + termios->c_cc[VINTR] = termio->c_cc[_VINTR]; + termios->c_cc[VQUIT] = termio->c_cc[_VQUIT]; + termios->c_cc[VERASE]= termio->c_cc[_VERASE]; + termios->c_cc[VKILL] = termio->c_cc[_VKILL]; + termios->c_cc[VEOF] = termio->c_cc[_VEOF]; + termios->c_cc[VMIN] = termio->c_cc[_VMIN]; + termios->c_cc[VEOL] = termio->c_cc[_VEOL]; + termios->c_cc[VTIME] = termio->c_cc[_VTIME]; + termios->c_cc[VEOL2] = termio->c_cc[_VEOL2]; + termios->c_cc[VSWTC] = termio->c_cc[_VSWTC]; +} + +/* + * Translate a "termios" structure into a "termio". Ugh. + * + * Note the "fun" _VMIN overloading. + */ +extern inline void trans_to_termio(struct termios * termios, + struct termio * termio) +{ + termio->c_iflag = termios->c_iflag; + termio->c_oflag = termios->c_oflag; + termio->c_cflag = termios->c_cflag; + termio->c_lflag = termios->c_lflag; + termio->c_line = termios->c_line; + termio->c_cc[_VINTR] = termios->c_cc[VINTR]; + termio->c_cc[_VQUIT] = termios->c_cc[VQUIT]; + termio->c_cc[_VERASE]= termios->c_cc[VERASE]; + termio->c_cc[_VKILL] = termios->c_cc[VKILL]; + termio->c_cc[_VEOF] = termios->c_cc[VEOF]; + termio->c_cc[_VEOL] = termios->c_cc[VEOL]; + termio->c_cc[_VEOL2] = termios->c_cc[VEOL2]; + termio->c_cc[_VSWTC] = termios->c_cc[VSWTC]; + if (1/*!(termios->c_lflag & ICANON)*/) { + termio->c_cc[_VMIN] = termios->c_cc[VMIN]; + termio->c_cc[_VTIME] = termios->c_cc[VTIME]; + } +} + +#endif /* __KERNEL__ */ + +#endif /* _PPC_TERMIOS_H */ diff --git a/include/asm-ppc/types.h b/include/asm-ppc/types.h new file mode 100644 index 000000000..0582b117c --- /dev/null +++ b/include/asm-ppc/types.h @@ -0,0 +1,44 @@ +#ifndef _PPC_TYPES_H +#define _PPC_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#endif /* __KERNEL__ */ + +#endif diff --git a/include/asm-ppc/unaligned.h b/include/asm-ppc/unaligned.h new file mode 100644 index 000000000..90a54eae9 --- /dev/null +++ b/include/asm-ppc/unaligned.h @@ -0,0 +1,16 @@ +#ifndef __PPC_UNALIGNED_H +#define __PPC_UNALIGNED_H + +/* + * The PowerPC can do unaligned accesses itself in big endian mode. + * + * The strange macros are there to make sure these can't + * be misused in a way that makes them not work on other + * architectures where unaligned accesses aren't as simple. + */ + +#define get_unaligned(ptr) (*(ptr)) + +#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) + +#endif diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h new file mode 100644 index 000000000..be4cee27e --- /dev/null +++ b/include/asm-ppc/unistd.h @@ -0,0 +1,376 @@ +#ifndef _ASM_PPC_UNISTD_H_ +#define _ASM_PPC_UNISTD_H_ + +#define _NR(n) #n +#define _lisc(n) "li 0," _NR(n) + +/* + * This file contains the system call numbers. + */ + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl 110 +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86 113 +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_modify_ldt 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 + +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 + + +#define _syscall0(type,name) \ +type name(void) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval);\ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2, type3 arg3) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#ifdef __KERNEL_SYSCALLS__ +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ + +/* + some of these had problems getting the right arguments (namely sys_clone()) + when they were inline so I made them non-inline until we get problems with gcc + worked out. I need to check with Linus to find out which he wants inline now + since the above comment was written a long time ago. + + Once I understand the macro language better this should go away. + -- Cort + */ + +#define __NR__exit __NR_exit +static /*__inline__*/ _syscall0(int,setup) +static __inline__ _syscall0(int,idle) +static /*__inline__*/ _syscall0(int,fork) +static __inline__ _syscall0(int,pause) +static __inline__ _syscall0(int,sync) +static __inline__ _syscall0(pid_t,setsid) +static __inline__ _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static /*__inline__*/ _syscall1(int,dup,int,fd) +static /*__inline__*/ _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static __inline__ _syscall3(int,open,const char *,file,int,flag,int,mode) +static /*__inline__*/ _syscall1(int,close,int,fd) +static /*__inline__*/ _syscall1(int,_exit,int,exitcode) +static __inline__ _syscall2(int,clone,unsigned long,flags,char *,esp) +static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +static __inline__ pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +/* + This is the mechanism for creating a new kernel thread. + For the time being it only behaves the same as clone(). + It should be changed very soon to work properly and cleanly. This + gets us going for now, though. + -- Cort + */ +static __inline__ long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + long retval; + __asm__ ( + "li 0, 120 \n\t" /* __NR_clone */ + "li 3, %5 \n\t" /* load flags as arg to clone */ + /*"mr 1,7 \n\t"*/ /* save kernel stack */ + "sc \n\t" /* syscall */ + /*"cmp 0,1,7 \n\t"*/ /* if kernel stack changes -- child */ + "cmpi 0,3,0 \n\t" + "bne 1f \n\t" /* return if parent */ + /* this is in child */ + "li 3, %3 \n\t" /* child -- load args and call fn */ + "mtlr %4 \n\t" + "blrl \n\t" + "li 0, %2 \n\t" /* exit after child exits */ + "li 3, 0 \n\t" + "sc \n\t" + /* parent */ + "1: \n\t" + :"=3" (retval) + :"i" (__NR_clone), "i" (__NR_exit), + "r" (arg), "r" (fn), "g" (CLONE_VM|flags) + :"cc", "1", "0", "3", "7", "31", "memory" ); + return retval; +} + + +#endif /* __KERNEL_SYSCALLS__ */ + +#endif /* _ASM_PPC_UNISTD_H_ */ diff --git a/include/asm-ppc/unistd.h.cort b/include/asm-ppc/unistd.h.cort new file mode 100644 index 000000000..be4cee27e --- /dev/null +++ b/include/asm-ppc/unistd.h.cort @@ -0,0 +1,376 @@ +#ifndef _ASM_PPC_UNISTD_H_ +#define _ASM_PPC_UNISTD_H_ + +#define _NR(n) #n +#define _lisc(n) "li 0," _NR(n) + +/* + * This file contains the system call numbers. + */ + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl 110 +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86 113 +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_modify_ldt 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 + +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 + + +#define _syscall0(type,name) \ +type name(void) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval);\ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2, type3 arg3) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#ifdef __KERNEL_SYSCALLS__ +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ + +/* + some of these had problems getting the right arguments (namely sys_clone()) + when they were inline so I made them non-inline until we get problems with gcc + worked out. I need to check with Linus to find out which he wants inline now + since the above comment was written a long time ago. + + Once I understand the macro language better this should go away. + -- Cort + */ + +#define __NR__exit __NR_exit +static /*__inline__*/ _syscall0(int,setup) +static __inline__ _syscall0(int,idle) +static /*__inline__*/ _syscall0(int,fork) +static __inline__ _syscall0(int,pause) +static __inline__ _syscall0(int,sync) +static __inline__ _syscall0(pid_t,setsid) +static __inline__ _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static /*__inline__*/ _syscall1(int,dup,int,fd) +static /*__inline__*/ _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static __inline__ _syscall3(int,open,const char *,file,int,flag,int,mode) +static /*__inline__*/ _syscall1(int,close,int,fd) +static /*__inline__*/ _syscall1(int,_exit,int,exitcode) +static __inline__ _syscall2(int,clone,unsigned long,flags,char *,esp) +static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +static __inline__ pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +/* + This is the mechanism for creating a new kernel thread. + For the time being it only behaves the same as clone(). + It should be changed very soon to work properly and cleanly. This + gets us going for now, though. + -- Cort + */ +static __inline__ long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + long retval; + __asm__ ( + "li 0, 120 \n\t" /* __NR_clone */ + "li 3, %5 \n\t" /* load flags as arg to clone */ + /*"mr 1,7 \n\t"*/ /* save kernel stack */ + "sc \n\t" /* syscall */ + /*"cmp 0,1,7 \n\t"*/ /* if kernel stack changes -- child */ + "cmpi 0,3,0 \n\t" + "bne 1f \n\t" /* return if parent */ + /* this is in child */ + "li 3, %3 \n\t" /* child -- load args and call fn */ + "mtlr %4 \n\t" + "blrl \n\t" + "li 0, %2 \n\t" /* exit after child exits */ + "li 3, 0 \n\t" + "sc \n\t" + /* parent */ + "1: \n\t" + :"=3" (retval) + :"i" (__NR_clone), "i" (__NR_exit), + "r" (arg), "r" (fn), "g" (CLONE_VM|flags) + :"cc", "1", "0", "3", "7", "31", "memory" ); + return retval; +} + + +#endif /* __KERNEL_SYSCALLS__ */ + +#endif /* _ASM_PPC_UNISTD_H_ */ diff --git a/include/asm-ppc/user.h b/include/asm-ppc/user.h new file mode 100644 index 000000000..e3bd611b3 --- /dev/null +++ b/include/asm-ppc/user.h @@ -0,0 +1,52 @@ +#ifndef _PPC_USER_H +#define _PPC_USER_H + +/* Adapted from <asm-alpha/user.h> */ + +#include <linux/ptrace.h> +#include <asm/page.h> + +/* + * Core file format: The core file is written in such a way that gdb + * can understand it and provide useful information to the user (under + * linux we use the `trad-core' bfd, NOT the osf-core). The file contents + * are as follows: + * + * upage: 1 page consisting of a user struct that tells gdb + * what is present in the file. Directly after this is a + * copy of the task_struct, which is currently not used by gdb, + * but it may come in handy at some point. All of the registers + * are stored as part of the upage. The upage should always be + * only one page long. + * data: The data segment follows next. We use current->end_text to + * current->brk to pick up all of the user variables, plus any memory + * that may have been sbrk'ed. No attempt is made to determine if a + * page is demand-zero or if a page is totally unused, we just cover + * the entire range. All of the addresses are rounded in such a way + * that an integral number of pages is written. + * stack: We need the stack information in order to get a meaningful + * backtrace. We need to write the data from usp to + * current->start_stack, so we round each of these in order to be able + * to write an integer number of pages. + */ +struct user { + struct pt_regs regs; /* entire machine state */ + size_t u_tsize; /* text size (pages) */ + size_t u_dsize; /* data size (pages) */ + size_t u_ssize; /* stack size (pages) */ + unsigned long start_code; /* text starting address */ + unsigned long start_data; /* data starting address */ + unsigned long start_stack; /* stack starting address */ + long int signal; /* signal causing core dump */ + struct regs * u_ar0; /* help gdb find registers */ + unsigned long magic; /* identifies a core file */ + char u_comm[32]; /* user command name */ +}; + +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_DATA_START_ADDR (u.start_data) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif /* _PPC_USER_H */ diff --git a/include/asm-sparc/a.out.h b/include/asm-sparc/a.out.h new file mode 100644 index 000000000..6443e7612 --- /dev/null +++ b/include/asm-sparc/a.out.h @@ -0,0 +1,96 @@ +/* $Id: a.out.h,v 1.9 1996/05/29 13:44:54 ecd Exp $ */ +#ifndef __SPARC_A_OUT_H__ +#define __SPARC_A_OUT_H__ + +#define SPARC_PGSIZE 0x2000 /* Thanks to the sun4 architecture... */ +#define SEGMENT_SIZE SPARC_PGSIZE /* whee... */ + +struct exec { + unsigned char a_dynamic:1; /* A __DYNAMIC is in this image */ + unsigned char a_toolversion:7; + unsigned char a_machtype; + unsigned short a_info; + unsigned long a_text; /* length of text, in bytes */ + unsigned long a_data; /* length of data, in bytes */ + unsigned long a_bss; /* length of bss, in bytes */ + unsigned long a_syms; /* length of symbol table, in bytes */ + unsigned long a_entry; /* where program begins */ + unsigned long a_trsize; + unsigned long a_drsize; +}; + +/* Where in the file does the text information begin? */ +#define N_TXTOFF(x) (N_MAGIC(x) == ZMAGIC ? 0 : sizeof (struct exec)) + +/* Where do the Symbols start? */ +#define N_SYMOFF(x) (N_TXTOFF(x) + (x).a_text + \ + (x).a_data + (x).a_trsize + \ + (x).a_drsize) + +/* Where does text segment go in memory after being loaded? */ +#define N_TXTADDR(x) (((N_MAGIC(x) == ZMAGIC) && \ + ((x).a_entry < SPARC_PGSIZE)) ? \ + 0 : SPARC_PGSIZE) + +/* And same for the data segment.. */ +#define N_DATADDR(x) (N_MAGIC(x)==OMAGIC ? \ + (N_TXTADDR(x) + (x).a_text) \ + : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x)))) + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +/* + * Sparc relocation types + */ +enum reloc_type +{ + RELOC_8, + RELOC_16, + RELOC_32, /* simplest relocs */ + RELOC_DISP8, + RELOC_DISP16, + RELOC_DISP32, /* Disp's (pc-rel) */ + RELOC_WDISP30, + RELOC_WDISP22, /* SR word disp's */ + RELOC_HI22, + RELOC_22, /* SR 22-bit relocs */ + RELOC_13, + RELOC_LO10, /* SR 13&10-bit relocs */ + RELOC_SFA_BASE, + RELOC_SFA_OFF13, /* SR S.F.A. relocs */ + RELOC_BASE10, + RELOC_BASE13, + RELOC_BASE22, /* base_relative pic */ + RELOC_PC10, + RELOC_PC22, /* special pc-rel pic */ + RELOC_JMP_TBL, /* jmp_tbl_rel in pic */ + RELOC_SEGOFF16, /* ShLib offset-in-seg */ + RELOC_GLOB_DAT, + RELOC_JMP_SLOT, + RELOC_RELATIVE /* rtld relocs */ +}; + +/* + * Format of a relocation datum. + */ +struct relocation_info /* used when header.a_machtype == M_SPARC */ +{ + unsigned long r_address; /* relocation addr */ + unsigned int r_index:24; /* segment index or symbol index */ + unsigned int r_extern:1; /* if F, r_index==SEG#; if T, SYM idx */ + int r_pad:2; /* <unused> */ + enum reloc_type r_type:5; /* type of relocation to perform */ + long r_addend; /* addend for relocation value */ +}; + +#define N_RELOCATION_INFO_DECLARED 1 + +#ifdef __KERNEL__ + +#define STACK_TOP TASK_SIZE + +#endif + +#endif /* __SPARC_A_OUT_H__ */ diff --git a/include/asm-sparc/asi.h b/include/asm-sparc/asi.h index 4a404573d..f81ab33b9 100644 --- a/include/asm-sparc/asi.h +++ b/include/asm-sparc/asi.h @@ -1,43 +1,108 @@ +/* $Id: asi.h,v 1.16 1996/04/25 06:12:43 davem Exp $ */ #ifndef _SPARC_ASI_H #define _SPARC_ASI_H /* asi.h: Address Space Identifier values for the sparc. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * + * Pioneer work for sun4m: Paul Hatchman (paul@sfe.com.au) + * Joint edition for sun4c+sun4m: Pete A. Zaitcev <zaitcev@ipmce.su> + */ + +/* The first batch are for the sun4c. */ + +#define ASI_NULL1 0x00 +#define ASI_NULL2 0x01 + +/* sun4c and sun4 control registers and mmu/vac ops */ +#define ASI_CONTROL 0x02 +#define ASI_SEGMAP 0x03 +#define ASI_PTE 0x04 +#define ASI_HWFLUSHSEG 0x05 +#define ASI_HWFLUSHPAGE 0x06 +#define ASI_REGMAP 0x06 +#define ASI_HWFLUSHCONTEXT 0x07 + +#define ASI_USERTXT 0x08 +#define ASI_KERNELTXT 0x09 +#define ASI_USERDATA 0x0a +#define ASI_KERNELDATA 0x0b + +/* VAC Cache flushing on sun4c and sun4 */ +#define ASI_FLUSHSEG 0x0c +#define ASI_FLUSHPG 0x0d +#define ASI_FLUSHCTX 0x0e - Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) -*/ +/* SPARCstation-5: only 6 bits are decoded. */ +/* wo = Write Only, rw = Read Write; */ +/* ss = Single Size, as = All Sizes; */ +#define ASI_M_RES00 0x00 /* Don't touch... */ +#define ASI_M_UNA01 0x01 /* Same here... */ +#define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */ +#define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */ +#define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */ +#define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */ +#define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */ +#define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */ +#define ASI_M_USERTXT 0x08 /* Same as ASI_USERTXT; rw, as */ +#define ASI_M_KERNELTXT 0x09 /* Same as ASI_KERNELTXT; rw, as */ +#define ASI_M_USERDATA 0x0A /* Same as ASI_USERDATA; rw, as */ +#define ASI_M_KERNELDATA 0x0B /* Same as ASI_KERNELDATA; rw, as */ +#define ASI_M_TXTC_TAG 0x0C /* Instruction Cache Tag; rw, ss */ +#define ASI_M_TXTC_DATA 0x0D /* Instruction Cache Data; rw, ss */ +#define ASI_M_DATAC_TAG 0x0E /* Data Cache Tag; rw, ss */ +#define ASI_M_DATAC_DATA 0x0F /* Data Cache Data; rw, ss */ -/* These are sun4c, beware on other architectures. Although things should - * be similar under regular sun4's. +/* The following cache flushing ASIs work only with the 'sta' + * instruction. Results are unpredictable for 'swap' and 'ldstuba', + * so don't do it. */ -#include <linux/config.h> -#ifdef CONFIG_SUN4M -#include "asi4m.h" -#else +/* These ASI flushes affect external caches too. */ +#define ASI_M_FLUSH_PAGE 0x10 /* Flush I&D Cache Line (page); wo, ss */ +#define ASI_M_FLUSH_SEG 0x11 /* Flush I&D Cache Line (seg); wo, ss */ +#define ASI_M_FLUSH_REGION 0x12 /* Flush I&D Cache Line (region); wo, ss */ +#define ASI_M_FLUSH_CTX 0x13 /* Flush I&D Cache Line (context); wo, ss */ +#define ASI_M_FLUSH_USER 0x14 /* Flush I&D Cache Line (user); wo, ss */ -#define ASI_NULL1 0x0 -#define ASI_NULL2 0x1 +/* Block-copy operations are available only on certain V8 cpus. */ +#define ASI_M_BCOPY 0x17 /* Block copy */ -/* sun4c and sun4 control registers and mmu/vac ops */ -#define ASI_CONTROL 0x2 -#define ASI_SEGMAP 0x3 -#define ASI_PTE 0x4 -#define ASI_HWFLUSHSEG 0x5 /* These are to initiate hw flushes of the cache */ -#define ASI_HWFLUSHPAGE 0x6 -#define ASI_HWFLUSHCONTEXT 0x7 +/* These affect only the ICACHE and are Ross HyperSparc specific. */ +#define ASI_M_IFLUSH_PAGE 0x18 /* Flush I Cache Line (page); wo, ss */ +#define ASI_M_IFLUSH_SEG 0x19 /* Flush I Cache Line (seg); wo, ss */ +#define ASI_M_IFLUSH_REGION 0x1A /* Flush I Cache Line (region); wo, ss */ +#define ASI_M_IFLUSH_CTX 0x1B /* Flush I Cache Line (context); wo, ss */ +#define ASI_M_IFLUSH_USER 0x1C /* Flush I Cache Line (user); wo, ss */ +/* Block-fill operations are available on certain V8 cpus */ +#define ASI_M_BFILL 0x1F -#define ASI_USERTXT 0x8 -#define ASI_KERNELTXT 0x9 -#define ASI_USERDATA 0xa -#define ASI_KERNELDATA 0xb +/* This allows direct access to main memory, actually 0x20 to 0x2f are + * the available ASI's for physical ram pass-through, but I don't have + * any idea what the other ones do.... + */ -/* VAC Cache flushing on sun4c and sun4 */ +#define ASI_M_BYPASS 0x20 /* Reference MMU bypass; rw, as */ +#define ASI_M_FBMEM 0x29 /* Graphics card frame buffer access */ +#define ASI_M_VMEUS 0x2A /* VME user 16-bit access */ +#define ASI_M_VMEPS 0x2B /* VME priv 16-bit access */ +#define ASI_M_VMEUT 0x2C /* VME user 32-bit access */ +#define ASI_M_VMEPT 0x2D /* VME priv 32-bit access */ +#define ASI_M_SBUS 0x2E /* Direct SBus access */ +#define ASI_M_CTL 0x2F /* Control Space (ECC and MXCC are here) */ + + +/* This is ROSS HyperSparc only. */ +#define ASI_M_FLUSH_IWHOLE 0x31 /* Flush entire ICACHE; wo, ss */ + +/* Tsunami/Viking i/d cache flash clear. */ +#define ASI_M_IC_FLCLEAR 0x36 +#define ASI_M_DC_FLCLEAR 0x37 -#define ASI_FLUSHSEG 0xc /* These are for "software" flushes of the cache */ -#define ASI_FLUSHPG 0xd -#define ASI_FLUSHCTX 0xe +#define ASI_M_DCDR 0x39 /* Data Cache Diagnostics Register rw, ss */ +#define ASI_M_ACTION 0x4c /* Breakpoint Action Register (GNU/Viking) */ -#endif /* CONFIG_SUN4M */ #endif /* _SPARC_ASI_H */ diff --git a/include/asm-sparc/asi4m.h b/include/asm-sparc/asi4m.h deleted file mode 100644 index 68b1d21e7..000000000 --- a/include/asm-sparc/asi4m.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _SPARC_ASI4M_H -#define _SPARC_ASI4M_H - -/* asi4m.h: Address Space Identifier values for sun4m - - Copyright (C) 1995 Paul Hatchman (paul@sfe.com.au) -*/ - -#define ASI_PTE 0x0 - -#define ASI_NULL1 0x0 -#define ASI_NULL2 0x1 -#define ASI_CONTROL 0x4 /* hmm? */ -#define ASI_USERTXT 0x8 /* user text */ -#define ASI_KERNELTXT 0x9 /* kernel text */ -#define ASI_USERDATA 0xA /* user data */ -#define ASI_KERNELDATA 0xB /* kernel data */ - -/* cache flushing */ -#define ASI_FLUSHPG 0x10 -#define ASI_FLUSHSEG 0x11 -#define ASI_FLUSHRGN 0x12 -#define ASI_FLUSHCTX 0x13 - -/* MMU REGS */ -#define SRMMU_CTL 0x000 -#define SRMMU_CTP 0x100 /* set/get context pointer */ -#define SRMMU_CTX 0x200 /* get/set context */ -#endif _SPARC_ASI4M_H diff --git a/include/asm-sparc/asmmacro.h b/include/asm-sparc/asmmacro.h new file mode 100644 index 000000000..8bf441c27 --- /dev/null +++ b/include/asm-sparc/asmmacro.h @@ -0,0 +1,196 @@ +/* asmmacro.h: Assembler macros. + * + * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu) + */ + +#ifndef _SPARC_ASMMACRO_H +#define _SPARC_ASMMACRO_H + +/* #define SMP_DEBUG */ + +#define GET_PROCESSOR_ID(reg) \ + rd %tbr, %reg; \ + srl %reg, 12, %reg; \ + and %reg, 3, %reg; + +#define GET_PROCESSOR_MID(reg, tmp) \ + GET_PROCESSOR_ID(reg) \ + set C_LABEL(mid_xlate), %tmp; \ + ldub [%tmp + %reg], %reg; + +#define GET_PROCESSOR_OFFSET(reg) \ + rd %tbr, %reg; \ + srl %reg, 10, %reg; \ + and %reg, 0xc, %reg; + +#define PROCESSOR_OFFSET_TO_ID(reg) \ + srl %reg, 2, %reg; + +#define PROCESSOR_ID_TO_OFFSET(reg) \ + sll %reg, 2, %reg; + +/* All trap entry points _must_ begin with this macro or else you + * lose. It makes sure the kernel has a proper window so that + * c-code can be called. + */ +#ifndef SMP_DEBUG +#define SAVE_ALL \ + sethi %hi(trap_setup), %l4; \ + jmpl %l4 + %lo(trap_setup), %l6; \ + nop; +#else +#define SAVE_ALL \ + GET_PROCESSOR_ID(l4); \ + set C_LABEL(trap_log), %l5; \ + sll %l4, 11, %l6; \ + add %l5, %l6, %l5; \ + set C_LABEL(trap_log_ent), %l6; \ + sll %l4, 2, %l4; \ + add %l6, %l4, %l6; \ + ld [%l6], %l6; \ + sll %l6, 3, %l6; \ + st %l1, [%l5 + %l6]; \ + add %l5, 4, %l5; \ + st %l0, [%l5 + %l6]; \ + set C_LABEL(trap_log_ent), %l5; \ + add %l5, %l4, %l5; \ + srl %l6, 3, %l6; \ + add %l6, 1, %l6; \ + and %l6, 255, %l6; \ + st %l6, [%l5]; \ + sethi %hi(trap_setup), %l4; \ + jmpl %l4 + %lo(trap_setup), %l6; \ + nop; +#endif + +/* All traps low-level code here must end with this macro. + * For SMP configurations the ret_trap_entry routine will + * have to appropriate code to actually release the kernel + * entry lock. + */ +#define RESTORE_ALL b ret_trap_entry; clr %l6; + +#ifndef __SMP__ + +#define ENTER_SYSCALL +#define LEAVE_SYSCALL +#define ENTER_IRQ +#define LEAVE_IRQ + +#else + +#define INCREMENT_COUNTER(symbol, tmp1, tmp2) \ + set C_LABEL(symbol), %tmp1; \ + ld [%tmp1], %tmp2; \ + add %tmp2, 1, %tmp2; \ + st %tmp2, [%tmp1]; + +#define DECREMENT_COUNTER(symbol, tmp1, tmp2) \ + set C_LABEL(symbol), %tmp1; \ + ld [%tmp1], %tmp2; \ + sub %tmp2, 1, %tmp2; \ + st %tmp2, [%tmp1]; + + /* This is so complicated I suggest you don't look at it. */ +#define ENTER_MASK(mask) \ + GET_PROCESSOR_OFFSET(l4) \ + set C_LABEL(smp_proc_in_lock), %l5; \ + ld [%l5 + %l4], %l6; \ + or %l6, mask, %l6; \ + st %l6, [%l5 + %l4]; \ +1: \ + set C_LABEL(kernel_flag), %l5; \ + ldstub [%l5], %l6; \ + cmp %l6, 0; \ + be 3f; \ + nop; \ + set C_LABEL(active_kernel_processor), %l5; \ + GET_PROCESSOR_ID(l4) \ + ldub [%l5], %l6; \ + cmp %l6, %l4; \ + be 4f; \ + nop; \ +2: \ + GET_PROCESSOR_MID(l4, l5) \ + set C_LABEL(sun4m_interrupts), %l5; \ + ld [%l5], %l5; \ + sll %l4, 12, %l4; \ + add %l5, %l4, %l5; \ + ld [%l5], %l4; \ + sethi %hi(0x80000000), %l6; \ + andcc %l6, %l4, %g0; \ + be 5f; \ + nop; \ + st %l6, [%l5 + 4]; \ + nop; nop; nop; \ + ld [%l5], %g0; \ + nop; nop; nop; \ + or %l0, PSR_PIL, %l4; \ + wr %l4, 0x0, %psr; \ + nop; nop; nop; \ + wr %l4, PSR_ET, %psr; \ + nop; nop; nop; \ + call C_LABEL(smp_message_irq); \ + nop; \ + wr %l0, 0x0, %psr; \ + nop; nop; nop; \ +5: \ + set C_LABEL(kernel_flag), %l5; \ + ldub [%l5], %l6; \ + cmp %l6, 0; \ + bne 2b; \ + nop; \ + b 1b; \ + nop; \ +3: \ + GET_PROCESSOR_ID(l4) \ + set C_LABEL(active_kernel_processor), %l5; \ + stb %l4, [%l5]; \ + GET_PROCESSOR_MID(l4, l5) \ + set C_LABEL(irq_rcvreg), %l5; \ + ld [%l5], %l5; \ + st %l4, [%l5]; \ +4: \ + +#define ENTER_SYSCALL \ + ENTER_MASK(SMP_FROM_SYSCALL) \ + INCREMENT_COUNTER(kernel_counter, l6, l5) \ + INCREMENT_COUNTER(syscall_count, l6, l5) + +#define ENTER_IRQ \ + ENTER_MASK(SMP_FROM_INT) \ + INCREMENT_COUNTER(kernel_counter, l6, l5) + +#define LEAVE_MASK(mask) \ + GET_PROCESSOR_OFFSET(l4) \ + set C_LABEL(smp_proc_in_lock), %l5; \ + ld [%l5 + %l4], %l6; \ + andn %l6, mask, %l6; \ + st %l6, [%l5 + %l4]; + +#define LEAVE_SYSCALL \ + LEAVE_MASK(SMP_FROM_SYSCALL) \ + DECREMENT_COUNTER(syscall_count, l6, l5) \ + set C_LABEL(kernel_counter), %l6; \ + ld [%l6], %l5; \ + subcc %l5, 1, %l5; \ + st %l5, [%l6]; \ + bne 1f; \ + nop; \ + set C_LABEL(active_kernel_processor), %l6; \ + mov NO_PROC_ID, %l5; \ + stb %l5, [%l6]; \ + set C_LABEL(kernel_flag), %l6; \ + stb %g0, [%l6]; \ +1: + +#define LEAVE_IRQ \ + LEAVE_MASK(SMP_FROM_INT) \ + INCREMENT_COUNTER(syscall_count, l6, l5) + + +#define RESTORE_ALL_FASTIRQ b,a ret_irq_entry; + +#endif /* !(__SMP__) */ + +#endif /* !(_SPARC_ASMMACRO_H) */ diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h new file mode 100644 index 000000000..3e46c262e --- /dev/null +++ b/include/asm-sparc/atomic.h @@ -0,0 +1,115 @@ +/* atomic.h: These really suck for now. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __ARCH_SPARC_ATOMIC__ +#define __ARCH_SPARC_ATOMIC__ + +typedef int atomic_t; + +#ifdef __KERNEL__ +#include <asm/system.h> +#include <asm/psr.h> + +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +#define __atomic_fool_gcc(x) ((struct { int a[100]; } *)x) + +static __inline__ void atomic_add(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__(" + rd %%psr, %%g2 + andcc %%g2, %2, %%g0 + be,a 1f + wr %%g2, %2, %%psr +1: ld [%0], %%g3 + add %%g3, %1, %%g3 + andcc %%g2, %2, %%g0 + st %%g3, [%0] + be,a 1f + wr %%g2, 0x0, %%psr +1: nop; nop; + " + : : "r" (__atomic_fool_gcc(v)), "r" (i), "i" (PSR_PIL) + : "g2", "g3"); +} + +static __inline__ void atomic_sub(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__(" + rd %%psr, %%g2 + andcc %%g2, %2, %%g0 + be,a 1f + wr %%g2, %2, %%psr +1: ld [%0], %%g3 + sub %%g3, %1, %%g3 + andcc %%g2, %2, %%g0 + st %%g3, [%0] + be,a 1f + wr %%g2, 0x0, %%psr +1: nop; nop; + " + : : "r" (__atomic_fool_gcc(v)), "r" (i), "i" (PSR_PIL) + : "g2", "g3"); +} + +static __inline__ int atomic_add_return(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__(" + rd %%psr, %%g2 + andcc %%g2, %3, %%g0 + be,a 1f + wr %%g2, %3, %%psr +1: ld [%1], %%g3 + add %%g3, %2, %0 + andcc %%g2, %3, %%g0 + st %0, [%1] + be,a 1f + wr %%g2, 0x0, %%psr +1: nop; nop; + " + : "=&r" (i) + : "r" (__atomic_fool_gcc(v)), "0" (i), "i" (PSR_PIL) + : "g2", "g3"); + + return i; +} + +static __inline__ int atomic_sub_return(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__(" + rd %%psr, %%g2 + andcc %%g2, %3, %%g0 + be,a 1f + wr %%g2, %3, %%psr +1: ld [%1], %%g3 + sub %%g3, %2, %0 + andcc %%g2, %3, %%g0 + st %0, [%1] + be,a 1f + wr %%g2, 0x0, %%psr +1: nop; nop; + " + : "=&r" (i) + : "r" (__atomic_fool_gcc(v)), "0" (i), "i" (PSR_PIL) + : "g2", "g3"); + + return i; +} + +#define atomic_dec_return(v) atomic_sub_return(1,(v)) +#define atomic_inc_return(v) atomic_add_return(1,(v)) + +#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) + +#define atomic_inc(v) atomic_add(1,(v)) +#define atomic_dec(v) atomic_sub(1,(v)) + +#endif /* !(__KERNEL__) */ + +#endif /* !(__ARCH_SPARC_ATOMIC__) */ diff --git a/include/asm-sparc/atops.h b/include/asm-sparc/atops.h new file mode 100644 index 000000000..0bb70752d --- /dev/null +++ b/include/asm-sparc/atops.h @@ -0,0 +1,22 @@ +/* atops.h: Atomic SPARC operations. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_ATOPS_H +#define _SPARC_ATOPS_H + +#ifdef __SMP__ + +extern __inline__ __volatile__ unsigned char ldstub(volatile unsigned char *lock) +{ + volatile unsigned char retval; + + __asm__ __volatile__("ldstub [%1], %0\n\t" : + "=&r" (retval) : + "r" (lock)); + return retval; +} + +#endif + +#endif diff --git a/include/asm-sparc/auxio.h b/include/asm-sparc/auxio.h new file mode 100644 index 000000000..be4107408 --- /dev/null +++ b/include/asm-sparc/auxio.h @@ -0,0 +1,70 @@ +/* $Id: auxio.h,v 1.14 1996/10/31 06:29:10 davem Exp $ + * auxio.h: Definitions and code for the Auxiliary I/O register. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_AUXIO_H +#define _SPARC_AUXIO_H + +#include <asm/system.h> +#include <asm/vaddrs.h> + +extern unsigned char *auxio_register; + +/* This register is an unsigned char in IO space. It does two things. + * First, it is used to control the front panel LED light on machines + * that have it (good for testing entry points to trap handlers and irq's) + * Secondly, it controls various floppy drive parameters. + */ +#define AUXIO_ORMEIN 0xf0 /* All writes must set these bits. */ +#define AUXIO_ORMEIN4M 0xc0 /* sun4m - All writes must set these bits. */ +#define AUXIO_FLPY_DENS 0x20 /* Floppy density, high if set. Read only. */ +#define AUXIO_FLPY_DCHG 0x10 /* A disk change occurred. Read only. */ +#define AUXIO_EDGE_ON 0x10 /* sun4m - On means Jumper block is in. */ +#define AUXIO_FLPY_DSEL 0x08 /* Drive select/start-motor. Write only. */ +#define AUXIO_LINK_TEST 0x08 /* sun4m - On means TPE Carrier detect. */ + +/* Set the following to one, then zero, after doing a pseudo DMA transfer. */ +#define AUXIO_FLPY_TCNT 0x04 /* Floppy terminal count. Write only. */ + +/* Set the following to zero to eject the floppy. */ +#define AUXIO_FLPY_EJCT 0x02 /* Eject floppy disk. Write only. */ +#define AUXIO_LED 0x01 /* On if set, off if unset. Read/Write */ + +#define AUXREG ((volatile unsigned char *)(auxio_register)) + +/* These are available on sun4c */ +#define TURN_ON_LED if (AUXREG) *AUXREG = (*AUXREG | AUXIO_ORMEIN | AUXIO_LED) +#define TURN_OFF_LED if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) & (~AUXIO_LED)) +#define FLIP_LED if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) ^ AUXIO_LED) +#define FLPY_MOTORON if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) | AUXIO_FLPY_DSEL) +#define FLPY_MOTOROFF if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) & (~AUXIO_FLPY_DSEL)) +#define FLPY_TCNTON if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) | AUXIO_FLPY_TCNT) +#define FLPY_TCNTOFF if (AUXREG) *AUXREG = ((*AUXREG | AUXIO_ORMEIN) & (~AUXIO_FLPY_TCNT)) + +#ifndef __ASSEMBLY__ +extern __inline__ void set_auxio(unsigned char bits_on, unsigned char bits_off) +{ + unsigned char regval; + unsigned long flags; + + save_flags(flags); cli(); + + switch(sparc_cpu_model) { + case sun4c: + regval = *AUXREG; + *AUXREG = ((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN; + break; + case sun4m: + regval = *AUXREG; + *AUXREG = ((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN4M; + break; + default: + panic("Can't set AUXIO register on this machine."); + }; + + restore_flags(flags); +} +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_SPARC_AUXIO_H) */ diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h index 241e5e8c1..85d86c6dd 100644 --- a/include/asm-sparc/bitops.h +++ b/include/asm-sparc/bitops.h @@ -1,121 +1,202 @@ +/* $Id: bitops.h,v 1.36 1996/09/29 22:57:21 davem Exp $ + * bitops.h: Bit string operations on the Sparc. + * + * Copyright 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright 1996 Eddie C. Dost (ecd@skynet.be) + */ + #ifndef _SPARC_BITOPS_H #define _SPARC_BITOPS_H -/* - * Copyright 1994, David S. Miller (davem@caip.rutgers.edu). - */ +#include <linux/kernel.h> +#ifndef __KERNEL__ -/* Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0' - * is in the highest of the four bytes and bit '31' is the high bit - * within the first byte. Sparc is BIG-Endian. Unless noted otherwise - * all bit-ops return 0 if bit was previously clear and != 0 otherwise. +/* User mode bitops, defined here for convenience. Note: these are not + * atomic, so packages like nthreads should do some locking around these + * themself. */ -/* For now, the sun4c implementation will disable and enable traps - * in order to insure atomicity. Things will have to be different - * for sun4m (ie. SMP) no doubt. - */ +#define __SMPVOL -extern __inline__ unsigned int set_bit(unsigned int nr, void *addr) +extern __inline__ unsigned long set_bit(unsigned long nr, void *addr) { - register unsigned long retval, tmp, mask, psr; - - __asm__ __volatile__("or %%g0, 0x1, %3\n\t" /* produce the mask */ - "sll %3, %4, %3\n\t" - "rd %%psr, %5\n\t" /* read the psr */ - "wr %5, 0x20, %%psr\n\t" /* traps disabled */ - "ld [%1], %2\n\t" /* critical section */ - "and %3, %2, %0\n\t" - "or %3, %2, %2\n\t" - "st %2, [%1]\n\t" - "wr %5, 0x0, %%psr\n\t" : /* re-enable traps */ - "=r" (retval) : - "r" (addr), "r" (tmp=0), "r" (mask=0), - "r" (nr), "r" (psr=0)); - - return retval; /* confuse gcc :-) */ - + int mask; + unsigned long *ADDR = (unsigned long *) addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + __asm__ __volatile__(" + ld [%0], %%g3 + or %%g3, %2, %%g2 + st %%g2, [%0] + and %%g3, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask) + : "g2", "g3"); + + return (unsigned long) ADDR; } -extern __inline__ unsigned int clear_bit(unsigned int nr, void *addr) +extern __inline__ unsigned long clear_bit(unsigned long nr, void *addr) { - register unsigned long retval, tmp, mask, psr; - - __asm__ __volatile__("or %%g0, 0x1, %3\n\t" - "sll %3, %4, %3\n\t" - "rd %%psr, %5\n\t" - "wr %5, 0x20, %%psr\n\t" /* disable traps */ - "ld [%1], %2\n\t" - "and %2, %3, %0\n\t" /* get old bit */ - "andn %2, %3, %2\n\t" /* set new val */ - "st %2, [%1]\n\t" - "wr %5, 0x0, %%psr\n\t" : /* enable traps */ - "=r" (retval) : - "r" (addr), "r" (tmp=0), "r" (mask=0), - "r" (nr), "r" (psr=0)); - - return retval; /* confuse gcc ;-) */ - + int mask; + unsigned long *ADDR = (unsigned long *) addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + __asm__ __volatile__(" + ld [%0], %%g3 + andn %%g3, %2, %%g2 + st %%g2, [%0] + and %%g3, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask) + : "g2", "g3"); + + return (unsigned long) ADDR; } -extern __inline__ unsigned int change_bit(unsigned int nr, void *addr) +extern __inline__ unsigned long change_bit(unsigned long nr, void *addr) { - register unsigned long retval, tmp, mask, psr; + int mask; + unsigned long *ADDR = (unsigned long *) addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + __asm__ __volatile__(" + ld [%0], %%g3 + xor %%g3, %2, %%g2 + st %%g2, [%0] + and %%g3, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask) + : "g2", "g3"); + + return (unsigned long) ADDR; +} - __asm__ __volatile__("or %%g0, 0x1, %3\n\t" - "sll %3, %4, %3\n\t" - "rd %%psr, %5\n\t" - "wr %5, 0x20, %%psr\n\t" /* disable traps */ - "ld [%1], %2\n\t" - "and %3, %2, %0\n\t" /* get old bit val */ - "xor %3, %2, %2\n\t" /* set new val */ - "st %2, [%1]\n\t" - "wr %5, 0x0, %%psr\n\t" : /* enable traps */ - "=r" (retval) : - "r" (addr), "r" (tmp=0), "r" (mask=0), - "r" (nr), "r" (psr=0)); +#else /* __KERNEL__ */ - return retval; /* confuse gcc ;-) */ +#include <asm/system.h> -} +#ifdef __SMP__ +#define __SMPVOL volatile +#else +#define __SMPVOL +#endif -/* The following routine need not be atomic. */ +/* Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0' + * is in the highest of the four bytes and bit '31' is the high bit + * within the first byte. Sparc is BIG-Endian. Unless noted otherwise + * all bit-ops return 0 if bit was previously clear and != 0 otherwise. + */ -extern __inline__ unsigned int test_bit(int nr, void *addr) +extern __inline__ unsigned long set_bit(unsigned long nr, __SMPVOL void *addr) { - register unsigned long retval, tmp; - - __asm__ __volatile__("ld [%1], %2\n\t" - "or %%g0, 0x1, %0\n\t" - "sll %0, %3, %0\n\t" - "and %0, %2, %0\n\t" : - "=r" (retval) : - "r" (addr), "r" (tmp=0), - "r" (nr)); + int mask; + unsigned long *ADDR = (unsigned long *) addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + __asm__ __volatile__(" + rd %%psr, %%g3 + andcc %%g3, %3, %%g0 + be,a 1f + wr %%g3, %3, %%psr +1: ld [%0], %%g4 + or %%g4, %2, %%g2 + andcc %%g3, %3, %%g0 + st %%g2, [%0] + be,a 1f + wr %%g3, 0x0, %%psr +1: nop + and %%g4, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask), "i" (PSR_PIL) + : "g2", "g3", "g4"); + + return (unsigned long) ADDR; +} - return retval; /* confuse gcc :> */ +extern __inline__ unsigned long clear_bit(unsigned long nr, __SMPVOL void *addr) +{ + int mask; + unsigned long *ADDR = (unsigned long *) addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + __asm__ __volatile__(" + rd %%psr, %%g3 + andcc %%g3, %3, %%g0 + be,a 1f + wr %%g3, %3, %%psr +1: ld [%0], %%g4 + andn %%g4, %2, %%g2 + andcc %%g3, %3, %%g0 + st %%g2, [%0] + be,a 1f + wr %%g3, 0x0, %%psr +1: nop + and %%g4, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask), "i" (PSR_PIL) + : "g2", "g3", "g4"); + + return (unsigned long) ADDR; +} +extern __inline__ unsigned long change_bit(unsigned long nr, __SMPVOL void *addr) +{ + int mask; + unsigned long *ADDR = (unsigned long *) addr; + + ADDR += nr >> 5; + mask = 1 << (nr & 31); + __asm__ __volatile__(" + rd %%psr, %%g3 + andcc %%g3, %3, %%g0 + be,a 1f + wr %%g3, %3, %%psr +1: ld [%0], %%g4 + xor %%g4, %2, %%g2 + andcc %%g3, %3, %%g0 + st %%g2, [%0] + be,a 1f + wr %%g3, 0x0, %%psr +1: nop + and %%g4, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask), "i" (PSR_PIL) + : "g2", "g3", "g4"); + + return (unsigned long) ADDR; } -/* There has to be a faster way to do this, sigh... */ +#endif /* __KERNEL__ */ -extern __inline__ unsigned long ffz(unsigned long word) +/* The following routine need not be atomic. */ +extern __inline__ unsigned long test_bit(int nr, __const__ __SMPVOL void *addr) { - register unsigned long cnt, tmp, tmp2; - - cnt = 0; + return 1UL & (((__const__ unsigned int *) addr)[nr >> 5] >> (nr & 31)); +} - __asm__("or %%g0, %3, %2\n\t" - "1: and %2, 0x1, %1\n\t" - "srl %2, 0x1, %2\n\t" - "cmp %1, 0\n\t" - "bne,a 1b\n\t" - "add %0, 0x1, %0\n\t" : - "=r" (cnt) : - "r" (tmp=0), "r" (tmp2=0), "r" (word)); +/* The easy/cheese version for now. */ +extern __inline__ unsigned long ffz(unsigned long word) +{ + unsigned long result = 0; - return cnt; + while(word & 1) { + result++; + word >>= 1; + } + return result; } /* find_next_zero_bit() finds the first zero bit in a bit string of length @@ -125,40 +206,38 @@ extern __inline__ unsigned long ffz(unsigned long word) extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) { - unsigned long *p = ((unsigned long *) addr) + (offset >> 6); - unsigned long result = offset & ~31UL; - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset &= 31UL; - if (offset) - { - tmp = *(p++); - tmp |= ~0UL >> (32-offset); - if (size < 32) - goto found_first; - if (~tmp) - goto found_middle; - size -= 32; - result += 32; - } - while (size & ~32UL) - { - if (~(tmp = *(p++))) - goto found_middle; - result += 32; - size -= 32; - } - if (!size) - return result; - tmp = *p; + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *(p++); + tmp |= ~0UL >> (32-offset); + if (size < 32) + goto found_first; + if (~tmp) + goto found_middle; + size -= 32; + result += 32; + } + while (size & ~31UL) { + if (~(tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; found_first: - tmp |= ~0UL << size; + tmp |= ~0UL << size; found_middle: - return result + ffz(tmp); + return result + ffz(tmp); } /* Linus sez that gcc can optimize the following correctly, we'll see if this @@ -168,6 +247,169 @@ found_middle: #define find_first_zero_bit(addr, size) \ find_next_zero_bit((addr), (size), 0) +#ifndef __KERNEL__ + +extern __inline__ int __ext2_set_bit(int nr, void *addr) +{ + int mask; + unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + __asm__ __volatile__(" + ldub [%0], %%g3 + or %%g3, %2, %%g2 + stb %%g2, [%0] + and %%g3, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask) + : "g2", "g3"); + + return (int) ADDR; +} + +extern __inline__ int __ext2_clear_bit(int nr, void *addr) +{ + int mask; + unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + __asm__ __volatile__(" + ldub [%0], %%g3 + andn %%g3, %2, %%g2 + stb %%g2, [%0] + and %%g3, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask) + : "g2", "g3"); + + return (int) ADDR; +} + +#else /* __KERNEL__ */ + +/* Now for the ext2 filesystem bit operations and helper routines. */ + +extern __inline__ int __ext2_set_bit(int nr,void * addr) +{ + int mask; + unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + __asm__ __volatile__(" + rd %%psr, %%g3 + andcc %%g3, %3, %%g0 + be,a 1f + wr %%g3, %3, %%psr +1: ldub [%0], %%g4 + or %%g4, %2, %%g2 + andcc %%g3, %3, %%g0 + stb %%g2, [%0] + be,a 1f + wr %%g3, 0x0, %%psr +1: nop + and %%g4, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask), "i" (PSR_PIL) + : "g2", "g3", "g4"); + + return (int) ADDR; +} + +extern __inline__ int __ext2_clear_bit(int nr, void * addr) +{ + int mask; + unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + __asm__ __volatile__(" + rd %%psr, %%g3 + andcc %%g3, %3, %%g0 + be,a 1f + wr %%g3, %3, %%psr +1: ldub [%0], %%g4 + andn %%g4, %2, %%g2 + andcc %%g3, %3, %%g0 + stb %%g2, [%0] + be,a 1f + wr %%g3, 0x0, %%psr +1: nop + and %%g4, %2, %0 + " + : "=&r" (ADDR) + : "0" (ADDR), "r" (mask), "i" (PSR_PIL) + : "g2", "g3", "g4"); + + return (int) ADDR; +} + +#endif /* __KERNEL__ */ + +extern __inline__ int __ext2_test_bit(int nr, __const__ void * addr) +{ + int mask; + __const__ unsigned char *ADDR = (__const__ unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + return ((mask & *ADDR) != 0); +} + +extern __inline__ unsigned short __swab16(unsigned short value) +{ + return ((value >> 8) | (value << 8)); +} + +extern __inline__ unsigned long __swab32(unsigned long value) +{ + return ((value >> 24) | ((value >> 8) & 0xff00) | + ((value << 8) & 0xff0000) | (value << 24)); +} + +#define __ext2_find_first_zero_bit(addr, size) \ + __ext2_find_next_zero_bit((addr), (size), 0) + +extern __inline__ unsigned long __ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +{ + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if(offset) { + tmp = *(p++); + tmp |= __swab32(~0UL >> (32-offset)); + if(size < 32) + goto found_first; + if(~tmp) + goto found_middle; + size -= 32; + result += 32; + } + while(size & ~31UL) { + if(~(tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if(!size) + return result; + tmp = *p; + +found_first: + return result + ffz(__swab32(tmp) | (~0UL << size)); +found_middle: + return result + ffz(__swab32(tmp)); +} #endif /* defined(_SPARC_BITOPS_H) */ diff --git a/include/asm-sparc/bsderrno.h b/include/asm-sparc/bsderrno.h new file mode 100644 index 000000000..54a75be43 --- /dev/null +++ b/include/asm-sparc/bsderrno.h @@ -0,0 +1,94 @@ +/* $Id: bsderrno.h,v 1.3 1996/04/25 06:12:47 davem Exp $ + * bsderrno.h: Error numbers for NetBSD binary compatibility + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_BSDERRNO_H +#define _SPARC_BSDERRNO_H + +#define BSD_EPERM 1 /* Operation not permitted */ +#define BSD_ENOENT 2 /* No such file or directory */ +#define BSD_ESRCH 3 /* No such process */ +#define BSD_EINTR 4 /* Interrupted system call */ +#define BSD_EIO 5 /* Input/output error */ +#define BSD_ENXIO 6 /* Device not configured */ +#define BSD_E2BIG 7 /* Argument list too long */ +#define BSD_ENOEXEC 8 /* Exec format error */ +#define BSD_EBADF 9 /* Bad file descriptor */ +#define BSD_ECHILD 10 /* No child processes */ +#define BSD_EDEADLK 11 /* Resource deadlock avoided */ +#define BSD_ENOMEM 12 /* Cannot allocate memory */ +#define BSD_EACCES 13 /* Permission denied */ +#define BSD_EFAULT 14 /* Bad address */ +#define BSD_ENOTBLK 15 /* Block device required */ +#define BSD_EBUSY 16 /* Device busy */ +#define BSD_EEXIST 17 /* File exists */ +#define BSD_EXDEV 18 /* Cross-device link */ +#define BSD_ENODEV 19 /* Operation not supported by device */ +#define BSD_ENOTDIR 20 /* Not a directory */ +#define BSD_EISDIR 21 /* Is a directory */ +#define BSD_EINVAL 22 /* Invalid argument */ +#define BSD_ENFILE 23 /* Too many open files in system */ +#define BSD_EMFILE 24 /* Too many open files */ +#define BSD_ENOTTY 25 /* Inappropriate ioctl for device */ +#define BSD_ETXTBSY 26 /* Text file busy */ +#define BSD_EFBIG 27 /* File too large */ +#define BSD_ENOSPC 28 /* No space left on device */ +#define BSD_ESPIPE 29 /* Illegal seek */ +#define BSD_EROFS 30 /* Read-only file system */ +#define BSD_EMLINK 31 /* Too many links */ +#define BSD_EPIPE 32 /* Broken pipe */ +#define BSD_EDOM 33 /* Numerical argument out of domain */ +#define BSD_ERANGE 34 /* Result too large */ +#define BSD_EAGAIN 35 /* Resource temporarily unavailable */ +#define BSD_EWOULDBLOCK EAGAIN /* Operation would block */ +#define BSD_EINPROGRESS 36 /* Operation now in progress */ +#define BSD_EALREADY 37 /* Operation already in progress */ +#define BSD_ENOTSOCK 38 /* Socket operation on non-socket */ +#define BSD_EDESTADDRREQ 39 /* Destination address required */ +#define BSD_EMSGSIZE 40 /* Message too long */ +#define BSD_EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define BSD_ENOPROTOOPT 42 /* Protocol not available */ +#define BSD_EPROTONOSUPPORT 43 /* Protocol not supported */ +#define BSD_ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define BSD_EOPNOTSUPP 45 /* Operation not supported */ +#define BSD_EPFNOSUPPORT 46 /* Protocol family not supported */ +#define BSD_EAFNOSUPPORT 47 /* Address family not supported by protocol family */ +#define BSD_EADDRINUSE 48 /* Address already in use */ +#define BSD_EADDRNOTAVAIL 49 /* Can't assign requested address */ +#define BSD_ENETDOWN 50 /* Network is down */ +#define BSD_ENETUNREACH 51 /* Network is unreachable */ +#define BSD_ENETRESET 52 /* Network dropped connection on reset */ +#define BSD_ECONNABORTED 53 /* Software caused connection abort */ +#define BSD_ECONNRESET 54 /* Connection reset by peer */ +#define BSD_ENOBUFS 55 /* No buffer space available */ +#define BSD_EISCONN 56 /* Socket is already connected */ +#define BSD_ENOTCONN 57 /* Socket is not connected */ +#define BSD_ESHUTDOWN 58 /* Can't send after socket shutdown */ +#define BSD_ETOOMANYREFS 59 /* Too many references: can't splice */ +#define BSD_ETIMEDOUT 60 /* Operation timed out */ +#define BSD_ECONNREFUSED 61 /* Connection refused */ +#define BSD_ELOOP 62 /* Too many levels of symbolic links */ +#define BSD_ENAMETOOLONG 63 /* File name too long */ +#define BSD_EHOSTDOWN 64 /* Host is down */ +#define BSD_EHOSTUNREACH 65 /* No route to host */ +#define BSD_ENOTEMPTY 66 /* Directory not empty */ +#define BSD_EPROCLIM 67 /* Too many processes */ +#define BSD_EUSERS 68 /* Too many users */ +#define BSD_EDQUOT 69 /* Disc quota exceeded */ +#define BSD_ESTALE 70 /* Stale NFS file handle */ +#define BSD_EREMOTE 71 /* Too many levels of remote in path */ +#define BSD_EBADRPC 72 /* RPC struct is bad */ +#define BSD_ERPCMISMATCH 73 /* RPC version wrong */ +#define BSD_EPROGUNAVAIL 74 /* RPC prog. not avail */ +#define BSD_EPROGMISMATCH 75 /* Program version wrong */ +#define BSD_EPROCUNAVAIL 76 /* Bad procedure for program */ +#define BSD_ENOLCK 77 /* No locks available */ +#define BSD_ENOSYS 78 /* Function not implemented */ +#define BSD_EFTYPE 79 /* Inappropriate file type or format */ +#define BSD_EAUTH 80 /* Authentication error */ +#define BSD_ENEEDAUTH 81 /* Need authenticator */ +#define BSD_ELAST 81 /* Must be equal largest errno */ + +#endif /* !(_SPARC_BSDERRNO_H) */ diff --git a/include/asm-sparc/bugs.h b/include/asm-sparc/bugs.h index 55f5434ad..534ce05ff 100644 --- a/include/asm-sparc/bugs.h +++ b/include/asm-sparc/bugs.h @@ -1,48 +1,7 @@ -/* include/asm-sparc/bugs.h: Sparc probes for various bugs. +/* $Id: bugs.h,v 1.5 1995/11/25 02:31:18 davem Exp $ + * include/asm-sparc/bugs.h: Sparc probes for various bugs. * * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) */ -/* - * This is included by init/main.c to check for architecture-dependent bugs. - * - * Needs: - * void check_bugs(void); - */ - -#define CONFIG_BUGSPARC - -#include <asm/openprom.h> - -extern struct linux_romvec *romvec; -extern int tbase_needs_unmapping; /* We do the bug workaround in pagetables.c */ - -static void check_mmu(void) -{ - register struct linux_romvec *lvec; - register int root_node; - unsigned int present; - - lvec = romvec; - - root_node = (*(romvec->pv_nodeops->no_nextnode))(0); - tbase_needs_unmapping=0; - - present = 0; - (*(romvec->pv_nodeops->no_getprop))(root_node, "buserr-type", - (char *) &present); - if(present == 1) - { - tbase_needs_unmapping=1; - printk("MMU bug found: not allowing trapbase to be cached\n"); - } - - return; -} - - -static void -check_bugs(void) -{ - check_mmu(); -} +static void check_bugs(void) { } diff --git a/include/asm-sparc/byteorder.h b/include/asm-sparc/byteorder.h index b734cf8a6..4f1cd2e65 100644 --- a/include/asm-sparc/byteorder.h +++ b/include/asm-sparc/byteorder.h @@ -1,85 +1,24 @@ +/* $Id: byteorder.h,v 1.9 1996/08/30 05:21:34 davem Exp $ */ #ifndef _SPARC_BYTEORDER_H #define _SPARC_BYTEORDER_H -#undef ntohl -#undef ntohs -#undef htonl -#undef htons +#define ntohl(x) x +#define ntohs(x) x +#define htonl(x) x +#define htons(x) x -#define BIG_ENDIAN -#define BIG_ENDIAN_BITFIELD +/* Some programs depend upon these being around. */ +#define __constant_ntohl(x) x +#define __constant_ntohs(x) x +#define __constant_htonl(x) x +#define __constant_htons(x) x -extern unsigned long int ntohl(unsigned long int); -extern unsigned short int ntohs(unsigned short int); -extern unsigned long int htonl(unsigned long int); -extern unsigned short int htons(unsigned short int); - -extern unsigned long int __ntohl(unsigned long int); -extern unsigned short int __ntohs(unsigned short int); -extern unsigned long int __constant_ntohl(unsigned long int); -extern unsigned short int __constant_ntohs(unsigned short int); - -/* - * The constant and non-constant versions here are the same. - * Maybe I'll come up with an alpha-optimized routine for the - * non-constant ones (the constant ones don't need it: gcc - * will optimize it to the correct constant) - */ - -extern __inline__ unsigned long int -__ntohl(unsigned long int x) -{ - return (((x & 0x000000ffU) << 24) | - ((x & 0x0000ff00U) << 8) | - ((x & 0x00ff0000U) >> 8) | - ((x & 0xff000000U) >> 24)); -} - -extern __inline__ unsigned long int -__constant_ntohl(unsigned long int x) -{ - return (((x & 0x000000ffU) << 24) | - ((x & 0x0000ff00U) << 8) | - ((x & 0x00ff0000U) >> 8) | - ((x & 0xff000000U) >> 24)); -} - -extern __inline__ unsigned short int -__ntohs(unsigned short int x) -{ - return (((x & 0x00ff) << 8) | - ((x & 0xff00) >> 8)); -} - -extern __inline__ unsigned short int -__constant_ntohs(unsigned short int x) -{ - return (((x & 0x00ff) << 8) | - ((x & 0xff00) >> 8)); -} - -#define __htonl(x) __ntohl(x) -#define __htons(x) __ntohs(x) -#define __constant_htonl(x) __constant_ntohl(x) -#define __constant_htons(x) __constant_ntohs(x) +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif -#ifdef __OPTIMIZE__ -# define ntohl(x) \ -(__builtin_constant_p((long)(x)) ? \ - __constant_ntohl((x)) : \ - __ntohl((x))) -# define ntohs(x) \ -(__builtin_constant_p((short)(x)) ? \ - __constant_ntohs((x)) : \ - __ntohs((x))) -# define htonl(x) \ -(__builtin_constant_p((long)(x)) ? \ - __constant_htonl((x)) : \ - __htonl((x))) -# define htons(x) \ -(__builtin_constant_p((short)(x)) ? \ - __constant_htons((x)) : \ - __htons((x))) +#ifndef __BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN_BITFIELD #endif #endif /* !(_SPARC_BYTEORDER_H) */ diff --git a/include/asm-sparc/cache.h b/include/asm-sparc/cache.h new file mode 100644 index 000000000..f537c5cc3 --- /dev/null +++ b/include/asm-sparc/cache.h @@ -0,0 +1,123 @@ +/* $Id: cache.h,v 1.5 1996/08/29 09:48:06 davem Exp $ + * cache.h: Cache specific code for the Sparc. These include flushing + * and direct tag/data line access. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_CACHE_H +#define _SPARC_CACHE_H + +#include <asm/asi.h> + +/* Direct access to the instruction cache is provided through and + * alternate address space. The IDC bit must be off in the ICCR on + * HyperSparcs for these accesses to work. The code below does not do + * any checking, the caller must do so. These routines are for + * diagnostics only, but could end up being useful. Use with care. + * Also, you are asking for trouble if you execute these in one of the + * three instructions following a %asr/%psr access or modification. + */ + +/* First, cache-tag access. */ +extern __inline__ unsigned int get_icache_tag(int setnum, int tagnum) +{ + unsigned int vaddr, retval; + + vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5); + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (vaddr), "i" (ASI_M_TXTC_TAG)); + return retval; +} + +extern __inline__ void put_icache_tag(int setnum, int tagnum, unsigned int entry) +{ + unsigned int vaddr; + + vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5); + __asm__ __volatile__("sta %0, [%1] %2\n\t" : : + "r" (entry), "r" (vaddr), "i" (ASI_M_TXTC_TAG) : + "memory"); +} + +/* Second cache-data access. The data is returned two-32bit quantities + * at a time. + */ +extern __inline__ void get_icache_data(int setnum, int tagnum, int subblock, + unsigned int *data) +{ + unsigned int value1, value2, vaddr; + + vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) | + ((subblock&0x3) << 3); + __asm__ __volatile__("ldda [%2] %3, %%g2\n\t" + "or %%g0, %%g2, %0\n\t" + "or %%g0, %%g3, %1\n\t" : + "=r" (value1), "=r" (value2) : + "r" (vaddr), "i" (ASI_M_TXTC_DATA) : + "g2", "g3"); + data[0] = value1; data[1] = value2; +} + +extern __inline__ void put_icache_data(int setnum, int tagnum, int subblock, + unsigned int *data) +{ + unsigned int value1, value2, vaddr; + + vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) | + ((subblock&0x3) << 3); + value1 = data[0]; value2 = data[1]; + __asm__ __volatile__("or %%g0, %0, %%g2\n\t" + "or %%g0, %1, %%g3\n\t" + "stda %%g2, [%2] %3\n\t" : : + "r" (value1), "r" (value2), + "r" (vaddr), "i" (ASI_M_TXTC_DATA) : + "g2", "g3", "memory" /* no joke */); +} + +/* Different types of flushes with the ICACHE. Some of the flushes + * affect both the ICACHE and the external cache. Others only clear + * the ICACHE entries on the cpu itself. V8's (most) allow + * granularity of flushes on the packet (element in line), whole line, + * and entire cache (ie. all lines) level. The ICACHE only flushes are + * ROSS HyperSparc specific and are in ross.h + */ + +/* Flushes which clear out both the on-chip and external caches */ +extern __inline__ void flush_ei_page(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_PAGE) : + "memory"); +} + +extern __inline__ void flush_ei_seg(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_SEG) : + "memory"); +} + +extern __inline__ void flush_ei_region(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_REGION) : + "memory"); +} + +extern __inline__ void flush_ei_ctx(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_CTX) : + "memory"); +} + +extern __inline__ void flush_ei_user(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_USER) : + "memory"); +} + +#endif /* !(_SPARC_CACHE_H) */ diff --git a/include/asm-sparc/checksum.h b/include/asm-sparc/checksum.h new file mode 100644 index 000000000..a11777025 --- /dev/null +++ b/include/asm-sparc/checksum.h @@ -0,0 +1,163 @@ +/* $Id: checksum.h,v 1.22 1996/11/10 21:28:25 davem Exp $ */ +#ifndef __SPARC_CHECKSUM_H +#define __SPARC_CHECKSUM_H + +/* checksum.h: IP/UDP/TCP checksum routines on the Sparc. + * + * Copyright(C) 1995 Linus Torvalds + * Copyright(C) 1995 Miguel de Icaza + * Copyright(C) 1996 David S. Miller + * Copyright(C) 1996 Eddie C. Dost + * + * derived from: + * Alpha checksum c-code + * ix86 inline assembly + * RFC1071 Computing the Internet Checksum + */ + +/* computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +extern unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum); + +/* the same as csum_partial, but copies from fs:src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +extern unsigned int csum_partial_copy(char *src, char *dst, int len, int sum); + +#define csum_partial_copy_fromuser(s, d, l, w) \ + csum_partial_copy((char *) (s), (d), (l), (w)) + +/* ihl is always 5 or greater, almost always is 5, and iph is word aligned + * the majority of the time. + */ +extern __inline__ unsigned short ip_fast_csum(__const__ unsigned char *iph, + unsigned int ihl) +{ + unsigned short sum; + + /* Note: We must read %2 before we touch %0 for the first time, + * because GCC can legitimately use the same register for + * both operands. + */ + __asm__ __volatile__("sub\t%2, 4, %%g4\n\t" + "ld\t[%1 + 0x00], %0\n\t" + "ld\t[%1 + 0x04], %%g2\n\t" + "ld\t[%1 + 0x08], %%g3\n\t" + "addcc\t%%g2, %0, %0\n\t" + "addxcc\t%%g3, %0, %0\n\t" + "ld\t[%1 + 0x0c], %%g2\n\t" + "ld\t[%1 + 0x10], %%g3\n\t" + "addxcc\t%%g2, %0, %0\n\t" + "addx\t%0, %%g0, %0\n" + "1:\taddcc\t%%g3, %0, %0\n\t" + "add\t%1, 4, %1\n\t" + "addxcc\t%0, %%g0, %0\n\t" + "subcc\t%%g4, 1, %%g4\n\t" + "be,a\t2f\n\t" + "sll\t%0, 16, %%g2\n\t" + "b\t1b\n\t" + "ld\t[%1 + 0x10], %%g3\n" + "2:\taddcc\t%0, %%g2, %%g2\n\t" + "srl\t%%g2, 16, %0\n\t" + "addx\t%0, %%g0, %0\n\t" + "xnor\t%%g0, %0, %0" + : "=r" (sum), "=&r" (iph) + : "r" (ihl), "1" (iph) + : "g2", "g3", "g4"); + return sum; +} + +/* computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +extern __inline__ unsigned short csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned int len, + unsigned short proto, + unsigned int sum) +{ + __asm__ __volatile__("addcc\t%1, %0, %0\n\t" + "addxcc\t%2, %0, %0\n\t" + "addxcc\t%3, %0, %0\n\t" + "addx\t%0, %%g0, %0\n\t" + "sll\t%0, 16, %1\n\t" + "addcc\t%1, %0, %0\n\t" + "srl\t%0, 16, %0\n\t" + "addx\t%0, %%g0, %0\n\t" + "xnor\t%%g0, %0, %0" + : "=r" (sum), "=r" (saddr) + : "r" (daddr), "r" ((proto<<16)+len), "0" (sum), + "1" (saddr)); + return sum; +} + +/* Fold a partial checksum without adding pseudo headers. */ +extern __inline__ unsigned int csum_fold(unsigned int sum) +{ + unsigned int tmp; + + __asm__ __volatile__("addcc\t%0, %1, %1\n\t" + "srl\t%1, 16, %1\n\t" + "addx\t%1, %%g0, %1\n\t" + "xnor\t%%g0, %1, %0" + : "=&r" (sum), "=r" (tmp) + : "0" (sum), "1" (sum<<16)); + return sum; +} + +#define _HAVE_ARCH_IPV6_CSUM + +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int sum) +{ + __asm__ __volatile__ (" + addcc %3, %4, %%g4 + addxcc %5, %%g4, %%g4 + ld [%2 + 0x0c], %%g2 + ld [%2 + 0x08], %%g3 + addxcc %%g2, %%g4, %%g4 + ld [%2 + 0x04], %%g2 + addxcc %%g3, %%g4, %%g4 + ld [%2 + 0x00], %%g3 + addxcc %%g2, %%g4, %%g4 + ld [%1 + 0x0c], %%g2 + addxcc %%g3, %%g4, %%g4 + ld [%1 + 0x08], %%g3 + addxcc %%g2, %%g4, %%g4 + ld [%1 + 0x04], %%g2 + addxcc %%g3, %%g4, %%g4 + ld [%1 + 0x00], %%g3 + addxcc %%g2, %%g4, %%g4 + addxcc %%g3, %%g4, %0 + addx 0, %0, %0 + " + : "=&r" (sum) + : "r" (saddr), "r" (daddr), + "r"(htonl((__u32) (len))), "r"(htonl(proto)), "r"(sum) + : "g2", "g3", "g4"); + + return csum_fold(sum); +} + +/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */ +extern __inline__ unsigned short ip_compute_csum(unsigned char * buff, int len) +{ + return csum_fold(csum_partial(buff, len, 0)); +} + +#endif /* !(__SPARC_CHECKSUM_H) */ diff --git a/include/asm-sparc/clock.h b/include/asm-sparc/clock.h index ce5ce6762..e708e6b50 100644 --- a/include/asm-sparc/clock.h +++ b/include/asm-sparc/clock.h @@ -1,53 +1,11 @@ -/* clock.h: Definitions for the clock/timer chips on the Sparc. +/* $Id: clock.h,v 1.3 1995/11/25 02:31:25 davem Exp $ + * clock.h: Definitions for clock operations on the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ +#ifndef _SPARC_CLOCK_H +#define _SPARC_CLOCK_H -/* Clock timer structures. The interrupt timer has two properties which - * are the counter (which is handled in do_timer in sched.c) and the limit. - * This limit is where the timer's counter 'wraps' around. Oddly enough, - * the sun4c timer when it hits the limit wraps back to 1 and not zero - * thus when calculating the value at which it will fire a microsecond you - * must adjust by one. Thanks SUN for designing such great hardware ;( - */ - -/* Note that I am only going to use the timer that interrupts at - * Sparc IRQ 10. There is another one available that can fire at - * IRQ 14. If I can think of some creative uses for it this may - * change. It might make a nice kernel/user profiler etc. - */ - -struct sparc_timer_info { - unsigned int cur_count10; - unsigned int timer_limit10; - unsigned int cur_count14; - unsigned int timer_limit14; -}; - -struct sparc_clock_info { - unsigned char hsec; - unsigned char hr; - unsigned char min; - unsigned char sec; - unsigned char mon; - unsigned char day; - unsigned char yr; - unsigned char wkday; - unsigned char ram_hsec; - unsigned char ram_hr; - unsigned char ram_min; - unsigned char ram_sec; - unsigned char ram_mon; - unsigned char ram_day; - unsigned char ram_year; - unsigned char ram_wkday; - unsigned char intr_reg; - unsigned char cmd_reg; - unsigned char foo[14]; -}; - -#define TIMER_PHYSADDR 0xf3000000 - -/* YUCK YUCK YUCK, grrr... */ -#define TIMER_STRUCT ((struct sparc_timer_info *)((struct sparc_clock_info *) TIMER_VADDR)) +/* Foo for now. */ +#endif /* !(_SPARC_CLOCK_H) */ diff --git a/include/asm-sparc/contregs.h b/include/asm-sparc/contregs.h index 326e888ff..adf4718a2 100644 --- a/include/asm-sparc/contregs.h +++ b/include/asm-sparc/contregs.h @@ -1,19 +1,50 @@ +/* $Id: contregs.h,v 1.6 1995/11/25 02:31:27 davem Exp $ */ #ifndef _SPARC_CONTREGS_H #define _SPARC_CONTREGS_H /* contregs.h: Addresses of registers in the ASI_CONTROL alternate address - space. These are for the mmu's context register, etc. + * space. These are for the mmu's context register, etc. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ - Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) -*/ +/* 4=sun4 (as in sun4 sysmaint student book), c=sun4c (according to davem) */ -#define AC_CONTEXT 0x30000000 /* current mmu-context, handy for invalidate()'s ;-) */ -#define AC_SENABLE 0x40000000 /* system dvma/cache enable, plus special reset poking */ -#define AC_CACHETAGS 0x80000000 /* direct access to the VAC cache, unused... */ -#define AC_SYNC_ERR 0x60000000 /* what type of synchronous memory error happened */ -#define AC_SYNC_VA 0x60000004 /* what virtual address caused the error to occur */ -#define AC_ASYNC_ERR 0x60000008 /* what type of asynchronous mem-error happened */ -#define AC_ASYNC_VA 0x6000000c /* what virtual address caused the async-err to happen */ -#define AC_CACHEDDATA 0x90000000 /* where the actual VAC cached data sits */ +#define AC_IDPROM 0x00000000 /* 4 ID PROM, R/O, byte, 32 bytes */ +#define AC_CONTEXT 0x30000000 /* 4c current mmu-context */ +#define AC_SENABLE 0x40000000 /* 4c system dvma/cache/reset enable reg */ +#define AC_UDVMA_ENB 0x50000000 /* 4 Not used on Sun boards, byte */ +#define AC_BUS_ERROR 0x60000000 /* 4 Cleared on read, byte. */ +#define AC_SYNC_ERR 0x60000000 /* c fault type */ +#define AC_SYNC_VA 0x60000004 /* c fault virtual address */ +#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */ +#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */ +#define AC_LEDS 0x70000000 /* 4 Zero turns on LEDs, byte */ +#define AC_CACHETAGS 0x80000000 /* 4c direct access to the VAC tags */ +#define AC_CACHEDDATA 0x90000000 /* c direct access to the VAC data */ +#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */ +#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */ +#define AC_BOOT_SCC 0xF0000000 /* 4 bypass to access Zilog 8530. byte. */ + +/* s=Swift, h=Ross_HyperSPARC, v=TI_Viking, t=Tsunami, r=Ross_Cypress */ +#define AC_M_PCR 0x0000 /* shv Processor Control Reg */ +#define AC_M_CTPR 0x0100 /* shv Context Table Pointer Reg */ +#define AC_M_CXR 0x0200 /* shv Context Register */ +#define AC_M_SFSR 0x0300 /* shv Synchronous Fault Status Reg */ +#define AC_M_SFAR 0x0400 /* shv Synchronous Fault Address Reg */ +#define AC_M_AFSR 0x0500 /* hv Asynchronous Fault Status Reg */ +#define AC_M_AFAR 0x0600 /* hv Asynchronous Fault Address Reg */ +#define AC_M_RESET 0x0700 /* hv Reset Reg */ +#define AC_M_RPR 0x1000 /* hv Root Pointer Reg */ +#define AC_M_TSUTRCR 0x1000 /* s TLB Replacement Ctrl Reg */ +#define AC_M_IAPTP 0x1100 /* hv Instruction Access PTP */ +#define AC_M_DAPTP 0x1200 /* hv Data Access PTP */ +#define AC_M_ITR 0x1300 /* hv Index Tag Register */ +#define AC_M_TRCR 0x1400 /* hv TLB Replacement Control Reg */ +#define AC_M_SFSRX 0x1300 /* s Synch Fault Status Reg prim */ +#define AC_M_SFARX 0x1400 /* s Synch Fault Address Reg prim */ +#define AC_M_RPR1 0x1500 /* h Root Pointer Reg (entry 2) */ +#define AC_M_IAPTP1 0x1600 /* h Instruction Access PTP (entry 2) */ +#define AC_M_DAPTP1 0x1700 /* h Data Access PTP (entry 2) */ #endif /* _SPARC_CONTREGS_H */ diff --git a/include/asm-sparc/cprefix.h b/include/asm-sparc/cprefix.h index 439c7c671..61cde329a 100644 --- a/include/asm-sparc/cprefix.h +++ b/include/asm-sparc/cprefix.h @@ -6,15 +6,18 @@ * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ +#ifndef __SPARC_CPREFIX_H +#define __SPARC_CPREFIX_H - -#ifndef __svr4__ -#define C_LABEL_PREFIX _ -#else +#if defined(__svr4__) || defined(__ELF__) #define C_LABEL_PREFIX +#else +#define C_LABEL_PREFIX _ #endif -#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT(a, b) CONCAT2(a, b) #define CONCAT2(a, b) a##b -#define C_LABEL(name) CONCAT1(C_LABEL_PREFIX, name) +#define C_LABEL(name) CONCAT(C_LABEL_PREFIX, name) + +#endif /* !(__SPARC_CPREFIX_H) */ diff --git a/include/asm-sparc/cypress.h b/include/asm-sparc/cypress.h new file mode 100644 index 000000000..fc92fc839 --- /dev/null +++ b/include/asm-sparc/cypress.h @@ -0,0 +1,79 @@ +/* $Id: cypress.h,v 1.6 1996/08/29 09:48:09 davem Exp $ + * cypress.h: Cypress module specific definitions and defines. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_CYPRESS_H +#define _SPARC_CYPRESS_H + +/* Cypress chips have %psr 'impl' of '0001' and 'vers' of '0001'. */ + +/* The MMU control register fields on the Sparc Cypress 604/605 MMU's. + * + * --------------------------------------------------------------- + * |implvers| MCA | MCM |MV| MID |BM| C|RSV|MR|CM|CL|CE|RSV|NF|ME| + * --------------------------------------------------------------- + * 31 24 23-22 21-20 19 18-15 14 13 12 11 10 9 8 7-2 1 0 + * + * MCA: MultiChip Access -- Used for configuration of multiple + * CY7C604/605 cache units. + * MCM: MultiChip Mask -- Again, for multiple cache unit config. + * MV: MultiChip Valid -- Indicates MCM and MCA have valid settings. + * MID: ModuleID -- Unique processor ID for MBus transactions. (605 only) + * BM: Boot Mode -- 0 = not in boot mode, 1 = in boot mode + * C: Cacheable -- Indicates whether accesses are cacheable while + * the MMU is off. 0=no 1=yes + * MR: MemoryReflection -- Indicates whether the bus attached to the + * MBus supports memory reflection. 0=no 1=yes (605 only) + * CM: CacheMode -- Indicates whether the cache is operating in write + * through or copy-back mode. 0=write-through 1=copy-back + * CL: CacheLock -- Indicates if the entire cache is locked or not. + * 0=not-locked 1=locked (604 only) + * CE: CacheEnable -- Is the virtual cache on? 0=no 1=yes + * NF: NoFault -- Do faults generate traps? 0=yes 1=no + * ME: MmuEnable -- Is the MMU doing translations? 0=no 1=yes + */ + +#define CYPRESS_MCA 0x00c00000 +#define CYPRESS_MCM 0x00300000 +#define CYPRESS_MVALID 0x00080000 +#define CYPRESS_MIDMASK 0x00078000 /* Only on 605 */ +#define CYPRESS_BMODE 0x00004000 +#define CYPRESS_ACENABLE 0x00002000 +#define CYPRESS_MRFLCT 0x00000800 /* Only on 605 */ +#define CYPRESS_CMODE 0x00000400 +#define CYPRESS_CLOCK 0x00000200 /* Only on 604 */ +#define CYPRESS_CENABLE 0x00000100 +#define CYPRESS_NFAULT 0x00000002 +#define CYPRESS_MENABLE 0x00000001 + +extern __inline__ void cypress_flush_page(unsigned long page) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (page), "i" (ASI_M_FLUSH_PAGE)); +} + +extern __inline__ void cypress_flush_segment(unsigned long addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_SEG)); +} + +extern __inline__ void cypress_flush_region(unsigned long addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_REGION)); +} + +extern __inline__ void cypress_flush_context(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : + "i" (ASI_M_FLUSH_CTX)); +} + +/* XXX Displacement flushes for buggy chips and initial testing + * XXX go here. + */ + +#endif /* !(_SPARC_CYPRESS_H) */ diff --git a/include/asm-sparc/delay.h b/include/asm-sparc/delay.h index d6c4b360e..71e1154a0 100644 --- a/include/asm-sparc/delay.h +++ b/include/asm-sparc/delay.h @@ -1,40 +1,28 @@ +/* $Id: delay.h,v 1.8 1996/01/28 02:09:21 davem Exp $ + * delay.h: Linux delay routines on the Sparc. + * + * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu). + */ + #ifndef __SPARC_DELAY_H #define __SPARC_DELAY_H extern unsigned long loops_per_sec; -/* - * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu). - * - * Delay quick inlined code using 'loops_per_second' which is - * calculated in calibrate_delay() in main.c (ie. BogoMIPS :-) - */ - -extern __inline__ void __delay(unsigned int loops) +extern __inline__ void __delay(unsigned long loops) { - __asm__ __volatile__("\n1:\tcmp %0, 0\n\t" - "bne,a 1b\n\t" - "sub %0, 1, %0\n": "=&r" (loops) : "0" (loops)); + __asm__ __volatile__("cmp %0, 0\n\t" + "1: bne 1b\n\t" + "subcc %0, 1, %0\n" : + "=&r" (loops) : + "0" (loops)); } -/* udelay(usecs) is used for very short delays up to 1 millisecond. */ - -extern __inline__ void udelay(unsigned int usecs) -{ - usecs *= 0x000010c6; /* Sparc is 32-bit just like ix86 */ - - __asm__("sethi %hi(_loops_per_sec), %o1\n\t" - "ld [%o1 + %lo(_loops_per_sec)], %o1\n\t" - "call ___delay\n\t" - "umul %o1, %o0, %o0\n\t"); -} +/* This is too messy with inline asm on the Sparc. */ +extern void udelay(unsigned long usecs); /* calibrate_delay() wants this... */ - -extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) -{ - return ((a*b)/c); -} +#define muldiv(a, b, c) (((a)*(b))/(c)) #endif /* defined(__SPARC_DELAY_H) */ diff --git a/include/asm-sparc/dma.h b/include/asm-sparc/dma.h index 138e7a445..a86379a71 100644 --- a/include/asm-sparc/dma.h +++ b/include/asm-sparc/dma.h @@ -1,20 +1,209 @@ -/* +/* $Id: dma.h,v 1.22 1996/10/17 05:29:01 davem Exp $ * include/asm-sparc/dma.h * - * Don't even ask, I am figuring out how this crap works - * on the Sparc. It may end up being real hairy to plug - * into this code, maybe not, we'll see. - * - * Copyright (C) David S. Miller (davem@caip.rutgers.edu) + * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu) */ +#ifndef _ASM_SPARC_DMA_H +#define _ASM_SPARC_DMA_H + +#include <linux/kernel.h> + #include <asm/vac-ops.h> /* for invalidate's, etc. */ +#include <asm/sbus.h> +#include <asm/delay.h> +#include <asm/oplib.h> +/* These are irrelevant for Sparc DMA, but we leave it in so that + * things can compile. + */ #define MAX_DMA_CHANNELS 8 -#define MAX_DMA_ADDRESS 0x0 +#define MAX_DMA_ADDRESS (~0UL) +#define DMA_MODE_READ 1 +#define DMA_MODE_WRITE 2 -#ifndef _ASM_SPARC_DMA_H -#define _ASM_SPARC_DMA_H +/* Useful constants */ +#define SIZE_16MB (16*1024*1024) +#define SIZE_64K (64*1024) + +/* Structure to describe the current status of DMA registers on the Sparc */ +struct sparc_dma_registers { + __volatile__ unsigned long cond_reg; /* DMA condition register */ + __volatile__ char * st_addr; /* Start address of this transfer */ + __volatile__ unsigned long cnt; /* How many bytes to transfer */ + __volatile__ unsigned long dma_test; /* DMA test register */ +}; + +/* DVMA chip revisions */ +enum dvma_rev { + dvmarev0, + dvmaesc1, + dvmarev1, + dvmarev2, + dvmarev3, + dvmarevplus, + dvmahme +}; + +#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1) + +/* Linux DMA information structure, filled during probe. */ +struct Linux_SBus_DMA { + struct Linux_SBus_DMA *next; + struct linux_sbus_device *SBus_dev; + struct sparc_dma_registers *regs; + + /* Status, misc info */ + int node; /* Prom node for this DMA device */ + int running; /* Are we doing DMA now? */ + int allocated; /* Are we "owned" by anyone yet? */ + + /* Transfer information. */ + unsigned long addr; /* Start address of current transfer */ + int nbytes; /* Size of current transfer */ + int realbytes; /* For splitting up large transfers, etc. */ + + /* DMA revision */ + enum dvma_rev revision; +}; + +extern struct Linux_SBus_DMA *dma_chain; + +/* Broken hardware... */ +#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1) +#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1) + +/* Main routines in dma.c */ +extern void dump_dma_regs(struct sparc_dma_registers *); +extern unsigned long dvma_init(struct linux_sbus *, unsigned long); + +/* Fields in the cond_reg register */ +/* First, the version identification bits */ +#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */ +#define DMA_VERS0 0x00000000 /* Sunray DMA version */ +#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */ +#define DMA_VERS1 0x80000000 /* DMA rev 1 */ +#define DMA_VERS2 0xa0000000 /* DMA rev 2 */ +#define DMA_VERHME 0xb0000000 /* DMA hme gate array */ +#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */ + +#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */ +#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */ +#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */ +#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */ +#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */ +#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */ +#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */ +#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */ +#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */ +#define DMA_ST_WRITE 0x00000100 /* write from device to memory */ +#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */ +#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */ +#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */ +#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */ +#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */ +#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */ +#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */ +#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */ +#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */ +#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */ +#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */ +#define DMA_E_BURST8 0x00040000 /* ENET: SBUS r/w burst size */ +#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */ +#define DMA_BRST64 0x00080000 /* SCSI: 64byte bursts (HME on UltraSparc only) */ +#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */ +#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */ +#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */ +#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */ +#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */ +#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */ +#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */ +#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */ +#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */ +#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */ +#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */ +#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */ +#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */ + +/* Values describing the burst-size property from the PROM */ +#define DMA_BURST1 0x01 +#define DMA_BURST2 0x02 +#define DMA_BURST4 0x04 +#define DMA_BURST8 0x08 +#define DMA_BURST16 0x10 +#define DMA_BURST32 0x20 +#define DMA_BURST64 0x40 +#define DMA_BURSTBITS 0x7f + +/* Determine highest possible final transfer address given a base */ +#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL)) + +/* Yes, I hack a lot of elisp in my spare time... */ +#define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR)) +#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))) +#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE)) +#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE))) +#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB))) +#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB))) +#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV)) +#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr)) +#define DMA_BEGINDMA_W(regs) \ + ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB)))) +#define DMA_BEGINDMA_R(regs) \ + ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE))))) + +/* For certain DMA chips, we need to disable ints upon irq entry + * and turn them back on when we are done. So in any ESP interrupt + * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT + * when leaving the handler. You have been warned... + */ +#define DMA_IRQ_ENTRY(dma, dregs) do { \ + if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \ + } while (0) + +#define DMA_IRQ_EXIT(dma, dregs) do { \ + if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \ + } while(0) + +/* Pause until counter runs out or BIT isn't set in the DMA condition + * register. + */ +extern __inline__ void sparc_dma_pause(struct sparc_dma_registers *regs, + unsigned long bit) +{ + int ctr = 50000; /* Let's find some bugs ;) */ + + /* Busy wait until the bit is not set any more */ + while((regs->cond_reg&bit) && (ctr>0)) { + ctr--; + __delay(5); + } + + /* Check for bogus outcome. */ + if(!ctr) + panic("DMA timeout"); +} + +/* Reset the friggin' thing... */ +#define DMA_RESET(dma) do { \ + struct sparc_dma_registers *regs = dma->regs; \ + /* Let the current FIFO drain itself */ \ + sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN)); \ + /* Reset the logic */ \ + regs->cond_reg |= (DMA_RST_SCSI); /* assert */ \ + __delay(400); /* let the bits set ;) */ \ + regs->cond_reg &= ~(DMA_RST_SCSI); /* de-assert */ \ + sparc_dma_enable_interrupts(regs); /* Re-enable interrupts */ \ + /* Enable FAST transfers if available */ \ + if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS; \ + dma->running = 0; \ +} while(0) + +#define for_each_dvma(dma) \ + for((dma) = dma_chain; (dma); (dma) = (dma)->next) +extern int get_dma_list(char *); +extern int request_dma(unsigned int, __const__ char *); +extern void free_dma(unsigned int); #endif /* !(_ASM_SPARC_DMA_H) */ diff --git a/include/asm-sparc/ecc.h b/include/asm-sparc/ecc.h new file mode 100644 index 000000000..8e27ceccb --- /dev/null +++ b/include/asm-sparc/ecc.h @@ -0,0 +1,122 @@ +/* $Id: ecc.h,v 1.3 1996/04/25 06:12:57 davem Exp $ + * ecc.h: Definitions and defines for the external cache/memory + * controller on the sun4m. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_ECC_H +#define _SPARC_ECC_H + +/* These registers are accessed through the SRMMU passthrough ASI 0x20 */ +#define ECC_ENABLE 0x00000000 /* ECC enable register */ +#define ECC_FSTATUS 0x00000008 /* ECC fault status register */ +#define ECC_FADDR 0x00000010 /* ECC fault address register */ +#define ECC_DIGNOSTIC 0x00000018 /* ECC diagnostics register */ +#define ECC_MBAENAB 0x00000020 /* MBus arbiter enable register */ +#define ECC_DMESG 0x00001000 /* Diagnostic message passing area */ + +/* ECC MBus Arbiter Enable register: + * + * ---------------------------------------- + * | |SBUS|MOD3|MOD2|MOD1|RSV| + * ---------------------------------------- + * 31 5 4 3 2 1 0 + * + * SBUS: Enable MBus Arbiter on the SBus 0=off 1=on + * MOD3: Enable MBus Arbiter on MBus module 3 0=off 1=on + * MOD2: Enable MBus Arbiter on MBus module 2 0=off 1=on + * MOD1: Enable MBus Arbiter on MBus module 1 0=off 1=on + */ + +#define ECC_MBAE_SBUS 0x00000010 +#define ECC_MBAE_MOD3 0x00000008 +#define ECC_MBAE_MOD2 0x00000004 +#define ECC_MBAE_MOD1 0x00000002 + +/* ECC Fault Control Register layout: + * + * ----------------------------- + * | RESV | ECHECK | EINT | + * ----------------------------- + * 31 2 1 0 + * + * ECHECK: Enable ECC checking. 0=off 1=on + * EINT: Enable Interrupts for correctable errors. 0=off 1=on + */ +#define ECC_FCR_CHECK 0x00000002 +#define ECC_FCR_INTENAB 0x00000001 + +/* ECC Fault Address Register Zero layout: + * + * ----------------------------------------------------- + * | MID | S | RSV | VA | BM |AT| C| SZ |TYP| PADDR | + * ----------------------------------------------------- + * 31-28 27 26-22 21-14 13 12 11 10-8 7-4 3-0 + * + * MID: ModuleID of the faulting processor. ie. who did it? + * S: Supervisor/Privileged access? 0=no 1=yes + * VA: Bits 19-12 of the virtual faulting address, these are the + * superset bits in the virtual cache and can be used for + * a flush operation if necessary. + * BM: Boot mode? 0=no 1=yes This is just like the SRMMU boot + * mode bit. + * AT: Did this fault happen during an atomic instruction? 0=no + * 1=yes. This means either an 'ldstub' or 'swap' instruction + * was in progress (but not finished) when this fault happened. + * This indicated whether the bus was locked when the fault + * occurred. + * C: Did the pte for this access indicate that it was cacheable? + * 0=no 1=yes + * SZ: The size of the transaction. + * TYP: The transaction type. + * PADDR: Bits 35-32 of the physical address for the fault. + */ +#define ECC_FADDR0_MIDMASK 0xf0000000 +#define ECC_FADDR0_S 0x08000000 +#define ECC_FADDR0_VADDR 0x003fc000 +#define ECC_FADDR0_BMODE 0x00002000 +#define ECC_FADDR0_ATOMIC 0x00001000 +#define ECC_FADDR0_CACHE 0x00000800 +#define ECC_FADDR0_SIZE 0x00000700 +#define ECC_FADDR0_TYPE 0x000000f0 +#define ECC_FADDR0_PADDR 0x0000000f + +/* ECC Fault Address Register One layout: + * + * ------------------------------------- + * | Physical Address 31-0 | + * ------------------------------------- + * 31 0 + * + * You get the upper 4 bits of the physical address from the + * PADDR field in ECC Fault Address Zero register. + */ + +/* ECC Fault Status Register layout: + * + * ---------------------------------------------- + * | RESV|C2E|MULT|SYNDROME|DWORD|UNC|TIMEO|BS|C| + * ---------------------------------------------- + * 31-18 17 16 15-8 7-4 3 2 1 0 + * + * C2E: A C2 graphics error occurred. 0=no 1=yes (SS10 only) + * MULT: Multiple errors occurred ;-O 0=no 1=prom_panic(yes) + * SYNDROME: Controller is mentally unstable. + * DWORD: + * UNC: Uncorrectable error. 0=no 1=yes + * TIMEO: Timeout occurred. 0=no 1=yes + * BS: C2 graphics bad slot access. 0=no 1=yes (SS10 only) + * C: Correctable error? 0=no 1=yes + */ + +#define ECC_FSR_C2ERR 0x00020000 +#define ECC_FSR_MULT 0x00010000 +#define ECC_FSR_SYND 0x0000ff00 +#define ECC_FSR_DWORD 0x000000f0 +#define ECC_FSR_UNC 0x00000008 +#define ECC_FSR_TIMEO 0x00000004 +#define ECC_FSR_BADSLOT 0x00000002 +#define ECC_FSR_C 0x00000001 + +#endif /* !(_SPARC_ECC_H) */ diff --git a/include/asm-sparc/eeprom.h b/include/asm-sparc/eeprom.h new file mode 100644 index 000000000..a8ff7496d --- /dev/null +++ b/include/asm-sparc/eeprom.h @@ -0,0 +1,9 @@ +/* $Id: eeprom.h,v 1.3 1995/11/25 02:31:38 davem Exp $ + * eeprom.h: Definitions for the Sun eeprom. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +/* The EEPROM and the Mostek Mk48t02 use the same IO address space + * for their registers/data areas. The IDPROM lives here too. + */ diff --git a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h new file mode 100644 index 000000000..46cd67f37 --- /dev/null +++ b/include/asm-sparc/elf.h @@ -0,0 +1,34 @@ +/* $Id: elf.h,v 1.5 1996/08/08 00:06:13 ecd Exp $ */ +#ifndef __ASMSPARC_ELF_H +#define __ASMSPARC_ELF_H + +/* + * ELF register definitions.. + */ + +#include <asm/ptrace.h> + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef unsigned long elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x) == EM_SPARC) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_ARCH EM_SPARC +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB; + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + + +#endif /* !(__ASMSPARC_ELF_H) */ diff --git a/include/asm-sparc/errno.h b/include/asm-sparc/errno.h new file mode 100644 index 000000000..3348a3833 --- /dev/null +++ b/include/asm-sparc/errno.h @@ -0,0 +1,133 @@ +/* $Id: errno.h,v 1.5 1996/07/13 02:05:13 tridge Exp $ */ +#ifndef _SPARC_ERRNO_H +#define _SPARC_ERRNO_H + +/* These match the SunOS error numbering scheme. */ +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define EINPROGRESS 36 /* Operation now in progress */ +#define EALREADY 37 /* Operation already in progress */ +#define ENOTSOCK 38 /* Socket operation on non-socket */ +#define EDESTADDRREQ 39 /* Destination address required */ +#define EMSGSIZE 40 /* Message too long */ +#define EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 42 /* Protocol not available */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define EOPNOTSUPP 45 /* Op not supported on transport endpoint */ +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Address family not supported by protocol */ +#define EADDRINUSE 48 /* Address already in use */ +#define EADDRNOTAVAIL 49 /* Cannot assign requested address */ +#define ENETDOWN 50 /* Network is down */ +#define ENETUNREACH 51 /* Network is unreachable */ +#define ENETRESET 52 /* Net dropped connection because of reset */ +#define ECONNABORTED 53 /* Software caused connection abort */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOBUFS 55 /* No buffer space available */ +#define EISCONN 56 /* Transport endpoint is already connected */ +#define ENOTCONN 57 /* Transport endpoint is not connected */ +#define ESHUTDOWN 58 /* No send after transport endpoint shutdown */ +#define ETOOMANYREFS 59 /* Too many references: cannot splice */ +#define ETIMEDOUT 60 /* Connection timed out */ +#define ECONNREFUSED 61 /* Connection refused */ +#define ELOOP 62 /* Too many symbolic links encountered */ +#define ENAMETOOLONG 63 /* File name too long */ +#define EHOSTDOWN 64 /* Host is down */ +#define EHOSTUNREACH 65 /* No route to host */ +#define ENOTEMPTY 66 /* Directory not empty */ +#define EPROCLIM 67 /* SUNOS: Too many processes */ +#define EUSERS 68 /* Too many users */ +#define EDQUOT 69 /* Quota exceeded */ +#define ESTALE 70 /* Stale NFS file handle */ +#define EREMOTE 71 /* Object is remote */ +#define ENOSTR 72 /* Device not a stream */ +#define ETIME 73 /* Timer expired */ +#define ENOSR 74 /* Out of streams resources */ +#define ENOMSG 75 /* No message of desired type */ +#define EBADMSG 76 /* Not a data message */ +#define EIDRM 77 /* Identifier removed */ +#define EDEADLK 78 /* Resource deadlock would occur */ +#define ENOLCK 79 /* No record locks available */ +#define ENONET 80 /* Machine is not on the network */ +#define ERREMOTE 81 /* SunOS: Too many lvls of remote in path */ +#define ENOLINK 82 /* Link has been severed */ +#define EADV 83 /* Advertise error */ +#define ESRMNT 84 /* Srmount error */ +#define ECOMM 85 /* Communication error on send */ +#define EPROTO 86 /* Protocol error */ +#define EMULTIHOP 87 /* Multihop attempted */ +#define EDOTDOT 88 /* RFS specific error */ +#define EREMCHG 89 /* Remote address changed */ +#define ENOSYS 90 /* Function not implemented */ + +/* The rest have no SunOS equivalent. */ +#define ESTRPIPE 91 /* Streams pipe error */ +#define EOVERFLOW 92 /* Value too large for defined data type */ +#define EBADFD 93 /* File descriptor in bad state */ +#define ECHRNG 94 /* Channel number out of range */ +#define EL2NSYNC 95 /* Level 2 not synchronized */ +#define EL3HLT 96 /* Level 3 halted */ +#define EL3RST 97 /* Level 3 reset */ +#define ELNRNG 98 /* Link number out of range */ +#define EUNATCH 99 /* Protocol driver not attached */ +#define ENOCSI 100 /* No CSI structure available */ +#define EL2HLT 101 /* Level 2 halted */ +#define EBADE 102 /* Invalid exchange */ +#define EBADR 103 /* Invalid request descriptor */ +#define EXFULL 104 /* Exchange full */ +#define ENOANO 105 /* No anode */ +#define EBADRQC 106 /* Invalid request code */ +#define EBADSLT 107 /* Invalid slot */ +#define EDEADLOCK 108 /* File locking deadlock error */ +#define EBFONT 109 /* Bad font file format */ +#define ELIBEXEC 110 /* Cannot exec a shared library directly */ +#define ENODATA 111 /* No data available */ +#define ELIBBAD 112 /* Accessing a corrupted shared library */ +#define ENOPKG 113 /* Package not installed */ +#define ELIBACC 114 /* Can not access a needed shared library */ +#define ENOTUNIQ 115 /* Name not unique on network */ +#define ERESTART 116 /* Interrupted syscall should be restarted */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EILSEQ 122 /* Illegal byte sequence */ +#define ELIBMAX 123 /* Atmpt to link in too many shared libs */ +#define ELIBSCN 124 /* .lib section in a.out corrupted */ + +#endif diff --git a/include/asm-sparc/fbio.h b/include/asm-sparc/fbio.h new file mode 100644 index 000000000..b7eb21003 --- /dev/null +++ b/include/asm-sparc/fbio.h @@ -0,0 +1,279 @@ +#ifndef __LINUX_FBIO_H +#define __LINUX_FBIO_H + +/* Constants used for fbio SunOS compatibility */ +/* (C) 1996 Miguel de Icaza */ + +/* Frame buffer types */ +#define FBTYPE_NOTYPE -1 +#define FBTYPE_SUN1BW 0 /* mono */ +#define FBTYPE_SUN1COLOR 1 +#define FBTYPE_SUN2BW 2 +#define FBTYPE_SUN2COLOR 3 +#define FBTYPE_SUN2GP 4 +#define FBTYPE_SUN5COLOR 5 +#define FBTYPE_SUN3COLOR 6 +#define FBTYPE_MEMCOLOR 7 +#define FBTYPE_SUN4COLOR 8 + +#define FBTYPE_NOTSUN1 9 +#define FBTYPE_NOTSUN2 10 +#define FBTYPE_NOTSUN3 11 + +#define FBTYPE_SUNFAST_COLOR 12 /* cg6 */ +#define FBTYPE_SUNROP_COLOR 13 +#define FBTYPE_SUNFB_VIDEO 14 +#define FBTYPE_SUNGIFB 15 +#define FBTYPE_SUNGPLAS 16 +#define FBTYPE_SUNGP3 17 +#define FBTYPE_SUNGT 18 +#define FBTYPE_SUNLEO 19 /* zx Leo card */ +#define FBTYPE_MDICOLOR 20 /* cg14 */ +#define FBTYPE_TCXCOLOR 21 /* SUNW,tcx card */ + +#define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */ + +/* fbio ioctls */ +/* Returned by FBIOGTYPE */ +struct fbtype { + int fb_type; /* fb type, see above */ + int fb_height; /* pixels */ + int fb_width; /* pixels */ + int fb_depth; + int fb_cmsize; /* color map entries */ + int fb_size; /* fb size in bytes */ +}; +#define FBIOGTYPE _IOR('F', 0, struct fbtype) + +/* Used by FBIOPUTCMAP */ +struct fbcmap { + int index; /* first element (0 origin) */ + int count; + unsigned char *red; + unsigned char *green; + unsigned char *blue; +}; + +#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap) +#define FBIOGETCMAP _IOW('F', 4, struct fbcmap) + +/* # of device specific values */ +#define FB_ATTR_NDEVSPECIFIC 8 +/* # of possible emulations */ +#define FB_ATTR_NEMUTYPES 4 + +struct fbsattr { + int flags; + int emu_type; /* -1 if none */ + int dev_specific[FB_ATTR_NDEVSPECIFIC]; +}; + +struct fbgattr { + int real_type; /* real frame buffer type */ + int owner; /* unknown */ + struct fbtype fbtype; /* real frame buffer fbtype */ + struct fbsattr sattr; + int emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */ +}; +#define FBIOSATTR _IOW('F', 5, struct fbgattr) /* Unsupported: */ +#define FBIOGATTR _IOR('F', 6, struct fbgattr) /* supported */ + +#define FBIOSVIDEO _IOW('F', 7, int) +#define FBIOGVIDEO _IOR('F', 8, int) + +/* Cursor position */ +struct fbcurpos { +#ifdef __KERNEL__ + short fbx, fby; +#else + short x, y; +#endif +}; + +/* Cursor operations */ +#define FB_CUR_SETCUR 0x01 /* Enable/disable cursor display */ +#define FB_CUR_SETPOS 0x02 /* set cursor position */ +#define FB_CUR_SETHOT 0x04 /* set cursor hotspot */ +#define FB_CUR_SETCMAP 0x08 /* set color map for the cursor */ +#define FB_CUR_SETSHAPE 0x10 /* set shape */ +#define FB_CUR_SETALL 0x1F /* all of the above */ + +struct fbcursor { + short set; /* what to set, choose from the list above */ + short enable; /* cursor on/off */ + struct fbcurpos pos; /* cursor position */ + struct fbcurpos hot; /* cursor hot spot */ + struct fbcmap cmap; /* color map info */ + struct fbcurpos size; /* cursor bit map size */ + char *image; /* cursor image bits */ + char *mask; /* cursor mask bits */ +}; + +/* set/get cursor attributes/shape */ +#define FBIOSCURSOR _IOW('F', 24, struct fbcursor) +#define FBIOGCURSOR _IOWR('F', 25, struct fbcursor) + +/* set/get cursor position */ +#define FBIOSCURPOS _IOW('F', 26, struct fbcurpos) +#define FBIOGCURPOS _IOW('F', 27, struct fbcurpos) + +/* get max cursor size */ +#define FBIOGCURMAX _IOR('F', 28, struct fbcurpos) + +/* wid manipulation */ +struct fb_wid_alloc { +#define FB_WID_SHARED_8 0 +#define FB_WID_SHARED_24 1 +#define FB_WID_DBL_8 2 +#define FB_WID_DBL_24 3 + __u32 wa_type; + __s32 wa_index; /* Set on return */ + __u32 wa_count; +}; +struct fb_wid_item { + __u32 wi_type; + __s32 wi_index; + __u32 wi_attrs; + __u32 wi_values[32]; +}; +struct fb_wid_list { + __u32 wl_flags; + __u32 wl_count; + struct fb_wid_item *wl_list; +}; + +#define FBIO_WID_ALLOC _IOWR('F', 30, struct fb_wid_alloc) +#define FBIO_WID_FREE _IOW('F', 31, struct fb_wid_alloc) +#define FBIO_WID_PUT _IOW('F', 32, struct fb_wid_list) +#define FBIO_WID_GET _IOWR('F', 33, struct fb_wid_list) + +/* Cg14 ioctls */ +#define MDI_IOCTL ('M'<<8) +#define MDI_RESET (MDI_IOCTL|1) +#define MDI_GET_CFGINFO (MDI_IOCTL|2) +#define MDI_SET_PIXELMODE (MDI_IOCTL|3) +# define MDI_32_PIX 32 +# define MDI_16_PIX 16 +# define MDI_8_PIX 8 + +struct mdi_cfginfo { + int mdi_ncluts; /* Number of implemented CLUTs in this MDI */ + int mdi_type; /* FBTYPE name */ + int mdi_height; /* height */ + int mdi_width; /* widht */ + int mdi_size; /* available ram */ + int mdi_mode; /* 8bpp, 16bpp or 32bpp */ + int mdi_pixfreq; /* pixel clock (from PROM) */ +}; + +/* SparcLinux specific ioctl for the MDI, should be replaced for + * the SET_XLUT/SET_CLUTn ioctls instead + */ +#define MDI_CLEAR_XLUT (MDI_IOCTL|9) + +/* leo ioctls */ +struct leo_clut_alloc { + __u32 clutid; /* Set on return */ + __u32 flag; + __u32 index; +}; + +struct leo_clut { +#define LEO_CLUT_WAIT 0x00000001 /* Not yet implemented */ + __u32 flag; + __u32 clutid; + __u32 offset; + __u32 count; + char * red; + char * green; + char * blue; +}; +#define LEO_CLUTALLOC _IOWR('L', 53, struct leo_clut_alloc) +#define LEO_CLUTFREE _IOW('L', 54, struct leo_clut_alloc) +#define LEO_CLUTREAD _IOW('L', 55, struct leo_clut) +#define LEO_CLUTPOST _IOW('L', 56, struct leo_clut) +#define LEO_SETGAMMA _IOW('L', 68, int) /* Not yet implemented */ +#define LEO_GETGAMMA _IOR('L', 69, int) /* Not yet implemented */ + +#ifdef __KERNEL__ +/* Addresses on the fd of a cgsix that are mappable */ +#define CG6_FBC 0x70000000 +#define CG6_TEC 0x70001000 +#define CG6_BTREGS 0x70002000 +#define CG6_FHC 0x70004000 +#define CG6_THC 0x70005000 +#define CG6_ROM 0x70006000 +#define CG6_RAM 0x70016000 +#define CG6_DHC 0x80000000 + +#define CG3_MMAP_OFFSET 0x4000000 + +/* Addresses on the fd of a tcx that are mappable */ +#define TCX_RAM8BIT 0x00000000 +#define TCX_RAM24BIT 0x01000000 +#define TCX_UNK3 0x10000000 +#define TCX_UNK4 0x20000000 +#define TCX_CONTROLPLANE 0x28000000 +#define TCX_UNK6 0x30000000 +#define TCX_UNK7 0x38000000 +#define TCX_TEC 0x70000000 +#define TCX_BTREGS 0x70002000 +#define TCX_THC 0x70004000 +#define TCX_DHC 0x70008000 +#define TCX_ALT 0x7000a000 +#define TCX_SYNC 0x7000e000 +#define TCX_UNK2 0x70010000 + +/* CG14 definitions */ + +/* Offsets into the OBIO space: */ +#define CG14_REGS 0 /* registers */ +#define CG14_CURSORREGS 0x1000 /* cursor registers */ +#define CG14_DACREGS 0x2000 /* DAC registers */ +#define CG14_XLUT 0x3000 /* X Look Up Table -- ??? */ +#define CG14_CLUT1 0x4000 /* Color Look Up Table */ +#define CG14_CLUT2 0x5000 /* Color Look Up Table */ +#define CG14_CLUT3 0x6000 /* Color Look Up Table */ +#define CG14_AUTO 0xf000 + +#endif /* KERNEL */ + +/* These are exported to userland for applications to use */ +/* Mappable offsets for the cg14: control registers */ +#define MDI_DIRECT_MAP 0x10000000 +#define MDI_CTLREG_MAP 0x20000000 +#define MDI_CURSOR_MAP 0x30000000 +#define MDI_SHDW_VRT_MAP 0x40000000 + +/* Mappable offsets for the cg14: frame buffer resolutions */ +/* 32 bits */ +#define MDI_CHUNKY_XBGR_MAP 0x50000000 +#define MDI_CHUNKY_BGR_MAP 0x60000000 + +/* 16 bits */ +#define MDI_PLANAR_X16_MAP 0x70000000 +#define MDI_PLANAR_C16_MAP 0x80000000 + +/* 8 bit is done as CG3 MMAP offset */ +/* 32 bits, planar */ +#define MDI_PLANAR_X32_MAP 0x90000000 +#define MDI_PLANAR_B32_MAP 0xa0000000 +#define MDI_PLANAR_G32_MAP 0xb0000000 +#define MDI_PLANAR_R32_MAP 0xc0000000 + +/* Mappable offsets on leo */ +#define LEO_SS0_MAP 0x00000000 +#define LEO_LC_SS0_USR_MAP 0x00800000 +#define LEO_LD_SS0_MAP 0x00801000 +#define LEO_LX_CURSOR_MAP 0x00802000 +#define LEO_SS1_MAP 0x00803000 +#define LEO_LC_SS1_USR_MAP 0x01003000 +#define LEO_LD_SS1_MAP 0x01004000 +#define LEO_UNK_MAP 0x01005000 +#define LEO_LX_KRN_MAP 0x01006000 +#define LEO_LC_SS0_KRN_MAP 0x01007000 +#define LEO_LC_SS1_KRN_MAP 0x01008000 +#define LEO_LD_GBL_MAP 0x01009000 +#define LEO_UNK2_MAP 0x0100a000 + +#endif /* __LINUX_FBIO_H */ diff --git a/include/asm-sparc/fcntl.h b/include/asm-sparc/fcntl.h new file mode 100644 index 000000000..792e29b56 --- /dev/null +++ b/include/asm-sparc/fcntl.h @@ -0,0 +1,60 @@ +/* $Id: fcntl.h,v 1.8 1996/10/27 08:55:26 davem Exp $ */ +#ifndef _SPARC_FCNTL_H +#define _SPARC_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_RDONLY 0x0000 +#define O_WRONLY 0x0001 +#define O_RDWR 0x0002 +#define O_ACCMODE 0x0003 +#define O_NDELAY 0x0004 +#define O_APPEND 0x0008 +#define FASYNC 0x0040 /* fcntl, for BSD compatibility */ +#define O_CREAT 0x0200 /* not fcntl */ +#define O_TRUNC 0x0400 /* not fcntl */ +#define O_EXCL 0x0800 /* not fcntl */ +#define O_SYNC 0x2000 +#define O_NONBLOCK 0x4000 +#define O_NOCTTY 0x8000 /* not fcntl */ + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get f_flags */ +#define F_SETFD 2 /* set f_flags */ +#define F_GETFL 3 /* more flags (cloexec) */ +#define F_SETFL 4 +#define F_GETOWN 5 /* for sockets. */ +#define F_SETOWN 6 /* for sockets. */ +#define F_GETLK 7 +#define F_SETLK 8 +#define F_SETLKW 9 + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 1 +#define F_WRLCK 2 +#define F_UNLCK 3 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; + short __unused; +}; + +#endif diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h new file mode 100644 index 000000000..3ccc79766 --- /dev/null +++ b/include/asm-sparc/floppy.h @@ -0,0 +1,359 @@ +/* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __ASM_SPARC_FLOPPY_H +#define __ASM_SPARC_FLOPPY_H + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/idprom.h> +#include <asm/machines.h> +#include <asm/oplib.h> +#include <asm/auxio.h> +#include <asm/irq.h> + +/* References: + * 1) Netbsd Sun floppy driver. + * 2) NCR 82077 controller manual + * 3) Intel 82077 controller manual + */ +struct sun_flpy_controller { + volatile unsigned char status_82072; /* Main Status reg. */ +#define dcr_82072 status_82072 /* Digital Control reg. */ +#define status1_82077 status_82072 /* Auxiliary Status reg. 1 */ + + volatile unsigned char data_82072; /* Data fifo. */ +#define status2_82077 data_82072 /* Auxiliary Status reg. 2 */ + + volatile unsigned char dor_82077; /* Digital Output reg. */ + volatile unsigned char tapectl_82077; /* What the? Tape control reg? */ + + volatile unsigned char status_82077; /* Main Status Register. */ +#define drs_82077 status_82077 /* Digital Rate Select reg. */ + + volatile unsigned char data_82077; /* Data fifo. */ + volatile unsigned char ___unused; + volatile unsigned char dir_82077; /* Digital Input reg. */ +#define dcr_82077 dir_82077 /* Config Control reg. */ +}; + +/* You'll only ever find one controller on a SparcStation anyways. */ +static struct sun_flpy_controller *sun_fdc = NULL; +volatile unsigned char *fdc_status; + +struct sun_floppy_ops { + unsigned char (*fd_inb)(int port); + void (*fd_outb)(unsigned char value, int port); +}; + +static struct sun_floppy_ops sun_fdops; + +#define fd_inb(port) sun_fdops.fd_inb(port) +#define fd_outb(value,port) sun_fdops.fd_outb(value,port) +#define fd_enable_dma() sun_fd_enable_dma() +#define fd_disable_dma() sun_fd_disable_dma() +#define fd_request_dma() (0) /* nothing... */ +#define fd_free_dma() /* nothing... */ +#define fd_clear_dma_ff() /* nothing... */ +#define fd_set_dma_mode(mode) sun_fd_set_dma_mode(mode) +#define fd_set_dma_addr(addr) sun_fd_set_dma_addr(addr) +#define fd_set_dma_count(count) sun_fd_set_dma_count(count) +#define fd_enable_irq() /* nothing... */ +#define fd_disable_irq() /* nothing... */ +#define fd_cacheflush(addr, size) /* nothing... */ +#define fd_request_irq() sun_fd_request_irq() +#define fd_free_irq() /* nothing... */ +#if 0 /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */ +#define fd_dma_mem_alloc(size) ((unsigned long) vmalloc(size)) +#define fd_dma_mem_free(addr,size) (vfree((void *)(addr))) +#endif + +#define FLOPPY_MOTOR_MASK 0x10 + +/* It's all the same... */ +#define virt_to_bus(x) (x) +#define bus_to_virt(x) (x) + +/* XXX This isn't really correct. XXX */ +#define get_dma_residue(x) (0) + +#define FLOPPY0_TYPE 4 +#define FLOPPY1_TYPE 0 + +/* Super paranoid... */ +#undef HAVE_DISABLE_HLT + +/* Here is where we catch the floppy driver trying to initialize, + * therefore this is where we call the PROM device tree probing + * routine etc. on the Sparc. + */ +#define FDC1 sun_floppy_init() + +static int FDC2=-1; + +#define N_FDC 1 +#define N_DRIVE 8 + +/* No 64k boundary crossing problems on the Sparc. */ +#define CROSS_64KB(a,s) (0) + +/* Routines unique to each controller type on a Sun. */ +static unsigned char sun_82072_fd_inb(int port) +{ + switch(port & 7) { + default: + printk("floppy: Asked to read unknown port %d\n", port); + panic("floppy: Port bolixed."); + case 4: /* FD_STATUS */ + return sun_fdc->status_82072 & ~STATUS_DMA; + case 5: /* FD_DATA */ + return sun_fdc->data_82072; + case 7: /* FD_DIR */ + return (*AUXREG & AUXIO_FLPY_DCHG)? 0x80: 0; + }; + panic("sun_82072_fd_inb: How did I get here?"); +} + +static void sun_82072_fd_outb(unsigned char value, int port) +{ + switch(port & 7) { + default: + printk("floppy: Asked to write to unknown port %d\n", port); + panic("floppy: Port bolixed."); + case 2: /* FD_DOR */ + /* Oh geese, 82072 on the Sun has no DOR register, + * the functionality is implemented via the AUXIO + * I/O register. So we must emulate the behavior. + * + * ASSUMPTIONS: There will only ever be one floppy + * drive attached to a Sun controller + * and it will be at drive zero. + */ + { + unsigned bits = 0; + if (value & 0x10) bits |= AUXIO_FLPY_DSEL; + if ((value & 0x80) == 0) bits |= AUXIO_FLPY_EJCT; + set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT)); + } + break; + case 5: /* FD_DATA */ + sun_fdc->data_82072 = value; + break; + case 7: /* FD_DCR */ + sun_fdc->dcr_82072 = value; + break; + case 4: /* FD_STATUS */ + sun_fdc->status_82072 = value; + break; + }; + return; +} + +static unsigned char sun_82077_fd_inb(int port) +{ + switch(port & 7) { + default: + printk("floppy: Asked to read unknown port %d\n", port); + panic("floppy: Port bolixed."); + case 4: /* FD_STATUS */ + return sun_fdc->status_82077 & ~STATUS_DMA; + case 5: /* FD_DATA */ + return sun_fdc->data_82077; + case 7: /* FD_DIR */ + /* XXX: Is DCL on 0x80 in sun4m? */ + return sun_fdc->dir_82077; + }; + panic("sun_82072_fd_inb: How did I get here?"); +} + +static void sun_82077_fd_outb(unsigned char value, int port) +{ + switch(port & 7) { + default: + printk("floppy: Asked to write to unknown port %d\n", port); + panic("floppy: Port bolixed."); + case 2: /* FD_DOR */ + /* Happily, the 82077 has a real DOR register. */ + sun_fdc->dor_82077 = value; + break; + case 5: /* FD_DATA */ + sun_fdc->data_82077 = value; + break; + case 7: /* FD_DCR */ + sun_fdc->dcr_82077 = value; + break; + case 4: /* FD_STATUS */ + sun_fdc->status_82077 = value; + break; + }; + return; +} + +/* For pseudo-dma (Sun floppy drives have no real DMA available to + * them so we must eat the data fifo bytes directly ourselves) we have + * three state variables. doing_pdma tells our inline low-level + * assembly floppy interrupt entry point whether it should sit and eat + * bytes from the fifo or just transfer control up to the higher level + * floppy interrupt c-code. I tried very hard but I could not get the + * pseudo-dma to work in c-code without getting many overruns and + * underruns. If non-zero, doing_pdma encodes the direction of + * the transfer for debugging. 1=read 2=write + */ +char *pdma_vaddr; +unsigned long pdma_size; +volatile int doing_pdma = 0; + +/* This is software state */ +char *pdma_base = 0; +unsigned long pdma_areasize; + +/* Common routines to all controller types on the Sparc. */ +static __inline__ void virtual_dma_init(void) +{ + /* nothing... */ +} + +static __inline__ void sun_fd_disable_dma(void) +{ + doing_pdma = 0; + if (pdma_base) { + mmu_unlockarea(pdma_base, pdma_areasize); + pdma_base = 0; + } +} + +static __inline__ void sun_fd_set_dma_mode(int mode) +{ + switch(mode) { + case DMA_MODE_READ: + doing_pdma = 1; + break; + case DMA_MODE_WRITE: + doing_pdma = 2; + break; + default: + printk("Unknown dma mode %d\n", mode); + panic("floppy: Giving up..."); + } +} + +static __inline__ void sun_fd_set_dma_addr(char *buffer) +{ + pdma_vaddr = buffer; +} + +static __inline__ void sun_fd_set_dma_count(int length) +{ + pdma_size = length; +} + +static __inline__ void sun_fd_enable_dma(void) +{ + pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size); + pdma_base = pdma_vaddr; + pdma_areasize = pdma_size; +} + +/* Our low-level entry point in arch/sparc/kernel/entry.S */ +extern void floppy_hardint(int irq, void *unused, struct pt_regs *regs); + +static int sun_fd_request_irq(void) +{ + static int once = 0; + int error; + + if(!once) { + once = 1; + error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, SA_INTERRUPT, "floppy"); + return ((error == 0) ? 0 : -1); + } else return 0; +} + +static struct linux_prom_registers fd_regs[2]; + +static int sun_floppy_init(void) +{ + char state[128]; + int tnode, fd_node, num_regs; + + use_virtual_dma = 1; + + FLOPPY_IRQ = 11; + /* Forget it if we aren't on a machine that could possibly + * ever have a floppy drive. + */ + if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) || + ((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) || + (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) { + /* We certainly don't have a floppy controller. */ + goto no_sun_fdc; + } + /* Well, try to find one. */ + tnode = prom_getchild(prom_root_node); + fd_node = prom_searchsiblings(tnode, "obio"); + if(fd_node != 0) { + tnode = prom_getchild(fd_node); + fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo"); + } else { + fd_node = prom_searchsiblings(tnode, "fd"); + } + if(fd_node == 0) { + goto no_sun_fdc; + } + + /* The sun4m lets us know if the controller is actually usable. */ + if(sparc_cpu_model == sun4m) { + prom_getproperty(fd_node, "status", state, sizeof(state)); + if(!strcmp(state, "disabled")) { + goto no_sun_fdc; + } + } + num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs)); + num_regs = (num_regs / sizeof(fd_regs[0])); + prom_apply_obio_ranges(fd_regs, num_regs); + sun_fdc = (struct sun_flpy_controller *) sparc_alloc_io(fd_regs[0].phys_addr, + 0x0, + fd_regs[0].reg_size, + "floppy", + fd_regs[0].which_io, + 0x0); + /* Last minute sanity check... */ + if(sun_fdc->status_82072 == 0xff) { + sun_fdc = NULL; + goto no_sun_fdc; + } + + if(sparc_cpu_model == sun4c) { + sun_fdops.fd_inb = sun_82072_fd_inb; + sun_fdops.fd_outb = sun_82072_fd_outb; + fdc_status = &sun_fdc->status_82072; + /* printk("AUXIO @0x%p\n", auxio_register); */ /* P3 */ + } else { + sun_fdops.fd_inb = sun_82077_fd_inb; + sun_fdops.fd_outb = sun_82077_fd_outb; + fdc_status = &sun_fdc->status_82077; + /* printk("DOR @0x%p\n", &sun_fdc->dor_82077); */ /* P3 */ + } + + /* Success... */ + return (int) sun_fdc; + +no_sun_fdc: + return -1; +} + +static int sparc_eject(void) +{ + set_dor(0x00, 0xff, 0x90); + udelay(500); + set_dor(0x00, 0x6f, 0x00); + udelay(500); + return 0; +} + +#define fd_eject(drive) sparc_eject() + +#endif /* !(__ASM_SPARC_FLOPPY_H) */ diff --git a/include/asm-sparc/head.h b/include/asm-sparc/head.h index b26067623..f89e41fc8 100644 --- a/include/asm-sparc/head.h +++ b/include/asm-sparc/head.h @@ -1,75 +1,114 @@ +/* $Id: head.h,v 1.30 1996/07/29 21:00:28 miguel Exp $ */ #ifndef __SPARC_HEAD_H #define __SPARC_HEAD_H -#define KERNSIZE 134217728 /* this is how much of a mapping the prom promises */ -#define PAGESIZE 4096 /* luckily this is the same on sun4c's and sun4m's */ -#define PAGESHIFT 12 -#define PROM_BASE -1568768 /* casa 'de PROM */ -#define LOAD_ADDR 0x4000 /* prom jumps to us here */ -#define C_STACK 96 +#define KERNBASE 0xf0000000 /* First address the kernel will eventually be */ +#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */ #define SUN4C_SEGSZ (1 << 18) -#define USRSTACK 0x0 /* no joke, this is temporary, trust me */ -#define INT_ENABLE_REG_PHYSADR 0xf5000000 -#define INTS_ENAB 0x01 +#define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2) /* Used in boot remapping. */ +#define INTS_ENAB 0x01 /* entry.S uses this. */ -#define BOOT_MSG_LEN 61 -#define BOOT_MSG2_LEN 50 +#define NCPUS 4 /* Architectural limit of sun4m. */ +#define SUN4_PROM_VECTOR 0xFFE81000 /* To safely die on a SUN4 */ +#define SUN4_PRINTF 0x84 /* Offset into SUN4_PROM_VECTOR */ -#define WRITE_PAUSE nop; nop; nop; - -#define PAGE_SIZE 4096 +#define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */ +#define NOP_INSN 0x01000000 /* Used to patch sparc_save_state */ /* Here are some trap goodies */ - /* Generic trap entry. */ - #define TRAP_ENTRY(type, label) \ - mov (type), %l3; b label; rd %psr, %l0; nop; + rd %psr, %l0; b label; rd %wim, %l3; nop; + +/* Data/text faults. Defaults to sun4c version at boot time. */ +#define SPARC_TFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 1, %l7; +#define SPARC_DFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 0, %l7; +#define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b C_LABEL(srmmu_fault); mov 1, %l7; +#define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b C_LABEL(srmmu_fault); mov 0, %l7; + +/* This is for traps we should NEVER get. */ +#define BAD_TRAP(num) \ + rd %psr, %l0; mov num, %l7; b bad_trap_handler; rd %wim, %l3; + +/* Notice that for the system calls we pull a trick. We load up a + * different pointer to the system call vector table in %l7, but call + * the same generic system call low-level entry point. The trap table + * entry sequences are also HyperSparc pipeline friendly ;-) + */ + +/* Software trap for Linux system calls. */ +#define LINUX_SYSCALL_TRAP \ + sethi %hi(C_LABEL(sys_call_table)), %l7; \ + or %l7, %lo(C_LABEL(sys_call_table)), %l7; \ + b linux_sparc_syscall; \ + rd %psr, %l0; + +/* Software trap for SunOS4.1.x system calls. */ +#define SUNOS_SYSCALL_TRAP \ + rd %psr, %l0; \ + sethi %hi(C_LABEL(sunos_sys_table)), %l7; \ + b linux_sparc_syscall; \ + or %l7, %lo(C_LABEL(sunos_sys_table)), %l7; + +/* Software trap for Slowaris system calls. */ +#define SOLARIS_SYSCALL_TRAP \ + sethi %hi(C_LABEL(sys_call_table)), %l7; \ + or %l7, %lo(C_LABEL(sys_call_table)), %l7; \ + b solaris_syscall; \ + rd %psr, %l0; + +#define INDIRECT_SOLARIS_SYSCALL(x) \ + sethi %hi(C_LABEL(sys_call_table)), %l7; \ + or %g0,%lo(x),%g1; \ + b solaris_indirect_syscall; \ + rd %psr, %l0; + +#define BREAKPOINT_TRAP \ + b breakpoint_trap; \ + rd %psr,%l0; \ + nop; \ + nop; + +/* Software trap for Sparc-netbsd system calls. */ +#define NETBSD_SYSCALL_TRAP \ + sethi %hi(C_LABEL(sys_call_table)), %l7; \ + or %l7, %lo(C_LABEL(sys_call_table)), %l7; \ + b bsd_syscall; \ + rd %psr, %l0; + +/* The Get Condition Codes software trap for userland. */ +#define GETCC_TRAP \ + b getcc_trap_handler; mov %psr, %l0; nop; nop; + +/* The Set Condition Codes software trap for userland. */ +#define SETCC_TRAP \ + b setcc_trap_handler; mov %psr, %l0; nop; nop; /* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and * gets handled with another macro. */ - #define TRAP_ENTRY_INTERRUPT(int_level) \ - mov int_level, %l3; b stray_irq_entry; rd %psr, %l0; nop; - -/* Here is the macro for soft interrupts (ie. not as urgent as hard ones) - * which need to jump to a different handler. + mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3; + +/* NMI's (Non Maskable Interrupts) are special, you can't keep them + * from coming in, and basically if you get one, the shows over. ;( + * On the sun4c they are usually asynchronous memory errors, on the + * the sun4m they could be either due to mem errors or a software + * initiated interrupt from the prom/kern on an SMP box saying "I + * command you to do CPU tricks, read your mailbox for more info." */ +#define NMI_TRAP \ + rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop; -#define TRAP_ENTRY_INTERRUPT_SOFT(int_level, ident) \ - mov int_level, %l3; rd %psr, %l0; b stray_irq_entry; mov ident, %l4; - -/* The above two macros are for generic traps. The following is made - * especially for timer interrupts at IRQ level 14. - */ - -#define TRAP_ENTRY_TIMER \ - mov 10, %l3; rd %psr, %l0; b sparc_timer; nop; - -/* Non-maskable interrupt entry macro. You have to turn off all interrupts - * to not receive this. This is usually due to a asynchronous memory error. - * All we can really do is stop the show. :-( - */ - -#define TRAP_ENTRY_INTERRUPT_NMI(t_type, jmp_to) \ - mov t_type, %l3; b jmp_to; rd %psr, %l0; nop; - -/* Trap entry code in entry.S needs the offsets into task_struct - * to get at the thread_struct goodies during window craziness. - * - * NOTE: We need to keep these values under 0x3ff in order to do - * efficient load/stores in the window fill/spill handlers. - * See TRAP_WIN_CLEAN in entry.S for details. +/* Window overflows/underflows are special and we need to try to be as + * efficient as possible here.... */ +#define WINDOW_SPILL \ + rd %psr, %l0; rd %wim, %l3; b spill_window_entry; andcc %l0, PSR_PS, %g0; -#define THREAD_UWINDOWS 0x3bc -#define THREAD_WIM 0x3c0 -#define THREAD_W_SAVED 0x3c4 -#define THREAD_KSP 0x3c8 -#define THREAD_USP 0x3cc -#define THREAD_REG_WINDOW 0x3d4 +#define WINDOW_FILL \ + rd %psr, %l0; rd %wim, %l3; b fill_window_entry; andcc %l0, PSR_PS, %g0; #endif __SPARC_HEAD_H diff --git a/include/asm-sparc/idprom.h b/include/asm-sparc/idprom.h index e7a136891..d856e640a 100644 --- a/include/asm-sparc/idprom.h +++ b/include/asm-sparc/idprom.h @@ -1,21 +1,33 @@ -/* idprom.h: Macros and defines for idprom routines +/* $Id: idprom.h,v 1.6 1996/08/04 10:35:07 ecd Exp $ + * idprom.h: Macros and defines for idprom routines * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ -extern struct linux_romvec *romvec; +#ifndef _SPARC_IDPROM_H +#define _SPARC_IDPROM_H -#define IDPROM_ADDR (0xffd04000 + 0x7d8) -#define IDPROM_SIZE 36 +/* Offset into the EEPROM where the id PROM is located on the 4c */ +#define IDPROM_OFFSET 0x7d8 -struct idp_struct +/* On sun4m; physical. */ +/* MicroSPARC(-II) does not decode 31rd bit, but it works. */ +#define IDPROM_OFFSET_M 0xfd8 + +struct idprom { - unsigned char id_f_id; /* format identifier */ - unsigned char id_machtype; /* Machine type */ - unsigned char id_eaddr[6]; /* hardware ethernet address */ - long id_domf; /* Date when this machine was manufactured */ - unsigned int id_sernum:24; /* Unique serial number */ - unsigned char id_cksum; /* XXX */ - unsigned char dummy[16]; /* XXX */ + unsigned char id_format; /* Format identifier (always 0x01) */ + unsigned char id_machtype; /* Machine type */ + unsigned char id_ethaddr[6]; /* Hardware ethernet address */ + long id_date; /* Date of manufacture */ + unsigned int id_sernum:24; /* Unique serial number */ + unsigned char id_cksum; /* Checksum - xor of the data bytes */ + unsigned char reserved[16]; }; +extern struct idprom *idprom; +extern void idprom_init(void); + +#define IDPROM_SIZE (sizeof(struct idprom)) + +#endif /* !(_SPARC_IDPROM_H) */ diff --git a/include/asm-sparc/io.h b/include/asm-sparc/io.h index 5aa1a3fac..88adf1621 100644 --- a/include/asm-sparc/io.h +++ b/include/asm-sparc/io.h @@ -1,7 +1,11 @@ +/* $Id: io.h,v 1.10 1996/08/29 09:48:14 davem Exp $ */ #ifndef __SPARC_IO_H #define __SPARC_IO_H +#include <linux/kernel.h> + #include <asm/page.h> /* IO address mapping routines need this */ +#include <asm/system.h> /* * Defines for io operations on the Sparc. Whether a memory access is going @@ -10,91 +14,129 @@ * space only works on sun4's */ -extern inline unsigned long inb_local(unsigned long addr) +extern __inline__ unsigned long inb_local(unsigned long addr) { - return 0; + return 0; } -extern inline void outb_local(unsigned char b, unsigned long addr) +extern __inline__ void outb_local(unsigned char b, unsigned long addr) { - return; + return; } -extern inline unsigned long inb(unsigned long addr) +extern __inline__ unsigned long inb(unsigned long addr) { - return 0; + return 0; } -extern inline unsigned long inw(unsigned long addr) +extern __inline__ unsigned long inw(unsigned long addr) { - return 0; + return 0; } -extern inline unsigned long inl(unsigned long addr) +extern __inline__ unsigned long inl(unsigned long addr) { - return 0; + return 0; } -extern inline void outb(unsigned char b, unsigned long addr) +extern __inline__ void outb(unsigned char b, unsigned long addr) { - return; + return; } -extern inline void outw(unsigned short b, unsigned long addr) +extern __inline__ void outw(unsigned short b, unsigned long addr) { - return; + return; } -extern inline void outl(unsigned int b, unsigned long addr) +extern __inline__ void outl(unsigned int b, unsigned long addr) { - return; + return; } /* * Memory functions */ -extern inline unsigned long readb(unsigned long addr) +extern __inline__ unsigned long readb(unsigned long addr) { - return 0; + return 0; } -extern inline unsigned long readw(unsigned long addr) +extern __inline__ unsigned long readw(unsigned long addr) { - return 0; + return 0; } -extern inline unsigned long readl(unsigned long addr) +extern __inline__ unsigned long readl(unsigned long addr) { - return 0; + return 0; } -extern inline void writeb(unsigned short b, unsigned long addr) +extern __inline__ void writeb(unsigned short b, unsigned long addr) { - return; + return; } -extern inline void writew(unsigned short b, unsigned long addr) +extern __inline__ void writew(unsigned short b, unsigned long addr) { - return; + return; } -extern inline void writel(unsigned int b, unsigned long addr) +extern __inline__ void writel(unsigned int b, unsigned long addr) { - return; + return; } #define inb_p inb #define outb_p outb -extern inline void mapioaddr(unsigned long physaddr, unsigned long virt_addr) +extern void sun4c_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly); +extern void srmmu_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly); + +extern __inline__ void mapioaddr(unsigned long physaddr, unsigned long virt_addr, + int bus, int rdonly) { - unsigned long page_entry; + switch(sparc_cpu_model) { + case sun4c: + sun4c_mapioaddr(physaddr, virt_addr, bus, rdonly); + break; + case sun4m: + case sun4d: + case sun4e: + srmmu_mapioaddr(physaddr, virt_addr, bus, rdonly); + break; + default: + printk("mapioaddr: Trying to map IO space for unsupported machine.\n"); + printk("mapioaddr: sparc_cpu_model = %d\n", sparc_cpu_model); + printk("mapioaddr: Halting...\n"); + halt(); + }; + return; +} - page_entry = physaddr >> PAGE_SHIFT; - page_entry |= (PTE_V | PTE_ACC | PTE_NC | PTE_IO); /* kernel io addr */ +extern void srmmu_unmapioaddr(unsigned long virt); +extern void sun4c_unmapioaddr(unsigned long virt); - put_pte(virt_addr, page_entry); - return; +extern __inline__ void unmapioaddr(unsigned long virt_addr) +{ + switch(sparc_cpu_model) { + case sun4c: + sun4c_unmapioaddr(virt_addr); + break; + case sun4m: + case sun4d: + case sun4e: + srmmu_unmapioaddr(virt_addr); + break; + default: + printk("unmapioaddr: sparc_cpu_model = %d, halt...\n", sparc_cpu_model); + halt(); + }; + return; } +extern void *sparc_alloc_io (void *, void *, int, char *, int, int); +extern void sparc_free_io (void *, int); +extern void *sparc_dvma_malloc (int, char *); + #endif /* !(__SPARC_IO_H) */ diff --git a/include/asm-sparc/ioctl.h b/include/asm-sparc/ioctl.h new file mode 100644 index 000000000..e6c645fff --- /dev/null +++ b/include/asm-sparc/ioctl.h @@ -0,0 +1,43 @@ +/* $Id: ioctl.h,v 1.5 1996/05/17 03:31:09 davem Exp $ */ +#ifndef _SPARC_IOCTL_H +#define _SPARC_IOCTL_H + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 8 +#define _IOC_RESVBITS 5 +#define _IOC_DIRBITS 3 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_RESVMASK ((1 << _IOC_RESVBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS) +#define _IOC_RESVSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS) +#define _IOC_DIRSHIFT (_IOC_RESVSHIFT + _IOC_RESVBITS) + +#define _IOC_NONE 1U +#define _IOC_READ 2U +#define _IOC_WRITE 4U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +#endif /* !(_SPARC_IOCTL_H) */ diff --git a/include/asm-sparc/ioctls.h b/include/asm-sparc/ioctls.h new file mode 100644 index 000000000..80eff02ea --- /dev/null +++ b/include/asm-sparc/ioctls.h @@ -0,0 +1,128 @@ +#ifndef _ASM_SPARC_IOCTLS_H +#define _ASM_SPARC_IOCTLS_H + +#include <asm/ioctl.h> + +/* Big T */ +#define TCGETA _IOR('T', 1, struct termio) +#define TCSETA _IOW('T', 2, struct termio) +#define TCSETAW _IOW('T', 3, struct termio) +#define TCSETAF _IOW('T', 4, struct termio) +#define TCSBRK _IO('T', 5) +#define TCXONC _IO('T', 6) +#define TCFLSH _IO('T', 7) +#define TCGETS _IOR('T', 8, struct termios) +#define TCSETS _IOW('T', 9, struct termios) +#define TCSETSW _IOW('T', 10, struct termios) +#define TCSETSF _IOW('T', 11, struct termios) + +/* Note that all the ioctls that are not available in Linux have a + * double underscore on the front to: a) avoid some programs to + * thing we support some ioctls under Linux (autoconfiguration stuff) + */ +/* Little t */ +#define TIOCGETD _IOR('t', 0, int) +#define TIOCSETD _IOW('t', 1, int) +#define __TIOCHPCL _IO('t', 2) /* SunOS Specific */ +#define __TIOCMODG _IOR('t', 3, int) /* SunOS Specific */ +#define __TIOCMODS _IOW('t', 4, int) /* SunOS Specific */ +#define __TIOCGETP _IOR('t', 8, struct sgttyb) /* SunOS Specific */ +#define __TIOCSETP _IOW('t', 9, struct sgttyb) /* SunOS Specific */ +#define __TIOCSETN _IOW('t', 10, struct sgttyb) /* SunOS Specific */ +#define TIOCEXCL _IO('t', 13) +#define TIOCNXCL _IO('t', 14) +#define __TIOCFLUSH _IOW('t', 16, int) /* SunOS Specific */ +#define __TIOCSETC _IOW('t', 17, struct tchars) /* SunOS Specific */ +#define __TIOCGETC _IOR('t', 18, struct tchars) /* SunOS Specific */ +#define __TIOCTCNTL _IOW('t', 32, int) /* SunOS Specific */ +#define __TIOCSIGNAL _IOW('t', 33, int) /* SunOS Specific */ +#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */ +#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */ +#define TIOCCONS _IO('t', 36) +#define __TIOCSSIZE _IOW('t', 37, struct sunos_ttysize) /* SunOS Specific */ +#define __TIOCGSIZE _IOR('t', 38, struct sunos_ttysize) /* SunOS Specific */ +#define TIOCGSOFTCAR _IOR('t', 100, int) +#define TIOCSSOFTCAR _IOW('t', 101, int) +#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */ +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define __TIOCREMOTE _IOW('t', 105, int) /* SunOS Specific */ +#define TIOCMGET _IOR('t', 106, int) +#define TIOCMBIC _IOW('t', 107, int) +#define TIOCMBIS _IOW('t', 108, int) +#define TIOCMSET _IOW('t', 109, int) +#define __TIOCSTART _IO('t', 110) /* SunOS Specific */ +#define __TIOCSTOP _IO('t', 111) /* SunOS Specific */ +#define TIOCPKT _IOW('t', 112, int) +#define TIOCNOTTY _IO('t', 113) +#define TIOCSTI _IOW('t', 114, char) +#define TIOCOUTQ _IOR('t', 115, int) +#define __TIOCGLTC _IOR('t', 116, struct ltchars) /* SunOS Specific */ +#define __TIOCSLTC _IOW('t', 117, struct ltchars) /* SunOS Specific */ +/* 118 is the non-posix setpgrp tty ioctl */ +/* 119 is the non-posix getpgrp tty ioctl */ +#define __TIOCCDTR _IO('t', 120) /* SunOS Specific */ +#define __TIOCSDTR _IO('t', 121) /* SunOS Specific */ +#define __TIOCCBRK _IO('t', 122) /* SunOS Specific */ +#define __TIOCSBRK _IO('t', 123) /* SunOS Specific */ +#define __TIOCLGET _IOW('t', 124, int) /* SunOS Specific */ +#define __TIOCLSET _IOW('t', 125, int) /* SunOS Specific */ +#define __TIOCLBIC _IOW('t', 126, int) /* SunOS Specific */ +#define __TIOCLBIS _IOW('t', 127, int) /* SunOS Specific */ +#define __TIOCISPACE _IOR('t', 128, int) /* SunOS Specific */ +#define __TIOCISIZE _IOR('t', 129, int) /* SunOS Specific */ +#define TIOCSPGRP _IOW('t', 130, int) +#define TIOCGPGRP _IOR('t', 131, int) +#define TIOCSCTTY _IO('t', 132) + +/* Little f */ +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD + +/* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it + * someday. This is completely bogus, I know... + */ +#define __TCGETSTAT _IO('T', 200) /* Rutgers specific */ +#define __TCSETSTAT _IO('T', 201) /* Rutgers specific */ + +/* Linux specific, no SunOS equivalent. */ +#define TIOCLINUX 0x541C +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TCSBRKP 0x5425 +#define TIOCTTYGSTRUCT 0x5426 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +/* Kernel definitions */ +#ifdef __KERNEL__ +#define TIOCGETC __TIOCGETC +#define TIOCGETP __TIOCGETP +#define TIOCGLTC __TIOCGLTC +#define TIOCSLTC __TIOCSLTC +#define TIOCSETP __TIOCSETP +#define TIOCSETN __TIOCSETN +#define TIOCSETC __TIOCSETC +#endif + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#endif /* !(_ASM_SPARC_IOCTLS_H) */ diff --git a/include/asm-sparc/iommu.h b/include/asm-sparc/iommu.h new file mode 100644 index 000000000..cf1d5b794 --- /dev/null +++ b/include/asm-sparc/iommu.h @@ -0,0 +1,120 @@ +/* iommu.h: Definitions for the sun4m IOMMU. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_IOMMU_H +#define _SPARC_IOMMU_H + +#include <asm/page.h> + +/* The iommu handles all virtual to physical address translations + * that occur between the SBUS and physical memory. Access by + * the cpu to IO registers and similar go over the mbus so are + * translated by the on chip SRMMU. The iommu and the srmmu do + * not need to have the same translations at all, in fact most + * of the time the translations they handle are a disjunct set. + * Basically the iommu handles all dvma sbus activity. + */ + +/* The IOMMU registers occupy three pages in IO space. */ +struct iommu_regs { + /* First page */ + volatile unsigned long control; /* IOMMU control */ + volatile unsigned long base; /* Physical base of iopte page table */ + volatile unsigned long _unused1[3]; + volatile unsigned long tlbflush; /* write only */ + volatile unsigned long pageflush; /* write only */ + volatile unsigned long _unused2[1017]; + /* Second page */ + volatile unsigned long afsr; /* Async-fault status register */ + volatile unsigned long afar; /* Async-fault physical address */ + volatile unsigned long _unused3[2]; + volatile unsigned long sbuscfg0; /* SBUS configuration registers, per-slot */ + volatile unsigned long sbuscfg1; + volatile unsigned long sbuscfg2; + volatile unsigned long sbuscfg3; + volatile unsigned long mfsr; /* Memory-fault status register */ + volatile unsigned long mfar; /* Memory-fault physical address */ + volatile unsigned long _unused4[1014]; + /* Third page */ + volatile unsigned long mid; /* IOMMU module-id */ +}; + +#define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */ +#define IOMMU_CTRL_VERS 0x0f000000 /* Version */ +#define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */ +#define IOMMU_RNGE_16MB 0x00000000 /* 0xff000000 -> 0xffffffff */ +#define IOMMU_RNGE_32MB 0x00000004 /* 0xfe000000 -> 0xffffffff */ +#define IOMMU_RNGE_64MB 0x00000008 /* 0xfc000000 -> 0xffffffff */ +#define IOMMU_RNGE_128MB 0x0000000c /* 0xf8000000 -> 0xffffffff */ +#define IOMMU_RNGE_256MB 0x00000010 /* 0xf0000000 -> 0xffffffff */ +#define IOMMU_RNGE_512MB 0x00000014 /* 0xe0000000 -> 0xffffffff */ +#define IOMMU_RNGE_1GB 0x00000018 /* 0xc0000000 -> 0xffffffff */ +#define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */ +#define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */ + +#define IOMMU_AFSR_ERR 0x80000000 /* LE, TO, or BE asserted */ +#define IOMMU_AFSR_LE 0x40000000 /* SBUS reports error after transaction */ +#define IOMMU_AFSR_TO 0x20000000 /* Write access took more than 12.8 us. */ +#define IOMMU_AFSR_BE 0x10000000 /* Write access received error acknowledge */ +#define IOMMU_AFSR_SIZE 0x0e000000 /* Size of transaction causing error */ +#define IOMMU_AFSR_S 0x01000000 /* Sparc was in supervisor mode */ +#define IOMMU_AFSR_RESV 0x00f00000 /* Reserver, forced to 0x8 by hardware */ +#define IOMMU_AFSR_ME 0x00080000 /* Multiple errors occurred */ +#define IOMMU_AFSR_RD 0x00040000 /* A read operation was in progress */ +#define IOMMU_AFSR_FAV 0x00020000 /* IOMMU afar has valid contents */ + +#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when bypass enabled */ +#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */ +#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */ +#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses + produced by this device as pure + physical. */ + +#define IOMMU_MFSR_ERR 0x80000000 /* One or more of PERR1 or PERR0 */ +#define IOMMU_MFSR_S 0x01000000 /* Sparc was in supervisor mode */ +#define IOMMU_MFSR_CPU 0x00800000 /* CPU transaction caused parity error */ +#define IOMMU_MFSR_ME 0x00080000 /* Multiple parity errors occurred */ +#define IOMMU_MFSR_PERR 0x00006000 /* high bit indicates parity error occurred + on the even word of the access, low bit + indicated odd word caused the parity error */ +#define IOMMU_MFSR_BM 0x00001000 /* Error occurred while in boot mode */ +#define IOMMU_MFSR_C 0x00000800 /* Address causing error was marked cacheable */ +#define IOMMU_MFSR_RTYP 0x000000f0 /* Memory request transaction type */ + +#define IOMMU_MID_SBAE 0x001f0000 /* SBus arbitration enable */ +#define IOMMU_MID_SE 0x00100000 /* Enables SCSI/ETHERNET arbitration */ +#define IOMMU_MID_SB3 0x00080000 /* Enable SBUS device 3 arbitration */ +#define IOMMU_MID_SB2 0x00040000 /* Enable SBUS device 2 arbitration */ +#define IOMMU_MID_SB1 0x00020000 /* Enable SBUS device 1 arbitration */ +#define IOMMU_MID_SB0 0x00010000 /* Enable SBUS device 0 arbitration */ +#define IOMMU_MID_MID 0x0000000f /* Module-id, hardcoded to 0x8 */ + +/* The format of an iopte in the page tables */ +#define IOPTE_PAGE 0x07ffff00 /* Physical page number (PA[30:12]) */ +#define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */ +#define IOPTE_WRITE 0x00000004 /* Writeable */ +#define IOPTE_VALID 0x00000002 /* IOPTE is valid */ +#define IOPTE_WAZ 0x00000001 /* Write as zeros */ + +struct iommu_struct { + struct iommu_regs *regs; + iopte_t *page_table; + iopte_t *lowest; /* to speed up searches... */ + unsigned long plow; + /* For convenience */ + unsigned long start; /* First managed virtual address */ + unsigned long end; /* Last managed virtual address */ +}; + +extern __inline__ void iommu_invalidate(struct iommu_regs *regs) +{ + regs->tlbflush = 0; +} + +extern __inline__ void iommu_invalidate_page(struct iommu_regs *regs, unsigned long page) +{ + regs->pageflush = (page & PAGE_MASK); +} + +#endif /* !(_SPARC_IOMMU_H) */ diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h index 0e96ffb8c..7b1a13efb 100644 --- a/include/asm-sparc/irq.h +++ b/include/asm-sparc/irq.h @@ -1,43 +1,126 @@ -#ifndef _ALPHA_IRQ_H -#define _ALPHA_IRQ_H - -/* - * linux/include/asm-sparc/irq.h +/* $Id: irq.h,v 1.14 1996/08/29 09:48:18 davem Exp $ + * irq.h: IRQ registers on the Sparc. * - * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ +#ifndef _SPARC_IRQ_H +#define _SPARC_IRQ_H + #include <linux/linkage.h> -extern void disable_irq(unsigned int); -extern void enable_irq(unsigned int); +#include <asm/system.h> /* For NCPUS */ + +#define NR_IRQS 15 + +/* Dave Redman (djhr@tadpole.co.uk) + * changed these to function pointers.. it saves cycles and will allow + * the irq dependencies to be split into different files at a later date + * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size. + */ +extern void (*disable_irq)(unsigned int); +extern void (*enable_irq)(unsigned int); +extern void (*clear_clock_irq)( void ); +extern void (*clear_profile_irq)( void ); +extern void (*load_profile_irq)( unsigned int timeout ); +extern void (*init_timers)(void (*lvl10_irq)(int, void *, struct pt_regs *)); +extern void claim_ticker14(void (*irq_handler)(int, void *, struct pt_regs *), + int irq, + unsigned int timeout); + +#ifdef __SMP__ +extern void (*set_cpu_int)(int, int); +extern void (*clear_cpu_int)(int, int); +extern void (*set_irq_udt)(int); +#endif + +extern int request_fast_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, __const__ char *devname); + +/* On the sun4m, just like the timers, we have both per-cpu and master + * interrupt registers. + */ + +/* These registers are used for sending/receiving irqs from/to + * different cpu's. + */ +struct sun4m_intreg_percpu { + unsigned int tbt; /* Interrupts still pending for this cpu. */ -#define __STR(x) #x -#define STR(x) __STR(x) - -#define SAVE_ALL "xx" + /* These next two registers are WRITE-ONLY and are only + * "on bit" sensitive, "off bits" written have NO affect. + */ + unsigned int clear; /* Clear this cpus irqs here. */ + unsigned int set; /* Set this cpus irqs here. */ + unsigned char space[PAGE_SIZE - 12]; +}; -#define SAVE_MOST "yy" +/* + * djhr + * Actually the clear and set fields in this struct are misleading.. + * according to the SLAVIO manual (and the same applies for the SEC) + * the clear field clears bits in the mask which will ENABLE that IRQ + * the set field sets bits in the mask to DISABLE the IRQ. + * + * Also the undirected_xx address in the SLAVIO is defined as + * RESERVED and write only.. + * + * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor + * sun4m machines, for MP the layout makes more sense. + */ +struct sun4m_intregs { + struct sun4m_intreg_percpu cpu_intregs[NCPUS]; + unsigned int tbt; /* IRQ's that are still pending. */ + unsigned int irqs; /* Master IRQ bits. */ -#define RESTORE_MOST "zz" + /* Again, like the above, two these registers are WRITE-ONLY. */ + unsigned int clear; /* Clear master IRQ's by setting bits here. */ + unsigned int set; /* Set master IRQ's by setting bits here. */ -#define ACK_FIRST(mask) "aa" + /* This register is both READ and WRITE. */ + unsigned int undirected_target; /* Which cpu gets undirected irqs. */ +}; -#define ACK_SECOND(mask) "dummy" +extern struct sun4m_intregs *sun4m_interrupts; + +/* + * Bit field defines for the interrupt registers on various + * Sparc machines. + */ + +/* The sun4c interrupt register. */ +#define SUN4C_INT_ENABLE 0x01 /* Allow interrupts. */ +#define SUN4C_INT_E14 0x80 /* Enable level 14 IRQ. */ +#define SUN4C_INT_E10 0x20 /* Enable level 10 IRQ. */ +#define SUN4C_INT_E8 0x10 /* Enable level 8 IRQ. */ +#define SUN4C_INT_E6 0x08 /* Enable level 6 IRQ. */ +#define SUN4C_INT_E4 0x04 /* Enable level 4 IRQ. */ +#define SUN4C_INT_E1 0x02 /* Enable level 1 IRQ. */ + +/* Dave Redman (djhr@tadpole.co.uk) + * The sun4m interrupt registers. + */ +#define SUN4M_INT_ENABLE 0x80000000 +#define SUN4M_INT_E14 0x00000080 +#define SUN4M_INT_E10 0x00080000 -#define UNBLK_FIRST(mask) "dummy" +#define SUN4M_HARD_INT(x) (0x000000001 << (x)) +#define SUN4M_SOFT_INT(x) (0x000010000 << (x)) -#define UNBLK_SECOND(mask) "dummy" +#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ +#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ +#define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */ +#define SUN4M_INT_ECC 0x10000000 /* ecc memory error */ +#define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */ +#define SUN4M_INT_MODULE 0x00200000 /* module interrupt */ +#define SUN4M_INT_VIDEO 0x00100000 /* onboard video */ +#define SUN4M_INT_REALTIME 0x00080000 /* system timer */ +#define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */ +#define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */ +#define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */ +#define SUN4M_INT_SERIAL 0x00008000 /* serial ports */ +#define SUN4M_INT_KBDMS 0x00004000 /* keyboard/mouse */ +#define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */ -#define IRQ_NAME2(nr) nr##_interrupt(void) -#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) -#define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr) -#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr) - -#define BUILD_IRQ(chip,nr,mask) \ -asmlinkage void IRQ_NAME(nr); \ -asmlinkage void FAST_IRQ_NAME(nr); \ -asmlinkage void BAD_IRQ_NAME(nr); \ -asm code comes here +#define SUN4M_INT_SBUS(x) (1 << (x+7)) #endif diff --git a/include/asm-sparc/kbio.h b/include/asm-sparc/kbio.h new file mode 100644 index 000000000..7382d396f --- /dev/null +++ b/include/asm-sparc/kbio.h @@ -0,0 +1,44 @@ +#ifndef __LINUX_KBIO_H +#define __LINUX_KBIO_H + +/* Return keyboard type */ +#define KIOCTYPE _IOR('k', 9, int) +/* Return Keyboard layout */ +#define KIOCLAYOUT _IOR('k', 20, int) + +enum { + TR_NONE, + TR_ASCII, /* keyboard is in regular state */ + TR_EVENT, /* keystrokes sent as firm events */ + TR_UNTRANS_EVENT /* EVENT+up and down+no translation */ +}; + +/* Return the current keyboard translation */ +#define KIOCGTRANS _IOR('k', 5, int) +/* Set the keyboard translation */ +#define KIOCTRANS _IOW('k', 0, int) + +/* Send a keyboard command */ +#define KIOCCMD _IOW('k', 8, int) + +/* Return if keystrokes are being sent to /dev/kbd */ + +/* Set routing of keystrokes to /dev/kbd */ +#define KIOCSDIRECT _IOW('k', 10, int) + +/* Set keyboard leds */ +#define KIOCSLED _IOW('k', 14, unsigned char) + +/* Get keyboard leds */ +#define KIOCGLED _IOR('k', 15, unsigned char) + +/* Top bit records if the key is up or down */ +#define KBD_UP 0x80 + +/* Usable information */ +#define KBD_KEYMASK 0x7f + +/* All keys up */ +#define KBD_IDLE 0x75 + +#endif /* __LINUX_KBIO_H */ diff --git a/include/asm-sparc/kdebug.h b/include/asm-sparc/kdebug.h new file mode 100644 index 000000000..8607d9b5c --- /dev/null +++ b/include/asm-sparc/kdebug.h @@ -0,0 +1,79 @@ +/* $Id: kdebug.h,v 1.9 1996/05/10 19:52:35 davem Exp $ + * kdebug.h: Defines and definitions for debugging the Linux kernel + * under various kernel debuggers. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_KDEBUG_H +#define _SPARC_KDEBUG_H + +#include <asm/openprom.h> + +/* The debugger lives in 1MB of virtual address space right underneath + * the boot prom. + */ + +#define DEBUG_FIRSTVADDR 0xffc00000 +#define DEBUG_LASTVADDR LINUX_OPPROM_BEGVM + +/* Breakpoints are enter through trap table entry 126. So in sparc assembly + * if you want to drop into the debugger you do: + * + * t DEBUG_BP_TRAP + */ + +#define DEBUG_BP_TRAP 126 + +#ifndef __ASSEMBLY__ +/* The debug vector is passed in %o1 at boot time. It is a pointer to + * a structure in the debuggers address space. Here is its format. + */ + +typedef unsigned int (*debugger_funct)(void); + +struct kernel_debug { + /* First the entry point into the debugger. You jump here + * to give control over to the debugger. + */ + unsigned long kdebug_entry; + unsigned long kdebug_trapme; /* Figure out later... */ + /* The following is the number of pages that the debugger has + * taken from to total pool. + */ + unsigned long *kdebug_stolen_pages; + /* Ok, after you remap yourself and/or change the trap table + * from what you were left with at boot time you have to call + * this synchronization function so the debugger can check out + * what you have done. + */ + debugger_funct teach_debugger; +}; /* I think that is it... */ + +extern struct kernel_debug *linux_dbvec; + +/* Use this macro in C-code to enter the debugger. */ +extern __inline__ void sp_enter_debugger(void) +{ + __asm__ __volatile__("jmpl %0, %%o7\n\t" + "nop\n\t" : : + "r" (linux_dbvec) : "o7", "memory"); +} + +#define SP_ENTER_DEBUGGER do { \ + if((linux_dbvec!=0) && ((*(short *)linux_dbvec)!=-1)) \ + sp_enter_debugger(); \ + } while(0) + +#endif /* !(__ASSEMBLY__) */ + +/* Some nice offset defines for assembler code. */ +#define KDEBUG_ENTRY_OFF 0x0 +#define KDEBUG_DUNNO_OFF 0x4 +#define KDEBUG_DUNNO2_OFF 0x8 +#define KDEBUG_TEACH_OFF 0xc + +/* ugh... */ +#define TRAP_TRACE(reg1, reg2) \ + + +#endif /* !(_SPARC_KDEBUG_H) */ diff --git a/include/asm-sparc/kgdb.h b/include/asm-sparc/kgdb.h new file mode 100644 index 000000000..79534dac8 --- /dev/null +++ b/include/asm-sparc/kgdb.h @@ -0,0 +1,90 @@ +/* $Id: kgdb.h,v 1.7 1995/11/27 02:43:18 davem Exp $ + * kgdb.h: Defines and declarations for serial line source level + * remote debugging of the Linux kernel using gdb. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_KGDB_H +#define _SPARC_KGDB_H + +#ifndef __ASSEMBLY__ +/* To init the kgdb engine. */ +extern void set_debug_traps(void); + +/* To enter the debugger explicitly. */ +extern void breakpoint(void); + +/* For convenience we define the format of a kgdb trap breakpoint + * frame here also. + */ +struct kgdb_frame { + unsigned long globals[8]; + unsigned long outs[8]; + unsigned long locals[8]; + unsigned long ins[8]; + unsigned long fpregs[32]; + unsigned long y; + unsigned long psr; + unsigned long wim; + unsigned long tbr; + unsigned long pc; + unsigned long npc; + unsigned long fpsr; + unsigned long cpsr; +}; +#endif /* !(__ASSEMBLY__) */ + +/* Macros for assembly usage of the kgdb breakpoint frame. */ +#define KGDB_G0 0x000 +#define KGDB_G1 0x004 +#define KGDB_G2 0x008 +#define KGDB_G4 0x010 +#define KGDB_G6 0x018 +#define KGDB_I0 0x020 +#define KGDB_I2 0x028 +#define KGDB_I4 0x030 +#define KGDB_I6 0x038 +#define KGDB_Y 0x100 +#define KGDB_PSR 0x104 +#define KGDB_WIM 0x108 +#define KGDB_TBR 0x10c +#define KGDB_PC 0x110 +#define KGDB_NPC 0x114 + +#define SAVE_KGDB_GLOBALS(reg) \ + std %g0, [%reg + REGWIN_SZ + KGDB_G0]; \ + std %g2, [%reg + REGWIN_SZ + KGDB_G2]; \ + std %g4, [%reg + REGWIN_SZ + KGDB_G4]; \ + std %g6, [%reg + REGWIN_SZ + KGDB_G6]; + +#define SAVE_KGDB_INS(reg) \ + std %i0, [%reg + REGWIN_SZ + KGDB_I0]; \ + std %i2, [%reg + REGWIN_SZ + KGDB_I2]; \ + std %i4, [%reg + REGWIN_SZ + KGDB_I4]; \ + std %i6, [%reg + REGWIN_SZ + KGDB_I6]; + +#define SAVE_KGDB_SREGS(reg, reg_y, reg_psr, reg_wim, reg_tbr, reg_pc, reg_npc) \ + st %reg_y, [%reg + REGWIN_SZ + KGDB_Y]; \ + st %reg_psr, [%reg + REGWIN_SZ + KGDB_PSR]; \ + st %reg_wim, [%reg + REGWIN_SZ + KGDB_WIM]; \ + st %reg_tbr, [%reg + REGWIN_SZ + KGDB_TBR]; \ + st %reg_pc, [%reg + REGWIN_SZ + KGDB_PC]; \ + st %reg_npc, [%reg + REGWIN_SZ + KGDB_NPC]; + +#define LOAD_KGDB_GLOBALS(reg) \ + ld [%reg + REGWIN_SZ + KGDB_G1], %g1; \ + ldd [%reg + REGWIN_SZ + KGDB_G2], %g2; \ + ldd [%reg + REGWIN_SZ + KGDB_G4], %g4; \ + ldd [%reg + REGWIN_SZ + KGDB_G6], %g6; + +#define LOAD_KGDB_INS(reg) \ + ldd [%reg + REGWIN_SZ + KGDB_I0], %i0; \ + ldd [%reg + REGWIN_SZ + KGDB_I2], %i2; \ + ldd [%reg + REGWIN_SZ + KGDB_I4], %i4; \ + ldd [%reg + REGWIN_SZ + KGDB_I6], %i6; + +#define LOAD_KGDB_SREGS(reg, reg_y_and_psr, reg_pc_and_npc) \ + ldd [%reg + REGWIN_SZ + KGDB_Y], %reg_y_and_psr; \ + ldd [%reg + REGWIN_SZ + KGDB_PC], %reg_pc_and_npc; + +#endif /* !(_SPARC_KGDB_H) */ diff --git a/include/asm-sparc/machines.h b/include/asm-sparc/machines.h new file mode 100644 index 000000000..d831350f5 --- /dev/null +++ b/include/asm-sparc/machines.h @@ -0,0 +1,69 @@ +/* $Id: machines.h,v 1.4 1995/11/25 02:31:58 davem Exp $ + * machines.h: Defines for taking apart the machine type value in the + * idprom and determining the kind of machine we are on. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_MACHINES_H +#define _SPARC_MACHINES_H + +struct Sun_Machine_Models { + char *name; + unsigned char id_machtype; +}; + +/* Current number of machines we know about that has an IDPROM + * machtype entry including one entry for the 0x80 OBP machines. + */ +#define NUM_SUN_MACHINES 15 + +extern struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES]; + +/* The machine type in the idprom area looks like this: + * + * --------------- + * | ARCH | MACH | + * --------------- + * 7 4 3 0 + * + * The ARCH field determines the architecture line (sun4, sun4c, etc). + * The MACH field determines the machine make within that architecture. + */ + +#define SM_ARCH_MASK 0xf0 +#define SM_SUN4 0x20 +#define SM_SUN4C 0x50 +#define SM_SUN4M 0x70 +#define SM_SUN4M_OBP 0x80 + +#define SM_TYP_MASK 0x0f +/* Sun4 machines */ +#define SM_4_260 0x01 /* Sun 4/200 series */ +#define SM_4_110 0x02 /* Sun 4/100 series */ +#define SM_4_330 0x03 /* Sun 4/300 series */ +#define SM_4_470 0x04 /* Sun 4/400 series */ + +/* Sun4c machines Full Name - PROM NAME */ +#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ +#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ +#define SM_4C_SS1PLUS 0x03 /* Sun4c SparcStation 1+ - Sun 4/65 */ +#define SM_4C_SLC 0x04 /* Sun4c SparcStation SLC - Sun 4/20 */ +#define SM_4C_SS2 0x05 /* Sun4c SparcStation 2 - Sun 4/75 */ +#define SM_4C_ELC 0x06 /* Sun4c SparcStation ELC - Sun 4/25 */ +#define SM_4C_IPX 0x07 /* Sun4c SparcStation IPX - Sun 4/50 */ + +/* Sun4m machines, these predate the OpenBoot. These values only mean + * something if the value in the ARCH field is SM_SUN4M, if it is + * SM_SUN4M_OBP then you have the following situation: + * 1) You either have a sun4d, a sun4e, or a recently made sun4m. + * 2) You have to consult OpenBoot to determine which machine this is. + */ +#define SM_4M_SS60 0x01 /* Sun4m SparcSystem 600 */ +#define SM_4M_SS50 0x02 /* Sun4m SparcStation 10 */ +#define SM_4M_SS40 0x03 /* Sun4m SparcStation 5 */ + +/* Sun4d machines -- N/A */ +/* Sun4e machines -- N/A */ +/* Sun4u machines -- N/A */ + +#endif /* !(_SPARC_MACHINES_H) */ diff --git a/include/asm-sparc/mbus.h b/include/asm-sparc/mbus.h new file mode 100644 index 000000000..e5e5a18c8 --- /dev/null +++ b/include/asm-sparc/mbus.h @@ -0,0 +1,100 @@ +/* $Id: mbus.h,v 1.8 1996/08/29 09:48:21 davem Exp $ + * mbus.h: Various defines for MBUS modules. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_MBUS_H +#define _SPARC_MBUS_H + +#include <asm/ross.h> /* HyperSparc stuff */ +#include <asm/cypress.h> /* Cypress Chips */ +#include <asm/viking.h> /* Ugh, bug city... */ + +enum mbus_module { + HyperSparc = 0, + Cypress = 1, + Cypress_vE = 2, + Cypress_vD = 3, + Swift_ok = 4, + Swift_bad_c = 5, + Swift_lots_o_bugs = 6, + Tsunami = 7, + Viking_12 = 8, + Viking_2x = 9, + Viking_30 = 10, + Viking_35 = 11, + Viking_new = 12, + SRMMU_INVAL_MOD = 13, +}; + +extern enum mbus_module srmmu_modtype; +extern unsigned int viking_rev, swift_rev, cypress_rev; + +/* HW Mbus module bugs we have to deal with */ +#define HWBUG_COPYBACK_BROKEN 0x00000001 +#define HWBUG_ASIFLUSH_BROKEN 0x00000002 +#define HWBUG_VACFLUSH_BITROT 0x00000004 +#define HWBUG_KERN_ACCBROKEN 0x00000008 +#define HWBUG_KERN_CBITBROKEN 0x00000010 +#define HWBUG_MODIFIED_BITROT 0x00000020 +#define HWBUG_PC_BADFAULT_ADDR 0x00000040 +#define HWBUG_SUPERSCALAR_BAD 0x00000080 +#define HWBUG_PACINIT_BITROT 0x00000100 + +extern unsigned int hwbug_bitmask; + +/* First the module type values. To find out which you have, just load + * the mmu control register from ASI_M_MMUREG alternate address space and + * shift the value right 28 bits. + */ +/* IMPL field means the company which produced the chip. */ +#define MBUS_VIKING 0x4 /* bleech, Texas Instruments Module */ +#define MBUS_LSI 0x3 /* LSI Logics */ +#define MBUS_ROSS 0x1 /* Ross is nice */ +#define MBUS_FMI 0x0 /* Fujitsu Microelectronics/Swift */ + +/* Ross Module versions */ +#define ROSS_604_REV_CDE 0x0 /* revisions c, d, and e */ +#define ROSS_604_REV_F 0x1 /* revision f */ +#define ROSS_605 0xf /* revision a, a.1, and a.2 */ +#define ROSS_605_REV_B 0xe /* revision b */ + +/* TI Viking Module versions */ +#define VIKING_REV_12 0x1 /* Version 1.2 or SPARCclassic's CPU */ +#define VIKING_REV_2 0x2 /* Version 2.1, 2.2, 2.3, and 2.4 */ +#define VIKING_REV_30 0x3 /* Version 3.0 */ +#define VIKING_REV_35 0x4 /* Version 3.5 */ + +/* LSI Logics. */ +#define LSI_L64815 0x0 + +/* Fujitsu */ +#define FMI_AURORA 0x4 /* MB8690x, a Swift module... */ + +/* For multiprocessor support we need to be able to obtain the CPU id and + * the MBUS Module id. + */ + +/* The CPU ID is encoded in the trap base register, 20 bits to the left of + * bit zero, with 2 bits being significant. + */ +#define TBR_ID_SHIFT 20 + +extern __inline__ int get_cpuid(void) +{ + register int retval; + __asm__ __volatile__("rd %%tbr, %0\n\t" + "srl %0, %1, %0\n\t" : + "=r" (retval) : + "i" (TBR_ID_SHIFT)); + return (retval & 3); +} + +extern __inline__ int get_modid(void) +{ + return (get_cpuid() | 0x8); +} + + +#endif /* !(_SPARC_MBUS_H) */ diff --git a/include/asm-sparc/memerr.h b/include/asm-sparc/memerr.h deleted file mode 100644 index cd0ca3264..000000000 --- a/include/asm-sparc/memerr.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _SPARC_MEMERR_H -#define _SPARC_MEMERR_H - -/* memerr.h: Bit fields in the asynchronous and synchronous memory error - registers used to determine what 'type' of error has just - induced a trap. - - Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) -*/ - -/* synchronous error register fields come first... */ - -#define SYNCER_WRITE 0x8000 /* write error... */ -#define SYNCER_INVAL 0x0080 /* invalid page access was attempted */ -#define SYNCER_PROT 0x0040 /* protection violation */ -#define SYNCER_TIMEOUT 0x0020 /* mem-bus access timeout (mem does not exist). */ -#define SYNCER_SBUSERR 0x0010 /* same as above, but for an SBUS access */ -#define SYNCER_MEMERR 0x0008 /* Bus parity error, lose lose... panic time */ -#define SYNCER_SZERR 0x0002 /* an attempted access was of BAD size, whoops */ -#define SYNCER_WATCHDOG 0x0001 /* although we never see these, the prom will.. */ - -/* asynchronous error bits go here */ - -#define ASYNCER_WBINVAL 0x80 /* situation arose where the cache tried to write - * back a page for which the valid bit was not set - * within the mmu. This is due to bad mm kernel bugs. - */ - -#define ASYNCER_TIMEOUT 0x20 /* mem-access bus timeout... */ -#define ASYNCER_DVMAERR 0x10 /* dvma transfer to/from memory bombed... */ - -#endif /* _SPARC_MEMERR_H */ diff --git a/include/asm-sparc/memreg.h b/include/asm-sparc/memreg.h new file mode 100644 index 000000000..c0498d3ba --- /dev/null +++ b/include/asm-sparc/memreg.h @@ -0,0 +1,52 @@ +/* $Id: memreg.h,v 1.8 1996/08/29 09:48:23 davem Exp $ */ +#ifndef _SPARC_MEMREG_H +#define _SPARC_MEMREG_H +/* memreg.h: Definitions of the values found in the synchronous + * and asynchronous memory error registers when a fault + * occurs on the sun4c. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +/* First the synchronous error codes, these are usually just + * normal page faults. + */ + +#define SUN4C_SYNC_WDRESET 0x0001 /* watchdog reset */ +#define SUN4C_SYNC_SIZE 0x0002 /* bad access size? whuz this? */ +#define SUN4C_SYNC_PARITY 0x0008 /* bad ram chips caused a parity error */ +#define SUN4C_SYNC_SBUS 0x0010 /* the SBUS had some problems... */ +#define SUN4C_SYNC_NOMEM 0x0020 /* translation to non-existent ram */ +#define SUN4C_SYNC_PROT 0x0040 /* access violated pte protections */ +#define SUN4C_SYNC_NPRESENT 0x0080 /* pte said that page was not present */ +#define SUN4C_SYNC_BADWRITE 0x8000 /* while writing something went bogus */ + +#define SUN4C_SYNC_BOLIXED \ + (SUN4C_SYNC_WDRESET | SUN4C_SYNC_SIZE | SUN4C_SYNC_SBUS | \ + SUN4C_SYNC_NOMEM | SUN4C_SYNC_PARITY) + +/* Now the asynchronous error codes, these are almost always produced + * by the cache writing things back to memory and getting a bad translation. + * Bad DVMA transactions can cause these faults too. + */ + +#define SUN4C_ASYNC_BADDVMA 0x0010 /* error during DVMA access */ +#define SUN4C_ASYNC_NOMEM 0x0020 /* write back pointed to bad phys addr */ +#define SUN4C_ASYNC_BADWB 0x0080 /* write back points to non-present page */ + +/* Memory parity error register with associated bit constants. */ +#ifndef __ASSEMBLY__ +extern __volatile__ unsigned long *sun4c_memerr_reg; +#endif + +#define SUN4C_MPE_ERROR 0x80 /* Parity error detected. (ro) */ +#define SUN4C_MPE_MULTI 0x40 /* Multiple parity errors detected. (ro) */ +#define SUN4C_MPE_TEST 0x20 /* Write inverse parity. (rw) */ +#define SUN4C_MPE_CHECK 0x10 /* Enable parity checking. (rw) */ +#define SUN4C_MPE_ERR00 0x08 /* Parity error in bits 0-7. (ro) */ +#define SUN4C_MPE_ERR08 0x04 /* Parity error in bits 8-15. (ro) */ +#define SUN4C_MPE_ERR16 0x02 /* Parity error in bits 16-23. (ro) */ +#define SUN4C_MPE_ERR24 0x01 /* Parity error in bits 24-31. (ro) */ +#define SUN4C_MPE_ERRS 0x0F /* Bit mask for the error bits. (ro) */ + +#endif /* !(_SPARC_MEMREG_H) */ diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h new file mode 100644 index 000000000..68bc526a1 --- /dev/null +++ b/include/asm-sparc/mman.h @@ -0,0 +1,49 @@ +/* $Id: mman.h,v 1.8 1996/10/27 08:55:28 davem Exp $ */ +#ifndef __SPARC_MMAN_H__ +#define __SPARC_MMAN_H__ + +/* SunOS'ified... */ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ +#define MAP_NORESERVE 0x40 /* don't reserve swap pages */ +#define MAP_INHERIT 0x80 /* SunOS doesn't do this, but... */ +#define MAP_LOCKED 0x100 /* lock the mapping */ +#define _MAP_NEW 0x80000000 /* Binary compatibility is fun... */ + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ +#define MCL_FUTURE 0x4000 /* lock all additions to address space */ + +/* XXX Need to add flags to SunOS's mctl, mlockall, and madvise system + * XXX calls. + */ + +/* SunOS sys_mctl() stuff... */ +#define MC_SYNC 1 /* Sync pages in memory with storage (usu. a file) */ +#define MC_LOCK 2 /* Lock pages into core ram, do not allow swapping of them */ +#define MC_UNLOCK 3 /* Unlock pages locked via previous mctl() with MC_LOCK arg */ +#define MC_LOCKAS 5 /* Lock an entire address space of the calling process */ +#define MC_UNLOCKAS 6 /* Unlock entire address space of calling process */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __SPARC_MMAN_H__ */ diff --git a/include/asm-sparc/mmu_context.h b/include/asm-sparc/mmu_context.h new file mode 100644 index 000000000..f9074dfae --- /dev/null +++ b/include/asm-sparc/mmu_context.h @@ -0,0 +1,14 @@ +#ifndef __SPARC_MMU_CONTEXT_H +#define __SPARC_MMU_CONTEXT_H + +/* For now I still leave the context handling in the + * switch_to() macro, I'll do it right soon enough. + */ +#define get_mmu_context(x) do { } while (0) + +/* Initialize the context related info for a new mm_struct + * instance. + */ +#define init_new_context(mm) ((mm)->context = NO_CONTEXT) + +#endif /* !(__SPARC_MMU_CONTEXT_H) */ diff --git a/include/asm-sparc/mostek.h b/include/asm-sparc/mostek.h new file mode 100644 index 000000000..12baee12a --- /dev/null +++ b/include/asm-sparc/mostek.h @@ -0,0 +1,120 @@ +/* $Id: mostek.h,v 1.8 1996/11/04 00:45:30 ecd Exp $ + * mostek.h: Describes the various Mostek time of day clock registers. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) + */ + +#ifndef _SPARC_MOSTEK_H +#define _SPARC_MOSTEK_H + +#include <asm/idprom.h> + +/* M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ) + * + * Data + * Address Function + * Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0 + * 7ff - - - - - - - - Year 00-99 + * 7fe 0 0 0 - - - - - Month 01-12 + * 7fd 0 0 - - - - - - Date 01-31 + * 7fc 0 FT 0 0 0 - - - Day 01-07 + * 7fb KS 0 - - - - - - Hours 00-23 + * 7fa 0 - - - - - - - Minutes 00-59 + * 7f9 ST - - - - - - - Seconds 00-59 + * 7f8 W R S - - - - - Control + * + * * ST is STOP BIT + * * W is WRITE BIT + * * R is READ BIT + * * S is SIGN BIT + * * FT is FREQ TEST BIT + * * KS is KICK START BIT + */ + +/* The Mostek 48t02 real time clock and NVRAM chip. The registers + * other than the control register are in binary coded decimal. Some + * control bits also live outside the control register. + */ + +struct mostek48t02 { + volatile char eeprom[2008]; /* This is the eeprom, don't touch! */ + struct idprom idprom; /* The idprom lives here. */ + volatile unsigned char creg; /* Control register */ + volatile unsigned char sec; /* Seconds (0-59) */ + volatile unsigned char min; /* Minutes (0-59) */ + volatile unsigned char hour; /* Hour (0-23) */ + volatile unsigned char dow; /* Day of the week (1-7) */ + volatile unsigned char dom; /* Day of the month (1-31) */ + volatile unsigned char month; /* Month of year (1-12) */ + volatile unsigned char year; /* Year (0-99) */ +}; + +extern struct mostek48t02 *mstk48t02_regs; + +/* Control register values. */ +#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */ +#define MSTK_CREG_READ 0x40 /* Stop updates to allow a clean read. */ +#define MSTK_CREG_SIGN 0x20 /* Slow/speed clock in calibration mode. */ + +/* Control bits that live in the other registers. */ +#define MSTK_STOP 0x80 /* Stop the clock oscillator. (sec) */ +#define MSTK_KICK_START 0x80 /* Kick start the clock chip. (hour) */ +#define MSTK_FREQ_TEST 0x40 /* Frequency test mode. (day) */ + +#define MSTK_YEAR_ZERO 1968 /* If year reg has zero, it is 1968. */ +#define MSTK_CVT_YEAR(yr) ((yr) + MSTK_YEAR_ZERO) + +/* Masks that define how much space each value takes up. */ +#define MSTK_SEC_MASK 0x7f +#define MSTK_MIN_MASK 0x7f +#define MSTK_HOUR_MASK 0x3f +#define MSTK_DOW_MASK 0x07 +#define MSTK_DOM_MASK 0x3f +#define MSTK_MONTH_MASK 0x1f +#define MSTK_YEAR_MASK 0xff + +/* Binary coded decimal conversion macros. */ +#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04)) +#define MSTK_DECIMAL_TO_REGVAL(x) ((((x) / 0x0A) << 0x04) + ((x) % 0x0A)) + +/* Generic register set and get macros for internal use. */ +#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(regs->var & MSTK_ ## mask ## _MASK)) +#define MSTK_SET(regs,var,value,mask) do { regs->var &= ~(MSTK_ ## mask ## _MASK); regs->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0) + +/* Macros to make register access easier on our fingers. These give you + * the decimal value of the register requested if applicable. You pass + * the a pointer to a 'struct mostek48t02'. + */ +#define MSTK_REG_CREG(regs) (regs->creg) +#define MSTK_REG_SEC(regs) MSTK_GET(regs,sec,SEC) +#define MSTK_REG_MIN(regs) MSTK_GET(regs,min,MIN) +#define MSTK_REG_HOUR(regs) MSTK_GET(regs,hour,HOUR) +#define MSTK_REG_DOW(regs) MSTK_GET(regs,dow,DOW) +#define MSTK_REG_DOM(regs) MSTK_GET(regs,dom,DOM) +#define MSTK_REG_MONTH(regs) MSTK_GET(regs,month,MONTH) +#define MSTK_REG_YEAR(regs) MSTK_GET(regs,year,YEAR) + +#define MSTK_SET_REG_SEC(regs,value) MSTK_SET(regs,sec,value,SEC) +#define MSTK_SET_REG_MIN(regs,value) MSTK_SET(regs,min,value,MIN) +#define MSTK_SET_REG_HOUR(regs,value) MSTK_SET(regs,hour,value,HOUR) +#define MSTK_SET_REG_DOW(regs,value) MSTK_SET(regs,dow,value,DOW) +#define MSTK_SET_REG_DOM(regs,value) MSTK_SET(regs,dom,value,DOM) +#define MSTK_SET_REG_MONTH(regs,value) MSTK_SET(regs,month,value,MONTH) +#define MSTK_SET_REG_YEAR(regs,value) MSTK_SET(regs,year,value,YEAR) + + +/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the + * same (basically) layout of the 48t02 chip except for the extra + * NVRAM on board (8 KB against the 48t02's 2 KB). + */ +struct mostek48t08 { + char offset[6*1024]; /* Magic things may be here, who knows? */ + struct mostek48t02 regs; /* Here is what we are interested in. */ +}; +extern struct mostek48t08 *mstk48t08_regs; + +enum sparc_clock_type { MSTK48T02, MSTK48T08, MSTK_INVALID }; +extern enum sparc_clock_type sp_clock_typ; + +#endif /* !(_SPARC_MOSTEK_H) */ diff --git a/include/asm-sparc/mpmbox.h b/include/asm-sparc/mpmbox.h new file mode 100644 index 000000000..0e1bc5801 --- /dev/null +++ b/include/asm-sparc/mpmbox.h @@ -0,0 +1,67 @@ +/* $Id: mpmbox.h,v 1.4 1996/04/25 06:13:19 davem Exp $ + * mpmbox.h: Interface and defines for the OpenProm mailbox + * facilities for MP machines under Linux. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_MPMBOX_H +#define _SPARC_MPMBOX_H + +/* The prom allocates, for each CPU on the machine an unsigned + * byte in physical ram. You probe the device tree prom nodes + * for these values. The purpose of this byte is to be able to + * pass messages from one cpu to another. + */ + +/* These are the main message types we have to look for in our + * Cpu mailboxes, based upon these values we decide what course + * of action to take. + */ + +/* The CPU is executing code in the kernel. */ +#define MAILBOX_ISRUNNING 0xf0 + +/* Another CPU called romvec->pv_exit(), you should call + * prom_stopcpu() when you see this in your mailbox. + */ +#define MAILBOX_EXIT 0xfb + +/* Another CPU called romvec->pv_enter(), you should call + * prom_cpuidle() when this is seen. + */ +#define MAILBOX_GOSPIN 0xfc + +/* Another CPU has hit a breakpoint either into kadb or the prom + * itself. Just like MAILBOX_GOSPIN, you should call prom_cpuidle() + * at this point. + */ +#define MAILBOX_BPT_SPIN 0xfd + +/* Oh geese, some other nitwit got a damn watchdog reset. The party's + * over so go call prom_stopcpu(). + */ +#define MAILBOX_WDOG_STOP 0xfe + +#ifndef __ASSEMBLY__ + +/* Handy macro's to determine a cpu's state. */ + +/* Is the cpu still in Power On Self Test? */ +#define MBOX_POST_P(letter) ((letter) >= 0x00 && (letter) <= 0x7f) + +/* Is the cpu at the 'ok' prompt of the PROM? */ +#define MBOX_PROMPROMPT_P(letter) ((letter) >= 0x80 && (letter) <= 0x8f) + +/* Is the cpu spinning in the PROM? */ +#define MBOX_PROMSPIN_P(letter) ((letter) >= 0x90 && (letter) <= 0xef) + +/* Sanity check... This is junk mail, throw it out. */ +#define MBOX_BOGON_P(letter) ((letter) >= 0xf1 && (letter) <= 0xfa) + +/* Is the cpu actively running an application/kernel-code? */ +#define MBOX_RUNNING_P(letter) ((letter) == MAILBOX_ISRUNNING) + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_SPARC_MPMBOX_H) */ diff --git a/include/asm-sparc/msi.h b/include/asm-sparc/msi.h new file mode 100644 index 000000000..b69543dd3 --- /dev/null +++ b/include/asm-sparc/msi.h @@ -0,0 +1,31 @@ +/* $Id: msi.h,v 1.3 1996/08/29 09:48:25 davem Exp $ + * msi.h: Defines specific to the MBus - Sbus - Interface. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) + */ + +#ifndef _SPARC_MSI_H +#define _SPARC_MSI_H + +/* + * Locations of MSI Registers. + */ +#define MSI_MBUS_ARBEN 0xe0001008 /* MBus Arbiter Enable register */ + +/* + * Useful bits in the MSI Registers. + */ +#define MSI_ASYNC_MODE 0x80000000 /* Operate the MSI asynchronously */ + + +extern __inline__ void msi_set_sync(void) +{ + __asm__ __volatile__ ("lda [%0] %1, %%g3\n\t" + "andn %%g3, %2, %%g3\n\t" + "sta %%g3, [%0] %1\n\t" : : + "r" (MSI_MBUS_ARBEN), + "i" (ASI_M_CTL), "r" (MSI_ASYNC_MODE) : "g3"); +} + +#endif /* !(_SPARC_MSI_H) */ diff --git a/include/asm-sparc/mxcc.h b/include/asm-sparc/mxcc.h new file mode 100644 index 000000000..87947bc0f --- /dev/null +++ b/include/asm-sparc/mxcc.h @@ -0,0 +1,133 @@ +/* $Id: mxcc.h,v 1.6 1996/08/29 09:48:27 davem Exp $ + * mxcc.h: Definitions of the Viking MXCC registers + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_MXCC_H +#define _SPARC_MXCC_H + +/* These registers are accessed through ASI 0x2. */ +#define MXCC_DATSTREAM 0x1C00000 /* Data stream register */ +#define MXCC_SRCSTREAM 0x1C00100 /* Source stream register */ +#define MXCC_DESSTREAM 0x1C00200 /* Destination stream register */ +#define MXCC_RMCOUNT 0x1C00300 /* Count of references and misses */ +#define MXCC_STEST 0x1C00804 /* Internal self-test */ +#define MXCC_CREG 0x1C00A04 /* Control register */ +#define MXCC_SREG 0x1C00B00 /* Status register */ +#define MXCC_RREG 0x1C00C04 /* Reset register */ +#define MXCC_EREG 0x1C00E00 /* Error code register */ +#define MXCC_PREG 0x1C00F04 /* Address port register */ + +/* Some MXCC constants. */ +#define MXCC_STREAM_SIZE 0x20 /* Size in bytes of one stream r/w */ + +/* The MXCC Control Register: + * + * ---------------------------------------------------------------------- + * | | RRC | RSV |PRE|MCE|PARE|ECE|RSV| + * ---------------------------------------------------------------------- + * 31 10 9 8-6 5 4 3 2 1-0 + * + * RRC: Controls what you read from MXCC_RMCOUNT reg. + * 0=Misses 1=References + * PRE: Prefetch enable + * MCE: Multiple Command Enable + * PARE: Parity enable + * ECE: External cache enable + */ + +#define MXCC_CTL_RRC 0x00000200 +#define MXCC_CTL_PRE 0x00000020 +#define MXCC_CTL_MCE 0x00000010 +#define MXCC_CTL_PARE 0x00000008 +#define MXCC_CTL_ECE 0x00000004 + +/* The MXCC Error Register: + * + * -------------------------------------------------------- + * |ME| RSV|CE|PEW|PEE|ASE|EIV| MOPC|ECODE|PRIV|RSV|HPADDR| + * -------------------------------------------------------- + * 31 30 29 28 27 26 25 24-15 14-7 6 5-3 2-0 + * + * ME: Multiple Errors have occurred + * CE: Cache consistency Error + * PEW: Parity Error during a Write operation + * PEE: Parity Error involving the External cache + * ASE: ASynchronous Error + * EIV: This register is toast + * MOPC: MXCC Operation Code for instance causing error + * ECODE: The Error CODE + * PRIV: A privileged mode error? 0=no 1=yes + * HPADDR: High PhysicalADDRess bits (35-32) + */ + +#define MXCC_ERR_ME 0x80000000 +#define MXCC_ERR_CE 0x20000000 +#define MXCC_ERR_PEW 0x10000000 +#define MXCC_ERR_PEE 0x08000000 +#define MXCC_ERR_ASE 0x04000000 +#define MXCC_ERR_EIV 0x02000000 +#define MXCC_ERR_MOPC 0x01FF8000 +#define MXCC_ERR_ECODE 0x00007F80 +#define MXCC_ERR_PRIV 0x00000040 +#define MXCC_ERR_HPADDR 0x0000000f + +/* The MXCC Port register: + * + * ----------------------------------------------------- + * | | MID | | + * ----------------------------------------------------- + * 31 21 20-18 17 0 + * + * MID: The moduleID of the cpu your read this from. + */ + +extern __inline__ void mxcc_set_stream_src(unsigned long *paddr) +{ + unsigned long data0 = paddr[0]; + unsigned long data1 = paddr[1]; + + __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t" + "or %%g0, %1, %%g3\n\t" + "stda %%g2, [%2] %3\n\t" : : + "r" (data0), "r" (data1), + "r" (MXCC_SRCSTREAM), + "i" (ASI_M_MXCC) : "g2", "g3"); +} + +extern __inline__ void mxcc_set_stream_dst(unsigned long *paddr) +{ + unsigned long data0 = paddr[0]; + unsigned long data1 = paddr[1]; + + __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t" + "or %%g0, %1, %%g3\n\t" + "stda %%g2, [%2] %3\n\t" : : + "r" (data0), "r" (data1), + "r" (MXCC_DESSTREAM), + "i" (ASI_M_MXCC) : "g2", "g3"); +} + +extern __inline__ unsigned long mxcc_get_creg(void) +{ + unsigned long mxcc_control; + + __asm__ __volatile__("set -1, %%g2\n\t" + "set -1, %%g3\n\t" + "stda %%g2, [%1] %2\n\t" + "lda [%3] %2, %0\n\t" : + "=r" (mxcc_control) : + "r" (MXCC_EREG), "i" (ASI_M_MXCC), + "r" (MXCC_CREG) : "g2", "g3"); + return mxcc_control; +} + +extern __inline__ void mxcc_set_creg(unsigned long mxcc_control) +{ + __asm__ __volatile__("sta %0, [%1] %2\n\t" : : + "r" (mxcc_control), "r" (MXCC_CREG), + "i" (ASI_M_MXCC)); +} + +#endif /* !(_SPARC_MXCC_H) */ diff --git a/include/asm-sparc/openprom.h b/include/asm-sparc/openprom.h index ca6d9e36d..34f5d3c33 100644 --- a/include/asm-sparc/openprom.h +++ b/include/asm-sparc/openprom.h @@ -1,304 +1,210 @@ +/* $Id: openprom.h,v 1.19 1996/09/25 03:51:08 davem Exp $ */ #ifndef __SPARC_OPENPROM_H #define __SPARC_OPENPROM_H /* openprom.h: Prom structures and defines for access to the OPENBOOT - prom routines and data areas. - - Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) -*/ + * prom routines and data areas. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ -/* In the v0 interface of the openboot prom we could traverse a nice - little list structure to figure out where in vm-space the prom had - mapped itself and how much space it was taking up. In the v2 prom - interface we have to rely on 'magic' values. :-( Most of the machines - I have checked on have the prom mapped here all the time though. -*/ +/* Empirical constants... */ +#define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */ #define LINUX_OPPROM_BEGVM 0xffd00000 #define LINUX_OPPROM_ENDVM 0xfff00000 - #define LINUX_OPPROM_MAGIC 0x10010407 -/* The device functions structure for the v0 prom. Nice and neat, open, - close, read & write divvied up between net + block + char devices. We - also have a seek routine only usable for block devices. The divide - and conquer strategy of this struct becomes unnecessary for v2. - - V0 device names are limited to two characters, 'sd' for scsi-disk, - 'le' for local-ethernet, etc. Note that it is technically possible - to boot a kernel off of a tape drive and use the tape as the root - partition! In order to do this you have to have 'magic' formatted - tapes from Sun supposedly :-) -*/ - +#ifndef __ASSEMBLY__ +/* V0 prom device operations. */ struct linux_dev_v0_funcs { - int (*v0_devopen)(char *device_str); - int (*v0_devclose)(int dev_desc); - int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char* buf); - int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char* buf); - int (*v0_wrnetdev)(int dev_desc, int num_bytes, char* buf); - int (*v0_rdnetdev)(int dev_desc, int num_bytes, char* buf); - int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char* buf); - int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char* buf); - int (*v0_seekdev)(int dev_desc, long logical_offst, int from); + int (*v0_devopen)(char *device_str); + int (*v0_devclose)(int dev_desc); + int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_seekdev)(int dev_desc, long logical_offst, int from); }; -/* The OpenBoot Prom device operations for version-2 interfaces are both - good and bad. They now allow you to address ANY device whatsoever - that is in the machine via these funny "device paths". They look like - this: - - "/sbus/esp@0,0xf004002c/sd@3,1" - - You can basically reference any device on the machine this way, and - you pass this string to the v2 dev_ops. Producing these strings all - the time can be a pain in the rear after a while. Why v2 has memory - allocations in here are beyond me. Perhaps they figure that if you - are going to use only the prom's device drivers then your memory - management is either non-existent or pretty sad. :-) -*/ - +/* V2 and later prom device operations. */ struct linux_dev_v2_funcs { - int (*v2_aieee)(int d); /* figure this out later... */ - - /* "dumb" prom memory management routines, probably - only safe to use for mapping device address spaces... - */ - - char* (*v2_dumb_mem_alloc)(char* va, unsigned sz); - void (*v2_dumb_mem_free)(char* va, unsigned sz); - - /* "dumb" mmap() munmap(), copy on write? what's that? */ - char* (*v2_dumb_mmap)(char* virta, int asi, unsigned prot, unsigned sz); - void (*v2_dumb_munmap)(char* virta, unsigned size); - - /* Basic Operations, self-explanatory */ - int (*v2_dev_open)(char *devpath); - void (*v2_dev_close)(int d); - int (*v2_dev_read)(int d, char* buf, int nbytes); - int (*v2_dev_write)(int d, char* buf, int nbytes); - void (*v2_dev_seek)(int d, int hi, int lo); - - /* huh? */ - void (*v2_wheee2)(void); - void (*v2_wheee3)(void); + int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */ + char * (*v2_dumb_mem_alloc)(char *va, unsigned sz); + void (*v2_dumb_mem_free)(char *va, unsigned sz); + + /* To map devices into virtual I/O space. */ + char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz); + void (*v2_dumb_munmap)(char *virta, unsigned size); + + int (*v2_dev_open)(char *devpath); + void (*v2_dev_close)(int d); + int (*v2_dev_read)(int d, char *buf, int nbytes); + int (*v2_dev_write)(int d, char *buf, int nbytes); + int (*v2_dev_seek)(int d, int hi, int lo); + + /* Never issued (multistage load support) */ + void (*v2_wheee2)(void); + void (*v2_wheee3)(void); }; -/* Just like the device ops, they slightly screwed up the mem-list - from v0 to v2. Probably easier on the prom-writer dude, sucks for - us though. See above comment about prom-vm mapped address space - magic numbers. :-( -*/ - struct linux_mlist_v0 { - struct linux_mlist_v0 *theres_more; - char* start_adr; + struct linux_mlist_v0 *theres_more; + char *start_adr; unsigned num_bytes; }; -/* The linux_mlist_v0's are pointer by this structure. One list - per description. This means one list for total physical memory, - one for prom's address mapping, and one for physical mem left after - the kernel is loaded. - */ struct linux_mem_v0 { - struct linux_mlist_v0 **v0_totphys; /* all of physical */ - struct linux_mlist_v0 **v0_prommap; /* addresses map'd by prom */ - struct linux_mlist_v0 **v0_available; /* what phys. is left over */ + struct linux_mlist_v0 **v0_totphys; + struct linux_mlist_v0 **v0_prommap; + struct linux_mlist_v0 **v0_available; /* What we can use */ }; /* Arguments sent to the kernel from the boot prompt. */ - struct linux_arguments_v0 { - char *argv[8]; /* argv format for boot string */ - char args[100]; /* string space */ - char boot_dev[2]; /* e.g., "sd" for `b sd(...' */ - int boot_dev_ctrl; /* controller # */ - int boot_dev_unit; /* unit # */ - int dev_partition; /* partition # */ - char *kernel_file_name; /* kernel to boot, e.g., "vmunix" */ - void *aieee1; /* give me some time :> */ + char *argv[8]; + char args[100]; + char boot_dev[2]; + int boot_dev_ctrl; + int boot_dev_unit; + int dev_partition; + char *kernel_file_name; + void *aieee1; /* XXX */ }; -/* Prom version-2 gives us the raw strings for boot arguments and - boot device path. We also get the stdin and stdout file pseudo - descriptors for use with the mungy v2 device functions. -*/ +/* V2 and up boot things. */ struct linux_bootargs_v2 { - char **bootpath; /* V2: Path to boot device */ - char **bootargs; /* V2: Boot args */ - int *fd_stdin; /* V2: Stdin descriptor */ - int *fd_stdout; /* V2: Stdout descriptor */ + char **bootpath; + char **bootargs; + int *fd_stdin; + int *fd_stdout; }; -/* This is the actual Prom Vector from which everything else is accessed - via struct and function pointers, etc. The prom when it loads us into - memory plops a pointer to this master structure in register %o0 before - it jumps to the kernel start address. I will update this soon to cover - the v3 semantics (cpu_start, cpu_stop and other SMP fun things). :-) -*/ +/* The top level PROM vector. */ struct linux_romvec { /* Version numbers. */ - unsigned int pv_magic_cookie; /* Magic Mushroom... */ - unsigned int pv_romvers; /* iface vers (0, 2, or 3) */ - unsigned int pv_plugin_revision; /* revision relative to above vers */ - unsigned int pv_printrev; /* print revision */ - - /* Version 0 memory descriptors (see below). */ - struct linux_mem_v0 pv_v0mem; /* V0: Memory description lists. */ + unsigned int pv_magic_cookie; + unsigned int pv_romvers; + unsigned int pv_plugin_revision; + unsigned int pv_printrev; - /* Node operations (see below). */ - struct linux_nodeops *pv_nodeops; /* node functions, gets device data */ + /* Version 0 memory descriptors. */ + struct linux_mem_v0 pv_v0mem; - char **pv_bootstr; /* Boot command, eg sd(0,0,0)vmunix */ + /* Node operations. */ + struct linux_nodeops *pv_nodeops; - struct linux_dev_v0_funcs pv_v0devops; /* V0: device ops */ + char **pv_bootstr; + struct linux_dev_v0_funcs pv_v0devops; - /* - * PROMDEV_* cookies. I fear these may vanish in lieu of fd0/fd1 - * (see below) in future PROMs, but for now they work fine. - */ - char *pv_stdin; /* stdin cookie */ - char *pv_stdout; /* stdout cookie */ + char *pv_stdin; + char *pv_stdout; #define PROMDEV_KBD 0 /* input from keyboard */ #define PROMDEV_SCREEN 0 /* output to screen */ #define PROMDEV_TTYA 1 /* in/out to ttya */ #define PROMDEV_TTYB 2 /* in/out to ttyb */ /* Blocking getchar/putchar. NOT REENTRANT! (grr) */ - int (*pv_getchar)(void); - void (*pv_putchar)(int ch); + int (*pv_getchar)(void); + void (*pv_putchar)(int ch); - /* Non-blocking variants that return -1 on error. */ - int (*pv_nbgetchar)(void); - int (*pv_nbputchar)(int ch); + /* Non-blocking variants. */ + int (*pv_nbgetchar)(void); + int (*pv_nbputchar)(int ch); - /* Put counted string (can be very slow). */ - void (*pv_putstr)(char *str, int len); + void (*pv_putstr)(char *str, int len); /* Miscellany. */ - void (*pv_reboot)(char *bootstr); - void (*pv_printf)(const char *fmt, ...); - void (*pv_abort)(void); /* BREAK key abort */ - int *pv_ticks; /* milliseconds since last reset */ - void (*pv_halt)(void); /* End the show */ - void (**pv_synchook)(void); /* "sync" ptr to function */ - - /* - * This eval's a FORTH string. Unfortunately, its interface - * changed between V0 and V2, which gave us much pain. - */ + void (*pv_reboot)(char *bootstr); + void (*pv_printf)(__const__ char *fmt, ...); + void (*pv_abort)(void); + __volatile__ int *pv_ticks; + void (*pv_halt)(void); + void (**pv_synchook)(void); + + /* Evaluate a forth string, not different proto for V0 and V2->up. */ union { - void (*v0_eval)(int len, char *str); - void (*v2_eval)(char *str); + void (*v0_eval)(int len, char *str); + void (*v2_eval)(char *str); } pv_fortheval; - struct linux_arguments_v0 **pv_v0bootargs; /* V0: Boot args */ + struct linux_arguments_v0 **pv_v0bootargs; - /* Extract Ethernet address from network device. */ - unsigned int (*pv_enaddr)(int d, char *enaddr); + /* Get ether address. */ + unsigned int (*pv_enaddr)(int d, char *enaddr); - struct linux_bootargs_v2 pv_v2bootargs; /* V2: Boot args+std-in/out */ - struct linux_dev_v2_funcs pv_v2devops; /* V2: device operations */ + struct linux_bootargs_v2 pv_v2bootargs; + struct linux_dev_v2_funcs pv_v2devops; - int whatzthis[15]; /* huh? */ + int filler[15]; - /* - * The following is machine-dependent. - * - * The sun4c needs a PROM function to set a PMEG for another - * context, so that the kernel can map itself in all contexts. - * It is not possible simply to set the context register, because - * contexts 1 through N may have invalid translations for the - * current program counter. The hardware has a mode in which - * all memory references go to the PROM, so the PROM can do it - * easily. - */ - void (*pv_setctxt)(int ctxt, char* va, int pmeg); + /* This one is sun4c/sun4 only. */ + void (*pv_setctxt)(int ctxt, char *va, int pmeg); /* Prom version 3 Multiprocessor routines. This stuff is crazy. * No joke. Calling these when there is only one cpu probably * crashes the machine, have to test this. :-) - */ + */ /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context * 'thiscontext' executing at address 'prog_counter' - * - * XXX Have to figure out what 'cancontext' means. - */ - - int (*v3_cpustart)(unsigned int whichcpu, int cancontext, - int thiscontext, char* prog_counter); + */ + int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr, + int thiscontext, char *prog_counter); /* v3_cpustop() will cause cpu 'whichcpu' to stop executing * until a resume cpu call is made. */ - int (*v3_cpustop)(unsigned int whichcpu); /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or * resume cpu call is made. */ - int (*v3_cpuidle)(unsigned int whichcpu); /* v3_cpuresume() will resume processor 'whichcpu' executing * starting with whatever 'pc' and 'npc' were left at the * last 'idle' or 'stop' call. */ - int (*v3_cpuresume)(unsigned int whichcpu); +}; +/* Routines for traversing the prom device tree. */ +struct linux_nodeops { + int (*no_nextnode)(int node); + int (*no_child)(int node); + int (*no_proplen)(int node, char *name); + int (*no_getprop)(int node, char *name, char *val); + int (*no_setprop)(int node, char *name, char *val, int len); + char * (*no_nextprop)(int node, char *name); }; -/* - * In addition to the global stuff defined in the PROM vectors above, - * the PROM has quite a collection of `nodes'. A node is described by - * an integer---these seem to be internal pointers, actually---and the - * nodes are arranged into an N-ary tree. Each node implements a fixed - * set of functions, as described below. The first two deal with the tree - * structure, allowing traversals in either breadth- or depth-first fashion. - * The rest deal with `properties'. - * - * A node property is simply a name/value pair. The names are C strings - * (NUL-terminated); the values are arbitrary byte strings (counted strings). - * Many values are really just C strings. Sometimes these are NUL-terminated, - * sometimes not, depending on the the interface version; v0 seems to - * terminate and v2 not. Many others are simply integers stored as four - * bytes in machine order: you just get them and go. The third popular - * format is an `address', which is made up of one or more sets of three - * integers as defined below. - * - * One uses these functions to traverse the device tree to see what devices - * this machine has attached to it. - * - * N.B.: for the `next' functions, next(0) = first, and next(last) = 0. - * Whoever designed this part had good taste. On the other hand, these - * operation vectors are global, rather than per-node, yet the pointers - * are not in the openprom vectors but rather found by indirection from - * there. So the taste balances out. - */ -struct linux_prom_addr { - int oa_space; /* address space (may be relative) */ - unsigned int oa_base; /* address within space */ - unsigned int oa_size; /* extent (number of bytes) */ +/* More fun PROM structures for device probing. */ +#define PROMREG_MAX 16 +#define PROMVADDR_MAX 16 +#define PROMINTR_MAX 15 + +struct linux_prom_registers { + int which_io; /* is this in OBIO space? */ + char *phys_addr; /* The physical address of this register */ + int reg_size; /* How many bytes does this register take up? */ }; -struct linux_nodeops { - /* - * Tree traversal. - */ - int (*no_nextnode)(int node); /* next(node) */ - int (*no_child)(int node); /* first child */ +struct linux_prom_irqs { + int pri; /* IRQ priority */ + int vector; /* This is foobar, what does it do? */ +}; - /* - * Property functions. Proper use of getprop requires calling - * proplen first to make sure it fits. Kind of a pain, but no - * doubt more convenient for the PROM coder. - */ - int (*no_proplen)(int node, char* name); - int (*no_getprop)(int node, char* name, char* val); - int (*no_setprop)(int node, char* name, char* val, int len); - char* (*no_nextprop)(int node, char* name); +/* Element of the "ranges" vector */ +struct linux_prom_ranges { + unsigned int ot_child_space; + unsigned int ot_child_base; /* Bus feels this */ + unsigned int ot_parent_space; + unsigned int ot_parent_base; /* CPU looks from here */ + unsigned int or_size; }; +#endif /* !(__ASSEMBLY__) */ + #endif /* !(__SPARC_OPENPROM_H) */ diff --git a/include/asm-sparc/openpromio.h b/include/asm-sparc/openpromio.h new file mode 100644 index 000000000..8989909de --- /dev/null +++ b/include/asm-sparc/openpromio.h @@ -0,0 +1,70 @@ +#ifndef _SPARC_OPENPROMIO_H +#define _SPARC_OPENPROMIO_H + +#include <linux/ioctl.h> +#include <linux/types.h> + +/* + * SunOS and Solaris /dev/openprom definitions. The ioctl values + * were chosen to be exactly equal to the SunOS equivalents. + */ + +struct openpromio +{ + u_int oprom_size; /* Actual size of the oprom_array. */ + char oprom_array[1]; /* Holds property names and values. */ +}; + +#define OPROMMAXPARAM 4096 /* Maximum size of oprom_array. */ + +#define OPROMGETOPT 0x20004F01 +#define OPROMSETOPT 0x20004F02 +#define OPROMNXTOPT 0x20004F03 +#define OPROMSETOPT2 0x20004F04 +#define OPROMNEXT 0x20004F05 +#define OPROMCHILD 0x20004F06 +#define OPROMGETPROP 0x20004F07 +#define OPROMNXTPROP 0x20004F08 +#define OPROMU2P 0x20004F09 +#define OPROMGETCONS 0x20004F0A +#define OPROMGETFBNAME 0x20004F0B +#define OPROMGETBOOTARGS 0x20004F0C + +/* + * Return values from OPROMGETCONS: + */ + +#define OPROMCONS_NOT_WSCONS 0 +#define OPROMCONS_STDIN_IS_KBD 0x1 /* stdin device is kbd */ +#define OPROMCONS_STDOUT_IS_FB 0x2 /* stdout is a framebuffer */ +#define OPROMCONS_OPENPROM 0x4 /* supports openboot */ + + +/* + * NetBSD/OpenBSD /dev/openprom definitions. + */ + +struct opiocdesc +{ + int op_nodeid; /* PROM Node ID (value-result) */ + int op_namelen; /* Length of op_name. */ + char *op_name; /* Pointer to the property name. */ + int op_buflen; /* Length of op_buf (value-result) */ + char *op_buf; /* Pointer to buffer. */ +}; + +#define OPIOCGET _IOWR('O', 1, struct opiocdesc) +#define OPIOCSET _IOW('O', 2, struct opiocdesc) +#define OPIOCNEXTPROP _IOWR('O', 3, struct opiocdesc) +#define OPIOCGETOPTNODE _IOR('O', 4, int) +#define OPIOCGETNEXT _IOWR('O', 5, int) +#define OPIOCGETCHILD _IOWR('O', 6, int) + + +#ifdef __KERNEL__ +int openprom_init(void); +#endif + + +#endif /* _SPARC_OPENPROMIO_H */ + diff --git a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h new file mode 100644 index 000000000..84248e0eb --- /dev/null +++ b/include/asm-sparc/oplib.h @@ -0,0 +1,297 @@ +/* $Id: oplib.h,v 1.12 1996/10/31 06:29:13 davem Exp $ + * oplib.h: Describes the interface and available routines in the + * Linux Prom library. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __SPARC_OPLIB_H +#define __SPARC_OPLIB_H + +#include <asm/openprom.h> + +/* The master romvec pointer... */ +extern struct linux_romvec *romvec; + +/* Enumeration to describe the prom major version we have detected. */ +enum prom_major_version { + PROM_V0, /* Original sun4c V0 prom */ + PROM_V2, /* sun4c and early sun4m V2 prom */ + PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */ + PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */ + PROM_AP1000, /* actually no prom at all */ +}; + +extern enum prom_major_version prom_vers; +/* Revision, and firmware revision. */ +extern unsigned int prom_rev, prom_prev; + +/* Root node of the prom device tree, this stays constant after + * initialization is complete. + */ +extern int prom_root_node; + +/* Pointer to prom structure containing the device tree traversal + * and usage utility functions. Only prom-lib should use these, + * users use the interface defined by the library only! + */ +extern struct linux_nodeops *prom_nodeops; + +/* The functions... */ + +/* You must call prom_init() before using any of the library services, + * preferably as early as possible. Pass it the romvec pointer. + */ +extern void prom_init(struct linux_romvec *rom_ptr); + +/* Boot argument acquisition, returns the boot command line string. */ +extern char *prom_getbootargs(void); + +/* Device utilities. */ + +/* Map and unmap devices in IO space at virtual addresses. Note that the + * virtual address you pass is a request and the prom may put your mappings + * somewhere else, so check your return value as that is where your new + * mappings really are! + * + * Another note, these are only available on V2 or higher proms! + */ +extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); +extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); + +/* Device operations. */ + +/* Open the device described by the passed string. Note, that the format + * of the string is different on V0 vs. V2->higher proms. The caller must + * know what he/she is doing! Returns the device descriptor, an int. + */ +extern int prom_devopen(char *device_string); + +/* Close a previously opened device described by the passed integer + * descriptor. + */ +extern int prom_devclose(int device_handle); + +/* Do a seek operation on the device described by the passed integer + * descriptor. + */ +extern void prom_seek(int device_handle, unsigned int seek_hival, + unsigned int seek_lowval); + +/* Machine memory configuration routine. */ + +/* This function returns a V0 format memory descriptor table, it has three + * entries. One for the total amount of physical ram on the machine, one + * for the amount of physical ram available, and one describing the virtual + * areas which are allocated by the prom. So, in a sense the physical + * available is a calculation of the total physical minus the physical mapped + * by the prom with virtual mappings. + * + * These lists are returned pre-sorted, this should make your life easier + * since the prom itself is way too lazy to do such nice things. + */ +extern struct linux_mem_v0 *prom_meminfo(void); + +/* Miscellaneous routines, don't really fit in any category per se. */ + +/* Reboot the machine with the command line passed. */ +extern void prom_reboot(char *boot_command); + +/* Evaluate the forth string passed. */ +extern void prom_feval(char *forth_string); + +/* Enter the prom, with possibility of continuation with the 'go' + * command in newer proms. + */ +extern void prom_cmdline(void); + +/* Enter the prom, with no chance of continuation for the stand-alone + * which calls this. + */ +extern void prom_halt(void); + +/* Set the PROM 'sync' callback function to the passed function pointer. + * When the user gives the 'sync' command at the prom prompt while the + * kernel is still active, the prom will call this routine. + * + * XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX + */ +typedef void (*sync_func_t)(void); +extern void prom_setsync(sync_func_t func_ptr); + +/* Acquire the IDPROM of the root node in the prom device tree. This + * gets passed a buffer where you would like it stuffed. The return value + * is the format type of this idprom or 0xff on error. + */ +extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); + +/* Get the prom major version. */ +extern int prom_version(void); + +/* Get the prom plugin revision. */ +extern int prom_getrev(void); + +/* Get the prom firmware revision. */ +extern int prom_getprev(void); + +/* Character operations to/from the console.... */ + +/* Non-blocking get character from console. */ +extern int prom_nbgetchar(void); + +/* Non-blocking put character to console. */ +extern int prom_nbputchar(char character); + +/* Blocking get character from console. */ +extern char prom_getchar(void); + +/* Blocking put character to console. */ +extern void prom_putchar(char character); + +/* Prom's internal printf routine, don't use in kernel/boot code. */ +void prom_printf(char *fmt, ...); + +/* Query for input device type */ + +enum prom_input_device { + PROMDEV_IKBD, /* input from keyboard */ + PROMDEV_ITTYA, /* input from ttya */ + PROMDEV_ITTYB, /* input from ttyb */ + PROMDEV_I_UNK, +}; + +extern enum prom_input_device prom_query_input_device(void); + +/* Query for output device type */ + +enum prom_output_device { + PROMDEV_OSCREEN, /* to screen */ + PROMDEV_OTTYA, /* to ttya */ + PROMDEV_OTTYB, /* to ttyb */ + PROMDEV_O_UNK, +}; + +extern enum prom_output_device prom_query_output_device(void); + +/* Multiprocessor operations... */ + +/* Start the CPU with the given device tree node, context table, and context + * at the passed program counter. + */ +extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table, + int context, char *program_counter); + +/* Stop the CPU with the passed device tree node. */ +extern int prom_stopcpu(int cpunode); + +/* Idle the CPU with the passed device tree node. */ +extern int prom_idlecpu(int cpunode); + +/* Re-Start the CPU with the passed device tree node. */ +extern int prom_restartcpu(int cpunode); + +/* PROM memory allocation facilities... */ + +/* Allocated at possibly the given virtual address a chunk of the + * indicated size. + */ +extern char *prom_alloc(char *virt_hint, unsigned int size); + +/* Free a previously allocated chunk. */ +extern void prom_free(char *virt_addr, unsigned int size); + +/* Sun4/sun4c specific memory-management startup hook. */ + +/* Map the passed segment in the given context at the passed + * virtual address. + */ +extern void prom_putsegment(int context, unsigned long virt_addr, + int physical_segment); + +/* PROM device tree traversal functions... */ + +/* Get the child node of the given node, or zero if no child exists. */ +extern int prom_getchild(int parent_node); + +/* Get the next sibling node of the given node, or zero if no further + * siblings exist. + */ +extern int prom_getsibling(int node); + +/* Get the length, at the passed node, of the given property type. + * Returns -1 on error (ie. no such property at this node). + */ +extern int prom_getproplen(int thisnode, char *property); + +/* Fetch the requested property using the given buffer. Returns + * the number of bytes the prom put into your buffer or -1 on error. + */ +extern int prom_getproperty(int thisnode, char *property, + char *prop_buffer, int propbuf_size); + +/* Acquire an integer property. */ +extern int prom_getint(int node, char *property); + +/* Acquire an integer property, with a default value. */ +extern int prom_getintdefault(int node, char *property, int defval); + +/* Acquire a boolean property, 0=FALSE 1=TRUE. */ +extern int prom_getbool(int node, char *prop); + +/* Acquire a string property, null string on error. */ +extern void prom_getstring(int node, char *prop, char *buf, int bufsize); + +/* Does the passed node have the given "name"? YES=1 NO=0 */ +extern int prom_nodematch(int thisnode, char *name); + +/* Puts in buffer a prom name in the form name@x,y or name (x for which_io + * and y for first regs phys address + */ +extern int prom_getname(int node, char *buf, int buflen); + +/* Search all siblings starting at the passed node for "name" matching + * the given string. Returns the node on success, zero on failure. + */ +extern int prom_searchsiblings(int node_start, char *name); + +/* Return the first property type, as a string, for the given node. + * Returns a null string on error. + */ +extern char *prom_firstprop(int node); + +/* Returns the next property after the passed property for the given + * node. Returns null string on failure. + */ +extern char *prom_nextprop(int node, char *prev_property); + +/* Returns 1 if the specified node has given property. */ +extern int prom_node_has_property(int node, char *property); + +/* Set the indicated property at the given node with the passed value. + * Returns the number of bytes of your value that the prom took. + */ +extern int prom_setprop(int node, char *prop_name, char *prop_value, + int value_size); + +extern int prom_pathtoinode(char *path); +extern int prom_inst2pkg(int); + +/* Dorking with Bus ranges... */ + +/* Adjust reg values with the passed ranges. */ +extern void prom_adjust_regs(struct linux_prom_registers *regp, int nregs, + struct linux_prom_ranges *rangep, int nranges); + +/* Adjust child ranges with the passed parent ranges. */ +extern void prom_adjust_ranges(struct linux_prom_ranges *cranges, int ncranges, + struct linux_prom_ranges *pranges, int npranges); + +/* Apply promlib probed OBIO ranges to registers. */ +extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs); + +/* Apply ranges of any prom node (and optionally parent node as well) to registers. */ +extern void prom_apply_generic_ranges(int node, int parent, + struct linux_prom_registers *sbusregs, int nregs); + + +#endif /* !(__SPARC_OPLIB_H) */ diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h index a048ac76c..43bbf1847 100644 --- a/include/asm-sparc/page.h +++ b/include/asm-sparc/page.h @@ -1,31 +1,42 @@ -/* page.h: Various defines and such for MMU operations on the Sparc for - the Linux kernel. - - Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) -*/ +/* $Id: page.h,v 1.30 1996/10/27 08:55:30 davem Exp $ + * page.h: Various defines and such for MMU operations on the Sparc for + * the Linux kernel. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ #ifndef _SPARC_PAGE_H #define _SPARC_PAGE_H -#include <asm/asi.h> /* for get/set segmap/pte routines */ -#include <asm/contregs.h> /* for switch_to_context */ +#include <asm/head.h> /* for KERNBASE */ -#define PAGE_SHIFT 12 /* This is the virtual page... */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1 << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) +#ifdef __KERNEL__ #ifndef __ASSEMBLY__ -#define PAGE_SIZE (1UL << PAGE_SHIFT) -/* to mask away the intra-page address bits */ -#define PAGE_MASK (~(PAGE_SIZE-1)) +#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) -#ifdef __KERNEL__ +extern unsigned long page_offset; + +#define PAGE_OFFSET (page_offset) + +/* translate between physical and virtual addresses */ +extern unsigned long (*mmu_v2p)(unsigned long); +extern unsigned long (*mmu_p2v)(unsigned long); + +#define __pa(x) mmu_v2p(x) +#define __va(x) mmu_p2v(x) /* The following structure is used to hold the physical - * memory configuration of the machine. This is filled - * in probe_memory() and is later used by mem_init() to - * set up mem_map[]. We statically allocate 14 of these - * structs, this is arbitrary. The entry after the last - * valid one has num_bytes==0. + * memory configuration of the machine. This is filled in + * probe_memory() and is later used by mem_init() to set up + * mem_map[]. We statically allocate SPARC_PHYS_BANKS of + * these structs, this is arbitrary. The entry after the + * last valid one has num_bytes==0. */ struct sparc_phys_banks { @@ -33,148 +44,95 @@ struct sparc_phys_banks { unsigned long num_bytes; }; -#define CONFIG_STRICT_MM_TYPECHECKS +#define SPARC_PHYS_BANKS 32 + +extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; + +/* Cache alias structure. Entry is valid if context != -1. */ +struct cache_palias { + unsigned long vaddr; + int context; +}; + +extern struct cache_palias *sparc_aliases; -#ifdef CONFIG_STRICT_MM_TYPECHECKS +/* passing structs on the Sparc slow us down tremendously... */ + +/* #define STRICT_MM_TYPECHECKS */ + +#ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long iopte; } iopte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long ctxd; } ctxd_t; typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct { unsigned long iopgprot; } iopgprot_t; #define pte_val(x) ((x).pte) +#define iopte_val(x) ((x).iopte) #define pmd_val(x) ((x).pmd) #define pgd_val(x) ((x).pgd) +#define ctxd_val(x) ((x).ctxd) #define pgprot_val(x) ((x).pgprot) +#define iopgprot_val(x) ((x).iopgprot) #define __pte(x) ((pte_t) { (x) } ) +#define __iopte(x) ((iopte_t) { (x) } ) #define __pmd(x) ((pmd_t) { (x) } ) #define __pgd(x) ((pgd_t) { (x) } ) +#define __ctxd(x) ((ctxd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) +#define __iopgprot(x) ((iopgprot_t) { (x) } ) #else /* * .. while these make it easier on the compiler */ typedef unsigned long pte_t; +typedef unsigned long iopte_t; typedef unsigned long pmd_t; typedef unsigned long pgd_t; +typedef unsigned long ctxd_t; typedef unsigned long pgprot_t; +typedef unsigned long iopgprot_t; #define pte_val(x) (x) +#define iopte_val(x) (x) #define pmd_val(x) (x) #define pgd_val(x) (x) +#define ctxd_val(x) (x) #define pgprot_val(x) (x) +#define iopgprot_val(x) (x) #define __pte(x) (x) +#define __iopte(x) (x) #define __pmd(x) (x) #define __pgd(x) (x) +#define __ctxd(x) (x) #define __pgprot(x) (x) +#define __iopgprot(x) (x) #endif -/* The current va context is global and known, so all that is needed to - * do an invalidate is flush the VAC. - */ +#define copy_page(from,to) memcpy((void *) to, (void *) from, PAGE_SIZE) -#define invalidate() flush_vac_context() /* how conveeeiiiiinnnient :> */ +extern unsigned long sparc_unmapped_base; -#define copy_page(from,to) memcpy((void *) to, (void *) from, PAGE_SIZE) +#define TASK_UNMAPPED_BASE (sparc_unmapped_base) /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -#define PAGE_OFFSET 0 -#define MAP_NR(addr) (((unsigned long)(addr)) >> PAGE_SHIFT) -#define MAP_PAGE_RESERVED (1<<15) - - -#endif /* !(__ASSEMBLY__) */ - -/* The rest is kind of funky because on the sparc, the offsets into the mmu - * entries are encoded in magic alternate address space tables. I will - * probably find some nifty inline assembly routines to do the equivalent. - * Much thought must go into this code. (davem@caip.rutgers.edu) +/* Now, to allow for very large physical memory configurations we + * place the page pool both above the kernel and below the kernel. */ +#define MAP_NR(addr) ((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT) -/* Bitfields within a Sparc sun4c PTE (page table entry). */ - -#define PTE_V 0x80000000 /* valid bit */ -#define PTE_ACC 0x60000000 /* access bits */ -#define PTE_W 0x40000000 /* writable bit */ -#define PTE_P 0x20000000 /* privileged page */ -#define PTE_NC 0x10000000 /* page is non-cacheable */ -#define PTE_TYP 0x0c000000 /* page type field */ -#define PTE_RMEM 0x00000000 /* type == on board real memory */ -#define PTE_IO 0x04000000 /* type == i/o area */ -#define PTE_VME16 0x08000000 /* type == 16-bit VME area */ -#define PTE_VME32 0x0c000000 /* type == 32-bit VME area */ -#define PTE_R 0x02000000 /* page has been referenced */ -#define PTE_M 0x01000000 /* page has been modified */ -#define PTE_RESV 0x00f80000 /* reserved bits */ -#define PTE_PHYPG 0x0007ffff /* phys pg number, sun4c only uses 16bits */ - -extern __inline__ unsigned long get_segmap(unsigned long addr) -{ - register unsigned long entry; - - __asm__ __volatile__("lduba [%1] 0x3, %0" : - "=r" (entry) : - "r" (addr)); - - return (entry&0x7f); -} - -extern __inline__ void put_segmap(unsigned long addr, unsigned long entry) -{ - - __asm__ __volatile__("stba %1, [%0] 0x3" : : "r" (addr), "r" (entry&0x7f)); - - return; -} - -extern __inline__ unsigned long get_pte(unsigned long addr) -{ - register unsigned long entry; - - __asm__ __volatile__("lda [%1] 0x4, %0" : - "=r" (entry) : - "r" (addr)); - return entry; -} - -extern __inline__ void put_pte(unsigned long addr, unsigned long entry) -{ - __asm__ __volatile__("sta %1, [%0] 0x4" : : - "r" (addr), - "r" (entry)); - - return; -} - -extern __inline__ void switch_to_context(int context) -{ - __asm__ __volatile__("stba %0, [%1] 0x2" : : - "r" (context), - "r" (0x30000000)); - - return; -} - -extern __inline__ int get_context(void) -{ - register int ctx; - - __asm__ __volatile__("lduba [%1] 0x2, %0" : - "=r" (ctx) : - "r" (0x30000000)); - - return ctx; -} - -typedef unsigned short mem_map_t; +#endif /* !(__ASSEMBLY__) */ #endif /* __KERNEL__ */ diff --git a/include/asm-sparc/param.h b/include/asm-sparc/param.h index 45a9133af..7e14a410e 100644 --- a/include/asm-sparc/param.h +++ b/include/asm-sparc/param.h @@ -1,3 +1,4 @@ +/* $Id: param.h,v 1.3 1995/11/25 02:32:18 davem Exp $ */ #ifndef _ASMSPARC_PARAM_H #define _ASMSPARC_PARAM_H @@ -5,7 +6,7 @@ #define HZ 100 #endif -#define EXEC_PAGESIZE 4096 +#define EXEC_PAGESIZE 8192 /* Thanks for sun4's we carry baggage... */ #ifndef NGROUPS #define NGROUPS 32 diff --git a/include/asm-sparc/pconf.h b/include/asm-sparc/pconf.h new file mode 100644 index 000000000..d73c1f1c4 --- /dev/null +++ b/include/asm-sparc/pconf.h @@ -0,0 +1,25 @@ +/* $Id: pconf.h,v 1.3 1996/04/25 06:13:25 davem Exp $ + * pconf.h: pathconf() and fpathconf() defines for SunOS + * system call compatibility. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_PCONF_H +#define _SPARC_PCONF_H + +#include <linux/fs.h> +#include <linux/limits.h> + +#define _PCONF_LINK 1 /* Max number of links to an object */ +#define _PCONF_CANON 2 /* TTY input buffer line size */ +#define _PCONF_INPUT 3 /* Biggest packet a tty can imbibe at once */ +#define _PCONF_NAME 4 /* Filename length max */ +#define _PCONF_PATH 5 /* Max size of a pathname */ +#define _PCONF_PIPE 6 /* Buffer size for a pipe */ +#define _PCONF_CHRESTRICT 7 /* Can only root chown files? */ +#define _PCONF_NOTRUNC 8 /* Are pathnames truncated if too big? */ +#define _PCONF_VDISABLE 9 /* Magic char to disable special tty chars */ +#define _PCONF_MAXPCONF 9 + +#endif /* !(_SPARC_PCONF_H) */ diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h index 45b652108..02435d788 100644 --- a/include/asm-sparc/pgtable.h +++ b/include/asm-sparc/pgtable.h @@ -1,3 +1,4 @@ +/* $Id: pgtable.h,v 1.51 1996/10/27 08:55:32 davem Exp $ */ #ifndef _SPARC_PGTABLE_H #define _SPARC_PGTABLE_H @@ -7,100 +8,133 @@ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ -/* PMD_SHIFT determines the size of the area a second-level page table can map */ -#define PMD_SHIFT 18 -#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 18 -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) -#define PGDIR_ALIGN(addr) (((addr)+PGDIR_SIZE-1)&PGDIR_MASK) +#include <linux/mm.h> +#include <asm/asi.h> +#include <asm/pgtsun4c.h> +#include <asm/pgtsrmmu.h> +#include <asm/vac-ops.h> +#include <asm/oplib.h> +#include <asm/sbus.h> + +extern void load_mmu(void); +extern int io_remap_page_range(unsigned long from, unsigned long to, + unsigned long size, pgprot_t prot, int space); + +extern void (*quick_kernel_fault)(unsigned long); + +/* Allocate a block of RAM which is aligned to its size. + This procedure can be used until the call to mem_init(). */ +extern void *sparc_init_alloc(unsigned long *kbrk, unsigned long size); + +/* mmu-specific process creation/cloning/etc hooks. */ +extern void (*mmu_exit_hook)(void); +extern void (*mmu_flush_hook)(void); + +/* translate between physical and virtual addresses */ +extern unsigned long (*mmu_v2p)(unsigned long); +extern unsigned long (*mmu_p2v)(unsigned long); + +/* Routines for data transfer buffers. */ +extern char *(*mmu_lockarea)(char *, unsigned long); +extern void (*mmu_unlockarea)(char *, unsigned long); + +/* Routines for getting a dvma scsi buffer. */ +struct mmu_sglist { + char *addr; + char *__dont_touch; + unsigned int len; + char *dvma_addr; +}; +extern char *(*mmu_get_scsi_one)(char *, unsigned long, struct linux_sbus *sbus); +extern void (*mmu_get_scsi_sgl)(struct mmu_sglist *, int, struct linux_sbus *sbus); +extern void (*mmu_release_scsi_one)(char *, unsigned long, struct linux_sbus *sbus); +extern void (*mmu_release_scsi_sgl)(struct mmu_sglist *, int, struct linux_sbus *sbus); + +extern void (*mmu_map_dma_area)(unsigned long addr, int len); + +extern unsigned int pmd_shift; +extern unsigned int pmd_size; +extern unsigned int pmd_mask; +extern unsigned int (*pmd_align)(unsigned int); + +extern unsigned int pgdir_shift; +extern unsigned int pgdir_size; +extern unsigned int pgdir_mask; +extern unsigned int (*pgdir_align)(unsigned int); + +extern unsigned int ptrs_per_pte; +extern unsigned int ptrs_per_pmd; +extern unsigned int ptrs_per_pgd; + +extern unsigned int ptrs_per_page; + +extern unsigned long (*(vmalloc_start))(void); + +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_START vmalloc_start() + +extern pgprot_t page_none; +extern pgprot_t page_shared; +extern pgprot_t page_copy; +extern pgprot_t page_readonly; +extern pgprot_t page_kernel; + +#define PMD_SHIFT (pmd_shift) +#define PMD_SIZE (pmd_size) +#define PMD_MASK (pmd_mask) +#define PMD_ALIGN (pmd_align) +#define PGDIR_SHIFT (pgdir_shift) +#define PGDIR_SIZE (pgdir_size) +#define PGDIR_MASK (pgdir_mask) +#define PGDIR_ALIGN (pgdir_align) +#define PTRS_PER_PTE (ptrs_per_pte) +#define PTRS_PER_PMD (ptrs_per_pmd) +#define PTRS_PER_PGD (ptrs_per_pgd) + +#define PAGE_NONE (page_none) +#define PAGE_SHARED (page_shared) +#define PAGE_COPY (page_copy) +#define PAGE_READONLY (page_readonly) +#define PAGE_KERNEL (page_kernel) +#define PAGE_INVALID (page_invalid) + +/* Top-level page directory */ +extern pgd_t swapper_pg_dir[1024]; -/* - * Just following the i386 lead, because it works on the Sparc sun4c - * machines. Two-level, therefore there is no real PMD. +/* Page table for 0-4MB for everybody, on the Sparc this + * holds the same as on the i386. */ +extern pte_t pg0[1024]; -#define PTRS_PER_PTE 1024 -#define PTRS_PER_PMD 1 -#define PTRS_PER_PGD 1024 +extern unsigned long ptr_in_current_pgd; /* the no. of pointers that fit on a page: this will go away */ #define PTRS_PER_PAGE (PAGE_SIZE/sizeof(void*)) -/* 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. ;) - */ -#define VMALLOC_OFFSET (8*1024*1024) -#define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -#define VMALLOC_VMADDR(x) (TASK_SIZE + (unsigned long)(x)) - -/* - * Sparc page table fields. - */ - -#define _PAGE_VALID 0x80000000 /* valid page */ -#define _PAGE_WRITE 0x40000000 /* can be written to */ -#define _PAGE_PRIV 0x20000000 /* bit to signify privileged page */ -#define _PAGE_NOCACHE 0x10000000 /* non-cacheable page */ -#define _PAGE_REF 0x02000000 /* Page has been accessed/referenced */ -#define _PAGE_DIRTY 0x01000000 /* Page has been modified, is dirty */ -#define _PAGE_COW 0x00800000 /* COW page, hardware ignores this bit (untested) */ - - -/* Sparc sun4c mmu has only a writable bit. Thus if a page is valid it can be - * read in a load, and executed as code automatically. Although, the memory fault - * hardware does make a distinction between date-read faults and insn-read faults - * which is determined by which trap happened plus magic sync/async fault register - * values which must be checked in the actual fault handler. +/* Here is a trick, since mmap.c need the initializer elements for + * protection_map[] to be constant at compile time, I set the following + * to all zeros. I set it to the real values after I link in the + * appropriate MMU page table routines at boot time. */ - -/* We want the swapper not to swap out page tables, thus dirty and writable - * so that the kernel can change the entries as needed. Also valid for - * obvious reasons. - */ -#define _PAGE_TABLE (_PAGE_VALID | _PAGE_WRITE | _PAGE_DIRTY) -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_REF | _PAGE_DIRTY) - -#define PAGE_NONE __pgprot(_PAGE_VALID | _PAGE_REF) -#define PAGE_SHARED __pgprot(_PAGE_VALID | _PAGE_WRITE | _PAGE_REF) -#define PAGE_COPY __pgprot(_PAGE_VALID | _PAGE_REF | _PAGE_COW) -#define PAGE_READONLY __pgprot(_PAGE_VALID | _PAGE_REF) -#define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_WRITE | _PAGE_NOCACHE | _PAGE_REF | _PAGE_PRIV) -#define PAGE_INVALID __pgprot(_PAGE_PRIV) - -#define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | _PAGE_REF | (x)) - -/* I define these like the i386 does because the check for text or data fault - * is done at trap time by the low level handler. Maybe I can set these bits - * then once determined. I leave them like this for now though. - */ -#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 - - -extern unsigned long pg0[1024]; +#define __P000 __pgprot(0) +#define __P001 __pgprot(0) +#define __P010 __pgprot(0) +#define __P011 __pgprot(0) +#define __P100 __pgprot(0) +#define __P101 __pgprot(0) +#define __P110 __pgprot(0) +#define __P111 __pgprot(0) + +#define __S000 __pgprot(0) +#define __S001 __pgprot(0) +#define __S010 __pgprot(0) +#define __S011 __pgprot(0) +#define __S100 __pgprot(0) +#define __S101 __pgprot(0) +#define __S110 __pgprot(0) +#define __S111 __pgprot(0) + +extern int num_contexts; /* * BAD_PAGETABLE is used when we need a bogus page-table, while @@ -112,231 +146,219 @@ extern unsigned long pg0[1024]; extern pte_t __bad_page(void); extern pte_t * __bad_pagetable(void); -extern unsigned long __zero_page(void); - +extern unsigned long empty_zero_page; #define BAD_PAGETABLE __bad_pagetable() #define BAD_PAGE __bad_page() -#define ZERO_PAGE __zero_page() +#define ZERO_PAGE ((unsigned long)(&(empty_zero_page))) /* number of bits that fit into a memory pointer */ -#define BITS_PER_PTR (8*sizeof(unsigned long)) /* better check this stuff */ +#define BITS_PER_PTR (8*sizeof(unsigned long)) /* to align the pointer to a pointer address */ #define PTR_MASK (~(sizeof(void*)-1)) - #define SIZEOF_PTR_LOG2 2 +extern unsigned long (*pte_page)(pte_t); +extern unsigned long (*pmd_page)(pmd_t); +extern unsigned long (*pgd_page)(pgd_t); -/* to set the page-dir - * - * On the Sparc the page segments hold 64 pte's which means 256k/segment. - * Therefore there is no global idea of 'the' page directory, although we - * make a virtual one in kernel memory so that we can keep the stats on - * all the pages since not all can be loaded at once in the mmu. - */ - -#define SET_PAGE_DIR(tsk,pgdir) +extern void (*sparc_update_rootmmu_dir)(struct task_struct *, pgd_t *pgdir); +#define SET_PAGE_DIR(tsk,pgdir) sparc_update_rootmmu_dir(tsk, pgdir) + /* to find an entry in a page-table */ #define PAGE_PTR(address) \ ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) -extern unsigned long high_memory; +extern int (*pte_none)(pte_t); +extern int (*pte_present)(pte_t); +extern void (*pte_clear)(pte_t *); -extern inline int pte_none(pte_t pte) { return !pte_val(pte); } -extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; } -extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] > 1; } -extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } -extern inline void pte_reuse(pte_t *ptep) -{ - if(!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(ptep)]++; -} +extern int (*pmd_none)(pmd_t); +extern int (*pmd_bad)(pmd_t); +extern int (*pmd_present)(pmd_t); +extern void (*pmd_clear)(pmd_t *); -extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); } -extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || pmd_val(pmd) > high_memory; } -extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_VALID; } -extern inline int pmd_inuse(pmd_t *pmdp) { return 0; } -extern inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = 0; } -extern inline void pmd_reuse(pmd_t * pmdp) { } - -extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); } -extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~PAGE_MASK) != _PAGE_TABLE || pgd_val(pgd) > high_memory; } -extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_VALID; } -extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)] > 1; } -extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; } -extern inline void pgd_reuse(pgd_t *pgdp) -{ - if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED)) - mem_map[MAP_NR(pgdp)]++; -} +extern int (*pgd_none)(pgd_t); +extern int (*pgd_bad)(pgd_t); +extern int (*pgd_present)(pgd_t); +extern void (*pgd_clear)(pgd_t *); /* * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_VALID; } -extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } -extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_VALID; } -extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_REF; } -extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_REF; } -extern inline int pte_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; } - -extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_WRITE; return pte; } -extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_VALID; return pte; } -extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_VALID; return pte; } -extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } -extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_REF; return pte; } -extern inline pte_t pte_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; } -extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; } -extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_VALID; return pte; } -extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_VALID; return pte; } -extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } -extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_REF; return pte; } -extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; } +extern int (*pte_write)(pte_t); +extern int (*pte_dirty)(pte_t); +extern int (*pte_young)(pte_t); + +extern pte_t (*pte_wrprotect)(pte_t); +extern pte_t (*pte_mkclean)(pte_t); +extern pte_t (*pte_mkold)(pte_t); +extern pte_t (*pte_mkwrite)(pte_t); +extern pte_t (*pte_mkdirty)(pte_t); +extern pte_t (*pte_mkyoung)(pte_t); /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) -{ pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; } - -extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } - -extern inline unsigned long pte_page(pte_t pte) { return pte_val(pte) & PAGE_MASK; } - -extern inline unsigned long pmd_page(pmd_t pmd) { return pmd_val(pmd) & PAGE_MASK; } - -extern inline unsigned long pgd_page(pgd_t pgd) { return pgd_val(pgd) & PAGE_MASK; } +extern pte_t (*mk_pte)(unsigned long, pgprot_t); +extern pte_t (*mk_pte_phys)(unsigned long, pgprot_t); +extern pte_t (*mk_pte_io)(unsigned long, pgprot_t, int); -extern inline void pgd_set(pgd_t * pgdp, pte_t * ptep) -{ pgd_val(*pgdp) = _PAGE_TABLE | (unsigned long) ptep; } +extern void (*pgd_set)(pgd_t *, pmd_t *); -/* to find an entry in a page-table-directory */ -#define PAGE_DIR_OFFSET(tsk,address) \ -((((unsigned long)(address)) >> 22) + (pgd_t *) (tsk)->tss.cr3) +extern pte_t (*pte_modify)(pte_t, pgprot_t); /* to find an entry in a page-table-directory */ -extern inline pgd_t * pgd_offset(struct task_struct * tsk, unsigned long address) -{ - return (pgd_t *) tsk->tss.cr3 + (address >> PGDIR_SHIFT); -} +extern pgd_t * (*pgd_offset)(struct mm_struct *, unsigned long); /* Find an entry in the second-level page table.. */ -extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *) dir; -} +extern pmd_t * (*pmd_offset)(pgd_t *, unsigned long); /* Find an entry in the third-level page table.. */ -extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) -{ - return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); -} - +extern pte_t * (*pte_offset)(pmd_t *, unsigned long); /* * Allocate and free page tables. The xxx_kernel() versions are * used to allocate a kernel page table - this turns on ASN bits * if any, and marks the page tables reserved. */ -extern inline void pte_free_kernel(pte_t * pte) -{ - mem_map[MAP_NR(pte)] = 1; - free_page((unsigned long) pte); -} +extern void (*pte_free_kernel)(pte_t *); -extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) -{ - address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); - if (pmd_none(*pmd)) { - pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); - if (pmd_none(*pmd)) { - if (page) { - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page; - mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED; - return page + address; - } - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; - return NULL; - } - free_page((unsigned long) page); - } - if (pmd_bad(*pmd)) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; - return NULL; - } - return (pte_t *) pmd_page(*pmd) + address; -} +extern pte_t * (*pte_alloc_kernel)(pmd_t *, unsigned long); /* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */ -extern inline void pmd_free_kernel(pmd_t * pmd) -{ -} +extern void (*pmd_free_kernel)(pmd_t *); -extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address) -{ - return (pmd_t *) pgd; -} +extern pmd_t * (*pmd_alloc_kernel)(pgd_t *, unsigned long); -extern inline void pte_free(pte_t * pte) -{ - free_page((unsigned long) pte); -} +extern void (*pte_free)(pte_t *); -extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) -{ - address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); - if (pmd_none(*pmd)) { - pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); - if (pmd_none(*pmd)) { - if (page) { - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page; - return page + address; - } - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; - return NULL; - } - free_page((unsigned long) page); - } - if (pmd_bad(*pmd)) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE; - return NULL; - } - return (pte_t *) pmd_page(*pmd) + address; -} +extern pte_t * (*pte_alloc)(pmd_t *, unsigned long); /* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */ -extern inline void pmd_free(pmd_t * pmd) -{ -} +extern void (*pmd_free)(pmd_t *); -extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) -{ - return (pmd_t *) pgd; -} +extern pmd_t * (*pmd_alloc)(pgd_t *, unsigned long); + +extern void (*pgd_free)(pgd_t *); + +extern pgd_t * (*pgd_alloc)(void); + +/* Fine grained cache/tlb flushing. */ + +#ifdef __SMP__ +extern void (*local_flush_cache_all)(void); +extern void (*local_flush_cache_mm)(struct mm_struct *); +extern void (*local_flush_cache_range)(struct mm_struct *, unsigned long start, + unsigned long end); +extern void (*local_flush_cache_page)(struct vm_area_struct *, unsigned long address); + +extern void (*local_flush_tlb_all)(void); +extern void (*local_flush_tlb_mm)(struct mm_struct *); +extern void (*local_flush_tlb_range)(struct mm_struct *, unsigned long start, + unsigned long end); +extern void (*local_flush_tlb_page)(struct vm_area_struct *, unsigned long address); + +extern void (*local_flush_page_to_ram)(unsigned long address); -extern inline void pgd_free(pgd_t *pgd) +extern void smp_flush_cache_all(void); +extern void smp_flush_cache_mm(struct mm_struct *mm); +extern void smp_flush_cache_range(struct mm_struct *mm, + unsigned long start, + unsigned long end); +extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page); + +extern void smp_flush_tlb_all(void); +extern void smp_flush_tlb_mm(struct mm_struct *mm); +extern void smp_flush_tlb_range(struct mm_struct *mm, + unsigned long start, + unsigned long end); +extern void smp_flush_tlb_page(struct vm_area_struct *mm, unsigned long page); +extern void smp_flush_page_to_ram(unsigned long page); +#endif + +extern void (*flush_cache_all)(void); +extern void (*flush_cache_mm)(struct mm_struct *); +extern void (*flush_cache_range)(struct mm_struct *, unsigned long start, + unsigned long end); +extern void (*flush_cache_page)(struct vm_area_struct *, unsigned long address); + +extern void (*flush_tlb_all)(void); +extern void (*flush_tlb_mm)(struct mm_struct *); +extern void (*flush_tlb_range)(struct mm_struct *, unsigned long start, unsigned long end); +extern void (*flush_tlb_page)(struct vm_area_struct *, unsigned long address); + +extern void (*flush_page_to_ram)(unsigned long page); + +/* The permissions for pgprot_val to make a page mapped on the obio space */ +extern unsigned int pg_iobits; + +/* MMU context switching. */ +extern void (*switch_to_context)(struct task_struct *tsk); + +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ + +#if 0 /* XXX try this soon XXX */ +extern void (*set_pte)(struct vm_area_struct *vma, unsigned long address, + pte_t *pteptr, pte_t pteval); +#else +extern void (*set_pte)(pte_t *pteptr, pte_t pteval); +#endif + +extern char *(*mmu_info)(void); + +/* Fault handler stuff... */ +#define FAULT_CODE_PROT 0x1 +#define FAULT_CODE_WRITE 0x2 +#define FAULT_CODE_USER 0x4 +extern void (*update_mmu_cache)(struct vm_area_struct *vma, unsigned long address, pte_t pte); + +extern int invalid_segment; + +#define SWP_TYPE(entry) (((entry)>>2) & 0x7f) +#define SWP_OFFSET(entry) (((entry) >> 9) & 0x7ffff) +#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9)) + +struct ctx_list { + struct ctx_list *next; + struct ctx_list *prev; + unsigned int ctx_number; + struct mm_struct *ctx_mm; +}; + +extern struct ctx_list *ctx_list_pool; /* Dynamically allocated */ +extern struct ctx_list ctx_free; /* Head of free list */ +extern struct ctx_list ctx_used; /* Head of used contexts list */ + +#define NO_CONTEXT -1 + +extern __inline__ void remove_from_ctx_list(struct ctx_list *entry) { - free_page((unsigned long) pgd); + entry->next->prev = entry->prev; + entry->prev->next = entry->next; } -extern inline pgd_t *pgd_alloc(void) + +extern __inline__ void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry) { - return (pgd_t *) get_free_page(GFP_KERNEL); + entry->next = head; + (entry->prev = head->prev)->next = entry; + head->prev = entry; } - -extern pgd_t swapper_pg_dir[1024]; +#define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry) +#define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry) #endif /* !(_SPARC_PGTABLE_H) */ diff --git a/include/asm-sparc/pgtsrmmu.h b/include/asm-sparc/pgtsrmmu.h new file mode 100644 index 000000000..f8ca14944 --- /dev/null +++ b/include/asm-sparc/pgtsrmmu.h @@ -0,0 +1,268 @@ +/* $Id: pgtsrmmu.h,v 1.24 1996/10/07 03:03:06 davem Exp $ + * pgtsrmmu.h: SRMMU page table defines and code. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_PGTSRMMU_H +#define _SPARC_PGTSRMMU_H + +#include <linux/config.h> +#include <asm/page.h> + +#if CONFIG_AP1000 +#include <asm/ap1000/apreg.h> +#endif + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#define SRMMU_PMD_SHIFT 18 +#define SRMMU_PMD_SIZE (1UL << SRMMU_PMD_SHIFT) +#define SRMMU_PMD_MASK (~(SRMMU_PMD_SIZE-1)) +#define SRMMU_PMD_ALIGN(addr) (((addr)+SRMMU_PMD_SIZE-1)&SRMMU_PMD_MASK) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define SRMMU_PGDIR_SHIFT 24 +#define SRMMU_PGDIR_SIZE (1UL << SRMMU_PGDIR_SHIFT) +#define SRMMU_PGDIR_MASK (~(SRMMU_PGDIR_SIZE-1)) +#define SRMMU_PGDIR_ALIGN(addr) (((addr)+SRMMU_PGDIR_SIZE-1)&SRMMU_PGDIR_MASK) + +#define SRMMU_PTRS_PER_PTE 64 +#define SRMMU_PTRS_PER_PMD 64 +#define SRMMU_PTRS_PER_PGD 256 + +#define SRMMU_PTE_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */ +#define SRMMU_PMD_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */ +#define SRMMU_PGD_TABLE_SIZE 0x400 /* 256 entries, 4 bytes a piece */ + +#define SRMMU_VMALLOC_START (0xfe300000) + +/* Definition of the values in the ET field of PTD's and PTE's */ +#define SRMMU_ET_MASK 0x3 +#define SRMMU_ET_INVALID 0x0 +#define SRMMU_ET_PTD 0x1 +#define SRMMU_ET_PTE 0x2 +#define SRMMU_ET_REPTE 0x3 /* AIEEE, SuperSparc II reverse endian page! */ + +/* Physical page extraction from PTP's and PTE's. */ +#define SRMMU_CTX_PMASK 0xfffffff0 +#define SRMMU_PTD_PMASK 0xfffffff0 +#define SRMMU_PTE_PMASK 0xffffff00 + +/* The pte non-page bits. Some notes: + * 1) cache, dirty, valid, and ref are frobbable + * for both supervisor and user pages. + * 2) exec and write will only give the desired effect + * on user pages + * 3) use priv and priv_readonly for changing the + * characteristics of supervisor ptes + */ +#define SRMMU_CACHE 0x80 +#define SRMMU_DIRTY 0x40 +#define SRMMU_REF 0x20 +#define SRMMU_EXEC 0x08 +#define SRMMU_WRITE 0x04 +#define SRMMU_VALID 0x02 /* SRMMU_ET_PTE */ +#define SRMMU_PRIV 0x1c +#define SRMMU_PRIV_RDONLY 0x18 + +#define SRMMU_CHG_MASK (0xffffff00 | SRMMU_REF | SRMMU_DIRTY) + +/* Some day I will implement true fine grained access bits for + * user pages because the SRMMU gives us the capabilities to + * enforce all the protection levels that vma's can have. + * XXX But for now... + */ +#define SRMMU_PAGE_NONE __pgprot(SRMMU_VALID | SRMMU_CACHE | \ + SRMMU_PRIV | SRMMU_REF) +#define SRMMU_PAGE_SHARED __pgprot(SRMMU_VALID | SRMMU_CACHE | \ + SRMMU_EXEC | SRMMU_WRITE | SRMMU_REF) +#define SRMMU_PAGE_COPY __pgprot(SRMMU_VALID | SRMMU_CACHE | \ + SRMMU_EXEC | SRMMU_REF) +#define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \ + SRMMU_EXEC | SRMMU_REF) +#define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \ + SRMMU_DIRTY | SRMMU_REF) + +/* SRMMU Register addresses in ASI 0x4. These are valid for all + * current SRMMU implementations that exist. + */ +#define SRMMU_CTRL_REG 0x00000000 +#define SRMMU_CTXTBL_PTR 0x00000100 +#define SRMMU_CTX_REG 0x00000200 +#define SRMMU_FAULT_STATUS 0x00000300 +#define SRMMU_FAULT_ADDR 0x00000400 + +/* + * "normal" sun systems have their memory on bus 0. This means the top + * 4 bits of 36 bit physical addresses are 0. We use this define to + * determine if a piece of memory might be normal memory, or if its + * definately some sort of device memory. + * + * On the AP+ normal memory is on bus 8. Why? Ask Fujitsu :-) +*/ +#if CONFIG_AP1000 +#define MEM_BUS_SPACE 8 +#else +#define MEM_BUS_SPACE 0 +#endif + +/* Accessing the MMU control register. */ +extern __inline__ unsigned int srmmu_get_mmureg(void) +{ + unsigned int retval; + __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : + "=r" (retval) : + "i" (ASI_M_MMUREGS)); + return retval; +} + +extern __inline__ void srmmu_set_mmureg(unsigned long regval) +{ + __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : : + "r" (regval), "i" (ASI_M_MMUREGS) : "memory"); + +} + +extern __inline__ void srmmu_set_ctable_ptr(unsigned long paddr) +{ + paddr = ((paddr >> 4) & SRMMU_CTX_PMASK); +#if MEM_BUS_SPACE + paddr |= (MEM_BUS_SPACE<<28); +#endif + __asm__ __volatile__("sta %0, [%1] %2\n\t" : : + "r" (paddr), "r" (SRMMU_CTXTBL_PTR), + "i" (ASI_M_MMUREGS) : + "memory"); +} + +extern __inline__ unsigned long srmmu_get_ctable_ptr(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (SRMMU_CTXTBL_PTR), + "i" (ASI_M_MMUREGS)); + return (retval & SRMMU_CTX_PMASK) << 4; +} + +extern __inline__ void srmmu_set_context(int context) +{ + __asm__ __volatile__("sta %0, [%1] %2\n\t" : : + "r" (context), "r" (SRMMU_CTX_REG), + "i" (ASI_M_MMUREGS) : "memory"); +#if CONFIG_AP1000 + /* The AP1000+ message controller also needs to know + the current task's context. */ + MSC_OUT(MSC_PID, context); +#endif +} + +extern __inline__ int srmmu_get_context(void) +{ + register int retval; + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (SRMMU_CTX_REG), + "i" (ASI_M_MMUREGS)); + return retval; +} + +extern __inline__ unsigned int srmmu_get_fstatus(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (SRMMU_FAULT_STATUS), "i" (ASI_M_MMUREGS)); + return retval; +} + +extern __inline__ unsigned int srmmu_get_faddr(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (SRMMU_FAULT_ADDR), "i" (ASI_M_MMUREGS)); + return retval; +} + +/* This is guaranteed on all SRMMU's. */ +extern __inline__ void srmmu_flush_whole_tlb(void) +{ +#if CONFIG_AP1000 + extern void mc_tlb_flush_all(void); + mc_tlb_flush_all(); +#endif + __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : + "r" (0x400), /* Flush entire TLB!! */ + "i" (ASI_M_FLUSH_PROBE) : "memory"); + +} + +/* These flush types are not available on all chips... */ +extern __inline__ void srmmu_flush_tlb_ctx(void) +{ +#if CONFIG_AP1000 + mc_tlb_flush_ctx(); +#endif + __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : + "r" (0x300), /* Flush TLB ctx.. */ + "i" (ASI_M_FLUSH_PROBE) : "memory"); + +} + +extern __inline__ void srmmu_flush_tlb_region(unsigned long addr) +{ +#if CONFIG_AP1000 + mc_tlb_flush_region(); +#endif + addr &= SRMMU_PGDIR_MASK; + __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : + "r" (addr | 0x200), /* Flush TLB region.. */ + "i" (ASI_M_FLUSH_PROBE) : "memory"); + +} + + +extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr) +{ +#if CONFIG_AP1000 + mc_tlb_flush_segment(); +#endif + addr &= SRMMU_PMD_MASK; + __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : + "r" (addr | 0x100), /* Flush TLB segment.. */ + "i" (ASI_M_FLUSH_PROBE) : "memory"); + +} + +extern __inline__ void srmmu_flush_tlb_page(unsigned long page) +{ +#if CONFIG_AP1000 + mc_tlb_flush_page(page); +#endif + page &= PAGE_MASK; + __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : + "r" (page), /* Flush TLB page.. */ + "i" (ASI_M_FLUSH_PROBE) : "memory"); + +} + +extern __inline__ unsigned long srmmu_hwprobe(unsigned long vaddr) +{ + unsigned long retval; + + vaddr &= PAGE_MASK; + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE)); + + return retval; +} + +extern unsigned long (*srmmu_read_physical)(unsigned long paddr); +extern void (*srmmu_write_physical)(unsigned long paddr, unsigned long word); + +#endif /* !(_SPARC_PGTSRMMU_H) */ diff --git a/include/asm-sparc/pgtsun4.h b/include/asm-sparc/pgtsun4.h new file mode 100644 index 000000000..4161526c0 --- /dev/null +++ b/include/asm-sparc/pgtsun4.h @@ -0,0 +1,10 @@ +/* $Id: pgtsun4.h,v 1.2 1995/11/25 02:32:26 davem Exp $ + * pgtsun4.c: Regular Sun4 MMU support goes in here. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_PGTSUN4_H +#define _SPARC_PGTSUN4_H + +#endif /* !(_SPARC_PGTSUN4_H) */ diff --git a/include/asm-sparc/pgtsun4c.h b/include/asm-sparc/pgtsun4c.h new file mode 100644 index 000000000..c54a6079d --- /dev/null +++ b/include/asm-sparc/pgtsun4c.h @@ -0,0 +1,151 @@ +/* $Id: pgtsun4c.h,v 1.27 1996/10/30 06:01:32 davem Exp $ + * pgtsun4c.h: Sun4c specific pgtable.h defines and code. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_PGTSUN4C_H +#define _SPARC_PGTSUN4C_H + +#include <asm/contregs.h> + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#define SUN4C_PMD_SHIFT 22 +#define SUN4C_PMD_SIZE (1UL << SUN4C_PMD_SHIFT) +#define SUN4C_PMD_MASK (~(SUN4C_PMD_SIZE-1)) +#define SUN4C_PMD_ALIGN(addr) (((addr)+SUN4C_PMD_SIZE-1)&SUN4C_PMD_MASK) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define SUN4C_PGDIR_SHIFT 22 +#define SUN4C_PGDIR_SIZE (1UL << SUN4C_PGDIR_SHIFT) +#define SUN4C_PGDIR_MASK (~(SUN4C_PGDIR_SIZE-1)) +#define SUN4C_PGDIR_ALIGN(addr) (((addr)+SUN4C_PGDIR_SIZE-1)&SUN4C_PGDIR_MASK) + +/* To represent how the sun4c mmu really lays things out. */ +#define SUN4C_REAL_PGDIR_SHIFT 18 +#define SUN4C_REAL_PGDIR_SIZE (1UL << SUN4C_REAL_PGDIR_SHIFT) +#define SUN4C_REAL_PGDIR_MASK (~(SUN4C_REAL_PGDIR_SIZE-1)) +#define SUN4C_REAL_PGDIR_ALIGN(addr) (((addr)+SUN4C_REAL_PGDIR_SIZE-1)&SUN4C_REAL_PGDIR_MASK) + +/* + * To be efficient, and not have to worry about allocating such + * a huge pgd, we make the kernel sun4c tables each hold 1024 + * entries and the pgd similarly just like the i386 tables. + */ +#define SUN4C_PTRS_PER_PTE 1024 +#define SUN4C_PTRS_PER_PMD 1 +#define SUN4C_PTRS_PER_PGD 1024 + +/* On the sun4c the physical ram limit is 128MB. We set up our I/O + * translations at KERNBASE + 128MB for 1MB, then we begin the VMALLOC + * area, makes sense. This works out to the value below. + */ +#define SUN4C_VMALLOC_START (0xfe300000) + +/* + * Sparc SUN4C pte fields. + */ +#define _SUN4C_PAGE_VALID 0x80000000 /* valid page */ +#define _SUN4C_PAGE_WRITE 0x40000000 /* can be written to */ +#define _SUN4C_PAGE_PRIV 0x20000000 /* bit to signify privileged page */ +#define _SUN4C_PAGE_USER 0x00000000 /* User page */ +#define _SUN4C_PAGE_NOCACHE 0x10000000 /* non-cacheable page */ +#define _SUN4C_PAGE_IO 0x04000000 /* I/O page */ +#define _SUN4C_PAGE_REF 0x02000000 /* Page has been accessed/referenced */ +#define _SUN4C_PAGE_DIRTY 0x01000000 /* Page has been modified, is dirty */ +#define _SUN4C_PAGE_PRESENT 0x00400000 /* present (known) page */ + +#define _SUN4C_PAGE_CHG_MASK (0xffff | _SUN4C_PAGE_REF | _SUN4C_PAGE_DIRTY) + +#define SUN4C_PAGE_NONE __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_PRIV | \ + _SUN4C_PAGE_REF) +#define SUN4C_PAGE_SHARED __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_WRITE | \ + _SUN4C_PAGE_USER | _SUN4C_PAGE_REF) +#define SUN4C_PAGE_COPY __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_USER | \ + _SUN4C_PAGE_REF) +#define SUN4C_PAGE_READONLY __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_USER | \ + _SUN4C_PAGE_REF) +#define SUN4C_PAGE_KERNEL __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_WRITE | \ + _SUN4C_PAGE_PRIV | _SUN4C_PAGE_DIRTY | \ + _SUN4C_PAGE_REF | _SUN4C_PAGE_NOCACHE) + +extern __inline__ unsigned long sun4c_get_synchronous_error(void) +{ + unsigned long sync_err; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (sync_err) : + "r" (AC_SYNC_ERR), "i" (ASI_CONTROL)); + return sync_err; +} + +extern __inline__ unsigned long sun4c_get_synchronous_address(void) +{ + unsigned long sync_addr; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (sync_addr) : + "r" (AC_SYNC_VA), "i" (ASI_CONTROL)); + return sync_addr; +} + +/* SUN4C pte, segmap, and context manipulation */ +extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr) +{ + register unsigned long entry; + + __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" : + "=r" (entry) : + "r" (addr), "i" (ASI_SEGMAP)); + + return entry; +} + +extern __inline__ void sun4c_put_segmap(unsigned long addr, unsigned long entry) +{ + + __asm__ __volatile__("\n\tstba %1, [%0] %2\n\t" : : + "r" (addr), "r" (entry), + "i" (ASI_SEGMAP)); + + return; +} + +extern __inline__ unsigned long sun4c_get_pte(unsigned long addr) +{ + register unsigned long entry; + + __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" : + "=r" (entry) : + "r" (addr), "i" (ASI_PTE)); + return entry; +} + +extern __inline__ void sun4c_put_pte(unsigned long addr, unsigned long entry) +{ + __asm__ __volatile__("\n\tsta %1, [%0] %2\n\t" : : + "r" (addr), + "r" (entry), "i" (ASI_PTE)); + + return; +} + +extern __inline__ int sun4c_get_context(void) +{ + register int ctx; + + __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" : + "=r" (ctx) : + "r" (AC_CONTEXT), "i" (ASI_CONTROL)); + + return ctx; +} + +extern __inline__ int sun4c_set_context(int ctx) +{ + __asm__ __volatile__("\n\tstba %0, [%1] %2\n\t" : : + "r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL)); + + return ctx; +} + +#endif /* !(_SPARC_PGTSUN4C_H) */ diff --git a/include/asm-sparc/posix_types.h b/include/asm-sparc/posix_types.h new file mode 100644 index 000000000..1df2f62d2 --- /dev/null +++ b/include/asm-sparc/posix_types.h @@ -0,0 +1,111 @@ +#ifndef __ARCH_SPARC_POSIX_TYPES_H +#define __ARCH_SPARC_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +/* When cross-compilation is no longer an issue, fix this. */ +#if defined(__svr4__) || defined(__ELF__) +typedef unsigned int __kernel_size_t; +#else +typedef long unsigned int __kernel_size_t; +#endif /* !(__svr4__ || __ELF__) */ + +typedef int __kernel_ssize_t; +typedef long int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_clock_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_umode_t; +typedef short __kernel_nlink_t; +typedef long __kernel_daddr_t; +typedef long __kernel_off_t; +typedef char * __kernel_caddr_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] |= (1UL<<_rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); +} + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant cases (8 or 32 longs, + * for 256 and 1024-bit fd_sets respectively) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set *p) +{ + unsigned long *tmp = p->fds_bits; + int i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 32: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0; + tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0; + tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0; + tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0; + tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0; + tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0; + return; + case 16: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0; + tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0; + return; + case 8: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + return; + case 4: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + return; + } + } + i = __FDSET_LONGS; + while (i) { + i--; + *tmp = 0; + tmp++; + } +} + +#endif /* !(__ARCH_SPARC_POSIX_TYPES_H) */ diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h index 7e18bfb2f..dd5a0dfcf 100644 --- a/include/asm-sparc/processor.h +++ b/include/asm-sparc/processor.h @@ -1,4 +1,5 @@ -/* include/asm-sparc/processor.h +/* $Id: processor.h,v 1.48 1996/10/27 08:55:36 davem Exp $ + * include/asm-sparc/processor.h * * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) */ @@ -6,151 +7,159 @@ #ifndef __ASM_SPARC_PROCESSOR_H #define __ASM_SPARC_PROCESSOR_H +#include <linux/a.out.h> + +#include <asm/psr.h> +#include <asm/ptrace.h> +#include <asm/head.h> +#include <asm/signal.h> +#include <asm/segment.h> + /* * Bus types */ -#define EISA_bus 1 +#define EISA_bus 0 #define EISA_bus__is_a_macro /* for versions in ksyms.c */ #define MCA_bus 0 #define MCA_bus__is_a_macro /* for versions in ksyms.c */ /* - * Write Protection works right in supervisor mode on the Sparc + * The sparc has no problems with write protection */ - #define wp_works_ok 1 #define wp_works_ok__is_a_macro /* for versions in ksyms.c */ -/* - * User space process size: 3GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - * - * "this is gonna have to change to 1gig for the sparc" - David S. Miller - */ -#define TASK_SIZE (0xC0000000UL) +/* Whee, this is STACK_TOP and the lowest kernel address too... */ +#define TASK_SIZE (page_offset) -/* - * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. - */ -#define IO_BITMAP_SIZE 32 - -/* The first five entries here MUST be the first four. This allows me to - * do %lo(offset) loads and stores in entry.S. See TRAP_WIN_CLEAN to see - * why. - */ +/* Ok this is hot. Sparc exception save area. */ +struct exception_struct { + unsigned long count; /* Exception count */ + unsigned long pc; /* Callers PC for copy/clear user */ + unsigned long expc; /* Where to jump when exception signaled */ + unsigned long address; /* Saved user base address for transfer */ +}; +/* The Sparc processor specific thread struct. */ struct thread_struct { - unsigned long uwindows; /* how many user windows are in the set */ - unsigned long wim; /* user's window invalid mask */ - unsigned long w_saved; /* how many windows saved in reg_window[] */ - unsigned long ksp; /* kernel stack pointer */ - unsigned long usp; /* user's sp, throw reg windows here */ - unsigned long psr; /* save for condition codes */ - unsigned long reg_window[16*24]; - unsigned long cr3; /* why changed from ptbr? */ - unsigned int pcc; - unsigned int asn; - unsigned long unique; + unsigned long uwinmask __attribute__ ((aligned (8))); + struct pt_regs *kregs; + + /* For signal handling */ + unsigned long sig_address __attribute__ ((aligned (8))); + unsigned long sig_desc; + + /* Context switch saved kernel state. */ + unsigned long ksp __attribute__ ((aligned (8))); + unsigned long kpc; + unsigned long kpsr; + unsigned long kwim; + + /* Special child fork kpsr/kwim values. */ + unsigned long fork_kpsr __attribute__ ((aligned (8))); + unsigned long fork_kwim; + + /* A place to store user windows and stack pointers + * when the stack needs inspection. + */ +#define NSWINS 8 + struct reg_window reg_window[NSWINS] __attribute__ ((aligned (8))); + unsigned long rwbuf_stkptrs[NSWINS] __attribute__ ((aligned (8))); + unsigned long w_saved; + + /* Floating point regs */ + unsigned long float_regs[64] __attribute__ ((aligned (8))); + unsigned long fsr; + unsigned long fpqdepth; + struct fpq { + unsigned long *insn_addr; + unsigned long insn; + } fpqueue[16]; + struct sigstack sstk_info; unsigned long flags; - unsigned long res1, res2; - unsigned long pc; /* program counter */ - unsigned long npc; /* next program counter */ - -/* 8 local registers + 8 in registers * 24 register windows. - * Most sparcs I know of only have 8 windows implemented, - * we determine how many at boot time and store that value - * in nwindows. - */ - unsigned long globl_regs[8]; /* global regs need to be saved too */ - unsigned long yreg; - unsigned long float_regs[64]; /* V8 and below have 32, V9 has 64 */ + struct exception_struct ex __attribute__ ((aligned (8))); + int current_ds; + struct exec core_exec; /* just what it says. */ }; -#define INIT_MMAP { &init_task, 0x0, 0x40000000, \ - PAGE_SHARED , VM_READ | VM_WRITE | VM_EXEC } +#define SPARC_FLAG_KTHREAD 0x1 /* task is a kernel thread */ +#define SPARC_FLAG_UNALIGNED 0x2 /* is allowed to do unaligned accesses */ + +#define INIT_MMAP { &init_mm, (0), (0), \ + __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC } #define INIT_TSS { \ - 0, 0, 0, 0, 0, 0, \ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - { 0, 0, 0, 0, 0, 0, 0, 0, }, \ - 0, \ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ +/* uwinmask, kregs, sig_address, sig_desc, ksp, kpc, kpsr, kwim */ \ + 0, 0, 0, 0, 0, 0, 0, 0, \ +/* fork_kpsr, fork_kwim */ \ + 0, 0, \ +/* reg_window */ \ +{ { { 0, }, { 0, } }, }, \ +/* rwbuf_stkptrs */ \ +{ 0, 0, 0, 0, 0, 0, 0, 0, }, \ +/* w_saved */ \ + 0, \ +/* FPU regs */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ +/* FPU status, FPU qdepth, FPU queue */ \ + 0, 0, { { 0, 0, }, }, \ +/* sstk_info */ \ +{ 0, 0, }, \ +/* flags, ex, current_ds, */ \ + SPARC_FLAG_KTHREAD, { 0, }, USER_DS, \ +/* core_exec */ \ +{ 0, }, \ } -/* The thread_frame is what needs to be set up in certain circumstances - * upon entry to a trap. It is also loaded sometimes during a window - * spill if things don't go right (bad user stack pointer). In reality - * it is not per-process per se, it just sits in the kernel stack while - * the current process is in a handler then it is basically forgotten - * about. - */ - -struct thread_frame { - unsigned int thr_psr; - unsigned int thr_pc; - unsigned int thr_npc; - unsigned int thr_y; - unsigned int thr_globals[8]; - unsigned int thr_outs[8]; -}; - -/* - * These are the "cli()" and "sti()" for software interrupts - * They work by increasing/decreasing the "intr_count" value, - * and as such can be nested arbitrarily. - */ -extern inline void start_bh_atomic(void) +/* Return saved PC of a blocked thread. */ +extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t) { - unsigned long dummy, psr; - __asm__ __volatile__("rd %%psr, %2\n\t" - "wr %2, 0x20, %%psr\n\t" /* disable traps */ - "ld %1,%0\n\t" - "add %0,1,%0\n\t" - "st %0,%1\n\t" - "wr %2, 0x0, %%psr\n\t" /* enable traps */ - : "=r" (dummy), "=m" (intr_count) - : "0" (0), "r" (psr=0)); + return t->kpc; } -extern inline void end_bh_atomic(void) +/* Do necessary setup to start up a newly executed thread. */ +extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc, + unsigned long sp) { - unsigned long dummy, psr; - __asm__ __volatile__("rd %%psr, %2\n\t" - "wr %2, 0x20, %%psr\n\t" - "ld %1,%0\n\t" - "sub %0,1,%0\n\t" - "st %0,%1\n\t" - "wr %2, 0x0, %%psr\n\t" - : "=r" (dummy), "=m" (intr_count) - : "0" (0), "r" (psr=0)); + register unsigned long zero asm("g1"); + + regs->psr = (regs->psr & (PSR_CWP)) | PSR_S; + regs->pc = ((pc & (~3)) - 4); + regs->npc = regs->pc + 4; + regs->y = 0; + zero = 0; + __asm__ __volatile__("std\t%%g0, [%0 + %3 + 0x00]\n\t" + "std\t%%g0, [%0 + %3 + 0x08]\n\t" + "std\t%%g0, [%0 + %3 + 0x10]\n\t" + "std\t%%g0, [%0 + %3 + 0x18]\n\t" + "std\t%%g0, [%0 + %3 + 0x20]\n\t" + "std\t%%g0, [%0 + %3 + 0x28]\n\t" + "std\t%%g0, [%0 + %3 + 0x30]\n\t" + "st\t%1, [%0 + %3 + 0x38]\n\t" + "st\t%%g0, [%0 + %3 + 0x3c]" + : : "r" (regs), "r" (sp - REGWIN_SZ), "r" (zero), + "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); } -#endif /* __ASM_SPARC_PROCESSOR_H */ +#define release_thread(tsk) do { } while(0) + +#ifdef __KERNEL__ +extern unsigned long (*alloc_kernel_stack)(struct task_struct *tsk); +extern void (*free_kernel_stack)(unsigned long stack); +extern struct task_struct *(*alloc_task_struct)(void); +extern void (*free_task_struct)(struct task_struct *tsk); +#endif + +/* + * Return_address is a replacement for __builtin_return_address(count) + * which on certain architectures cannot reasonably be implemented in GCC + * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * Note that __builtin_return_address(x>=1) is forbidden because the GCC + * aborts compilation on some CPUs. It's simply not possible to unwind + * some CPU's stackframes. + */ +#define return_address() __builtin_return_address(0) +#endif /* __ASM_SPARC_PROCESSOR_H */ diff --git a/include/asm-sparc/psr.h b/include/asm-sparc/psr.h index 60b9757ad..829ca47b6 100644 --- a/include/asm-sparc/psr.h +++ b/include/asm-sparc/psr.h @@ -1,36 +1,23 @@ -/* psr.h: This file holds the macros for masking off various parts of - the processor status register on the Sparc. This is valid - for Version 8. On the V9 this is renamed to the PSTATE - register and its members are accessed as fields like - PSTATE.PRIV for the current CPU privilege level. - - Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) -*/ +/* $Id: psr.h,v 1.12 1996/09/30 02:23:19 davem Exp $ + * psr.h: This file holds the macros for masking off various parts of + * the processor status register on the Sparc. This is valid + * for Version 8. On the V9 this is renamed to the PSTATE + * register and its members are accessed as fields like + * PSTATE.PRIV for the current CPU privilege level. + * + * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) + */ #ifndef __LINUX_SPARC_PSR_H #define __LINUX_SPARC_PSR_H -#define __LINUX_SPARC_V8 /* duh */ - -#ifdef __LINUX_SPARC_V8 - /* The Sparc PSR fields are laid out as the following: - - ------------------------------------------------------------------------ - | impl | vers | icc | resv | EC | EF | PIL | S | PS | ET | CWP | -bits| 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 | - ------------------------------------------------------------------------ - - The PSR can only be directly be written/read by the privileged instructions - 'rd' and 'wr'. Certain fields are changed as a side effect due to the 'Ticc', - 'save', 'restore', and 'rett' instructions. Also the integer condition codes - 'icc' are modified by various arithmetic instructions. - - For example: wr %o2, or'd_bit_pattern, %psr - rd %psr, %o3 - -*/ - + * + * ------------------------------------------------------------------------ + * | impl | vers | icc | resv | EC | EF | PIL | S | PS | ET | CWP | + * | 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 | + * ------------------------------------------------------------------------ + */ #define PSR_CWP 0x0000001f /* current window pointer */ #define PSR_ET 0x00000020 /* enable traps field */ #define PSR_PS 0x00000040 /* previous privilege level */ @@ -38,6 +25,7 @@ bits| 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 | #define PSR_PIL 0x00000f00 /* processor interrupt level */ #define PSR_EF 0x00001000 /* enable floating point */ #define PSR_EC 0x00002000 /* enable co-processor */ +#define PSR_LE 0x00008000 /* SuperSparcII little-endian */ #define PSR_ICC 0x00f00000 /* integer condition codes */ #define PSR_C 0x00100000 /* carry bit */ #define PSR_V 0x00200000 /* overflow bit */ @@ -46,54 +34,45 @@ bits| 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 | #define PSR_VERS 0x0f000000 /* cpu-version field */ #define PSR_IMPL 0xf0000000 /* cpu-implementation field */ -#endif /* !(__LINUX_SPARC_V8) */ - -#ifdef __LINUX_SPARC_V9 - -/* The information available in the %psr on the V8 is spread amongst - a whole bunch of registers on the V9. The main one being PSTATE. - - -------------------------------------------------------- - | CLE | TLE | MM | RED | PEF | AM | PRIV | IE | AG | -bits | 9 | 8 | 7-6 | 5 | 4 | 3 | 2 | 1 | 0 | - -------------------------------------------------------- - - Writes and reads to PSTATE are done via 'wrpr' and 'rdpr' instructions. - - For example: wrpr %o2, or'd_bit_pattern, %pstate - rdpr %pstate, %o3 -*/ - -#define PSTATE_AG 0x001 /* Alternate Globals */ -#define PSTATE_IE 0x002 /* Interrupt Enable */ -#define PSTATE_PRIV 0x004 /* Current privilege level */ -#define PSTATE_AM 0x008 /* Address mask (data reads can */ - /* be chosen to be either big or */ - /* little endian on V9). */ -#define PSTATE_PEF 0x010 /* enable floating point */ -#define PSTATE_RED 0x020 /* RED trap state (set if trap */ - /* trap_level == max_tl). */ -#define PSTATE_MM 0x0c0 /* Memory model (Total Store */ - /* Order=0, Partial Store Order */ - /* =1 or Relaxed Memory Order=2) */ -#define PSTATE_TLE 0x100 /* Trap Little Endian */ -#define PSTATE_CLE 0x200 /* Current Little Endian */ - - -/* The Version Register holds vendor information for the chip: - - --------------------------------------------------------------------------- - | manufacturer | implementation | mask | reserved | maxtl | resv | maxwin | -bits| 63-48 | 47-32 | 31-24| 23-16 | 15-8 | 7-5 | 4-0 | - --------------------------------------------------------------------------- - -*/ - -#define VERS_MAXWIN 0x000000000000001f /* 'nwindows' on this chip */ -#define VERS_MAXTL 0x00000000000ff000 /* Maximum Trap-level supported */ -#define VERS_MASK 0x0000000ff0000000 /* impl. dep. chip mask revision */ -#define VERS_MANUF 0xffff000000000000 /* Manufacturer ID code */ - -#endif /* !(__LINUX_SPARC_V9) */ +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +/* Get the %psr register. */ +extern __inline__ unsigned int get_psr(void) +{ + unsigned int psr; + __asm__ __volatile__("rd\t%%psr, %0" : + "=r" (psr)); + return psr; +} + +extern __inline__ void put_psr(unsigned int new_psr) +{ + __asm__ __volatile__("wr\t%0, 0x0, %%psr\n\t" + "nop; nop; nop;" : : + "r" (new_psr)); +} + +/* Get the %fsr register. Be careful, make sure the floating point + * enable bit is set in the %psr when you execute this or you will + * incur a trap. + */ + +extern unsigned int fsr_storage; + +extern __inline__ unsigned int get_fsr(void) +{ + unsigned int fsr = 0; + + __asm__ __volatile__("st\t%%fsr, %1\n\t" + "ld\t%1, %0" : + "=r" (fsr) : + "m" (fsr_storage)); + return fsr; +} + +#endif /* !(__ASSEMBLY__) */ + +#endif /* (__KERNEL__) */ #endif /* !(__LINUX_SPARC_PSR_H) */ diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h index 70fb8d5df..d357ab034 100644 --- a/include/asm-sparc/ptrace.h +++ b/include/asm-sparc/ptrace.h @@ -1,32 +1,195 @@ +/* $Id: ptrace.h,v 1.22 1996/10/27 08:55:38 davem Exp $ */ #ifndef _SPARC_PTRACE_H #define _SPARC_PTRACE_H -/* I have not looked enough into how this should be done. Without playing - * lots of tricks to optimize I think we need to save the whole register - * window frame plus the floating-point registers. We'll see... +#include <asm/psr.h> + +/* This struct defines the way the registers are stored on the + * stack during a system call and basically all traps. */ -/* this struct defines the way the registers are stored on the - stack during a system call. */ +#ifndef __ASSEMBLY__ struct pt_regs { - unsigned long ps; /* previous supervisor, same as alpha I believe */ - unsigned long pc; /* current and next program counter */ + unsigned long psr; + unsigned long pc; unsigned long npc; - unsigned long sp; /* stack and frame pointer */ - unsigned long fp; - unsigned long psr; /* for condition codes */ - unsigned long nuwin; /* number of user windows */ - /* not sure yet whether all regs are necessary - * but this is how it is traditionally done on the sparc. - */ - unsigned long u_regs[24*16]; - unsigned long f_regs[64]; /* yuck yuck yuck */ + unsigned long y; + unsigned long u_regs[16]; /* globals and ins */ +}; + +#define UREG_G0 0 +#define UREG_G1 1 +#define UREG_G2 2 +#define UREG_G3 3 +#define UREG_G4 4 +#define UREG_G5 5 +#define UREG_G6 6 +#define UREG_G7 7 +#define UREG_I0 8 +#define UREG_I1 9 +#define UREG_I2 10 +#define UREG_I3 11 +#define UREG_I4 12 +#define UREG_I5 13 +#define UREG_I6 14 +#define UREG_I7 15 +#define UREG_WIM UREG_G0 +#define UREG_FADDR UREG_G0 +#define UREG_FP UREG_I6 +#define UREG_RETPC UREG_I7 + +/* A register window */ +struct reg_window { + unsigned long locals[8]; + unsigned long ins[8]; }; +/* A Sparc stack frame */ +struct sparc_stackf { + unsigned long locals[8]; + unsigned long ins[6]; + struct sparc_stackf *fp; + unsigned long callers_pc; + char *structptr; + unsigned long xargs[6]; + unsigned long xxargs[1]; +}; + +#define TRACEREG_SZ sizeof(struct pt_regs) +#define STACKFRAME_SZ sizeof(struct sparc_stackf) +#define REGWIN_SZ sizeof(struct reg_window) + #ifdef __KERNEL__ -#define user_mode(regs) (0x0) /* if previous supervisor is 0, came from user */ +#define user_mode(regs) (!((regs)->psr & PSR_PS)) +#define instruction_pointer(regs) ((regs)->pc) extern void show_regs(struct pt_regs *); #endif +#else /* __ASSEMBLY__ */ +/* For assembly code. */ +#define TRACEREG_SZ 0x50 +#define STACKFRAME_SZ 0x60 +#define REGWIN_SZ 0x40 #endif + +/* First generic task_struct offsets. sizeof(task_struct)=1616 */ +#define TASK_STATE 0x000 +#define TASK_PRIORITY 0x008 +#define TASK_SIGNAL 0x00c +#define TASK_BLOCKED 0x010 +#define TASK_FLAGS 0x014 +#define TASK_SAVED_KSTACK 0x054 +#define TASK_KSTACK_PG 0x058 + +/* Thread stuff. */ +#define THREAD_UMASK 0x210 +#define THREAD_SADDR 0x218 +#define THREAD_SDESC 0x21c +#define THREAD_KSP 0x220 +#define THREAD_KPC 0x224 +#define THREAD_KPSR 0x228 +#define THREAD_KWIM 0x22c +#define THREAD_FORK_KPSR 0x230 +#define THREAD_FORK_KWIM 0x234 +#define THREAD_REG_WINDOW 0x238 +#define THREAD_STACK_PTRS 0x438 +#define THREAD_W_SAVED 0x458 +#define THREAD_FLOAT_REGS 0x460 +#define THREAD_FSR 0x560 +#define THREAD_SIGSTK 0x5e8 +#define THREAD_FLAGS 0x5f0 +#define THREAD_EX_COUNT 0x5f8 +#define THREAD_EX_PC 0x5fc +#define THREAD_EX_EXPC 0x600 +#define THREAD_EX_ADDR 0x604 +#define THREAD_DS 0x608 +#define THREAD_MM 0x638 +#define THREAD_MM_CTX 0x008 + +/* These are for pt_regs. */ +#define PT_PSR 0x0 +#define PT_PC 0x4 +#define PT_NPC 0x8 +#define PT_Y 0xc +#define PT_G0 0x10 +#define PT_WIM PT_G0 +#define PT_G1 0x14 +#define PT_G2 0x18 +#define PT_G3 0x1c +#define PT_G4 0x20 +#define PT_G5 0x24 +#define PT_G6 0x28 +#define PT_G7 0x2c +#define PT_I0 0x30 +#define PT_I1 0x34 +#define PT_I2 0x38 +#define PT_I3 0x3c +#define PT_I4 0x40 +#define PT_I5 0x44 +#define PT_I6 0x48 +#define PT_FP PT_I6 +#define PT_I7 0x4c + +/* Reg_window offsets */ +#define RW_L0 0x00 +#define RW_L1 0x04 +#define RW_L2 0x08 +#define RW_L3 0x0c +#define RW_L4 0x10 +#define RW_L5 0x14 +#define RW_L6 0x18 +#define RW_L7 0x1c +#define RW_I0 0x20 +#define RW_I1 0x24 +#define RW_I2 0x28 +#define RW_I3 0x2c +#define RW_I4 0x30 +#define RW_I5 0x34 +#define RW_I6 0x38 +#define RW_I7 0x3c + +/* Stack_frame offsets */ +#define SF_L0 0x00 +#define SF_L1 0x04 +#define SF_L2 0x08 +#define SF_L3 0x0c +#define SF_L4 0x10 +#define SF_L5 0x14 +#define SF_L6 0x18 +#define SF_L7 0x1c +#define SF_I0 0x20 +#define SF_I1 0x24 +#define SF_I2 0x28 +#define SF_I3 0x2c +#define SF_I4 0x30 +#define SF_I5 0x34 +#define SF_FP 0x38 +#define SF_PC 0x3c +#define SF_RETP 0x40 +#define SF_XARG0 0x44 +#define SF_XARG1 0x48 +#define SF_XARG2 0x4c +#define SF_XARG3 0x50 +#define SF_XARG4 0x54 +#define SF_XARG5 0x58 +#define SF_XXARG 0x5c + +/* Stuff for the ptrace system call */ +#define PTRACE_SUNATTACH 10 +#define PTRACE_SUNDETACH 11 +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +#define PTRACE_READDATA 16 +#define PTRACE_WRITEDATA 17 +#define PTRACE_READTEXT 18 +#define PTRACE_WRITETEXT 19 +#define PTRACE_GETFPAREGS 20 +#define PTRACE_SETFPAREGS 21 + +#define PTRACE_GETUCODE 29 /* stupid bsd-ism */ + + +#endif /* !(_SPARC_PTRACE_H) */ diff --git a/include/asm-sparc/reg.h b/include/asm-sparc/reg.h new file mode 100644 index 000000000..ed60ebec5 --- /dev/null +++ b/include/asm-sparc/reg.h @@ -0,0 +1,79 @@ +/* + * linux/asm-sparc/reg.h + * Layout of the registers as expected by gdb on the Sparc + * we should replace the user.h definitions with those in + * this file, we don't even use the other + * -miguel + * + * The names of the structures, constants and aliases in this file + * have the same names as the sunos ones, some programs rely on these + * names (gdb for example). + * + */ + +#ifndef __SPARC_REG_H +#define __SPARC_REG_H + +struct regs { + int r_psr; +#define r_ps r_psr + int r_pc; + int r_npc; + int r_y; + int r_g1; + int r_g2; + int r_g3; + int r_g4; + int r_g5; + int r_g6; + int r_g7; + int r_o0; + int r_o1; + int r_o2; + int r_o3; + int r_o4; + int r_o5; + int r_o6; + int r_o7; +}; + +struct fpq { + unsigned long *addr; + unsigned long instr; +}; + +struct fq { + union { + double whole; + struct fpq fpq; + } FQu; +}; + +#define FPU_REGS_TYPE unsigned int +#define FPU_FSR_TYPE unsigned + +struct fp_status { + union { + FPU_REGS_TYPE Fpu_regs[32]; + double Fpu_dregs[16]; + } fpu_fr; + FPU_FSR_TYPE Fpu_fsr; + unsigned Fpu_flags; + unsigned Fpu_extra; + unsigned Fpu_qcnt; + struct fq Fpu_q[16]; +}; + +#define fpu_regs f_fpstatus.fpu_fr.Fpu_regs +#define fpu_dregs f_fpstatus.fpu_fr.Fpu_dregs +#define fpu_fsr f_fpstatus.Fpu_fsr +#define fpu_flags f_fpstatus.Fpu_flags +#define fpu_extra f_fpstatus.Fpu_extra +#define fpu_q f_fpstatus.Fpu_q +#define fpu_qcnt f_fpstatus.Fpu_qcnt + +struct fpu { + struct fp_status f_fpstatus; +}; + +#endif /* __SPARC_REG_H */ diff --git a/include/asm-sparc/resource.h b/include/asm-sparc/resource.h new file mode 100644 index 000000000..61a137b48 --- /dev/null +++ b/include/asm-sparc/resource.h @@ -0,0 +1,38 @@ +/* $Id: resource.h,v 1.5 1995/11/25 02:32:35 davem Exp $ + * resource.h: Resource definitions. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_RESOURCE_H +#define _SPARC_RESOURCE_H + +/* + * Resource limits + */ + +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_RSS 5 /* max resident set size */ +#define RLIMIT_NOFILE 6 /* max number of open files */ +#define RLIMIT_NPROC 7 /* max number of processes */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ +#define RLIM_NLIMITS 9 + +#ifdef __KERNEL__ + +#define INIT_RLIMITS \ +{ \ + {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM}, \ + { 0, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ + {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, {NR_OPEN, NR_OPEN}, \ + {LONG_MAX, LONG_MAX}, \ +} + +#endif /* __KERNEL__ */ + +#endif /* !(_SPARC_RESOURCE_H) */ diff --git a/include/asm-sparc/ross.h b/include/asm-sparc/ross.h new file mode 100644 index 000000000..e6b0ddc26 --- /dev/null +++ b/include/asm-sparc/ross.h @@ -0,0 +1,174 @@ +/* $Id: ross.h,v 1.11 1996/08/29 09:48:40 davem Exp $ + * ross.h: Ross module specific definitions and defines. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_ROSS_H +#define _SPARC_ROSS_H + +#include <asm/asi.h> + +/* Ross made Hypersparcs have a %psr 'impl' field of '0001'. The 'vers' + * field has '1111'. + */ + +/* The MMU control register fields on the HyperSparc. + * + * ----------------------------------------------------------------- + * |implvers| RSV |CWR|SE|WBE| MID |BM| C|CS|MR|CM|RSV|CE|RSV|NF|ME| + * ----------------------------------------------------------------- + * 31 24 23-22 21 20 19 18-15 14 13 12 11 10 9 8 7-2 1 0 + * + * Phew, lots of fields there ;-) + * + * CWR: Cache Wrapping Enabled, if one cache wrapping is on. + * SE: Snoop Enable, turns on bus snooping for cache activity if one. + * WBE: Write Buffer Enable, one turns it on. + * MID: The ModuleID of the chip for MBus transactions. + * BM: Boot-Mode. One indicates the MMU is in boot mode. + * C: Indicates whether accesses are cachable while the MMU is + * disabled. + * CS: Cache Size -- 0 = 128k, 1 = 256k + * MR: Memory Reflection, one indicates that the memory bus connected + * to the MBus supports memory reflection. + * CM: Cache Mode -- 0 = write-through, 1 = copy-back + * CE: Cache Enable -- 0 = no caching, 1 = cache is on + * NF: No Fault -- 0 = faults trap the CPU from supervisor mode + * 1 = faults from supervisor mode do not generate traps + * ME: MMU Enable -- 0 = MMU is off, 1 = MMU is on + */ + +#define HYPERSPARC_CWENABLE 0x00200000 +#define HYPERSPARC_SBENABLE 0x00100000 +#define HYPERSPARC_WBENABLE 0x00080000 +#define HYPERSPARC_MIDMASK 0x00078000 +#define HYPERSPARC_BMODE 0x00004000 +#define HYPERSPARC_ACENABLE 0x00002000 +#define HYPERSPARC_CSIZE 0x00001000 +#define HYPERSPARC_MRFLCT 0x00000800 +#define HYPERSPARC_CMODE 0x00000400 +#define HYPERSPARC_CENABLE 0x00000100 +#define HYPERSPARC_NFAULT 0x00000002 +#define HYPERSPARC_MENABLE 0x00000001 + + +/* The ICCR instruction cache register on the HyperSparc. + * + * ----------------------------------------------- + * | | FTD | ICE | + * ----------------------------------------------- + * 31 1 0 + * + * This register is accessed using the V8 'wrasr' and 'rdasr' + * opcodes, since not all assemblers understand them and those + * that do use different semantics I will just hard code the + * instruction with a '.word' statement. + * + * FTD: If set to one flush instructions executed during an + * instruction cache hit occurs, the corresponding line + * for said cache-hit is invalidated. If FTD is zero, + * an unimplemented 'flush' trap will occur when any + * flush is executed by the processor. + * + * ICE: If set to one, the instruction cache is enabled. If + * zero, the cache will not be used for instruction fetches. + * + * All other bits are read as zeros, and writes to them have no + * effect. + * + * Wheee, not many assemblers understand the %iccr register nor + * the generic asr r/w instructions. + * + * 1000 0011 0100 0111 1100 0000 0000 0000 ! rd %iccr, %g1 + * + * 0x 8 3 4 7 c 0 0 0 ! 0x8347c000 + * + * 1011 1111 1000 0000 0110 0000 0000 0000 ! wr %g1, 0x0, %iccr + * + * 0x b f 8 0 6 0 0 0 ! 0xbf806000 + * + */ + +#define HYPERSPARC_ICCR_FTD 0x00000002 +#define HYPERSPARC_ICCR_ICE 0x00000001 + +extern __inline__ unsigned int get_ross_icr(void) +{ + unsigned int icreg; + + __asm__ __volatile__(".word 0x8347c000\n\t" /* rd %iccr, %g1 */ + "mov %%g1, %0\n\t" : + "=r" (icreg) : : + "g1", "memory"); + + return icreg; +} + +extern __inline__ void put_ross_icr(unsigned int icreg) +{ + __asm__ __volatile__("or %%g0, %0, %%g1\n\t" + ".word 0xbf806000\n\t" /* wr %g1, 0x0, %iccr */ + "nop\n\t" + "nop\n\t" + "nop\n\t" : : + "r" (icreg) : + "g1", "memory"); + + return; +} + +/* HyperSparc specific cache flushing. */ + +/* This is for the on-chip instruction cache. */ +extern __inline__ void hyper_flush_whole_icache(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : + "i" (ASI_M_FLUSH_IWHOLE)); + return; +} + +extern int vac_cache_size; +extern int vac_line_size; + +extern __inline__ void hyper_clear_all_tags(void) +{ + unsigned long addr; + + for(addr = 0; addr < vac_cache_size; addr += vac_line_size) + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_DATAC_TAG)); +} + +extern __inline__ void hyper_flush_unconditional_combined(void) +{ + unsigned long addr; + + for(addr = 0; addr < vac_cache_size; addr += vac_line_size) + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_CTX)); +} + +extern __inline__ void hyper_flush_cache_user(void) +{ + unsigned long addr; + + for(addr = 0; addr < vac_cache_size; addr += vac_line_size) + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_USER)); +} + +extern __inline__ void hyper_flush_cache_page(unsigned long page) +{ + unsigned long end; + + page &= PAGE_MASK; + end = page + PAGE_SIZE; + while(page < end) { + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (page), "i" (ASI_M_FLUSH_PAGE)); + page += vac_line_size; + } +} + +#endif /* !(_SPARC_ROSS_H) */ diff --git a/include/asm-sparc/rtc.h b/include/asm-sparc/rtc.h new file mode 100644 index 000000000..f4f261dde --- /dev/null +++ b/include/asm-sparc/rtc.h @@ -0,0 +1,27 @@ +/* $Id: rtc.h,v 1.2 1996/08/21 23:17:39 ecd Exp $ + * + * rtc.h: Definitions for access to the Mostek real time clock + * + * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) + */ + +#ifndef _RTC_H +#define _RTC_H + +#include <linux/ioctl.h> + +struct rtc_time +{ + int sec; /* Seconds (0-59) */ + int min; /* Minutes (0-59) */ + int hour; /* Hour (0-23) */ + int dow; /* Day of the week (1-7) */ + int dom; /* Day of the month (1-31) */ + int month; /* Month of year (1-12) */ + int year; /* Year (0-99) */ +}; + +#define RTCGET _IOR('p', 20, struct rtc_time) +#define RTCSET _IOW('p', 21, struct rtc_time) + +#endif diff --git a/include/asm-sparc/sbus.h b/include/asm-sparc/sbus.h new file mode 100644 index 000000000..cc9e75ae6 --- /dev/null +++ b/include/asm-sparc/sbus.h @@ -0,0 +1,101 @@ +/* $Id: sbus.h,v 1.11 1996/10/31 06:29:12 davem Exp $ + * sbus.h: Defines for the Sun SBus. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_SBUS_H +#define _SPARC_SBUS_H + +#include <asm/oplib.h> +#include <asm/iommu.h> + +/* We scan which devices are on the SBus using the PROM node device + * tree. SBus devices are described in two different ways. You can + * either get an absolute address at which to access the device, or + * you can get a SBus 'slot' number and an offset within that slot. + */ + +/* The base address at which to calculate device OBIO addresses. */ +#define SUN_SBUS_BVADDR 0xf8000000 +#define SBUS_OFF_MASK 0x01ffffff + +/* These routines are used to calculate device address from slot + * numbers + offsets, and vice versa. + */ + +extern __inline__ unsigned long sbus_devaddr(int slotnum, unsigned long offset) +{ + return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset)); +} + +extern __inline__ int sbus_dev_slot(unsigned long dev_addr) +{ + return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25); +} + +extern __inline__ unsigned long sbus_dev_offset(unsigned long dev_addr) +{ + return (unsigned long) (((dev_addr)-SUN_SBUS_BVADDR)&SBUS_OFF_MASK); +} + +struct linux_sbus; + +/* Linux SBUS device tables */ +struct linux_sbus_device { + struct linux_sbus_device *next; /* next device on this SBus or null */ + struct linux_sbus_device *child; /* For ledma and espdma on sun4m */ + struct linux_sbus *my_bus; /* Back ptr to sbus */ + int prom_node; /* PROM device tree node for this device */ + char prom_name[64]; /* PROM device name */ + char linux_name[64]; /* Name used internally by Linux */ + + struct linux_prom_registers reg_addrs[PROMREG_MAX]; + int num_registers; + + struct linux_prom_irqs irqs[PROMINTR_MAX]; + int num_irqs; + + unsigned long sbus_addr; /* Absolute base address for device. */ + unsigned long sbus_vaddrs[PROMVADDR_MAX]; + unsigned long num_vaddrs; + unsigned long offset; /* Offset given by PROM */ + int slot; +}; + +/* This struct describes the SBus(s) found on this machine. */ +struct linux_sbus { + struct linux_sbus *next; /* next SBus, if more than one SBus */ + struct linux_sbus_device *devices; /* Link to devices on this SBus */ + struct iommu_struct *iommu; /* IOMMU for this sbus if applicable */ + int prom_node; /* PROM device tree node for this SBus */ + char prom_name[64]; /* Usually "sbus" or "sbi" */ + int clock_freq; + struct linux_prom_ranges sbus_ranges[PROMREG_MAX]; + int num_sbus_ranges; +}; + +extern struct linux_sbus *SBus_chain; + +extern __inline__ int +sbus_is_slave(struct linux_sbus_device *dev) +{ + /* Have to write this for sun4c's */ + return 0; +} + +/* Device probing routines could find these handy */ +#define for_each_sbus(bus) \ + for((bus) = SBus_chain; (bus); (bus)=(bus)->next) + +#define for_each_sbusdev(device, bus) \ + for((device) = (bus)->devices; (device); (device)=(device)->next) + +#define for_all_sbusdev(device, bus) \ + for((bus) = SBus_chain, (device) = (bus)->devices; (bus); (device)=((device)->next ? (device)->next : ((bus) = (bus)->next, (bus) ? (bus)->devices : 0))) + +/* Apply promlib probed SBUS ranges to registers. */ +extern void prom_apply_sbus_ranges(struct linux_sbus *sbus, + struct linux_prom_registers *sbusregs, int nregs); + +#endif /* !(_SPARC_SBUS_H) */ diff --git a/include/asm-sparc/segment.h b/include/asm-sparc/segment.h index 27489b3e5..a1b7ffc9e 100644 --- a/include/asm-sparc/segment.h +++ b/include/asm-sparc/segment.h @@ -1,87 +1,6 @@ -#ifndef _ASM_SEGMENT_H -#define _ASM_SEGMENT_H +#ifndef __SPARC_SEGMENT_H +#define __SPARC_SEGMENT_H -#define KERNEL_CS 0x0 -#define KERNEL_DS 0x0 +/* Only here because we have some old header files that expect it.. */ -#define USER_CS 0x1 -#define USER_DS 0x1 - -#include <linux/string.h> -#include <asm/vac-ops.h> - -static inline unsigned char get_user_byte(const char * addr) -{ - return *addr; -} - -#define get_fs_byte(addr) get_user_byte((char *)(addr)) - -static inline unsigned short get_user_word(const short *addr) -{ - return *addr; -} - -#define get_fs_word(addr) get_user_word((short *)(addr)) - -static inline unsigned long get_user_long(const int *addr) -{ - return *addr; -} - -#define get_fs_long(addr) get_user_long((int *)(addr)) - -static inline unsigned long get_user_quad(const long *addr) -{ - return *addr; -} - -#define get_fs_quad(addr) get_user_quad((long *)(addr)) - -static inline void put_user_byte(char val,char *addr) -{ - *addr = val; -} - -#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) - -static inline void put_user_word(short val,short * addr) -{ - *addr = val; -} - -#define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) - -static inline void put_user_long(unsigned long val,int * addr) -{ - *addr = val; -} - -#define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) - -static inline void put_user_quad(unsigned long val,long * addr) -{ - *addr = val; -} - -#define put_fs_quad(x,addr) put_user_quad((x),(long *)(addr)) - -#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n)) - -#define memcpy_tofs(to, from, n) memcpy((to),(from),(n)) - -static inline unsigned long get_fs(void) -{ - return 0; -} - -static inline unsigned long get_ds(void) -{ - return 0; -} - -static inline void set_fs(unsigned long val) -{ -} - -#endif /* _ASM_SEGMENT_H */ +#endif diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h new file mode 100644 index 000000000..4892ccb26 --- /dev/null +++ b/include/asm-sparc/semaphore.h @@ -0,0 +1,42 @@ +#ifndef _SPARC_SEMAPHORE_H +#define _SPARC_SEMAPHORE_H + +/* Dinky, good for nothing, just barely irq safe, Sparc semaphores. + * + * I'll write better ones later. + */ + +#include <asm/atomic.h> + +struct semaphore { + atomic_t count; + atomic_t waiting; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { 1, 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) + +extern void __down(struct semaphore * sem); +extern void __up(struct semaphore * sem); + +/* + * This isn't quite as clever as the x86 side, but the gp register + * makes things a bit more complicated on the alpha.. + */ +extern inline void down(struct semaphore * sem) +{ + for (;;) { + if (atomic_dec_return(&sem->count) >= 0) + break; + __down(sem); + } +} + +extern inline void up(struct semaphore * sem) +{ + if (atomic_inc_return(&sem->count) <= 0) + __up(sem); +} + +#endif /* !(_SPARC_SEMAPHORE_H) */ diff --git a/include/asm-sparc/shmparam.h b/include/asm-sparc/shmparam.h new file mode 100644 index 000000000..54420d89d --- /dev/null +++ b/include/asm-sparc/shmparam.h @@ -0,0 +1,45 @@ +/* $Id: shmparam.h,v 1.3 1995/11/25 02:32:42 davem Exp $ */ +#ifndef _ASMSPARC_SHMPARAM_H +#define _ASMSPARC_SHMPARAM_H + +/* address range for shared memory attaches if no address passed to shmat() */ +#define SHM_RANGE_START 0x10000000 +#define SHM_RANGE_END 0x20000000 + +/* + * Format of a swap-entry for shared memory pages currently out in + * swap space (see also mm/swap.c). + * + * SWP_TYPE = SHM_SWP_TYPE + * SWP_OFFSET is used as follows: + * + * bits 0..6 : id of shared memory segment page belongs to (SHM_ID) + * bits 7..21: index of page within shared memory segment (SHM_IDX) + * (actually fewer bits get used since SHMMAX is so low) + */ + +/* + * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and + * there is a static array of size SHMMNI. + */ +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +/* + * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and + * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). + */ + +#define SHMMAX (1024 * 1024) /* max shared seg size (bytes) */ +#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ +#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ +#define SHMALL /* max shm system wide (pages) */ \ + (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ +#define SHMSEG SHMMNI /* max shared segs per process */ + +#endif /* _ASMSPARC_SHMPARAM_H */ diff --git a/include/asm-sparc/sigcontext.h b/include/asm-sparc/sigcontext.h new file mode 100644 index 000000000..c7a9993fe --- /dev/null +++ b/include/asm-sparc/sigcontext.h @@ -0,0 +1,42 @@ +/* $Id: sigcontext.h,v 1.9 1996/10/27 08:55:42 davem Exp $ */ +#ifndef _ASMsparc_SIGCONTEXT_H +#define _ASMsparc_SIGCONTEXT_H + +#include <asm/ptrace.h> + +#define SUNOS_MAXWIN 31 + +#ifndef __ASSEMBLY__ + +/* SunOS system call sigstack() uses this arg. */ +struct sunos_sigstack { + unsigned long sig_sp; + int onstack_flag; +}; + +/* This is what SunOS does, so shall I. */ +struct sigcontext { + int sigc_onstack; /* state to restore */ + int sigc_mask; /* sigmask to restore */ + int sigc_sp; /* stack pointer */ + int sigc_pc; /* program counter */ + int sigc_npc; /* next program counter */ + int sigc_psr; /* for condition codes etc */ + int sigc_g1; /* User uses these two registers */ + int sigc_o0; /* within the trampoline code. */ + + /* Now comes information regarding the users window set + * at the time of the signal. + */ + int sigc_oswins; /* outstanding windows */ + + /* stack ptrs for each regwin buf */ + char *sigc_spbuf[SUNOS_MAXWIN]; + + /* Windows to restore after signal */ + struct reg_window sigc_wbuf[SUNOS_MAXWIN]; +}; +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_ASMsparc_SIGCONTEXT_H) */ + diff --git a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h index 2e599e18d..2cc321d13 100644 --- a/include/asm-sparc/signal.h +++ b/include/asm-sparc/signal.h @@ -1,11 +1,177 @@ +/* $Id: signal.h,v 1.29 1996/10/27 08:55:45 davem Exp $ */ #ifndef _ASMSPARC_SIGNAL_H #define _ASMSPARC_SIGNAL_H -struct sigcontext_struct { - /* - * Have to find out what SUNOS and Solaris do. This could - * get real ugly. David S. Miller (davem@caip.rutgers.edu) - */ +#include <asm/sigcontext.h> + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ +#include <linux/personality.h> +#endif +#endif + +/* On the Sparc the signal handlers get passed a 'sub-signal' code + * for certain signal types, which we document here. + */ +#define _NSIG 32 +#define NSIG _NSIG + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SUBSIG_STACK 0 +#define SUBSIG_ILLINST 2 +#define SUBSIG_PRIVINST 3 +#define SUBSIG_BADTRAP(t) (0x80 + (t)) + +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 + +#define SIGEMT 7 +#define SUBSIG_TAG 10 + +#define SIGFPE 8 +#define SUBSIG_FPDISABLED 0x400 +#define SUBSIG_FPERROR 0x404 +#define SUBSIG_FPINTOVFL 0x001 +#define SUBSIG_FPSTSIG 0x002 +#define SUBSIG_IDIVZERO 0x014 +#define SUBSIG_FPINEXACT 0x0c4 +#define SUBSIG_FPDIVZERO 0x0c8 +#define SUBSIG_FPUNFLOW 0x0cc +#define SUBSIG_FPOPERROR 0x0d0 +#define SUBSIG_FPOVFLOW 0x0d4 + +#define SIGKILL 9 +#define SIGBUS 10 +#define SUBSIG_BUSTIMEOUT 1 +#define SUBSIG_ALIGNMENT 2 +#define SUBSIG_MISCERROR 5 + +#define SIGSEGV 11 +#define SUBSIG_NOMAPPING 3 +#define SUBSIG_PROTECTION 4 +#define SUBSIG_SEGERROR 5 + +#define SIGSYS 12 + +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGURG 16 + +/* SunOS values which deviate from the Linux/i386 ones */ +#define SIGSTOP 17 +#define SIGTSTP 18 +#define SIGCONT 19 +#define SIGCHLD 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGIO 23 +#define SIGPOLL SIGIO /* SysV name for SIGIO */ +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGLOST 29 +#define SIGUSR1 30 +#define SIGUSR2 31 + +#ifndef __ASSEMBLY__ + +typedef unsigned long sigset_t; + +#ifdef __KERNEL__ +#include <asm/sigcontext.h> +#endif + +/* A SunOS sigstack */ +struct sigstack { + char *the_stack; + int cur_status; }; +/* Sigvec flags */ +#define SV_SSTACK 1 /* This signal handler should use sig-stack */ +#define SV_INTR 2 /* Sig return should not restart system call */ +#define SV_RESET 4 /* Set handler to SIG_DFL upon taken signal */ +#define SV_IGNCHILD 8 /* Do not send SIGCHLD */ + +/* + * sa_flags values: SA_STACK is not currently supported, but will allow the + * usage of signal stacks by using the (now obsolete) sa_restorer field in + * the sigaction structure as a stack pointer. This is now possible due to + * the changes in signal handling. LBT 010493. + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. + */ +#define SA_NOCLDSTOP SV_IGNCHILD +#define SA_STACK SV_SSTACK +#define SA_RESTART SV_INTR +#define SA_ONESHOT SV_RESET +#define SA_INTERRUPT 0x10 +#define SA_NOMASK 0x20 +#define SA_SHIRQ 0x40 + +#define SIG_BLOCK 0x01 /* for blocking signals */ +#define SIG_UNBLOCK 0x02 /* for unblocking signals */ +#define SIG_SETMASK 0x04 /* for setting the signal mask */ + +#ifdef __KERNEL__ +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + * + * DJHR + * SA_STATIC_ALLOC is used for the SPARC system to indicate that this + * interrupt handler's irq structure should be statically allocated + * by the request_irq routine. + * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge + * of interrupt usage and that sucks. Also without a flag like this + * it may be possible for the free_irq routine to attempt to free + * statically allocated data.. which is NOT GOOD. + * + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#define SA_STATIC_ALLOC 0x80 +#endif + +/* Type of a signal handler. */ +#ifdef __KERNEL__ +typedef void (*__sighandler_t)(int, int, struct sigcontext *, char *); +#else +typedef void (*__sighandler_t)(int); #endif + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +struct sigaction { + __sighandler_t sa_handler; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer) (void); /* not used by Linux/SPARC yet */ +}; + +#ifdef __KERNEL__ + +/* use the following macro to get the size of a sigaction struct + when copying to/from userland */ +#define SIGACTION_SIZE(personality) (((personality) & PER_BSD)?\ + sizeof(struct sigaction)-sizeof(void *):\ + sizeof(struct sigaction)) + +#endif /* __KERNEL__ */ + + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_ASMSPARC_SIGNAL_H) */ diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h new file mode 100644 index 000000000..0d1cab1eb --- /dev/null +++ b/include/asm-sparc/smp.h @@ -0,0 +1,172 @@ +/* smp.h: Sparc specific SMP stuff. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_SMP_H +#define _SPARC_SMP_H + +#ifndef __ASSEMBLY__ +/* PROM provided per-processor information we need + * to start them all up. + */ + +struct prom_cpuinfo { + int prom_node; + int mid; +}; +#endif /* !(__ASSEMBLY__) */ + +#ifdef __SMP__ + +#ifndef __ASSEMBLY__ + +extern struct prom_cpuinfo linux_cpus[NCPUS]; + +/* Per processor Sparc parameters we need. */ + +struct cpuinfo_sparc { + unsigned long udelay_val; /* that's it */ +}; + +extern struct cpuinfo_sparc cpu_data[NR_CPUS]; + +typedef __volatile__ unsigned char klock_t; +extern klock_t kernel_flag; + +#define KLOCK_HELD 0xff +#define KLOCK_CLEAR 0x00 + +/* + * Private routines/data + */ + +extern int smp_found_cpus; +extern unsigned char boot_cpu_id; +extern unsigned long cpu_present_map; +extern __volatile__ unsigned long smp_invalidate_needed[NR_CPUS]; +extern __volatile__ unsigned long kernel_counter; +extern __volatile__ unsigned char active_kernel_processor; +extern void smp_message_irq(void); +extern unsigned long ipi_count; +extern __volatile__ unsigned long kernel_counter; +extern __volatile__ unsigned long syscall_count; + +extern void print_lock_state(void); + +typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long, + unsigned long, unsigned long); + +/* + * General functions that each host system must provide. + */ + +extern void smp_callin(void); +extern void smp_boot_cpus(void); +extern void smp_store_cpu_info(int id); +extern void smp_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, unsigned long arg5); +extern void smp_capture(void); +extern void smp_release(void); + +extern __inline__ void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); } +extern __inline__ void xc1(smpfunc_t func, unsigned long arg1) +{ smp_cross_call(func, arg1, 0, 0, 0, 0); } +extern __inline__ void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) +{ smp_cross_call(func, arg1, arg2, 0, 0, 0); } +extern __inline__ void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, + unsigned long arg3) +{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); } +extern __inline__ void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4) +{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); } +extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, unsigned long arg5) +{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); } + +extern __volatile__ int cpu_number_map[NR_CPUS]; +extern __volatile__ int cpu_logical_map[NR_CPUS]; + +extern __inline__ int smp_processor_id(void) +{ + int cpuid; + + __asm__ __volatile__("rd %%tbr, %0\n\t" + "srl %0, 12, %0\n\t" + "and %0, 3, %0\n\t" : + "=&r" (cpuid)); + return cpuid; +} + + +extern __volatile__ unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */ +extern __volatile__ int smp_process_available; + +extern __inline__ int smp_swap(volatile int *addr, int value) +{ + __asm__ __volatile__("swap [%2], %0\n\t" : + "=&r" (value) : + "0" (value), "r" (addr)); + return value; +} + +extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr) +{ + int tmp; + + while((tmp = smp_swap(ctr, -1)) == -1) + while(*ctr == -1) + ; + + *ctr = (tmp + 1); +} + +extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr) +{ + int tmp; + + while((tmp = smp_swap(ctr, -1)) == -1) + while(*ctr == -1) + ; + + *ctr = (tmp - 1); +} + +extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr) +{ + int value; + + while((value = *ctr) == -1) + ; + + return value; +} + +#endif /* !(__ASSEMBLY__) */ + +/* Sparc specific messages. */ +#define MSG_CAPTURE 0x0004 /* Park a processor. */ +#define MSG_CROSS_CALL 0x0005 /* run func on cpus */ + +/* Empirical PROM processor mailbox constants. If the per-cpu mailbox + * contains something other than one of these then the ipi is from + * Linux's active_kernel_processor. This facility exists so that + * the boot monitor can capture all the other cpus when one catches + * a watchdog reset or the user enters the monitor using L1-A keys. + */ +#define MBOX_STOPCPU 0xFB +#define MBOX_IDLECPU 0xFC +#define MBOX_IDLECPU2 0xFD +#define MBOX_STOPCPU2 0xFE + + +#define NO_PROC_ID 0xFF + +#define PROC_CHANGE_PENALTY 20 + +#define SMP_FROM_INT 1 +#define SMP_FROM_SYSCALL 2 + +#endif /* !(__SMP__) */ + +#endif /* !(_SPARC_SMP_H) */ diff --git a/include/asm-sparc/smp_lock.h b/include/asm-sparc/smp_lock.h new file mode 100644 index 000000000..7ce71d8ff --- /dev/null +++ b/include/asm-sparc/smp_lock.h @@ -0,0 +1,60 @@ +/* smp_lock.h: Locking and unlocking the kernel on the Sparc. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __SPARC_SMPLOCK_H +#define __SPARC_SMPLOCK_H + +#include <asm/smp.h> +#include <asm/bitops.h> +#include <asm/atops.h> +#include <asm/pgtable.h> + +#ifdef __SMP__ + +/* + * Locking the kernel + */ + +/* Knock knock... */ +extern __inline__ void lock_kernel(void) +{ + unsigned long flags; + int proc = smp_processor_id(); + + save_flags(flags); cli(); /* need this on sparc? */ + while(ldstub(&kernel_flag)) { + if(proc == active_kernel_processor) + break; + do { +#ifdef __SMP_PROF__ + smp_spins[smp_processor_id()]++; +#endif + barrier(); + } while(kernel_flag); /* Don't lock the bus more than we have to. */ + } + active_kernel_processor = proc; + kernel_counter++; + restore_flags(flags); +} + +/* I want out... */ +extern __inline__ void unlock_kernel(void) +{ + unsigned long flags; + + save_flags(flags); cli(); /* need this on sparc? */ + if(kernel_counter == 0) + panic("Bogus kernel counter.\n"); + + if(!--kernel_counter) { + active_kernel_processor = NO_PROC_ID; + kernel_flag = KLOCK_CLEAR; + } + restore_flags(flags); +} + +#endif /* !(__SPARC_SMPLOCK_H) */ + +#endif /* (__SMP__) */ diff --git a/include/asm-sparc/smpprim.h b/include/asm-sparc/smpprim.h new file mode 100644 index 000000000..9b9c28ed7 --- /dev/null +++ b/include/asm-sparc/smpprim.h @@ -0,0 +1,54 @@ +/* $Id: smpprim.h,v 1.5 1996/08/29 09:48:49 davem Exp $ + * smpprim.h: SMP locking primitives on the Sparc + * + * God knows we won't be actually using this code for some time + * but I thought I'd write it since I knew how. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __SPARC_SMPPRIM_H +#define __SPARC_SMPPRIM_H + +/* Test and set the unsigned byte at ADDR to 1. Returns the previous + * value. On the Sparc we use the ldstub instruction since it is + * atomic. + */ + +extern __inline__ __volatile__ char test_and_set(void *addr) +{ + char state = 0; + + __asm__ __volatile__("ldstub [%0], %1 ! test_and_set\n\t" + "=r" (addr), "=r" (state) : + "0" (addr), "1" (state) : "memory"); + + return state; +} + +/* Initialize a spin-lock. */ +extern __inline__ __volatile__ smp_initlock(void *spinlock) +{ + /* Unset the lock. */ + *((unsigned char *) spinlock) = 0; + + return; +} + +/* This routine spins until it acquires the lock at ADDR. */ +extern __inline__ __volatile__ smp_lock(void *addr) +{ + while(test_and_set(addr) == 0xff) + ; + + /* We now have the lock */ + return; +} + +/* This routine releases the lock at ADDR. */ +extern __inline__ __volatile__ smp_unlock(void *addr) +{ + *((unsigned char *) addr) = 0; +} + +#endif /* !(__SPARC_SMPPRIM_H) */ diff --git a/include/asm-sparc/socket.h b/include/asm-sparc/socket.h new file mode 100644 index 000000000..1c5348030 --- /dev/null +++ b/include/asm-sparc/socket.h @@ -0,0 +1,32 @@ +/* $Id: socket.h,v 1.6 1996/04/04 12:51:26 davem Exp $ */ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockoptions(2) */ +#define SOL_SOCKET 0xffff + +#define SO_DEBUG 0x0001 +#define SO_REUSEADDR 0x0004 +#define SO_KEEPALIVE 0x0008 +#define SO_DONTROUTE 0x0010 +#define SO_BROADCAST 0x0020 +#define SO_LINGER 0x0080 +#define SO_OOBINLINE 0x0100 +/* To add :#define SO_REUSEPORT 0x0200 */ +#define SO_BSDCOMPAT 0x0400 + +/* wha!??? */ +#define SO_DONTLINGER (~SO_LINGER) /* Older SunOS compat. hack */ + +#define SO_SNDBUF 0x1001 +#define SO_RCVBUF 0x1002 +#define SO_ERROR 0x1007 +#define SO_TYPE 0x1008 + +/* Linux specific, keep the same. */ +#define SO_NO_CHECK 0x000b +#define SO_PRIORITY 0x000c + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-sparc/sockios.h b/include/asm-sparc/sockios.h new file mode 100644 index 000000000..0c01b597b --- /dev/null +++ b/include/asm-sparc/sockios.h @@ -0,0 +1,13 @@ +#ifndef _ASM_SPARC_SOCKIOS_H +#define _ASM_SPARC_SOCKIOS_H + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +#endif /* !(_ASM_SPARC_SOCKIOS_H) */ + diff --git a/include/asm-sparc/solerrno.h b/include/asm-sparc/solerrno.h new file mode 100644 index 000000000..8abce7e46 --- /dev/null +++ b/include/asm-sparc/solerrno.h @@ -0,0 +1,132 @@ +/* $Id: solerrno.h,v 1.5 1996/04/25 06:13:32 davem Exp $ + * solerrno.h: Solaris error return codes for compatibility. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_SOLERRNO_H +#define _SPARC_SOLERRNO_H + +#define SOL_EPERM 1 /* Required superuser access perms */ +#define SOL_ENOENT 2 /* File or directory does not exist */ +#define SOL_ESRCH 3 /* Process did not exist */ +#define SOL_EINTR 4 /* System call was interrupted */ +#define SOL_EIO 5 /* An i/o error occurred */ +#define SOL_ENXIO 6 /* Device or Address does not exist */ +#define SOL_E2BIG 7 /* Too many arguments were given */ +#define SOL_ENOEXEC 8 /* Header of executable was munged */ +#define SOL_EBADF 9 /* Bogus file number */ +#define SOL_ECHILD 10 /* No children of process exist */ +#define SOL_EAGAIN 11 /* beep beep, "try again later" */ +#define SOL_ENOMEM 12 /* No memory available */ +#define SOL_EACCES 13 /* Access not allowed */ +#define SOL_EFAULT 14 /* Address passed was invalid */ +#define SOL_ENOTBLK 15 /* blkdev op on non-block device */ +#define SOL_EBUSY 16 /* Mounted device was busy */ +#define SOL_EEXIST 17 /* File specified already exists */ +#define SOL_EXDEV 18 /* Link request across diff devices */ +#define SOL_ENODEV 19 /* Device does not exist on system */ +#define SOL_ENOTDIR 20 /* Dir operation on non-directory */ +#define SOL_EISDIR 21 /* File was of directory type */ +#define SOL_EINVAL 22 /* Argument passed was invalid */ +#define SOL_ENFILE 23 /* No more room in file table */ +#define SOL_EMFILE 24 /* Proc has too many files open */ +#define SOL_ENOTTY 25 /* Ioctl was invalid for req device */ +#define SOL_ETXTBSY 26 /* Text file in busy state */ +#define SOL_EFBIG 27 /* Too big of a file for operation */ +#define SOL_ENOSPC 28 /* Disk is full */ +#define SOL_ESPIPE 29 /* Seek attempted on non-seeking dev*/ +#define SOL_EROFS 30 /* Write attempted on read-only fs */ +#define SOL_EMLINK 31 /* Too many links in file search */ +#define SOL_EPIPE 32 /* Call a plumber */ +#define SOL_EDOM 33 /* Argument was out of fct domain */ +#define SOL_ERANGE 34 /* Could not represent math result */ +#define SOL_ENOMSG 35 /* Message of req type doesn't exist */ +#define SOL_EIDRM 36 /* Identifier has been removed */ +#define SOL_ECHRNG 37 /* Req channel number out of range */ +#define SOL_EL2NSYNC 38 /* Could not sync at run level 2 */ +#define SOL_EL3HLT 39 /* Halted at run level 3 */ +#define SOL_EL3RST 40 /* Reset at run level 3 */ +#define SOL_ELNRNG 41 /* Out of range link number */ +#define SOL_EUNATCH 42 /* Driver for protocol not attached */ +#define SOL_ENOCSI 43 /* CSI structure not around */ +#define SOL_EL2HLT 44 /* Halted at run level 2 */ +#define SOL_EDEADLK 45 /* Deadlock condition detected */ +#define SOL_ENOLCK 46 /* Record locks unavailable */ +#define SOL_ECANCELED 47 /* Cancellation of oper. happened */ +#define SOL_ENOTSUP 48 /* Attempt of unsupported operation */ +#define SOL_EDQUOT 49 /* Users disk quota exceeded */ +#define SOL_EBADE 50 /* Invalid exchange */ +#define SOL_EBADR 51 /* Request descriptor was invalid */ +#define SOL_EXFULL 52 /* Full exchange */ +#define SOL_ENOANO 53 /* ano does not exist */ +#define SOL_EBADRQC 54 /* Req code was invalid */ +#define SOL_EBADSLT 55 /* Bad slot number */ +#define SOL_EDEADLOCK 56 /* Deadlock in fs error */ +#define SOL_EBFONT 57 /* Font file format invalid */ +/* YOW, I LOVE SYSV STREAMS!!!! */ +#define SOL_ENOSTR 60 /* Stream-op on non-stream dev */ +#define SOL_ENODATA 61 /* No data avail at this time */ +#define SOL_ETIME 62 /* Expiration of time occurred */ +#define SOL_ENOSR 63 /* Streams resources exhausted */ +#define SOL_ENONET 64 /* No network connected */ +#define SOL_ENOPKG 65 /* Non-installed package */ +#define SOL_EREMOTE 66 /* Object was on remote machine */ +#define SOL_ENOLINK 67 /* Cut link */ +#define SOL_EADV 68 /* Error in advertise */ +#define SOL_ESRMNT 69 /* Some magic srmount problem */ +#define SOL_ECOMM 70 /* During send, comm error occurred */ +#define SOL_EPROTO 71 /* Protocol botch */ +#define SOL_EMULTIHOP 74 /* Multihop attempted */ +#define SOL_EBADMSG 77 /* Message was unreadable */ +#define SOL_ENAMETOOLONG 78 /* Too long of a path name */ +#define SOL_EOVERFLOW 79 /* Data type too small for datum */ +#define SOL_ENOTUNIQ 80 /* Logical name was not unique */ +#define SOL_EBADFD 81 /* Op cannot be performed on fd */ +#define SOL_EREMCHG 82 /* Remote address is now different */ +#define SOL_ELIBACC 83 /* Shared lib could not be accessed */ +#define SOL_ELIBBAD 84 /* ShLib is corrupted in some way */ +#define SOL_ELIBSCN 85 /* A.out ShLib problems */ +#define SOL_ELIBMAX 86 /* Exceeded ShLib linkage limit */ +#define SOL_ELIBEXEC 87 /* Execution of ShLib attempted */ +#define SOL_EILSEQ 88 /* Bad byte sequence found */ +#define SOL_ENOSYS 89 /* Invalid filesystem operation */ +#define SOL_ELOOP 90 /* Detected loop in symbolic links */ +#define SOL_ERESTART 91 /* System call is restartable */ +#define SOL_ESTRPIPE 92 /* Do not sleep in head of stream */ +#define SOL_ENOTEMPTY 93 /* Rmdir of non-empty directory */ +#define SOL_EUSERS 94 /* Over abundance of users for ufs */ +#define SOL_ENOTSOCK 95 /* Sock-op on non-sock */ +#define SOL_EDESTADDRREQ 96 /* No dest addr given, but needed */ +#define SOL_EMSGSIZE 97 /* Msg too big */ +#define SOL_EPROTOTYPE 98 /* Bad socket protocol */ +#define SOL_ENOPROTOOPT 99 /* Unavailable protocol */ +#define SOL_EPROTONOSUPPORT 120 /* Unsupported protocol */ +#define SOL_ESOCKTNOSUPPORT 121 /* Unsupported socket type */ +#define SOL_EOPNOTSUPP 122 /* Unsupported sock-op */ +#define SOL_EPFNOSUPPORT 123 /* Unsupported protocol family */ +#define SOL_EAFNOSUPPORT 124 /* Unsup addr family for protocol */ +#define SOL_EADDRINUSE 125 /* Req addr is already in use */ +#define SOL_EADDRNOTAVAIL 126 /* Req addr not available right now */ +#define SOL_ENETDOWN 127 /* Your subnet is on fire */ +#define SOL_ENETUNREACH 128 /* Someone playing with gateway and */ + /* did not tell you he was going to */ +#define SOL_ENETRESET 129 /* Buy less-buggy ethernet cards */ +#define SOL_ECONNABORTED 130 /* Aborted connection due to sw */ +#define SOL_ECONNRESET 131 /* Your peers reset your connection */ +#define SOL_ENOBUFS 132 /* No buffer space available */ +#define SOL_EISCONN 133 /* Connect on already connected */ + /* socket attempted */ +#define SOL_ENOTCONN 134 /* Comm on non-connected socket */ +#define SOL_ESHUTDOWN 143 /* Op attempted after sock-shutdown */ +#define SOL_ETOOMANYREFS 144 /* Reference limit exceeded */ +#define SOL_ETIMEDOUT 145 /* Timed out connection */ +#define SOL_ECONNREFUSED 146 /* Connection refused by remote host*/ +#define SOL_EHOSTDOWN 147 /* Remote host is up in flames */ +#define SOL_EHOSTUNREACH 148 /* Make a left at Easton Ave..... */ +#define SOL_EWOULDBLOCK EAGAIN /* Just an alias */ +#define SOL_EALREADY 149 /* Operation is already occurring */ +#define SOL_EINPROGRESS 150 /* Operation is happening now */ +#define SOL_ESTALE 151 /* Fungus growth on NFS file handle */ + +#endif /* !(_SPARC_SOLERRNO_H) */ diff --git a/include/asm-sparc/stat.h b/include/asm-sparc/stat.h new file mode 100644 index 000000000..35f929c56 --- /dev/null +++ b/include/asm-sparc/stat.h @@ -0,0 +1,41 @@ +/* $Id: stat.h,v 1.7 1996/10/27 08:55:48 davem Exp $ */ +#ifndef _SPARC_STAT_H +#define _SPARC_STAT_H + +#include <linux/types.h> + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +struct stat { + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + short st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + off_t st_size; + time_t st_atime; + unsigned long __unused1; + time_t st_mtime; + unsigned long __unused2; + time_t st_ctime; + unsigned long __unused3; + off_t st_blksize; + off_t st_blocks; + unsigned long __unused4[2]; +}; + +#endif diff --git a/include/asm-sparc/statfs.h b/include/asm-sparc/statfs.h new file mode 100644 index 000000000..91a19b92a --- /dev/null +++ b/include/asm-sparc/statfs.h @@ -0,0 +1,26 @@ +/* $Id: statfs.h,v 1.4 1996/06/07 00:41:05 ecd Exp $ */ +#ifndef _SPARC_STATFS_H +#define _SPARC_STATFS_H + +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif + +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; /* SunOS ignores this field. */ + long f_spare[6]; +}; + +#endif diff --git a/include/asm-sparc/string.h b/include/asm-sparc/string.h index 6e0bfc1f7..856e96f6d 100644 --- a/include/asm-sparc/string.h +++ b/include/asm-sparc/string.h @@ -1,367 +1,178 @@ -/* string.h: External definitions for optimized assembly string - routines for the Linux Kernel. +/* $Id: string.h,v 1.27 1996/10/27 08:55:50 davem Exp $ + * string.h: External definitions for optimized assembly string + * routines for the Linux Kernel. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ - Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) -*/ +#ifndef __SPARC_STRING_H__ +#define __SPARC_STRING_H__ -extern inline size_t strlen(const char * str) -{ - register size_t retval = 0; - register char tmp = 0; - register char * lstr; - - lstr = (char *) str; - - __asm__("ldub [%1], %2\n\t" - "or %%g0, %%g0, %0\n\t" - "orcc %2, %%g0, %%g0\n\t" - "be 2f\n\t" - "add %1, 0x1, %1\n\t" - "1: ldub [%1], %2\n\t" - "add %0, 0x1, %0\n\t" - "orcc %2, %%g0, %%g0\n\t" - "bne 1b\n\t" - "add %1, 0x1, %1\n\t" - "2:" : - "=r" (retval), "=r" (lstr), "=r" (tmp) : - "0" (retval), "1" (lstr), "2" (tmp)); - - return retval; -} - -extern __inline__ int strcmp(const char* str1, const char* str2) -{ - register unsigned int tmp1=0, tmp2=0; - register int retval=0; - - __asm__("ldub [%1], %3\n\t" - "ldub [%2], %4\n\t" - "1: add %2, 0x1, %2\n\t" - "cmp %3, %4\n\t" - "bne,a 2f\n\t" - "sub %2, 0x1, %2\n\t" - "ldub [%1], %3\n\t" - "add %1, 0x1, %1\n\t" - "cmp %3, 0x0\n\t" - "bne,a 1b\n\t" - "ldub [%2], %4\n\t" - "b 3f\n\t" - "or %%g0, %%g0, %0\n\t" - "2: ldub [%1], %3\n\t" - "ldub [%2], %4\n\t" - "sub %3, %4, %0\n\t" - "3: \n\t" : - "=r" (retval), "=r" (str1), "=r" (str2), "=r" (tmp1), "=r" (tmp2) : - "0" (retval), "1" (str1), "2" (str2), - "3" (tmp1), "4" (tmp2)); - - return retval; -} - -extern __inline__ int strncmp(const char* str1, const char* str2, size_t strlen) -{ - register int retval=0; - - __asm__("cmp %3, 0x0\n\t" - "be 2f\n\t" - "ldub [%2], %%g3\n\t" - "1: ldub [%1], %%g2\n\t" - "sub %%g2, %%g3, %0\n\t" - "cmp %0, 0x0\n\t" - "bne 2f\n\t" - "add %2, 0x1, %2\n\t" - "cmp %%g2, 0x0\n\t" - "be 2f\n\t" - "add %1, 0x1, %1\n\t" - "addcc %3, -1, %3\n\t" - "bne,a 1b\n\t" - "ldub [%2], %%g3\n\t" - "2: " : - "=r" (retval), "=r" (str1), "=r" (str2), "=r" (strlen) : - "0" (retval), "1" (str1), "2" (str2), "3" (strlen) : - "%g2", "%g3"); - - return retval; -} +/* Really, userland/ksyms should not see any of this stuff. */ +#if defined(__KERNEL__) && !defined(EXPORT_SYMTAB) -extern __inline__ char *strcpy(char* dest, const char* source) -{ - register char tmp; - register char *retval; - - __asm__("or %%g0, %2, %0\n\t" - "ldub [%1], %3\n\t" - "1: stb %3, [%2]\n\t" - "cmp %3, 0x0\n\t" - "bne,a 1b\n\t" - "ldub [%1], %3\n\t" : - "=r" (retval), "=r" (source), "=r" (dest), "=r" (tmp) : - "0" (retval), "1" (source), "2" (dest), "3" (tmp)); - - return retval; -} +/* First the mem*() things. */ +#define __HAVE_ARCH_BCOPY +#define __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMCPY +extern void *__memcpy(void *,const void *,__kernel_size_t); -extern __inline__ char *strncpy(char *dest, const char *source, size_t cpylen) +extern inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n) { - register char tmp; - register char *retval; - - __asm__("or %%g0, %1, %0\n\t" - "1: cmp %4, 0x0\n\t" - "be 2f\n\t" - "ldub [%1], %3\n\t" - "add %1, 0x1, %1\n\t" - "stb %3, [%2]\n\t" - "sub %4, 0x1, %4\n\t" - "ba 1\n\t" - "add %2, 0x1, %2\n\t" : - "=r" (retval), "=r" (dest), "=r" (source), "=r"(tmp), "=r" (cpylen) : - "0" (retval), "1" (dest), "2" (source), - "3" (tmp), "4" (cpylen)); - - return retval; -} - -extern __inline__ char *strcat(char *dest, const char *src) -{ - register char *retval; - register char temp=0; - - __asm__("or %%g0, %1, %0\n\t" - "1: ldub [%1], %3\n\t" - "cmp %3, 0x0\n\t" - "bne,a 1b\n\t" - "add %1, 0x1, %1\n\t" - "2: ldub [%2], %3\n\t" - "stb %3, [%1]\n\t" - "add %1, 0x1, %1\n\t" - "cmp %3, 0x0\n\t" - "bne 2b\n\t" - "add %2, 0x1, %2\n\t" : - "=r" (retval), "=r" (dest), "=r" (src), "=r" (temp) : - "0" (retval), "1" (dest), "2" (src), "3" (temp)); - - return retval; -} - -extern __inline__ char *strncat(char *dest, const char *src, size_t len) -{ - register char *retval; - register char temp=0; - - __asm__("or %%g0, %1, %0\n\t" - "1: ldub [%1], %3\n\t" - "cmp %3, 0x0\n\t" - "bne,a 1b\n\t" - "add %1, 0x1, %1\n\t" - "2: ldub [%2], %3\n\t" - "stb %3, [%1]\n\t" - "add %1, 0x1, %1\n\t" - "add %3, -1, %3\n\t" - "cmp %3, 0x0\n\t" - "bne 2b\n\t" - "add %2, 0x1, %2\n\t" : - "=r" (retval), "=r" (dest), "=r" (src), "=r" (len), "=r" (temp) : - "0" (retval), "1" (dest), "2" (src), "3" (len), "4" (temp)); - - return retval; + extern void __copy_1page(void *, const void *); + + if(n <= 32) { + __builtin_memcpy(to, from, n); + } else { + switch(n) { + case 4096: + __copy_1page(to, from); + break; + default: + __memcpy(to, from, n); + break; + } + } + return to; } -extern __inline__ char *strchr(const char *src, int c) +extern inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n) { - register char temp=0; - register char *trick=0; - - __asm__("1: ldub [%0], %2\n\t" - "cmp %2, %1\n\t" - "bne,a 1b\n\t" - "add %0, 0x1, %0\n\t" - "or %%g0, %0, %3\n\t" : - "=r" (src), "=r" (c), "=r" (temp), "=r" (trick), "=r" (src) : - "0" (src), "1" (c), "2" (temp), "3" (trick), "4" (src)); - - return trick; + __memcpy(to, from, n); + return to; } -extern __inline__ char *strpbrk(const char *cs, const char *ct) -{ - register char temp1, temp2; - register char *scratch; - register char *trick; - - __asm__("or %%g0, %1, %4\n\t" - "1: ldub [%0], %2\n\t" - "2: ldub [%1], %3\n\t" - "cmp %3, %2\n\t" - "be 3f\n\t" - "nop\n\t" - "cmp %3, 0x0\n\t" - "bne 2b\n\t" - "add %1, 0x1, %1\n\t" - "or %%g0, %4, %1\n\t" - "b 1b\n\t" - "add %0, 0x1, %0\n\t" - "or %%g0, %0, %5\n\t" : - "=r" (cs) : - "r" (ct), "r" (temp1), "r" (temp2), "r" (scratch), "r" (trick=0), - "0" (cs), "1" (ct)); +#undef memcpy +#define memcpy(t, f, n) \ +(__builtin_constant_p(n) ? \ + __constant_memcpy((t),(f),(n)) : \ + __nonconstant_memcpy((t),(f),(n))) - return trick; - -} +#define __HAVE_ARCH_MEMSET +extern void *__memset(void *,int,__kernel_size_t); - -extern __inline__ size_t strspn(const char *s, const char *accept) +extern inline void *__constant_c_and_count_memset(void *s, char c, size_t count) { - register char temp1, temp2; - register char* scratch; - register size_t trick; - - __asm__("or %%g0, %1, %4\n\t" - "1: ldub [%0], %2\n\t" - "2: ldub [%1], %3\n\t" - "cmp %3, 0x0\n\t" - "be 3f\n\t" - "cmp %3, %2" - "bne 2b\n\t" - "add %1, 0x1, %1\n\t" - "add %0, 0x1, %0\n\t" - "b 1b\n\t" - "add %5, 0x1, %5\n\t" - "3: or %%g0, %0, %4\n\t" : - "=r" (s) : - "r" (accept), "r" (temp1), "r" (temp2), - "r" (scratch), "r" (trick=0), "0" (s)); - - return trick; - -} - -extern __inline__ char *strtok(char *s, const char *ct) -{ - static char* old; /* frob this kludge for now */ - register char *tok; - - if (s == (char *) 0) - { - if (old == (char *) 0) - { - return (char *) 0; + extern void *bzero_1page(void *); + extern void *__bzero(void *, size_t); + + if(!c) { + if(count == 4096) + bzero_1page(s); + else + __bzero(s, count); + } else { + __memset(s, c, count); } - else - s = old; - } - - s += strspn(s, ct); - if(*s == '\0') - { - old = (char *) 0; - return (char *) 0; - } - - tok = s; - s = strpbrk(tok, ct); - if (s == (char *) 0) - old = (char *) 0; - else - { - *s = '\0'; - old = s + 1; - } - return tok; -} - - -extern __inline__ void *memset(void *src, int c, size_t count) -{ - register void *retval; - - __asm__("or %%g0, %1, %0\n\t" - "1: add %1, 0x1, %1\n\t" - "2: add %3, -1, %3\n\t" - "cmp %3, -1\n\t" - "bne,a 1b\n\t" - "stb %2, [%1]\n\t" : - "=r" (retval), "=r" (src), "=r" (c), "=r" (count) : - "0" (retval), "1" (src), "2" (c), "3" (count)); - - return retval; + return s; } -extern __inline__ void *memcpy(void *dest, const void *src, size_t count) +extern inline void *__constant_c_memset(void *s, char c, size_t count) { - register void *retval; - register char tmp; + extern void *__bzero(void *, size_t); - __asm__("or %%g0, %1, %0\n\t" - "add %3, -1, %3\n\t" - "cmp %3, -1\n\t" - "be 2f\n\t" - "1: ldub [%2], %4\n\t" - "add %2, 0x1, %2\n\t" - "add %3, -1, %3\n\t" - "cmp %3, -1\n\t" - "stb %4, [%1]\n\t" - "bne 1b\n\t" - "add %1, 0x1, %1\n\t" - "2: " : - "=r" (retval), "=r" (dest), "=r" (src), "=r" (count), "=r" (tmp) : - "0" (retval), "1" (dest), "2" (src), "3" (count), "4" (tmp)); - - return retval; + if(!c) + __bzero(s, count); + else + __memset(s, c, count); + return s; } -extern __inline__ void *memmove(void *dest, const void *src, size_t count) +#undef memset +#define memset(s, c, count) \ +(__builtin_constant_p(c) ? (__builtin_constant_p(count) ? \ + __constant_c_and_count_memset((s), (c), (count)) : \ + __constant_c_memset((s), (c), (count))) \ + : __memset((s), (c), (count))) + +#define __HAVE_ARCH_MEMSCAN + +#undef memscan +#define memscan(__arg0, __char, __arg2) \ +({ \ + extern void *__memscan_zero(void *, size_t); \ + extern void *__memscan_generic(void *, int, size_t); \ + void *__retval, *__addr = (__arg0); \ + size_t __size = (__arg2); \ + \ + if(__builtin_constant_p(__char) && !(__char)) \ + __retval = __memscan_zero(__addr, __size); \ + else \ + __retval = __memscan_generic(__addr, (__char), __size); \ + \ + __retval; \ +}) + +#define __HAVE_ARCH_MEMCMP + +/* Now the str*() stuff... */ +#define __HAVE_ARCH_STRLEN + +#define __HAVE_ARCH_STRNCMP + +extern int __strncmp(const char *, const char *, __kernel_size_t); + +extern inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count) { - register void *retval; - register char tmp; - - __asm__("or %%g0, %1, %1\n\t" - "add %3, -1, %3\n\t" - "cmp %3, -1\n\t" - "be 2f\n\t" - "1: ldub [%2], %4\n\t" - "add %2, 0x1, %2\n\t" - "add %3, -1, %3\n\t" - "cmp %3, -1\n\t" - "stb %4, [%1]\n\t" - "bne 1b\n\t" - "add %1, 0x1, %1\n\t" - "2: " : - "=r" (retval), "=r" (dest), "=r" (src), "=r" (count), "=r" (tmp) : - "0" (retval), "1" (dest), "2" (src), "3" (count), "4" (tmp)); - - return retval; + register int retval; + switch(count) { + case 0: return 0; + case 1: return (src[0] - dest[0]); + case 2: retval = (src[0] - dest[0]); + if(!retval && src[0]) + retval = (src[1] - dest[1]); + return retval; + case 3: retval = (src[0] - dest[0]); + if(!retval && src[0]) { + retval = (src[1] - dest[1]); + if(!retval && src[1]) + retval = (src[2] - dest[2]); + } + return retval; + case 4: retval = (src[0] - dest[0]); + if(!retval && src[0]) { + retval = (src[1] - dest[1]); + if(!retval && src[1]) { + retval = (src[2] - dest[2]); + if (!retval && src[2]) + retval = (src[3] - dest[3]); + } + } + return retval; + case 5: retval = (src[0] - dest[0]); + if(!retval && src[0]) { + retval = (src[1] - dest[1]); + if(!retval && src[1]) { + retval = (src[2] - dest[2]); + if (!retval && src[2]) { + retval = (src[3] - dest[3]); + if (!retval && src[3]) + retval = (src[4] - dest[4]); + } + } + } + return retval; + default: + retval = (src[0] - dest[0]); + if(!retval && src[0]) { + retval = (src[1] - dest[1]); + if(!retval && src[1]) { + retval = (src[2] - dest[2]); + if(!retval && src[2]) + retval = __strncmp(src+3,dest+3,count-3); + } + } + return retval; + } } -extern __inline__ int memcmp(const void *cs, const void *ct, size_t count) -{ - register int retval; - register unsigned long tmp1, tmp2; - - __asm__("or %%g0, %1, %0\n\t" - "cmp %3, 0x0\n\t" - "ble,a 3f\n\t" - "or %%g0, %%g0, %0\n\t" - "1: ldub [%1], %4\n\t" - "ldub [%2], %5\n\t" - "cmp %4, %5\n\t" - "be,a 2f\n\t" - "add %1, 0x1, %1\n\t" - "bgeu 3f\n\t" - "or %%g0, 0x1, %0\n\t" - "b 3f\n\t" - "or %%g0, -1, %0\n\t" - "2: add %3, -1, %3\n\t" - "cmp %3, 0x0\n\t" - "bg 1b\n\t" - "add %2, 0x1, %2\n\t" - "or %%g0, %%g0, %0\n\t" - "3: " : - "=r" (retval) : - "r" (cs), "r" (ct), "r" (count), "r" (tmp1=0), "r" (tmp2=0)); +#undef strncmp +#define strncmp(__arg0, __arg1, __arg2) \ +(__builtin_constant_p(__arg2) ? \ + __constant_strncmp(__arg0, __arg1, __arg2) : \ + __strncmp(__arg0, __arg1, __arg2)) - return retval; -} +#endif /* (__KERNEL__) && !(_KSYMS_INTERNEL) */ +#endif /* !(__SPARC_STRING_H__) */ diff --git a/include/asm-sparc/svr4.h b/include/asm-sparc/svr4.h new file mode 100644 index 000000000..7eb1c3aad --- /dev/null +++ b/include/asm-sparc/svr4.h @@ -0,0 +1,119 @@ +/* Solaris/SPARC constants and definitions -- + * (C) 1996 Miguel de Icaza + * + * This file is not meant to be included by user level applications + * but the solaris syscall emulator + */ + +#ifndef _SPARC_SVR4_H +#define _SPARC_SVR4_H + +/* Signals as used by svr4 */ +typedef struct { /* signal set type */ + ulong sigbits[4]; +} svr4_sigset_t; + +/* Values for siginfo.code */ +#define SVR4_SINOINFO 32767 +/* Siginfo, sucker expects bunch of information on those parameters */ +typedef union { + char total_size [128]; + struct { + int signo; + int code; + int error; + union { + } data; + } siginfo; +} svr4_siginfo_t; + +/* Context definition */ + +/* Location of the user stored registers into a greg_t */ +enum { + SVR4_PSR, SVR4_PC, SVR4_NPC, SVR4_Y, + SVR4_G1, SVR4_G2, SVR4_G3, SVR4_G4, + SVR4_G5, SVR4_G6, SVR4_G7, SVR4_O0, + SVR4_O1, SVR4_O2, SVR4_O3, SVR4_O4, + SVR4_O5, SVR4_O6, SVR4_O7 +}; + +/* sizeof (regs) / sizeof (greg_t), defined in the ABI */ +#define SVR4_NREGS 19 +#define SVR4_MAXWIN 31 + +typedef struct { + uint rwin_lo[8]; + uint rwin_in[8]; +} svr4_rwindow_t; + +typedef struct { + int count; + int *winptr [SVR4_MAXWIN]; /* pointer to the windows */ + svr4_rwindow_t win[SVR4_MAXWIN]; /* the windows */ +} svr4_gwindows_t; + +typedef int svr4_gregset_t[SVR4_NREGS]; + +typedef struct { + double fpu_regs[32]; + void *fp_q; + unsigned fp_fsr; + u_char fp_nqel; + u_char fp_nqsize; + u_char inuse; /* if fpu is in use */ +} svr4_fregset_t; + +typedef struct { + uint id; /* if this holds "xrs" string => ptr is valid */ + caddr_t ptr; +} svr4_xrs_t; + +/* Machine dependant context */ +typedef struct { + svr4_gregset_t greg; /* registers 0..19 (see top) */ + svr4_gwindows_t *gwin; /* may point to register windows */ + svr4_fregset_t freg; /* floating point registers */ + svr4_xrs_t xrs; /* mhm? */ + long pad[19]; +} svr4_mcontext_t; + +/* flags for stack_t.flags */ +enum svr4_stack_flags { + SS_ONSTACK, + SVR4_SS_DISABLE, +}; + +/* signal stack exection place, unsupported */ +typedef struct svr4_stack_t { + char *sp; + int size; + int flags; +} svr4_stack_t; + +/* Context used by getcontext and setcontext */ +typedef struct svr4_ucontext_t { + u_long flags; /* context flags, indicate what is loaded */ + struct svr4_ucontext *link; + svr4_sigset_t sigmask; + svr4_stack_t stack; + svr4_mcontext_t mcontext; + long pad[23]; +} svr4_ucontext_t; + +/* windows hold the windows as they were at signal time, + * ucontext->mcontext holds a pointer to them. + * addresses for uc and si are passed as parameters to svr4 signal + * handler + */ + +/* This is the signal frame that is passed to the signal handler */ +typedef struct { + svr4_gwindows_t gw; /* windows */ + svr4_ucontext_t uc; /* machine context */ + svr4_siginfo_t si; /* siginfo */ +} svr4_signal_frame_t; + +#define SVR4_SF_ALIGNED (((sizeof (svr4_signal_frame_t) + 7) & (~7))) + +#endif /* include control */ diff --git a/include/asm-sparc/swift.h b/include/asm-sparc/swift.h new file mode 100644 index 000000000..c3e2ffe2d --- /dev/null +++ b/include/asm-sparc/swift.h @@ -0,0 +1,94 @@ +/* swift.h: Specific definitions for the _broken_ Swift SRMMU + * MMU module. + * + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_SWIFT_H +#define _SPARC_SWIFT_H + +/* Swift is so brain damaged, here is the mmu control register. */ +#define SWIFT_ST 0x00800000 /* SW tablewalk enable */ +#define SWIFT_WP 0x00400000 /* Watchpoint enable */ + +/* Branch folding (buggy, disable on production systems!) */ +#define SWIFT_BF 0x00200000 +#define SWIFT_PMC 0x00180000 /* Page mode control */ +#define SWIFT_PE 0x00040000 /* Parity enable */ +#define SWIFT_PC 0x00020000 /* Parity control */ +#define SWIFT_AP 0x00010000 /* Graphics page mode control (TCX/SX) */ +#define SWIFT_AC 0x00008000 /* Alternate Cacheability (see viking.h) */ +#define SWIFT_BM 0x00004000 /* Boot mode */ +#define SWIFT_RC 0x00003c00 /* DRAM refresh control */ +#define SWIFT_IE 0x00000200 /* Instruction cache enable */ +#define SWIFT_DE 0x00000100 /* Data cache enable */ +#define SWIFT_SA 0x00000080 /* Store Allocate */ +#define SWIFT_NF 0x00000002 /* No fault mode */ +#define SWIFT_EN 0x00000001 /* MMU enable */ + +/* Bits [13:5] select one of 512 instruction cache tags */ +extern __inline__ void swift_inv_insn_tag(unsigned long addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_TXTC_TAG)); +} + +/* Bits [12:4] select one of 512 data cache tags */ +extern __inline__ void swift_inv_data_tag(unsigned long addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_DATAC_TAG)); +} + +extern __inline__ void swift_flush_dcache(void) +{ + unsigned long addr; + + for(addr = 0; addr < 0x2000; addr += 0x10) + swift_inv_data_tag(addr); +} + +extern __inline__ void swift_flush_icache(void) +{ + unsigned long addr; + + for(addr = 0; addr < 0x4000; addr += 0x20) + swift_inv_insn_tag(addr); +} + +extern __inline__ void swift_idflash_clear(void) +{ + unsigned long addr; + + for(addr = 0; addr < 0x2000; addr += 0x10) { + swift_inv_insn_tag(addr<<1); + swift_inv_data_tag(addr); + } +} + +/* Swift is so broken, it isn't even safe to use the following. */ +extern __inline__ void swift_flush_page(unsigned long page) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (page), "i" (ASI_M_FLUSH_PAGE)); +} + +extern __inline__ void swift_flush_segment(unsigned long addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_SEG)); +} + +extern __inline__ void swift_flush_region(unsigned long addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_REGION)); +} + +extern __inline__ void swift_flush_context(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : + "i" (ASI_M_FLUSH_CTX)); +} + +#endif /* !(_SPARC_SWIFT_H) */ diff --git a/include/asm-sparc/sysen.h b/include/asm-sparc/sysen.h index f72b40c67..692fa6f22 100644 --- a/include/asm-sparc/sysen.h +++ b/include/asm-sparc/sysen.h @@ -1,14 +1,15 @@ +/* $Id: sysen.h,v 1.3 1995/11/25 02:32:58 davem Exp $ + * sysen.h: Bit fields within the "System Enable" register accessed via + * the ASI_CONTROL address space at address AC_SYSENABLE. + * + * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) + */ + #ifndef _SPARC_SYSEN_H #define _SPARC_SYSEN_H -/* sysen.h: Bit fields within the "System Enable" register accessed via - the ASI_CONTROL address space at address AC_SYSENABLE. - - Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) -*/ - #define SENABLE_DVMA 0x20 /* enable dvma transfers */ #define SENABLE_CACHE 0x10 /* enable VAC cache */ -#define SENABLE_RESET 0x04 /* reset the whole machine, danger Will Robinson */ +#define SENABLE_RESET 0x04 /* reset whole machine, danger Will Robinson */ #endif /* _SPARC_SYSEN_H */ diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h index 3c4a62c9a..34800571c 100644 --- a/include/asm-sparc/system.h +++ b/include/asm-sparc/system.h @@ -1,135 +1,250 @@ +/* $Id: system.h,v 1.42 1996/09/30 02:23:21 davem Exp $ */ #ifndef __SPARC_SYSTEM_H #define __SPARC_SYSTEM_H -#include <asm/segment.h> +#include <linux/kernel.h> -/* - * System defines.. Note that this is included both from .c and .S - * files, so it does only defines, not any C code. - */ - -/* - * I wish the boot time image was as beautiful as the Alpha's - * but no such luck. The icky PROM loads us at 0x0, and jumps - * to magic address 0x4000 to start thing going. This means that - * I can stick the pcb and user/kernel stacks in the area from - * 0x0-0x4000 and be reasonably sure that this is sane. - * - * Sorry, I can't impress people with cool looking 64-bit values - * yet. ;-) - */ +#include <asm/segment.h> -#include <asm/openprom.h> +#ifdef __KERNEL__ +#include <asm/page.h> +#include <asm/oplib.h> #include <asm/psr.h> +#endif -#define INIT_PCB 0x00011fe0 -#define INIT_STACK 0x00013fe0 -#define START_ADDR 0x00004000 -#define START_SIZE (32*1024) -#define EMPTY_PGT 0x00001000 -#define EMPTY_PGE 0x00001000 -#define ZERO_PGE 0x00001000 - -#define IRQ_ENA_ADR 0x2000 /* This is a bitmap of all activated IRQ's - * which is mapped in head.S during boot. - */ +#define EMPTY_PGT (&empty_bad_page) +#define EMPTY_PGE (&empty_bad_page_table) #ifndef __ASSEMBLY__ -extern void wrent(void *, unsigned long); -extern void wrkgp(unsigned long); -extern struct linux_romvec *romvec; +/* + * Sparc (general) CPU types + */ +enum sparc_cpu { + sun4 = 0x00, + sun4c = 0x01, + sun4m = 0x02, + sun4d = 0x03, + sun4e = 0x04, + sun4u = 0x05, /* V8 ploos ploos */ + sun_unknown = 0x06, +}; + +extern enum sparc_cpu sparc_cpu_model; + +extern unsigned long empty_bad_page; +extern unsigned long empty_bad_page_table; +extern unsigned long empty_zero_page; -#define halt() { romvec->pv_halt(); } -#define move_to_user_mode() halt() -#define switch_to(x) halt() +extern struct linux_romvec *romvec; +#define halt() romvec->pv_halt() -#ifndef stbar /* store barrier Sparc insn to synchronize stores in PSO */ -#define stbar() __asm__ __volatile__("stbar": : :"memory") +/* When a context switch happens we must flush all user windows so that + * the windows of the current process are flushed onto its stack. This + * way the windows are all clean for the next process and the stack + * frames are up to date. + */ +extern void flush_user_windows(void); +extern void synchronize_user_stack(void); +extern void fpsave(unsigned long *fpregs, unsigned long *fsr, + void *fpqueue, unsigned long *fpqdepth); + +#ifdef __SMP__ +#define SWITCH_ENTER \ + cli(); \ + if(prev->flags & PF_USEDFPU) { \ + fpsave(&prev->tss.float_regs[0], &prev->tss.fsr, \ + &prev->tss.fpqueue[0], &prev->tss.fpqdepth); \ + prev->flags &= ~PF_USEDFPU; \ + prev->tss.kregs->psr &= ~PSR_EF; \ + } \ + prev->lock_depth = syscall_count; \ + kernel_counter += (next->lock_depth - prev->lock_depth); \ + syscall_count = next->lock_depth; + +#define SWITCH_EXIT sti(); +#define SWITCH_DO_LAZY_FPU +#else +#define SWITCH_ENTER +#define SWITCH_EXIT +#define SWITCH_DO_LAZY_FPU if(last_task_used_math != next) next->tss.kregs->psr&=~PSR_EF; #endif -/* Changing the PIL on the sparc is a bit hairy. I'll figure out some - * more optimized way of doing this soon. This is bletcherous code. + /* Much care has gone into this code, do not touch it. */ +#define switch_to(prev, next) do { \ + __label__ here; \ + register unsigned long task_pc asm("o7"); \ + SWITCH_ENTER \ + SWITCH_DO_LAZY_FPU \ + __asm__ __volatile__( \ + ".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \ + "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \ + "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \ + "save %sp, -0x40, %sp\n\t" \ + "restore; restore; restore; restore; restore; restore; restore"); \ + if(!(next->tss.flags & SPARC_FLAG_KTHREAD) && \ + !(next->flags & PF_EXITING)) \ + switch_to_context(next); \ + task_pc = ((unsigned long) &&here) - 0x8; \ + __asm__ __volatile__( \ + "rd\t%%psr, %%g4\n\t" \ + "std\t%%sp, [%%g6 + %3]\n\t" \ + "rd\t%%wim, %%g5\n\t" \ + "wr\t%%g4, 0x20, %%psr\n\t" \ + "std\t%%g4, [%%g6 + %2]\n\t" \ + "mov\t%1, %%g6\n\t" \ + "ldd\t[%%g6 + %2], %%g4\n\t" \ + "st\t%1, [%0]\n\t" \ + "wr\t%%g4, 0x20, %%psr\n\t" \ + "ldd\t[%%g6 + %3], %%sp\n\t" \ + "wr\t%%g5, 0x0, %%wim\n\t" \ + "ldd\t[%%sp + 0x00], %%l0\n\t" \ + "ldd\t[%%sp + 0x08], %%l2\n\t" \ + "ldd\t[%%sp + 0x10], %%l4\n\t" \ + "ldd\t[%%sp + 0x18], %%l6\n\t" \ + "ldd\t[%%sp + 0x20], %%i0\n\t" \ + "ldd\t[%%sp + 0x28], %%i2\n\t" \ + "ldd\t[%%sp + 0x30], %%i4\n\t" \ + "ldd\t[%%sp + 0x38], %%i6\n\t" \ + "wr\t%%g4, 0x0, %%psr\n\t" \ + "nop\n\t" \ + "jmpl\t%%o7 + 0x8, %%g0\n\t" \ + " nop\n\t" : : "r" (&(current_set[smp_processor_id()])), "r" (next), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.kpsr)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ksp)), \ + "r" (task_pc) : "g4", "g5"); \ +here: SWITCH_EXIT } while(0) + +/* Changing the IRQ level on the Sparc. We now avoid writing the psr + * whenever possible. */ +extern __inline__ void setipl(unsigned long __orig_psr) +{ + __asm__ __volatile__("wr\t%0, 0x0, %%psr\n\t" + "nop; nop; nop;" : : "r" (__orig_psr) : "memory"); +} -#define swpipl(__new_ipl) \ -({ unsigned long psr, retval; \ -__asm__ __volatile__( \ - "rd %%psr, %0\n\t" : "=&r" (psr)); \ -retval = psr; \ -psr = (psr & ~(PSR_PIL)); \ -psr |= ((__new_ipl << 8) & PSR_PIL); \ -__asm__ __volatile__( \ - "wr %0, 0x0, %%psr\n\t" \ - : : "r" (psr)); \ -retval = ((retval>>8)&15); \ -retval; }) - -#define cli() swpipl(15) /* 15 = no int's except nmi's */ -#define sti() swpipl(0) /* I'm scared */ -#define save_flags(flags) do { flags = swpipl(15); } while (0) -#define restore_flags(flags) swpipl(flags) - -#define iret() __asm__ __volatile__ ("jmp %%l1\n\t" \ - "rett %%l2\n\t": : :"memory") - -#define _set_gate(gate_addr,type,dpl,addr) \ -__asm__ __volatile__ ("nop\n\t") - -#define set_intr_gate(n,addr) \ - _set_gate(&idt[n],14,0,addr) - -#define set_trap_gate(n,addr) \ - _set_gate(&idt[n],15,0,addr) +extern __inline__ void cli(void) +{ + unsigned long tmp; + + __asm__ __volatile__("rd\t%%psr, %0\n\t" + "andcc\t%0, %1, %%g0\n\t" + "be,a\t1f\n\t" + " wr\t%0, %1, %%psr\n" + "1:\tnop; nop" + : "=r" (tmp) + : "i" (PSR_PIL) + : "memory"); +} -#define set_system_gate(n,addr) \ - _set_gate(&idt[n],15,3,addr) +extern __inline__ void sti(void) +{ + unsigned long tmp; + + __asm__ __volatile__("rd\t%%psr, %0\n\t" + "andcc\t%0, %1, %%g0\n\t" + "bne,a\t1f\n\t" + " wr\t%0, %1, %%psr\n" + "1:\tnop; nop" + : "=r" (tmp) + : "i" (PSR_PIL) + : "memory"); +} -#define set_call_gate(a,addr) \ - _set_gate(a,12,3,addr) +extern __inline__ unsigned long getipl(void) +{ + unsigned long retval; + __asm__ __volatile__("rd\t%%psr, %0" : "=r" (retval)); + return retval; +} -extern inline unsigned int get_psr(void) +extern __inline__ unsigned long swap_pil(unsigned long __new_psr) { - unsigned int ret_val; - __asm__("rd %%psr, %0\n\t" : - "=r" (ret_val)); - return ret_val; + unsigned long retval, tmp1, tmp2; + + __asm__ __volatile__("rd\t%%psr, %0\n\t" + "and\t%0, %4, %1\n\t" + "and\t%3, %4, %2\n\t" + "xorcc\t%1, %2, %%g0\n\t" + "bne,a\t1f\n\t" + " wr %0, %4, %%psr\n" + "1:\tnop; nop" + : "=r" (retval), "=r" (tmp1), "=r" (tmp2) + : "r" (__new_psr), "i" (PSR_PIL) + : "memory"); + return retval; } -extern inline void put_psr(unsigned int new_psr) +extern __inline__ unsigned long read_psr_and_cli(void) { - __asm__("wr %0, 0x0, %%psr\n\t" : : - "r" (new_psr)); + unsigned long retval; + + __asm__ __volatile__("rd\t%%psr, %0\n\t" + "andcc\t%0, %1, %%g0\n\t" + "be,a\t1f\n\t" + " wr\t%0, %1, %%psr\n" + "1:\tnop; nop" + : "=r" (retval) + : "i" (PSR_PIL) + : "memory"); + return retval; } -/* Must this be atomic? */ +extern char spdeb_buf[256]; -extern inline void *xchg_u32(int * m, unsigned long val) -{ - unsigned long dummy; - - __asm__ __volatile__( - "ld %1,%2 ! xchg_u32() is here\n\t" - "st %0, %1\n\t" - "or %%g0, %2, %0" - : "=r" (val), "=m" (*m), "=r" (dummy) - : "0" (val)); - return (void *) val; -} +#define save_flags(flags) ((flags) = getipl()) +#define save_and_cli(flags) ((flags) = read_psr_and_cli()) +#define restore_flags(flags) setipl((flags)) +/* XXX Change this if we ever use a PSO mode kernel. */ +#define mb() __asm__ __volatile__ ("" : : : "memory") -/* pointers are 32 bits on the sparc (at least the v8, and they'll work - * on the V9 none the less). I don't need the xchg_u64 routine for now. - */ +#define nop() __asm__ __volatile__ ("nop"); -extern inline void *xchg_ptr(void *m, void *val) +extern __inline__ unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val) { - return (void *) xchg_u32((int *) m, (unsigned long) val); + __asm__ __volatile__(" + rd %%psr, %%g3 + andcc %%g3, %3, %%g0 + be,a 1f + wr %%g3, %3, %%psr +1: ld [%1], %%g2 + andcc %%g3, %3, %%g0 + st %2, [%1] + be,a 1f + wr %%g3, 0x0, %%psr +1: nop + mov %%g2, %0 + " + : "=&r" (val) + : "r" (m), "0" (val), "i" (PSR_PIL) + : "g2", "g3"); + + return val; } +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) + +extern void __xchg_called_with_bad_pointer(void); +static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size) +{ + switch (size) { + case 4: + return xchg_u32(ptr, x); + }; + __xchg_called_with_bad_pointer(); + return x; +} #endif /* __ASSEMBLY__ */ -#endif +/* + * Reset the machine. + */ +extern void hard_reset_now(void); + +#endif /* !(__SPARC_SYSTEM_H) */ diff --git a/include/asm-sparc/termbits.h b/include/asm-sparc/termbits.h new file mode 100644 index 000000000..9a078c619 --- /dev/null +++ b/include/asm-sparc/termbits.h @@ -0,0 +1,208 @@ +#ifndef _SPARC_TERMBITS_H +#define _SPARC_TERMBITS_H + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned long tcflag_t; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#define NCCS 17 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +#ifdef __KERNEL__ +#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t)) + cc_t _x_cc[2]; /* We need them to hold vmin/vtime */ +#endif +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VEOL 5 +#define VEOL2 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 + + + +#define VSUSP 10 +#define VDSUSP 11 /* SunOS POSIX nicety I do believe... */ +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 + +/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is + * shared with eof/eol + */ +#ifdef __KERNEL__ +#define VMIN 16 +#define VTIME 17 +#else +#define VMIN VEOF +#define VTIME VEOL +#endif + +/* c_iflag bits */ +#define IGNBRK 0x00000001 +#define BRKINT 0x00000002 +#define IGNPAR 0x00000004 +#define PARMRK 0x00000008 +#define INPCK 0x00000010 +#define ISTRIP 0x00000020 +#define INLCR 0x00000040 +#define IGNCR 0x00000080 +#define ICRNL 0x00000100 +#define IUCLC 0x00000200 +#define IXON 0x00000400 +#define IXANY 0x00000800 +#define IXOFF 0x00001000 +#define IMAXBEL 0x00002000 + +/* c_oflag bits */ +#define OPOST 0x00000001 +#define OLCUC 0x00000002 +#define ONLCR 0x00000004 +#define OCRNL 0x00000008 +#define ONOCR 0x00000010 +#define ONLRET 0x00000020 +#define OFILL 0x00000040 +#define OFDEL 0x00000080 +#define NLDLY 0x00000100 +#define NL0 0x00000000 +#define NL1 0x00000100 +#define CRDLY 0x00000600 +#define CR0 0x00000000 +#define CR1 0x00000200 +#define CR2 0x00000400 +#define CR3 0x00000600 +#define TABDLY 0x00001800 +#define TAB0 0x00000000 +#define TAB1 0x00000800 +#define TAB2 0x00001000 +#define TAB3 0x00001800 +#define XTABS 0x00001800 +#define BSDLY 0x00002000 +#define BS0 0x00000000 +#define BS1 0x00002000 +#define VTDLY 0x00004000 +#define VT0 0x00000000 +#define VT1 0x00004000 +#define FFDLY 0x00008000 +#define FF0 0x00000000 +#define FF1 0x00008000 +#define PAGEOUT 0x00010000 /* SUNOS specific */ +#define WRAP 0x00020000 /* SUNOS specific */ + +/* c_cflag bit meaning */ +#define CBAUD 0x0000000f +#define B0 0x00000000 /* hang up */ +#define B50 0x00000001 +#define B75 0x00000002 +#define B110 0x00000003 +#define B134 0x00000004 +#define B150 0x00000005 +#define B200 0x00000006 +#define B300 0x00000007 +#define B600 0x00000008 +#define B1200 0x00000009 +#define B1800 0x0000000a +#define B2400 0x0000000b +#define B4800 0x0000000c +#define B9600 0x0000000d +#define B19200 0x0000000e +#define B38400 0x0000000f +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0x00000030 +#define CS5 0x00000000 +#define CS6 0x00000010 +#define CS7 0x00000020 +#define CS8 0x00000030 +#define CSTOPB 0x00000040 +#define CREAD 0x00000080 +#define PARENB 0x00000100 +#define PARODD 0x00000200 +#define HUPCL 0x00000400 +#define CLOCAL 0x00000800 +/* We'll never see these speeds with the Zilogs' but for completeness... */ +#define CBAUDEX 0x00010000 +#define B57600 0x00010001 +#define B115200 0x00010002 +#define B230400 0x00010003 +#define B460800 0x00010004 +#define CIBAUD 0x000f0000 /* input baud rate (not used) */ +#define CRTSCTS 0x80000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0x00000001 +#define ICANON 0x00000002 +#define XCASE 0x00000004 +#define ECHO 0x00000008 +#define ECHOE 0x00000010 +#define ECHOK 0x00000020 +#define ECHONL 0x00000040 +#define NOFLSH 0x00000080 +#define TOSTOP 0x00000100 +#define ECHOCTL 0x00000200 +#define ECHOPRT 0x00000400 +#define ECHOKE 0x00000800 +#define DEFECHO 0x00001000 /* SUNOS thing, what is it? */ +#define FLUSHO 0x00002000 +#define PENDIN 0x00004000 +#define IEXTEN 0x00008000 + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* !(_SPARC_TERMBITS_H) */ diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h new file mode 100644 index 000000000..e2991ecf7 --- /dev/null +++ b/include/asm-sparc/termios.h @@ -0,0 +1,168 @@ +/* $Id: termios.h,v 1.20 1996/10/31 00:59:54 davem Exp $ */ +#ifndef _SPARC_TERMIOS_H +#define _SPARC_TERMIOS_H + +#include <asm/ioctls.h> +#include <asm/termbits.h> + +#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS) +struct sgttyb { + char sg_ispeed; + char sg_ospeed; + char sg_erase; + char sg_kill; + short sg_flags; +}; + +struct tchars { + char t_intrc; + char t_quitc; + char t_startc; + char t_stopc; + char t_eofc; + char t_brkc; +}; + +struct ltchars { + char t_suspc; + char t_dsuspc; + char t_rprntc; + char t_flushc; + char t_werasc; + char t_lnextc; +}; +#endif /* __KERNEL__ */ + +struct sunos_ttysize { + int st_lines; /* Lines on the terminal */ + int st_columns; /* Columns on the terminal */ +}; + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 + +#ifdef __KERNEL__ + +/* + * c_cc characters in the termio structure. Oh, how I love being + * backwardly compatible. Notice that character 4 and 5 are + * interpreted differently depending on whether ICANON is set in + * c_lflag. If it's set, they are used as _VEOF and _VEOL, otherwise + * as _VMIN and V_TIME. This is for compatibility with OSF/1 (which + * is compatible with sysV)... + */ +#define _VMIN 4 +#define _VTIME 5 + + +#include <linux/string.h> + +/* intr=^C quit=^\ erase=del kill=^U + eof=^D eol=\0 eol2=\0 sxtc=\0 + start=^Q stop=^S susp=^Z dsusp=^Y + reprint=^R discard=^U werase=^W lnext=^V + vmin=\1 vtime=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\000\000\000\021\023\032\031\022\025\027\026\001\000" + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +extern __inline__ void trans_from_termio(struct termio * termio, + struct termios * termios) +{ +#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y)) + SET_LOW_BITS(termios->c_iflag, termio->c_iflag); + SET_LOW_BITS(termios->c_oflag, termio->c_oflag); + SET_LOW_BITS(termios->c_cflag, termio->c_cflag); + SET_LOW_BITS(termios->c_lflag, termio->c_lflag); +#undef SET_LOW_BITS + memcpy (termios->c_cc, termio->c_cc, NCC); +} + +/* + * Translate a "termios" structure into a "termio". Ugh. + * + * Note the "fun" _VMIN overloading. + */ +extern __inline__ void trans_to_termio(struct termios * termios, + struct termio * termio) +{ + termio->c_iflag = termios->c_iflag; + termio->c_oflag = termios->c_oflag; + termio->c_cflag = termios->c_cflag; + termio->c_lflag = termios->c_lflag; + termio->c_line = termios->c_line; + memcpy(termio->c_cc, termios->c_cc, NCC); + if (!(termios->c_lflag & ICANON)) { + termio->c_cc[_VMIN] = termios->c_cc[VMIN]; + termio->c_cc[_VTIME] = termios->c_cc[VTIME]; + } +} + +/* Note that in this case DEST is a user buffer and thus the checking + * and this ugly macro to avoid header file problems. + */ +#define termios_to_userland(d, s) \ +do { \ + struct termios *dest = (d); \ + struct termios *source = (s); \ + put_user(source->c_iflag, &dest->c_iflag); \ + put_user(source->c_oflag, &dest->c_oflag); \ + put_user(source->c_cflag, &dest->c_cflag); \ + put_user(source->c_lflag, &dest->c_lflag); \ + put_user(source->c_line, &dest->c_line); \ + copy_to_user(dest->c_cc, source->c_cc, NCCS); \ + if (!(source->c_lflag & ICANON)){ \ + put_user(source->c_cc[VMIN], &dest->c_cc[_VMIN]); \ + put_user(source->c_cc[VTIME], &dest->c_cc[_VTIME]); \ + } else { \ + put_user(source->c_cc[VEOF], &dest->c_cc[VEOF]); \ + put_user(source->c_cc[VEOL], &dest->c_cc[VEOL]); \ + } \ +} while(0) + +/* termios to termios handling SunOS overloading of eof,eol/vmin,vtime + * In this case we are only working with kernel buffers so direct + * accesses are ok. + */ +extern __inline__ void termios_from_userland(struct termios * source, + struct termios * dest) +{ + dest->c_iflag = source->c_iflag; + dest->c_oflag = source->c_oflag; + dest->c_cflag = source->c_cflag; + dest->c_lflag = source->c_lflag; + dest->c_line = source->c_line; + memcpy(dest->c_cc, source->c_cc, NCCS); + if (dest->c_lflag & ICANON){ + dest->c_cc [VEOF] = source->c_cc [VEOF]; + dest->c_cc [VEOL] = source->c_cc [VEOL]; + } else { + dest->c_cc[VMIN] = source->c_cc[_VMIN]; + dest->c_cc[VTIME] = source->c_cc[_VTIME]; + } +} + +#endif /* __KERNEL__ */ + +#endif /* _SPARC_TERMIOS_H */ diff --git a/include/asm-sparc/timer.h b/include/asm-sparc/timer.h new file mode 100644 index 000000000..3820794e7 --- /dev/null +++ b/include/asm-sparc/timer.h @@ -0,0 +1,82 @@ +/* $Id: timer.h,v 1.13 1996/08/29 09:48:59 davem Exp $ + * timer.h: Definitions for the timer chips on the Sparc. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_TIMER_H +#define _SPARC_TIMER_H + +#include <asm/system.h> /* For NCPUS */ + +/* Timer structures. The interrupt timer has two properties which + * are the counter (which is handled in do_timer in sched.c) and the limit. + * This limit is where the timer's counter 'wraps' around. Oddly enough, + * the sun4c timer when it hits the limit wraps back to 1 and not zero + * thus when calculating the value at which it will fire a microsecond you + * must adjust by one. Thanks SUN for designing such great hardware ;( + */ + +/* Note that I am only going to use the timer that interrupts at + * Sparc IRQ 10. There is another one available that can fire at + * IRQ 14. Currently it is left untouched, we keep the PROM's limit + * register value and let the prom take these interrupts. This allows + * L1-A to work. + */ + +struct sun4c_timer_info { + __volatile__ unsigned int cur_count10; + __volatile__ unsigned int timer_limit10; + __volatile__ unsigned int cur_count14; + __volatile__ unsigned int timer_limit14; +}; + +#define SUN4C_TIMER_PHYSADDR 0xf3000000 + +/* A sun4m has two blocks of registers which are probably of the same + * structure. LSI Logic's L64851 is told to _decrement_ from the limit + * value. Aurora behaves similarly but its limit value is compacted in + * other fashion (it's wider). Documented fields are defined here. + */ + +/* As with the interrupt register, we have two classes of timer registers + * which are per-cpu and master. Per-cpu timers only hit that cpu and are + * only level 14 ticks, master timer hits all cpus and is level 10. + */ + +#define SUN4M_PRM_CNT_L 0x80000000 +#define SUN4M_PRM_CNT_LVALUE 0x7FFFFC00 + +struct sun4m_timer_percpu_info { + __volatile__ unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */ + __volatile__ unsigned int l14_cur_count; + + /* This register appears to be write only and/or inaccessible + * on Uni-Processor sun4m machines. + */ + __volatile__ unsigned int l14_limit_noclear; /* Data access error is here */ + + __volatile__ unsigned int cntrl; /* =1 after POST on Aurora */ + __volatile__ unsigned char space[PAGE_SIZE - 16]; +}; + +struct sun4m_timer_regs { + struct sun4m_timer_percpu_info cpu_timers[NCPUS]; + volatile unsigned int l10_timer_limit; + volatile unsigned int l10_cur_count; + + /* Again, this appears to be write only and/or inaccessible + * on uni-processor sun4m machines. + */ + volatile unsigned int l10_limit_noclear; + + /* This register too, it must be magic. */ + volatile unsigned int foobar; + + volatile unsigned int cfg; /* equals zero at boot time... */ +}; + +extern struct sun4m_timer_regs *sun4m_timers; +extern __volatile__ unsigned int *master_l10_counter; +extern __volatile__ unsigned int *master_l10_limit; + +#endif /* !(_SPARC_TIMER_H) */ diff --git a/include/asm-sparc/traps.h b/include/asm-sparc/traps.h new file mode 100644 index 000000000..3a3940df2 --- /dev/null +++ b/include/asm-sparc/traps.h @@ -0,0 +1,159 @@ +/* $Id: traps.h,v 1.8 1996/05/17 10:38:53 davem Exp $ + * traps.h: Format of entries for the Sparc trap table. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_TRAPS_H +#define _SPARC_TRAPS_H + +#define NUM_SPARC_TRAPS 255 + +#ifndef __ASSEMBLY__ + +/* This is for V8 and V9 compliant Sparc CPUS */ +struct tt_entry { + unsigned long inst_one; + unsigned long inst_two; + unsigned long inst_three; + unsigned long inst_four; +}; + +/* We set this to _start in system setup. */ +extern struct tt_entry *sparc_ttable; + +/* This for V9 compliant Sparc CPUS */ +struct tt_v9_entry { + unsigned long inst_one; + unsigned long inst_two; + unsigned long inst_three; + unsigned long inst_four; + unsigned long inst_five; + unsigned long inst_six; + unsigned long inst_seven; + unsigned long inst_eight; +}; + +/* V9 has multiple trap tables, which one is used depends + * upon how deep within multiple traps you are. + * I believe the UltraSparc supports two levels now. + */ +extern struct tt_v9_entry *sparc_v9_ttablel0; +extern struct tt_v9_entry *sparc_v9_ttablel1; + +extern __inline__ unsigned long get_tbr(void) +{ + unsigned long tbr; + + __asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (tbr)); + return tbr; +} + +#endif /* !(__ASSEMBLY__) */ + +/* For patching the trap table at boot time, we need to know how to + * form various common Sparc instructions. Thus these macros... + */ + +#define SPARC_MOV_CONST_L3(const) (0xa6102000 | (const&0xfff)) + +/* The following assumes that the branch lies before the place we + * are branching to. This is the case for a trap vector... + * You have been warned. + */ +#define SPARC_BRANCH(dest_addr, inst_addr) \ + (0x10800000 | (((dest_addr-inst_addr)>>2)&0x3fffff)) + +#define SPARC_RD_PSR_L0 (0xa1480000) +#define SPARC_RD_WIM_L3 (0xa7500000) +#define SPARC_NOP (0x01000000) + +/* Various interesting trap levels. */ +/* First, hardware traps. */ +#define SP_TRAP_TFLT 0x1 /* Text fault */ +#define SP_TRAP_II 0x2 /* Illegal Instruction */ +#define SP_TRAP_PI 0x3 /* Privileged Instruction */ +#define SP_TRAP_FPD 0x4 /* Floating Point Disabled */ +#define SP_TRAP_WOVF 0x5 /* Window Overflow */ +#define SP_TRAP_WUNF 0x6 /* Window Underflow */ +#define SP_TRAP_MNA 0x7 /* Memory Address Unaligned */ +#define SP_TRAP_FPE 0x8 /* Floating Point Exception */ +#define SP_TRAP_DFLT 0x9 /* Data Fault */ +#define SP_TRAP_TOF 0xa /* Tag Overflow */ +#define SP_TRAP_WDOG 0xb /* Watchpoint Detected */ +#define SP_TRAP_IRQ1 0x11 /* IRQ level 1 */ +#define SP_TRAP_IRQ2 0x12 /* IRQ level 2 */ +#define SP_TRAP_IRQ3 0x13 /* IRQ level 3 */ +#define SP_TRAP_IRQ4 0x14 /* IRQ level 4 */ +#define SP_TRAP_IRQ5 0x15 /* IRQ level 5 */ +#define SP_TRAP_IRQ6 0x16 /* IRQ level 6 */ +#define SP_TRAP_IRQ7 0x17 /* IRQ level 7 */ +#define SP_TRAP_IRQ8 0x18 /* IRQ level 8 */ +#define SP_TRAP_IRQ9 0x19 /* IRQ level 9 */ +#define SP_TRAP_IRQ10 0x1a /* IRQ level 10 */ +#define SP_TRAP_IRQ11 0x1b /* IRQ level 11 */ +#define SP_TRAP_IRQ12 0x1c /* IRQ level 12 */ +#define SP_TRAP_IRQ13 0x1d /* IRQ level 13 */ +#define SP_TRAP_IRQ14 0x1e /* IRQ level 14 */ +#define SP_TRAP_IRQ15 0x1f /* IRQ level 15 Non-maskable */ +#define SP_TRAP_RACC 0x20 /* Register Access Error ??? */ +#define SP_TRAP_IACC 0x21 /* Instruction Access Error */ +#define SP_TRAP_CPDIS 0x24 /* Co-Processor Disabled */ +#define SP_TRAP_BADFL 0x25 /* Unimplemented Flush Instruction */ +#define SP_TRAP_CPEXP 0x28 /* Co-Processor Exception */ +#define SP_TRAP_DACC 0x29 /* Data Access Error */ +#define SP_TRAP_DIVZ 0x2a /* Divide By Zero */ +#define SP_TRAP_DSTORE 0x2b /* Data Store Error ??? */ +#define SP_TRAP_DMM 0x2c /* Data Access MMU Miss ??? */ +#define SP_TRAP_IMM 0x3c /* Instruction Access MMU Miss ??? */ + +/* Now the Software Traps... */ +#define SP_TRAP_SUNOS 0x80 /* SunOS System Call */ +#define SP_TRAP_SBPT 0x81 /* Software Breakpoint */ +#define SP_TRAP_SDIVZ 0x82 /* Software Divide-by-Zero trap */ +#define SP_TRAP_FWIN 0x83 /* Flush Windows */ +#define SP_TRAP_CWIN 0x84 /* Clean Windows */ +#define SP_TRAP_RCHK 0x85 /* Range Check */ +#define SP_TRAP_FUNA 0x86 /* Fix Unaligned Access */ +#define SP_TRAP_IOWFL 0x87 /* Integer Overflow */ +#define SP_TRAP_SOLARIS 0x88 /* Solaris System Call */ +#define SP_TRAP_NETBSD 0x89 /* NetBSD System Call */ +#define SP_TRAP_LINUX 0x90 /* Linux System Call */ + +/* Names used for compatibility with SunOS */ +#define ST_SYSCALL 0x00 +#define ST_BREAKPOINT 0x01 +#define ST_DIV0 0x02 +#define ST_FLUSH_WINDOWS 0x03 +#define ST_CLEAN_WINDOWS 0x04 +#define ST_RANGE_CHECK 0x05 +#define ST_FIX_ALIGN 0x06 +#define ST_INT_OVERFLOW 0x07 + +/* Special traps... */ +#define SP_TRAP_KBPT1 0xfe /* KADB/PROM Breakpoint one */ +#define SP_TRAP_KBPT2 0xff /* KADB/PROM Breakpoint two */ + +/* Handy Macros */ +/* Is this a trap we never expect to get? */ +#define BAD_TRAP_P(level) \ + ((level > SP_TRAP_WDOG && level < SP_TRAP_IRQ1) || \ + (level > SP_TRAP_IACC && level < SP_TRAP_CPDIS) || \ + (level > SP_TRAP_BADFL && level < SP_TRAP_CPEXP) || \ + (level > SP_TRAP_DMM && level < SP_TRAP_IMM) || \ + (level > SP_TRAP_IMM && level < SP_TRAP_SUNOS) || \ + (level > SP_TRAP_LINUX && level < SP_TRAP_KBPT1)) + +/* Is this a Hardware trap? */ +#define HW_TRAP_P(level) ((level > 0) && (level < SP_TRAP_SUNOS)) + +/* Is this a Software trap? */ +#define SW_TRAP_P(level) ((level >= SP_TRAP_SUNOS) && (level <= SP_TRAP_KBPT2)) + +/* Is this a system call for some OS we know about? */ +#define SCALL_TRAP_P(level) ((level == SP_TRAP_SUNOS) || \ + (level == SP_TRAP_SOLARIS) || \ + (level == SP_TRAP_NETBSD) || \ + (level == SP_TRAP_LINUX)) + +#endif /* !(_SPARC_TRAPS_H) */ diff --git a/include/asm-sparc/tsunami.h b/include/asm-sparc/tsunami.h new file mode 100644 index 000000000..384ea6e68 --- /dev/null +++ b/include/asm-sparc/tsunami.h @@ -0,0 +1,60 @@ +/* $Id: tsunami.h,v 1.5 1996/08/29 09:49:03 davem Exp $ + * tsunami.h: Module specific definitions for Tsunami V8 Sparcs + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_TSUNAMI_H +#define _SPARC_TSUNAMI_H + +#include <asm/asi.h> + +/* The MMU control register on the Tsunami: + * + * ----------------------------------------------------------------------- + * | implvers |SW|AV|DV|MV| RSV |PC|ITD|ALC| RSV |PE| RC |IE|DE|RSV|NF|ME| + * ----------------------------------------------------------------------- + * 31 24 23 22 21 20 19-18 17 16 14 13-12 11 10-9 8 7 6-2 1 0 + * + * SW: Enable Software Table Walks 0=off 1=on + * AV: Address View bit + * DV: Data View bit + * MV: Memory View bit + * PC: Parity Control + * ITD: ITBR disable + * ALC: Alternate Cacheable + * PE: Parity Enable 0=off 1=on + * RC: Refresh Control + * IE: Instruction cache Enable 0=off 1=on + * DE: Data cache Enable 0=off 1=on + * NF: No Fault, same as all other SRMMUs + * ME: MMU Enable, same as all other SRMMUs + */ + +#define TSUNAMI_SW 0x00800000 +#define TSUNAMI_AV 0x00400000 +#define TSUNAMI_DV 0x00200000 +#define TSUNAMI_MV 0x00100000 +#define TSUNAMI_PC 0x00020000 +#define TSUNAMI_ITD 0x00010000 +#define TSUNAMI_ALC 0x00008000 +#define TSUNAMI_PE 0x00001000 +#define TSUNAMI_RCMASK 0x00000C00 +#define TSUNAMI_IENAB 0x00000200 +#define TSUNAMI_DENAB 0x00000100 +#define TSUNAMI_NF 0x00000002 +#define TSUNAMI_ME 0x00000001 + +extern __inline__ void tsunami_flush_icache(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : + "i" (ASI_M_IC_FLCLEAR) : "memory"); +} + +extern __inline__ void tsunami_flush_dcache(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : + "i" (ASI_M_DC_FLCLEAR) : "memory"); +} + +#endif /* !(_SPARC_TSUNAMI_H) */ diff --git a/include/asm-sparc/types.h b/include/asm-sparc/types.h index c7b65be7a..d8334325a 100644 --- a/include/asm-sparc/types.h +++ b/include/asm-sparc/types.h @@ -1,62 +1,46 @@ +/* $Id: types.h,v 1.10 1996/08/29 09:49:04 davem Exp $ */ #ifndef _SPARC_TYPES_H #define _SPARC_TYPES_H /* * _xx is ok: it doesn't pollute the POSIX namespace. Use these in the - * header files exported to user space <-- Linus sez this + * header files exported to user space. */ -/* NOTE: I will have to change these when the V9 sparcs come into play, - * however this won't be for a while. +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. */ -#ifndef _SIZE_T -#define _SIZE_T -#ifdef __svr4__ -typedef unsigned int size_t; /* solaris sucks */ -#else -typedef long unsigned int size_t; /* sunos is much better */ -#endif /* !(__svr4__) */ -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef int ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef int ptrdiff_t; -#endif +typedef unsigned short umode_t; -typedef signed char __s8; +typedef __signed__ char __s8; typedef unsigned char __u8; -typedef signed short __s16; +typedef __signed__ short __s16; typedef unsigned short __u16; -typedef signed int __s32; +typedef __signed__ int __s32; typedef unsigned int __u32; -/* Only 32-bit sparcs for now so.... */ - -typedef signed long long __s64; +typedef __signed__ long long __s64; typedef unsigned long long __u64; #ifdef __KERNEL__ -typedef signed char s8; +typedef __signed__ char s8; typedef unsigned char u8; -typedef signed short s16; +typedef __signed__ short s16; typedef unsigned short u16; -typedef signed int s32; +typedef __signed__ int s32; typedef unsigned int u32; -/* Again, only have to worry about 32-bits */ - -typedef signed long long s64; +typedef __signed__ long long s64; typedef unsigned long long u64; #endif /* __KERNEL__ */ diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h new file mode 100644 index 000000000..53eb75cae --- /dev/null +++ b/include/asm-sparc/uaccess.h @@ -0,0 +1,261 @@ +/* $Id: uaccess.h,v 1.2 1996/10/31 00:59:56 davem Exp $ */ +#ifndef _ASM_UACCESS_H +#define _ASM_UACCESS_H + +/* + * User space memory access functions + */ + +#ifdef __KERNEL__ +#include <linux/sched.h> +#include <linux/string.h> +#include <asm/vac-ops.h> +#endif + +#ifndef __ASSEMBLY__ + +/* Sparc is not segmented, however we need to be able to fool verify_area() + * when doing system calls from kernel mode legitimately. + * + * "For historical reasons, these macros are grossly misnamed." -Linus + */ +#define KERNEL_DS 0 +#define USER_DS 1 + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define get_fs() (current->tss.current_ds) +#define get_ds() (KERNEL_DS) +#define set_fs(val) ((current->tss.current_ds) = (val)) + +#define __user_ok(addr,size) (((size) <= page_offset)&&((addr) <= page_offset-(size))) +#define __kernel_ok (get_fs() == KERNEL_DS) +#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) +#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) + +extern inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size)?0:-EFAULT; +} + +/* Uh, these should become the main single-value transfer routines.. + * They automatically use the right size if we just have the right + * pointer type.. + * + * This gets kind of ugly. We want to return _two_ values in "get_user()" + * and yet we don't want to do any pointers, because that is too much + * of a performance impact. Thus we have a few rather ugly macros here, + * and hide all the uglyness from the user. + */ +#define put_user(x,ptr) ({ \ +unsigned long __pu_addr = (unsigned long)(ptr); \ +__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); }) + +#define get_user(x,ptr) ({ \ +unsigned long __gu_addr = (unsigned long)(ptr); \ +__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); }) + +/* + * The "__xxx" versions do not do address space checking, useful when + * doing multiple accesses to the same area (the user has to do the + * checks by hand with "access_ok()") + */ +#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr))) +#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr))) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) ((struct __large_struct *)(x)) + +#define __put_user_check(x,addr,size) ({ \ +register int __pu_ret asm("g1"); \ +__pu_ret = -EFAULT; \ +if (__access_ok(addr,size)) { \ +switch (size) { \ +case 1: __put_user_8(x,addr,__pu_ret); break; \ +case 2: __put_user_16(x,addr,__pu_ret); break; \ +case 4: __put_user_32(x,addr,__pu_ret); break; \ +default: __pu_ret = __put_user_bad(); break; \ +} } __pu_ret; }) + +#define __put_user_nocheck(x,addr,size) ({ \ +register int __pu_ret asm("g1"); \ +__pu_ret = -EFAULT; \ +switch (size) { \ +case 1: __put_user_8(x,addr,__pu_ret); break; \ +case 2: __put_user_16(x,addr,__pu_ret); break; \ +case 4: __put_user_32(x,addr,__pu_ret); break; \ +default: __pu_ret = __put_user_bad(); break; \ +} __pu_ret; }) + +#define __put_user_8(x,addr,ret) \ +__asm__ __volatile( \ + "/* Put user 8, inline. */\n\t" \ + "ld [%%g6 + %3], %%g2\n\t" \ + "set 1f, %0\n\t" \ + "add %%g2, 1, %%g3\n\t" \ + "st %0, [%%g6 + %4]\n\t" \ + "st %%g3, [%%g6 + %3]\n\t" \ + "stb %1, [%2]\n\t" \ + "mov 0, %0\n\t" \ + "st %%g2, [%%g6 + %3]\n" \ +"1:\n" : "=&r" (ret) : "r" (x), "r" (__m(addr)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \ + : "g2", "g3") + +#define __put_user_16(x,addr,ret) \ +__asm__ __volatile( \ + "/* Put user 16, inline. */\n\t" \ + "ld [%%g6 + %3], %%g2\n\t" \ + "set 1f, %0\n\t" \ + "add %%g2, 1, %%g3\n\t" \ + "st %0, [%%g6 + %4]\n\t" \ + "st %%g3, [%%g6 + %3]\n\t" \ + "sth %1, [%2]\n\t" \ + "mov 0, %0\n\t" \ + "st %%g2, [%%g6 + %3]\n" \ +"1:\n" : "=&r" (ret) : "r" (x), "r" (__m(addr)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \ + : "g2", "g3") + +#define __put_user_32(x,addr,ret) \ +__asm__ __volatile( \ + "/* Put user 32, inline. */\n\t" \ + "ld [%%g6 + %3], %%g2\n\t" \ + "set 1f, %0\n\t" \ + "add %%g2, 1, %%g3\n\t" \ + "st %0, [%%g6 + %4]\n\t" \ + "st %%g3, [%%g6 + %3]\n\t" \ + "st %1, [%2]\n\t" \ + "mov 0, %0\n\t" \ + "st %%g2, [%%g6 + %3]\n" \ +"1:\n" : "=&r" (ret) : "r" (x), "r" (__m(addr)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \ + : "g2", "g3") + +extern int __put_user_bad(void); + +#define __get_user_check(x,addr,size,type) ({ \ +register int __gu_ret asm("g1"); \ +register unsigned long __gu_val = 0; \ +__gu_ret = -EFAULT; \ +if (__access_ok(addr,size)) { \ +switch (size) { \ +case 1: __get_user_8(__gu_val,addr,__gu_ret); break; \ +case 2: __get_user_16(__gu_val,addr,__gu_ret); break; \ +case 4: __get_user_32(__gu_val,addr,__gu_ret); break; \ +default: __gu_ret = __get_user_bad(); break; \ +} } x = (type) __gu_val; __gu_ret; }) + +#define __get_user_nocheck(x,addr,size,type) ({ \ +register int __gu_ret asm("g1"); \ +register unsigned long __gu_val = 0; \ +__gu_ret = -EFAULT; \ +switch (size) { \ +case 1: __get_user_8(__gu_val,addr,__gu_ret); break; \ +case 2: __get_user_16(__gu_val,addr,__gu_ret); break; \ +case 4: __get_user_32(__gu_val,addr,__gu_ret); break; \ +default: __gu_ret = __get_user_bad(); break; \ +} x = (type) __gu_val; __gu_ret; }) + +#define __get_user_8(x,addr,ret) \ +__asm__ __volatile__( \ + "/* Get user 8, inline. */\n\t" \ + "ld [%%g6 + %3], %%g2\n\t" \ + "set 1f, %0\n\t" \ + "add %%g2, 1, %%g3\n\t" \ + "st %0, [%%g6 + %4]\n\t" \ + "st %%g3, [%%g6 + %3]\n\t" \ + "ldub [%2], %1\n\t" \ + "mov 0, %0\n\t" \ + "st %%g2, [%%g6 + %3]\n" \ +"1:\n" : "=&r" (ret), "=&r" (x) : "r" (__m(addr)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \ + : "g2", "g3") + +#define __get_user_16(x,addr,ret) \ +__asm__ __volatile__( \ + "/* Get user 16, inline. */\n\t" \ + "ld [%%g6 + %3], %%g2\n\t" \ + "set 1f, %0\n\t" \ + "add %%g2, 1, %%g3\n\t" \ + "st %0, [%%g6 + %4]\n\t" \ + "st %%g3, [%%g6 + %3]\n\t" \ + "lduh [%2], %1\n\t" \ + "mov 0, %0\n\t" \ + "st %%g2, [%%g6 + %3]\n" \ +"1:\n" : "=&r" (ret), "=&r" (x) : "r" (__m(addr)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \ + : "g2", "g3") + +#define __get_user_32(x,addr,ret) \ +__asm__ __volatile__( \ + "/* Get user 32, inline. */\n\t" \ + "ld [%%g6 + %3], %%g2\n\t" \ + "set 1f, %0\n\t" \ + "add %%g2, 1, %%g3\n\t" \ + "st %0, [%%g6 + %4]\n\t" \ + "st %%g3, [%%g6 + %3]\n\t" \ + "ld [%2], %1\n\t" \ + "mov 0, %0\n\t" \ + "st %%g2, [%%g6 + %3]\n" \ +"1:\n" : "=&r" (ret), "=&r" (x) : "r" (__m(addr)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.count)), \ + "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ex.expc)) \ + : "g2", "g3") + +extern int __get_user_bad(void); + +extern int __copy_to_user(unsigned long to, unsigned long from, int size); +extern int __copy_from_user(unsigned long to, unsigned long from, int size); + +#define copy_to_user(to,from,n) ({ \ +unsigned long __copy_to = (unsigned long) (to); \ +unsigned long __copy_size = (unsigned long) (n); \ +unsigned long __copy_res; \ +if(__copy_size && __access_ok(__copy_to, __copy_size)) { \ +__copy_res = __copy_to_user(__copy_to, (unsigned long) (from), __copy_size); \ +if(__copy_res) __copy_res = __copy_size - __copy_res; \ +} else __copy_res = __copy_size; \ +__copy_res; }) + +#define copy_from_user(to,from,n) ({ \ +unsigned long __copy_from = (unsigned long) (from); \ +unsigned long __copy_size = (unsigned long) (n); \ +unsigned long __copy_res; \ +if(__copy_size && __access_ok(__copy_from, __copy_size)) { \ +__copy_res = __copy_from_user((unsigned long) (to), __copy_from, __copy_size); \ +if(__copy_res) __copy_res = __copy_size - __copy_res; \ +} else __copy_res = __copy_size; \ +__copy_res; }) + +extern int __clear_user(unsigned long addr, int size); + +#define clear_user(addr,n) ({ \ +unsigned long __clear_addr = (unsigned long) (addr); \ +int __clear_size = (int) (n); \ +int __clear_res; \ +if(__clear_size && __access_ok(__clear_addr, __clear_size)) { \ +__clear_res = __clear_user(__clear_addr, __clear_size); \ +if(__clear_res) __clear_res = __clear_size - __clear_res; \ +} else __clear_res = __clear_size; \ +__clear_res; }) + +extern int __strncpy_from_user(unsigned long dest, unsigned long src, int count); + +#define strncpy_from_user(dest,src,count) ({ \ +unsigned long __sfu_src = (unsigned long) (src); \ +int __sfu_count = (int) (count); \ +long __sfu_res = -EFAULT; \ +if(__access_ok(__sfu_src, __sfu_count)) { \ +__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \ +} __sfu_res; }) + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_UACCESS_H */ diff --git a/include/asm-sparc/ultra.h b/include/asm-sparc/ultra.h new file mode 100644 index 000000000..fdc6c7f48 --- /dev/null +++ b/include/asm-sparc/ultra.h @@ -0,0 +1,52 @@ +/* $Id: ultra.h,v 1.2 1995/11/25 02:33:10 davem Exp $ + * ultra.h: Definitions and defines for the TI V9 UltraSparc. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_ULTRA_H +#define _SPARC_ULTRA_H + +/* Spitfire MMU control register: + * + * ---------------------------------------------------------- + * | | IMPL | VERS | | MID | | + * ---------------------------------------------------------- + * 64 31-28 27-24 23-22 21-17 16 0 + * + * IMPL: Implementation of this Spitfire. + * VERS: Version of this Spitfire. + * MID: Module ID of this processor. + */ + +#define SPITFIRE_MIDMASK 0x00000000003e0000 + +/* Spitfire Load Store Unit control register: + * + * --------------------------------------------------------------------- + * | RSV | PWR | PWW | VWR | VWW | RSV | PMASK | DME | IME | DCE | ICE | + * --------------------------------------------------------------------- + * 63-25 24 23 22 21 20 19-4 3 2 1 0 + * + * PWR: Physical Watchpoint Read enable: 0=off 1=on + * PWW: Physical Watchpoint Write enable: 0=off 1=on + * VWR: Virtual Watchpoint Read enable: 0=off 1=on + * VWW: Virtual Watchpoint Write enable: 0=off 1=on + * PMASK: Parity MASK ??? + * DME: Data MMU Enable: 0=off 1=on + * IME: Instruction MMU Enable: 0=off 1=on + * DCE: Data Cache Enable: 0=off 1=on + * ICE: Instruction Cache Enable: 0=off 1=on + */ + +#define SPITFIRE_LSU_PWR 0x01000000 +#define SPITFIRE_LSU_PWW 0x00800000 +#define SPITFIRE_LSU_VWR 0x00400000 +#define SPITFIRE_LSU_VWW 0x00200000 +#define SPITFIRE_LSU_PMASK 0x000ffff0 +#define SPITFIRE_LSU_DME 0x00000008 +#define SPITFIRE_LSU_IME 0x00000004 +#define SPITFIRE_LSU_DCE 0x00000002 +#define SPITFIRE_LSU_ICE 0x00000001 + +#endif /* !(_SPARC_ULTRA_H) */ diff --git a/include/asm-sparc/unaligned.h b/include/asm-sparc/unaligned.h new file mode 100644 index 000000000..470b8fe59 --- /dev/null +++ b/include/asm-sparc/unaligned.h @@ -0,0 +1,19 @@ +#ifndef _ASM_SPARC_UNALIGNED_H_ +#define _ASM_SPARC_UNALIGNED_H_ + +/* Sparc can't handle unaligned accesses. */ + +#include <asm/string.h> + + +/* Use memmove here, so gcc does not insert a __builtin_memcpy. */ + +#define get_unaligned(ptr) \ + ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) + +#define put_unaligned(val, ptr) \ + ({ __typeof__(*(ptr)) __tmp = (val); \ + memmove((ptr), &__tmp, sizeof(*(ptr))); \ + (void)0; }) + +#endif /* _ASM_SPARC_UNALIGNED_H */ diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 3b0551461..468097d6f 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -1,3 +1,4 @@ +/* $Id: unistd.h,v 1.24 1996/08/29 09:49:06 davem Exp $ */ #ifndef _SPARC_UNISTD_H #define _SPARC_UNISTD_H @@ -8,19 +9,282 @@ * think of right now to force the arguments into fixed registers * before the trap into the system call with gcc 'asm' statements. * - * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * + * SunOS compatibility based upon preliminary work which is: + * + * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu) */ -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +#define __NR_setup 0 /* Used only by init, to get system going. */ +#define __NR_exit 1 /* Common */ +#define __NR_fork 2 /* Common */ +#define __NR_read 3 /* Common */ +#define __NR_write 4 /* Common */ +#define __NR_open 5 /* Common */ +#define __NR_close 6 /* Common */ +#define __NR_wait4 7 /* Common */ +#define __NR_creat 8 /* Common */ +#define __NR_link 9 /* Common */ +#define __NR_unlink 10 /* Common */ +#define __NR_execv 11 /* SunOS Specific */ +#define __NR_chdir 12 /* Common */ +/* #define __NR_ni_syscall 13 ENOSYS under SunOS */ +#define __NR_mknod 14 /* Common */ +#define __NR_chmod 15 /* Common */ +#define __NR_chown 16 /* Common */ +#define __NR_brk 17 /* Common */ +/* #define __NR_ni_syscall 18 ENOSYS under SunOS */ +#define __NR_lseek 19 /* Common */ +#define __NR_getpid 20 /* Common */ +/* #define __NR_ni_syscall 21 ENOSYS under SunOS */ +/* #define __NR_ni_syscall 22 ENOSYS under SunOS */ +#define __NR_setuid 23 /* Implemented via setreuid in SunOS */ +#define __NR_getuid 24 /* Common */ +/* #define __NR_ni_syscall 25 ENOSYS under SunOS */ +#define __NR_ptrace 26 /* Common */ +#define __NR_alarm 27 /* Implemented via setitimer in SunOS */ +/* #define __NR_ni_syscall 28 ENOSYS under SunOS */ +#define __NR_pause 29 /* Is sigblock(0)->sigpause() in SunOS */ +#define __NR_utime 30 /* Implemented via utimes() under SunOS */ +#define __NR_stty 31 /* Implemented via ioctl() under SunOS */ +#define __NR_gtty 32 /* Implemented via ioctl() under SunOS */ +#define __NR_access 33 /* Common */ +#define __NR_nice 34 /* Implemented via get/setpriority() in SunOS */ +#define __NR_ftime 35 /* Implemented via gettimeofday() in SunOS */ +#define __NR_sync 36 /* Common */ +#define __NR_kill 37 /* Common */ +#define __NR_stat 38 /* Common */ +/* #define __NR_ni_syscall 39 ENOSYS under SunOS */ +#define __NR_lstat 40 /* Common */ +#define __NR_dup 41 /* Common */ +#define __NR_pipe 42 /* Common */ +#define __NR_times 43 /* Implemented via getrusage() in SunOS */ +#define __NR_profil 44 /* Common */ +/* #define __NR_ni_syscall 45 ENOSYS under SunOS */ +#define __NR_setgid 46 /* Implemented via setregid() in SunOS */ +#define __NR_getgid 47 /* Common */ +#define __NR_signal 48 /* Implemented via sigvec() in SunOS */ +#define __NR_geteuid 49 /* SunOS calls getuid() */ +#define __NR_getegid 50 /* SunOS calls getgid() */ +#define __NR_acct 51 /* Common */ +/* #define __NR_ni_syscall 52 ENOSYS under SunOS */ +#define __NR_mctl 53 /* SunOS specific */ +#define __NR_ioctl 54 /* Common */ +#define __NR_reboot 55 /* Common */ +/* #define __NR_ni_syscall 56 ENOSYS under SunOS */ +#define __NR_symlink 57 /* Common */ +#define __NR_readlink 58 /* Common */ +#define __NR_execve 59 /* Common */ +#define __NR_umask 60 /* Common */ +#define __NR_chroot 61 /* Common */ +#define __NR_fstat 62 /* Common */ +/* #define __NR_ni_syscall 63 ENOSYS under SunOS */ +#define __NR_getpagesize 64 /* Common */ +#define __NR_msync 65 /* Common in newer 1.3.x revs... */ +/* #define __NR_ni_syscall 66 ENOSYS under SunOS */ +/* #define __NR_ni_syscall 67 ENOSYS under SunOS */ +/* #define __NR_ni_syscall 68 ENOSYS under SunOS */ +#define __NR_sbrk 69 /* SunOS Specific */ +#define __NR_sstk 70 /* SunOS Specific */ +#define __NR_mmap 71 /* Common */ +#define __NR_vadvise 72 /* SunOS Specific */ +#define __NR_munmap 73 /* Common */ +#define __NR_mprotect 74 /* Common */ +#define __NR_madvise 75 /* SunOS Specific */ +#define __NR_vhangup 76 /* Common */ +/* #define __NR_ni_syscall 77 ENOSYS under SunOS */ +#define __NR_mincore 78 /* SunOS Specific */ +#define __NR_getgroups 79 /* Common */ +#define __NR_setgroups 80 /* Common */ +#define __NR_getpgrp 81 /* Common */ +#define __NR_setpgrp 82 /* setpgid, same difference... */ +#define __NR_setitimer 83 /* Common */ +/* #define __NR_ni_syscall 84 ENOSYS under SunOS */ +#define __NR_swapon 85 /* Common */ +#define __NR_getitimer 86 /* Common */ +#define __NR_gethostname 87 /* SunOS Specific */ +#define __NR_sethostname 88 /* Common */ +#define __NR_getdtablesize 89 /* SunOS Specific */ +#define __NR_dup2 90 /* Common */ +#define __NR_getdopt 91 /* SunOS Specific */ +#define __NR_fcntl 92 /* Common */ +#define __NR_select 93 /* Common */ +#define __NR_setdopt 94 /* SunOS Specific */ +#define __NR_fsync 95 /* Common */ +#define __NR_setpriority 96 /* Common */ +#define __NR_socket 97 /* SunOS Specific */ +#define __NR_connect 98 /* SunOS Specific */ +#define __NR_accept 99 /* SunOS Specific */ +#define __NR_getpriority 100 /* Common */ +#define __NR_send 101 /* SunOS Specific */ +#define __NR_recv 102 /* SunOS Specific */ +/* #define __NR_ni_syscall 103 ENOSYS under SunOS */ +#define __NR_bind 104 /* SunOS Specific */ +#define __NR_setsockopt 105 /* SunOS Specific */ +#define __NR_listen 106 /* SunOS Specific */ +/* #define __NR_ni_syscall 107 ENOSYS under SunOS */ +#define __NR_sigvec 108 /* SunOS Specific */ +#define __NR_sigblock 109 /* SunOS Specific */ +#define __NR_sigsetmask 110 /* SunOS Specific */ +#define __NR_sigpause 111 /* SunOS Specific */ +#define __NR_sigstack 112 /* SunOS Specific */ +#define __NR_recvmsg 113 /* SunOS Specific */ +#define __NR_sendmsg 114 /* SunOS Specific */ +#define __NR_vtrace 115 /* SunOS Specific */ +#define __NR_gettimeofday 116 /* Common */ +#define __NR_getrusage 117 /* Common */ +#define __NR_getsockopt 118 /* SunOS Specific */ +/* #define __NR_ni_syscall 119 ENOSYS under SunOS */ +#define __NR_readv 120 /* Common */ +#define __NR_writev 121 /* Common */ +#define __NR_settimeofday 122 /* Common */ +#define __NR_fchown 123 /* Common */ +#define __NR_fchmod 124 /* Common */ +#define __NR_recvfrom 125 /* SunOS Specific */ +#define __NR_setreuid 126 /* Common */ +#define __NR_setregid 127 /* Common */ +#define __NR_rename 128 /* Common */ +#define __NR_truncate 129 /* Common */ +#define __NR_ftruncate 130 /* Common */ +#define __NR_flock 131 /* Common */ +/* #define __NR_ni_syscall 132 ENOSYS under SunOS */ +#define __NR_sendto 133 /* SunOS Specific */ +#define __NR_shutdown 134 /* SunOS Specific */ +#define __NR_socketpair 135 /* SunOS Specific */ +#define __NR_mkdir 136 /* Common */ +#define __NR_rmdir 137 /* Common */ +#define __NR_utimes 138 /* SunOS Specific */ +/* #define __NR_ni_syscall 139 ENOSYS under SunOS */ +#define __NR_adjtime 140 /* SunOS Specific */ +#define __NR_getpeername 141 /* SunOS Specific */ +#define __NR_gethostid 142 /* SunOS Specific */ +/* #define __NR_ni_syscall 143 ENOSYS under SunOS */ +#define __NR_getrlimit 144 /* Common */ +#define __NR_setrlimit 145 /* Common */ +#define __NR_killpg 146 /* SunOS Specific */ +/* #define __NR_ni_syscall 147 ENOSYS under SunOS */ +/* #define __NR_ni_syscall 148 ENOSYS under SunOS */ +/* #define __NR_ni_syscall 149 ENOSYS under SunOS */ +#define __NR_getsockname 150 /* SunOS Specific */ +#define __NR_getmsg 151 /* SunOS Specific */ +#define __NR_putmsg 152 /* SunOS Specific */ +#define __NR_poll 153 /* SunOS Specific */ +/* #define __NR_ni_syscall 154 ENOSYS under SunOS */ +#define __NR_nfssvc 155 /* SunOS Specific */ +#define __NR_getdirentries 156 /* SunOS Specific */ +#define __NR_statfs 157 /* Common */ +#define __NR_fstatfs 158 /* Common */ +#define __NR_umount 159 /* Common */ +#define __NR_async_daemon 160 /* SunOS Specific */ +#define __NR_getfh 161 /* SunOS Specific */ +#define __NR_getdomainname 162 /* SunOS Specific */ +#define __NR_setdomainname 163 /* Common */ +/* #define __NR_ni_syscall 164 ENOSYS under SunOS */ +#define __NR_quotactl 165 /* Common */ +#define __NR_exportfs 166 /* SunOS Specific */ +#define __NR_mount 167 /* Common */ +#define __NR_ustat 168 /* Common */ +#define __NR_semsys 169 /* SunOS Specific */ +#define __NR_msgsys 170 /* SunOS Specific */ +#define __NR_shmsys 171 /* SunOS Specific */ +#define __NR_auditsys 172 /* SunOS Specific */ +#define __NR_rfssys 173 /* SunOS Specific */ +#define __NR_getdents 174 /* Common */ +#define __NR_setsid 175 /* Common */ +#define __NR_fchdir 176 /* Common */ +#define __NR_fchroot 177 /* SunOS Specific */ +#define __NR_vpixsys 178 /* SunOS Specific */ +#define __NR_aioread 179 /* SunOS Specific */ +#define __NR_aiowrite 180 /* SunOS Specific */ +#define __NR_aiowait 181 /* SunOS Specific */ +#define __NR_aiocancel 182 /* SunOS Specific */ +#define __NR_sigpending 183 /* Common */ +/* #define __NR_ni_syscall 184 ENOSYS under SunOS */ +#define __NR_setpgid 185 /* Common */ +#define __NR_pathconf 186 /* SunOS Specific */ +#define __NR_fpathconf 187 /* SunOS Specific */ +#define __NR_sysconf 188 /* SunOS Specific */ +#define __NR_uname 189 /* Linux Specific */ +#define __NR_init_module 190 /* Linux Specific */ +#define __NR_personality 191 /* Linux Specific */ +#define __NR_prof 192 /* Linux Specific */ +#define __NR_break 193 /* Linux Specific */ +#define __NR_lock 194 /* Linux Specific */ +#define __NR_mpx 195 /* Linux Specific */ +#define __NR_ulimit 196 /* Linux Specific */ +#define __NR_getppid 197 /* Linux Specific */ +#define __NR_sigaction 198 /* Linux Specific */ +#define __NR_sgetmask 199 /* Linux Specific */ +#define __NR_ssetmask 200 /* Linux Specific */ +#define __NR_sigsuspend 201 /* Linux Specific */ +#define __NR_oldlstat 202 /* Linux Specific */ +#define __NR_uselib 203 /* Linux Specific */ +#define __NR_readdir 204 /* Linux Specific */ +#define __NR_ioperm 205 /* Linux Specific - i386 specific, unused */ +#define __NR_socketcall 206 /* Linux Specific */ +#define __NR_syslog 207 /* Linux Specific */ +#define __NR_olduname 208 /* Linux Specific */ +#define __NR_iopl 209 /* Linux Specific - i386 specific, unused */ +#define __NR_idle 210 /* Linux Specific */ +#define __NR_vm86 211 /* Linux Specific - i386 specific, unused */ +#define __NR_waitpid 212 /* Linux Specific */ +#define __NR_swapoff 213 /* Linux Specific */ +#define __NR_sysinfo 214 /* Linux Specific */ +#define __NR_ipc 215 /* Linux Specific */ +#define __NR_sigreturn 216 /* Linux Specific */ +#define __NR_clone 217 /* Linux Specific */ +#define __NR_modify_ldt 218 /* Linux Specific - i386 specific, unused */ +#define __NR_adjtimex 219 /* Linux Specific */ +#define __NR_sigprocmask 220 /* Linux Specific */ +#define __NR_create_module 221 /* Linux Specific */ +#define __NR_delete_module 222 /* Linux Specific */ +#define __NR_get_kernel_syms 223 /* Linux Specific */ +#define __NR_getpgid 224 /* Linux Specific */ +#define __NR_bdflush 225 /* Linux Specific */ +#define __NR_sysfs 226 /* Linux Specific */ +#define __NR_afs_syscall 227 /* Linux Specific */ +#define __NR_setfsuid 228 /* Linux Specific */ +#define __NR_setfsgid 229 /* Linux Specific */ +#define __NR__newselect 230 /* Linux Specific */ +#define __NR_time 231 /* Linux Specific */ +#define __NR_oldstat 232 /* Linux Specific */ +#define __NR_stime 233 /* Linux Specific */ +#define __NR_oldfstat 234 /* Linux Specific */ +#define __NR_phys 235 /* Linux Specific */ +#define __NR__llseek 236 /* Linux Specific */ +#define __NR_mlock 237 +#define __NR_munlock 238 +#define __NR_mlockall 239 +#define __NR_munlockall 240 +#define __NR_sched_setparam 241 +#define __NR_sched_getparam 242 +#define __NR_sched_setscheduler 243 +#define __NR_sched_getscheduler 244 +#define __NR_sched_yield 245 +#define __NR_sched_get_priority_max 246 +#define __NR_sched_get_priority_min 247 +#define __NR_sched_rr_get_interval 248 +#define __NR_nanosleep 249 +#define __NR_mremap 250 +#define __NR__sysctl 251 +#define __NR_getsid 252 +#define __NR_fdatasync 253 +#define __NR_nfsctl 254 + #define _syscall0(type,name) \ type name(void) \ { \ long __res; \ -__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ - "t 0xa\n\t" \ - : "=r" (__res) \ - : "0" (__NR_##name) \ - : "o0"); \ +__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \ + "t 0x10\n\t" \ + "bcc 1f\n\t" \ + "or %%g0, %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res)\ + : "0" (__NR_##name) \ + : "g1", "o0"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -31,12 +295,16 @@ return -1; \ type name(type1 arg1) \ { \ long __res; \ -__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ - "or %%g0, %1, %%o1\n\t" \ - "t 0xa\n\t" \ - : "=r" (__res), "=r" ((long)(arg1)) \ - : "0" (__NR_##name),"1" ((long)(arg1)) \ - : "o0", "o1"); \ +__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \ + "or %%g0, %1, %%o0\n\t" \ + "t 0x10\n\t" \ + "bcc 1f\n\t" \ + "or %%g0, %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=r" ((long)(arg1)) \ + : "0" (__NR_##name),"1" ((long)(arg1)) \ + : "g1", "o0"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -47,13 +315,17 @@ return -1; \ type name(type1 arg1,type2 arg2) \ { \ long __res; \ -__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ - "or %%g0, %1, %%o1\n\t" \ - "or %%g0, %2, %%o2\n\t" \ - "t 0xa\n\t" \ - : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(args)) \ - : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \ - : "o0", "o1", "o2"); \ +__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \ + "or %%g0, %1, %%o0\n\t" \ + "or %%g0, %2, %%o1\n\t" \ + "t 0x10\n\t" \ + "bcc 1f\n\t" \ + "or %%g0, %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)) \ + : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \ + : "g1", "o0", "o1"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -64,19 +336,23 @@ return -1; \ type name(type1 arg1,type2 arg2,type3 arg3) \ { \ long __res; \ -__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ - "or %%g0, %1, %%o1\n\t" \ - "or %%g0, %2, %%o2\n\t" \ - "or %%g0, %3, %%o3\n\t" \ - "t 0xa\n\t" \ - : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \ - "=r" ((long)(arg3)) \ - : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \ - "3" ((long)(arg3)) \ - : "o0", "o1", "o2", "o3"); \ +__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \ + "or %%g0, %1, %%o0\n\t" \ + "or %%g0, %2, %%o1\n\t" \ + "or %%g0, %3, %%o2\n\t" \ + "t 0x10\n\t" \ + "bcc 1f\n\t" \ + "or %%g0, %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \ + "=r" ((long)(arg3)) \ + : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \ + "3" ((long)(arg3)) \ + : "g1", "o0", "o1", "o2"); \ if (__res>=0) \ return (type) __res; \ -errno=-__res; \ +errno = -__res; \ return -1; \ } @@ -84,20 +360,24 @@ return -1; \ type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ { \ long __res; \ -__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ - "or %%g0, %1, %%o1\n\t" \ - "or %%g0, %2, %%o2\n\t" \ - "or %%g0, %3, %%o3\n\t" \ - "or %%g0, %4, %%o4\n\t" \ - "t 0xa\n\t" \ - : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \ - "=r" ((long)(arg3)), "=r" ((long)(arg4)) \ - : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \ - "3" ((long)(arg3)),"4" ((long)(arg4)) \ - : "o0", "o1", "o2", "o3", "o4"); \ +__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \ + "or %%g0, %1, %%o0\n\t" \ + "or %%g0, %2, %%o1\n\t" \ + "or %%g0, %3, %%o2\n\t" \ + "or %%g0, %4, %%o3\n\t" \ + "t 0x10\n\t" \ + "bcc 1f\n\t" \ + "or %%g0, %%o0, %0\n\t" \ + "sub %%g0,%%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \ + "=r" ((long)(arg3)), "=r" ((long)(arg4)) \ + : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \ + "3" ((long)(arg3)),"4" ((long)(arg4)) \ + : "g1", "o0", "o1", "o2", "o3"); \ if (__res>=0) \ return (type) __res; \ -errno=-__res; \ +errno = -__res; \ return -1; \ } @@ -105,25 +385,29 @@ return -1; \ type5,arg5) \ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ { \ -long __res; \ -__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ - "or %%g0, %1, %%o1\n\t" \ - "or %%g0, %2, %%o2\n\t" \ - "or %%g0, %3, %%o3\n\t" \ - "or %%g0, %4, %%o4\n\t" \ - "or %%g0, %5, %%o5\n\t" \ - "t 0xa\n\t" \ - : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \ - "=r" ((long)(arg3)), "=r" ((long)(arg4)), "=r" ((long)(arg5)) \ - : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \ - "3" ((long)(arg3)),"4" ((long)(arg4)),"5" ((long)(arg5)) \ - : "o0", "o1", "o2", "o3", "o4", "o5"); \ + long __res; \ +\ +__asm__ __volatile__ ("or %%g0, %1, %%o0\n\t" \ + "or %%g0, %2, %%o1\n\t" \ + "or %%g0, %3, %%o2\n\t" \ + "or %%g0, %4, %%o3\n\t" \ + "or %%g0, %5, %%o4\n\t" \ + "or %%g0, %6, %%g1\n\t" \ + "t 0x10\n\t" \ + "bcc 1f\n\t" \ + "or %%g0, %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res) \ + : "r" ((long)(arg1)),"r" ((long)(arg2)), \ + "r" ((long)(arg3)),"r" ((long)(arg4)),"r" ((long)(arg5)), \ + "i" (__NR_##name) \ + : "g1", "o0", "o1", "o2", "o3", "o4"); \ if (__res>=0) \ return (type) __res; \ -errno=-__res; \ +errno = -__res; \ return -1; \ } - #ifdef __KERNEL_SYSCALLS__ /* @@ -139,25 +423,70 @@ return -1; \ * some others too. */ #define __NR__exit __NR_exit -static inline _syscall0(int,idle) -static inline _syscall0(int,fork) -static inline _syscall0(int,pause) -static inline _syscall0(int,setup) -static inline _syscall0(int,sync) -static inline _syscall0(pid_t,setsid) -static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) -static inline _syscall1(int,dup,int,fd) -static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) -static inline _syscall3(int,open,const char *,file,int,flag,int,mode) -static inline _syscall1(int,close,int,fd) -static inline _syscall1(int,_exit,int,exitcode) -static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) +static __inline__ _syscall0(int,idle) +static __inline__ _syscall0(int,fork) +static __inline__ _syscall2(int,clone,unsigned long,flags,char *,ksp) +static __inline__ _syscall0(int,pause) +static __inline__ _syscall0(int,setup) +static __inline__ _syscall0(int,sync) +static __inline__ _syscall0(pid_t,setsid) +static __inline__ _syscall3(int,write,int,fd,__const__ char *,buf,off_t,count) +static __inline__ _syscall1(int,dup,int,fd) +static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp) +static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode) +static __inline__ _syscall1(int,close,int,fd) +static __inline__ _syscall1(int,_exit,int,exitcode) +static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) -static inline pid_t wait(int * wait_stat) +static __inline__ pid_t wait(int * wait_stat) { return waitpid(-1,wait_stat,0); } -#endif +/* + * This is the mechanism for creating a new kernel thread. + * + * NOTE! Only a kernel-only process(ie the swapper or direct descendants + * who haven't done an "execve()") should use this: it will work within + * a system call from a "real" process, but the process memory space will + * not be free'd until both the parent and the child have exited. + */ +static __inline__ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + long retval; + + __asm__ __volatile("mov %4, %%g2\n\t" /* Set aside fn ptr... */ + "mov %5, %%g3\n\t" /* and arg. */ + "mov %1, %%g1\n\t" + "mov %2, %%o0\n\t" /* Clone flags. */ + "mov 0, %%o1\n\t" /* usp arg == 0 */ + "t 0x10\n\t" /* Linux/Sparc clone(). */ + "cmp %%o1, 0\n\t" + "be 1f\n\t" /* The parent, just return. */ + " nop\n\t" /* Delay slot. */ + "jmpl %%g2, %%o7\n\t" /* Call the function. */ + " mov %%g3, %%o0\n\t" /* Get back the arg in delay. */ + "mov %3, %%g1\n\t" + "t 0x10\n\t" /* Linux/Sparc exit(). */ + /* Notreached by child. */ + "1: mov %%o0, %0\n\t" : + "=r" (retval) : + "i" (__NR_clone), "r" (flags | CLONE_VM), + "i" (__NR_exit), "r" (fn), "r" (arg) : + "g1", "g2", "g3", "o0", "o1", "memory"); + return retval; +} + +#endif /* __KERNEL_SYSCALLS__ */ + +/* sysconf options, for SunOS compatibility */ +#define _SC_ARG_MAX 1 +#define _SC_CHILD_MAX 2 +#define _SC_CLK_TCK 3 +#define _SC_NGROUPS_MAX 4 +#define _SC_OPEN_MAX 5 +#define _SC_JOB_CONTROL 6 +#define _SC_SAVED_IDS 7 +#define _SC_VERSION 8 #endif /* _SPARC_UNISTD_H */ diff --git a/include/asm-sparc/user.h b/include/asm-sparc/user.h new file mode 100644 index 000000000..7306b0d10 --- /dev/null +++ b/include/asm-sparc/user.h @@ -0,0 +1,60 @@ +/* $Id: user.h,v 1.4 1996/07/24 23:17:14 miguel Exp $ + * asm-sparc/user.h: Core file definitions for the Sparc. + * + * Keep in sync with reg.h. Actually, we could get rid of this + * one, since we won't a.out core dump that much anyways - miguel. + * Copyright (C) 1995 (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_USER_H +#define _SPARC_USER_H + +#include <asm/a.out.h> +struct sunos_regs { + unsigned long psr, pc, npc, y; + unsigned long regs[15]; +}; + +struct sunos_fpqueue { + unsigned long *addr; + unsigned long inst; +}; + +struct sunos_fp { + union { + unsigned long regs[32]; + double reg_dbls[16]; + } fregs; + unsigned long fsr; + unsigned long flags; + unsigned long extra; + unsigned long fpq_count; + struct sunos_fpqueue fpq[16]; +}; + +struct sunos_fpu { + struct sunos_fp fpstatus; +}; + +/* The SunOS core file header layout. */ +struct user { + unsigned long magic; + unsigned long len; + struct sunos_regs regs; + struct exec uexec; + int signal; + size_t u_tsize; /* all of these in bytes! */ + size_t u_dsize; + size_t u_ssize; + char u_comm[17]; + struct sunos_fpu fpu; + unsigned long sigcode; /* Special sigcontext subcode, if any */ +}; + +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_DATA_START_ADDR (u.start_data) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) +#define SUNOS_CORE_MAGIC 0x080456 + +#endif /* !(_SPARC_USER_H) */ diff --git a/include/asm-sparc/vac-ops.h b/include/asm-sparc/vac-ops.h index 18755e048..d963a7fa3 100644 --- a/include/asm-sparc/vac-ops.h +++ b/include/asm-sparc/vac-ops.h @@ -1,89 +1,125 @@ +/* $Id: vac-ops.h,v 1.12 1996/07/08 15:12:30 ecd Exp $ */ #ifndef _SPARC_VAC_OPS_H #define _SPARC_VAC_OPS_H /* vac-ops.h: Inline assembly routines to do operations on the Sparc - VAC (virtual address cache). - - Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu) -*/ - -extern unsigned long *trapbase; -extern char end, etext, msgbuf; - -extern void flush_vac_context(void); -extern void flush_vac_segment(unsigned int foo_segment); -extern void flush_vac_page(unsigned int foo_addr); - -extern int vac_do_hw_vac_flushes, vac_size, vac_linesize; -extern int vac_entries_per_context, vac_entries_per_segment; -extern int vac_entries_per_page; - -/* enable_vac() enables the virtual address cache. It returns 0 on - success, 1 on failure. -*/ - -extern __inline__ int enable_vac(void) -{ - int success=0; - - __asm__ __volatile__("lduba [%1] 2, %0\n\t" - "or %0, 0x10, %0\n\t" - "stba %0, [%1] 2\n\t" - "or %%g0, %%g0, %0" : - "=r" (success) : - "r" ((unsigned int) 0x40000000), - "0" (success)); - return success; -} - -/* disable_vac() disables the virtual address cache. It returns 0 on - success, 1 on failure. -*/ - -extern __inline__ int disable_vac(void) + * VAC (virtual address cache) for the sun4c. + * + * Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu) + */ + +#include <asm/sysen.h> +#include <asm/contregs.h> +#include <asm/asi.h> + +/* The SUN4C models have a virtually addressed write-through + * cache. + * + * The cache tags are directly accessible through an ASI and + * each have the form: + * + * ------------------------------------------------------------ + * | MBZ | CONTEXT | WRITE | PRIV | VALID | MBZ | TagID | MBZ | + * ------------------------------------------------------------ + * 31 25 24 22 21 20 19 18 16 15 2 1 0 + * + * MBZ: These bits are either unused and/or reserved and should + * be written as zeroes. + * + * CONTEXT: Records the context to which this cache line belongs. + * + * WRITE: A copy of the writable bit from the mmu pte access bits. + * + * PRIV: A copy of the privileged bit from the pte access bits. + * + * VALID: If set, this line is valid, else invalid. + * + * TagID: Fourteen bits of tag ID. + * + * Every virtual address is seen by the cache like this: + * + * ---------------------------------------- + * | RESV | TagID | LINE | BYTE-in-LINE | + * ---------------------------------------- + * 31 30 29 16 15 4 3 0 + * + * RESV: Unused/reserved. + * + * TagID: Used to match the Tag-ID in that vac tags. + * + * LINE: Which line within the cache + * + * BYTE-in-LINE: Which byte within the cache line. + */ + +/* Sun4c VAC Tags */ +#define S4CVACTAG_CID 0x01c00000 +#define S4CVACTAG_W 0x00200000 +#define S4CVACTAG_P 0x00100000 +#define S4CVACTAG_V 0x00080000 +#define S4CVACTAG_TID 0x0000fffc + +/* Sun4c VAC Virtual Address */ +#define S4CVACVA_TID 0x3fff0000 +#define S4CVACVA_LINE 0x0000fff0 +#define S4CVACVA_BIL 0x0000000f + +/* The indexing of cache lines creates a problem. Because the line + * field of a virtual address extends past the page offset within + * the virtual address it is possible to have what are called + * 'bad aliases' which will create inconsistencies. So we must make + * sure that within a context that if a physical page is mapped + * more than once, that 'extra' line bits are the same. If this is + * not the case, and thus is a 'bad alias' we must turn off the + * cacheable bit in the pte's of all such pages. + */ +#define S4CVAC_BADBITS 0x0000f000 + +/* The following is true if vaddr1 and vaddr2 would cause + * a 'bad alias'. + */ +#define S4CVAC_BADALIAS(vaddr1, vaddr2) \ + ((((unsigned long) (vaddr1)) ^ ((unsigned long) (vaddr2))) & \ + (S4CVAC_BADBITS)) + +/* The following structure describes the characteristics of a sun4c + * VAC as probed from the prom during boot time. + */ +struct sun4c_vac_props { + unsigned int num_bytes; /* Size of the cache */ + unsigned int num_lines; /* Number of cache lines */ + unsigned int do_hwflushes; /* Hardware flushing available? */ + unsigned int linesize; /* Size of each line in bytes */ + unsigned int log2lsize; /* log2(linesize) */ + unsigned int on; /* VAC is enabled */ +}; + +extern struct sun4c_vac_props sun4c_vacinfo; + +extern void sun4c_flush_all(void); + +/* sun4c_enable_vac() enables the sun4c virtual address cache. */ +extern __inline__ void sun4c_enable_vac(void) { - int success=0; - - __asm__ __volatile__("lduba [%1] 0x2, %0\n\t" - "xor %0, 0x10, %0\n\t" - "stba %0, [%1] 0x2\n\t" - "or %%g0, %%g0, %0" : - "=r" (success) : - "r" (0x40000000), - "0" (success)); - return success; + __asm__ __volatile__("lduba [%0] %1, %%g1\n\t" + "or %%g1, %2, %%g1\n\t" + "stba %%g1, [%0] %1\n\t" : : + "r" ((unsigned int) AC_SENABLE), + "i" (ASI_CONTROL), "i" (SENABLE_CACHE) : + "g1"); + sun4c_vacinfo.on = 1; } -/* Various one-shot VAC entry flushes on the Sparc */ - -extern __inline__ void hw_flush_vac_context_entry(char* addr) +/* sun4c_disable_vac() disables the virtual address cache. */ +extern __inline__ void sun4c_disable_vac(void) { - __asm__ __volatile__("sta %%g0, [%0] 0x7" : : "r" (addr)); + __asm__ __volatile__("lduba [%0] %1, %%g1\n\t" + "andn %%g1, %2, %%g1\n\t" + "stba %%g1, [%0] %1\n\t" : : + "r" ((unsigned int) AC_SENABLE), + "i" (ASI_CONTROL), "i" (SENABLE_CACHE) : + "g1"); + sun4c_vacinfo.on = 0; } -extern __inline__ void sw_flush_vac_context_entry(char* addr) -{ - __asm__ __volatile__("sta %%g0, [%0] 0xe" : : "r" (addr)); -} - -extern __inline__ void hw_flush_vac_segment_entry(char* addr) -{ - __asm__ __volatile__("sta %%g0, [%0] 0x5" : : "r" (addr)); -} - -extern __inline__ void sw_flush_vac_segment_entry(char* addr) -{ - __asm__ __volatile__("sta %%g0, [%0] 0xc" : : "r" (addr)); -} - -extern __inline__ void hw_flush_vac_page_entry(unsigned long* addr) -{ - __asm__ __volatile__("sta %%g0, [%0] 0x6" : : "r" (addr)); -} - -extern __inline__ void sw_flush_vac_page_entry(unsigned long* addr) -{ - __asm__ __volatile__("sta %%g0, [%0] 0xd" : : "r" (addr)); -} - #endif /* !(_SPARC_VAC_OPS_H) */ diff --git a/include/asm-sparc/vaddrs.h b/include/asm-sparc/vaddrs.h index 7df443103..30e927b1b 100644 --- a/include/asm-sparc/vaddrs.h +++ b/include/asm-sparc/vaddrs.h @@ -1,6 +1,9 @@ +/* $Id: vaddrs.h,v 1.21 1996/10/07 03:03:02 davem Exp $ */ #ifndef _SPARC_VADDRS_H #define _SPARC_VADDRS_H +#include <asm/head.h> + /* asm-sparc/vaddrs.h: Here will be define the virtual addresses at * which important I/O addresses will be mapped. * For instance the timer register virtual address @@ -9,8 +12,54 @@ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ -#define TIMER_VADDR 0x3000 /* Next page after where the interrupt enable - * register gets mapped at boot. - */ +/* I can see only one reason why we should have statically defined + * mappings for devices and is the speedup improvements of not loading + * a pointer and then the value in the assembly code + */ +#define IOBASE_VADDR 0xfe000000 /* Base for mapping pages */ +#define IOBASE_LEN 0x00300000 /* Length of the IO area */ +#define IOBASE_END 0xfe300000 +#define DVMA_VADDR 0xfff00000 /* Base area of the DVMA on suns */ +#define DVMA_LEN 0x00040000 /* Size of the DVMA address space */ +#define DVMA_END 0xfff40000 + +/* IOMMU Mapping area, must be on a 16MB boundary! Note this + * doesn't count the DVMA areas, the prom lives between the + * iommu mapping area (for scsi transfer buffers) and the + * dvma upper range (for lance packet ring buffers). + */ +#define IOMMU_VADDR 0xff000000 +#define IOMMU_LEN 0x00c00000 +#define IOMMU_END 0xffc00000 /* KADB debugger vm starts here */ + +/* On the sun4/4c we don't need an IOMMU area, but we need a place + * to reliably map locked down kernel data. This includes the + * task_struct and kernel stack pages of each process plus the + * scsi buffers during dvma IO transfers, also the floppy buffers + * during pseudo dma which runs with traps off (no faults allowed). + * Some quick calculations yield: + * NR_TASKS <512> * (3 * PAGE_SIZE) == 0x600000 + * Subtract this from 0xc00000 and you get 0x927C0 of vm left + * over to map SCSI dvma + floppy pseudo-dma buffers. So be + * careful if you change NR_TASKS or else there won't be enough + * room for it all. + */ +#define SUN4C_LOCK_VADDR 0xff000000 +#define SUN4C_LOCK_LEN 0x00c00000 +#define SUN4C_LOCK_END 0xffc00000 + +/* On sun4m machines we need per-cpu virtual areas */ +#define PERCPU_VADDR 0xffc00000 /* Base for per-cpu virtual mappings */ +#define PERCPU_ENTSIZE 0x00100000 +#define PERCPU_LEN ((PERCPU_ENTSIZE*NCPUS)) + +/* per-cpu offsets */ +#define PERCPU_TBR_OFFSET 0x00000 /* %tbr, mainly used for identification. */ +#define PERCPU_KSTACK_OFFSET 0x01000 /* Beginning of kernel stack for this cpu */ +#define PERCPU_MBOX_OFFSET 0x03000 /* Prom SMP Mailbox */ +#define PERCPU_CPUID_OFFSET 0x04000 /* Per-cpu ID number. */ +#define PERCPU_ISALIVE_OFFSET 0x04004 /* Has CPU been initted yet? */ +#define PERCPU_ISIDLING_OFFSET 0x04008 /* Is CPU in idle loop spinning? */ #endif /* !(_SPARC_VADDRS_H) */ + diff --git a/include/asm-sparc/version.h b/include/asm-sparc/version.h deleted file mode 100644 index 0c238e9cf..000000000 --- a/include/asm-sparc/version.h +++ /dev/null @@ -1 +0,0 @@ -#define WHO_COMPILED_ME "someone@somewhere.domain" diff --git a/include/asm-sparc/viking.h b/include/asm-sparc/viking.h new file mode 100644 index 000000000..dc4adc393 --- /dev/null +++ b/include/asm-sparc/viking.h @@ -0,0 +1,198 @@ +/* $Id: viking.h,v 1.16 1996/08/29 09:49:10 davem Exp $ + * viking.h: Defines specific to the GNU/Viking MBUS module. + * This is SRMMU stuff. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_VIKING_H +#define _SPARC_VIKING_H + +#include <asm/asi.h> +#include <asm/mxcc.h> + +/* Bits in the SRMMU control register for GNU/Viking modules. + * + * ----------------------------------------------------------- + * |impl-vers| RSV |TC|AC|SP|BM|PC|MBM|SB|IC|DC|PSO|RSV|NF|ME| + * ----------------------------------------------------------- + * 31 24 23-17 16 15 14 13 12 11 10 9 8 7 6-2 1 0 + * + * TC: Tablewalk Cacheable -- 0 = Twalks are not cacheable in E-cache + * 1 = Twalks are cacheable in E-cache + * + * GNU/Viking will only cache tablewalks in the E-cache (mxcc) if present + * and never caches them internally (or so states the docs). Therefore + * for machines lacking an E-cache (ie. in MBUS mode) this bit must + * remain cleared. + * + * AC: Alternate Cacheable -- 0 = Passthru physical accesses not cacheable + * 1 = Passthru physical accesses cacheable + * + * This indicates whether accesses are cacheable when no cachable bit + * is present in the pte when the processor is in boot-mode or the + * access does not need pte's for translation (ie. pass-thru ASI's). + * "Cachable" is only referring to E-cache (if present) and not the + * on chip split I/D caches of the GNU/Viking. + * + * SP: SnooP Enable -- 0 = bus snooping off, 1 = bus snooping on + * + * This enables snooping on the GNU/Viking bus. This must be on + * for the hardware cache consistency mechanisms of the GNU/Viking + * to work at all. On non-mxcc GNU/Viking modules the split I/D + * caches will snoop regardless of whether they are enabled, this + * takes care of the case where the I or D or both caches are turned + * off yet still contain valid data. Note also that this bit does + * not affect GNU/Viking store-buffer snoops, those happen if the + * store-buffer is enabled no matter what. + * + * BM: Boot Mode -- 0 = not in boot mode, 1 = in boot mode + * + * This indicates whether the GNU/Viking is in boot-mode or not, + * if it is then all instruction fetch physical addresses are + * computed as 0xff0000000 + low 28 bits of requested address. + * GNU/Viking boot-mode does not affect data accesses. Also, + * in boot mode instruction accesses bypass the split on chip I/D + * caches, they may be cached by the GNU/MXCC if present and enabled. + * + * MBM: MBus Mode -- 0 = not in MBus mode, 1 = in MBus mode + * + * This indicated the GNU/Viking configuration present. If in + * MBUS mode, the GNU/Viking lacks a GNU/MXCC E-cache. If it is + * not then the GNU/Viking is on a module VBUS connected directly + * to a GNU/MXCC cache controller. The GNU/MXCC can be thus connected + * to either an GNU/MBUS (sun4m) or the packet-switched GNU/XBus (sun4d). + * + * SB: StoreBuffer enable -- 0 = store buffer off, 1 = store buffer on + * + * The GNU/Viking store buffer allows the chip to continue execution + * after a store even if the data cannot be placed in one of the + * caches during that cycle. If disabled, all stores operations + * occur synchronously. + * + * IC: Instruction Cache -- 0 = off, 1 = on + * DC: Data Cache -- 0 = off, 1 = 0n + * + * These bits enable the on-cpu GNU/Viking split I/D caches. Note, + * as mentioned above, these caches will snoop the bus in GNU/MBUS + * configurations even when disabled to avoid data corruption. + * + * NF: No Fault -- 0 = faults generate traps, 1 = faults don't trap + * ME: MMU enable -- 0 = mmu not translating, 1 = mmu translating + * + */ + +#define VIKING_MMUENABLE 0x00000001 +#define VIKING_NOFAULT 0x00000002 +#define VIKING_PSO 0x00000080 +#define VIKING_DCENABLE 0x00000100 /* Enable data cache */ +#define VIKING_ICENABLE 0x00000200 /* Enable instruction cache */ +#define VIKING_SBENABLE 0x00000400 /* Enable store buffer */ +#define VIKING_MMODE 0x00000800 /* MBUS mode */ +#define VIKING_PCENABLE 0x00001000 /* Enable parity checking */ +#define VIKING_BMODE 0x00002000 +#define VIKING_SPENABLE 0x00004000 /* Enable bus cache snooping */ +#define VIKING_ACENABLE 0x00008000 /* Enable alternate caching */ +#define VIKING_TCENABLE 0x00010000 /* Enable table-walks to be cached */ +#define VIKING_DPENABLE 0x00040000 /* Enable the data prefetcher */ + +/* + * GNU/Viking Breakpoint Action Register fields. + */ +#define VIKING_ACTION_MIX 0x00001000 /* Enable multiple instructions */ + +/* + * GNU/Viking Cache Tags. + */ +#define VIKING_PTAG_VALID 0x01000000 /* Cache block is valid */ +#define VIKING_PTAG_DIRTY 0x00010000 /* Block has been modified */ +#define VIKING_PTAG_SHARED 0x00000100 /* Shared with some other cache */ + +extern __inline__ void viking_flush_icache(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : + "i" (ASI_M_IC_FLCLEAR)); +} + +extern __inline__ void viking_flush_dcache(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : + "i" (ASI_M_DC_FLCLEAR)); +} + +extern __inline__ void viking_unlock_icache(void) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (0x80000000), "i" (ASI_M_IC_FLCLEAR)); +} + +extern __inline__ void viking_unlock_dcache(void) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (0x80000000), "i" (ASI_M_DC_FLCLEAR)); +} + +extern __inline__ void viking_set_bpreg(unsigned long regval) +{ + __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : : + "r" (regval), + "i" (ASI_M_ACTION)); +} + +extern __inline__ unsigned long viking_get_bpreg(void) +{ + unsigned long regval; + + __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : + "=r" (regval) : + "i" (ASI_M_ACTION)); + return regval; +} + +extern __inline__ void viking_get_dcache_ptag(int set, int block, + unsigned long *data) +{ + unsigned long ptag = ((set & 0x7f) << 5) | ((block & 0x3) << 26) | + 0x80000000; + unsigned long info, page; + + __asm__ __volatile__ ("ldda [%2] %3, %%g2\n\t" + "or %%g0, %%g2, %0\n\t" + "or %%g0, %%g3, %1\n\t" : + "=r" (info), "=r" (page) : + "r" (ptag), "i" (ASI_M_DATAC_TAG) : + "g2", "g3"); + data[0] = info; + data[1] = page; +} + +extern __inline__ void viking_mxcc_turn_off_parity(unsigned long *mregp, + unsigned long *mxcc_cregp) +{ + unsigned long mreg = *mregp; + unsigned long mxcc_creg = *mxcc_cregp; + + mreg &= ~(VIKING_PCENABLE); + mxcc_creg &= ~(MXCC_CTL_PARE); + + __asm__ __volatile__ ("set 1f, %%g2\n\t" + "andcc %%g2, 4, %%g0\n\t" + "bne 2f\n\t" + " nop\n" + "1:\n\t" + "sta %0, [%%g0] %3\n\t" + "sta %1, [%2] %4\n\t" + "b 1f\n\t" + " nop\n\t" + "nop\n" + "2:\n\t" + "sta %0, [%%g0] %3\n\t" + "sta %1, [%2] %4\n" + "1:\n\t" : : + "r" (mreg), "r" (mxcc_creg), + "r" (MXCC_CREG), "i" (ASI_M_MMUREGS), + "i" (ASI_M_MXCC) : "g2"); + *mregp = mreg; + *mxcc_cregp = mxcc_creg; +} + +#endif /* !(_SPARC_VIKING_H) */ diff --git a/include/asm-sparc/vuid_event.h b/include/asm-sparc/vuid_event.h new file mode 100644 index 000000000..7781e9f2f --- /dev/null +++ b/include/asm-sparc/vuid_event.h @@ -0,0 +1,41 @@ +/* SunOS Virtual User Input Device (VUID) compatibility */ + + +typedef struct firm_event { + unsigned short id; /* tag for this event */ + unsigned char pair_type; /* unused by X11 */ + unsigned char pair; /* unused by X11 */ + int value; /* VKEY_UP, VKEY_DOWN or delta */ + struct timeval time; +} Firm_event; + +enum { + FE_PAIR_NONE, + FE_PAIR_SET, + FE_PAIR_DELTA, + FE_PAIR_ABSOLUTE +}; + +/* VUID stream formats */ +#define VUID_NATIVE 0 /* Native byte stream format */ +#define VUID_FIRM_EVENT 1 /* send firm_event structures */ + +/* ioctls */ + /* Set input device byte stream format (any of VUID_{NATIVE,FIRM_EVENT}) */ +#define VUIDSFORMAT _IOW('v', 1, int) + /* Retrieve input device byte stream format */ +#define VUIDGFORMAT _IOR('v', 2, int) + +/* Possible tag values */ +/* mouse buttons: */ +#define MS_LEFT 0x7f20 +#define MS_MIDDLE 0x7f21 +#define MS_RIGHT 0x7f22 +/* motion: */ +#define LOC_X_DELTA 0x7f80 +#define LOC_Y_DELTA 0x7f81 +#define LOC_X_ABSOLUTE 0x7f82 /* X compat, unsupported */ +#define LOC_Y_ABSOLUTE 0x7f83 /* X compat, unsupported */ + +#define VKEY_UP 0 +#define VKEY_DOWN 1 diff --git a/include/asm-sparc/wim.h b/include/asm-sparc/wim.h deleted file mode 100644 index 74b0a65a9..000000000 --- a/include/asm-sparc/wim.h +++ /dev/null @@ -1,56 +0,0 @@ -/* wim.h: Defines the layout of the "Window Invalid Register" on - Version 8 of the Sparc Architecture. - - Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) -*/ - -#ifndef __LINUX_SPARC_WIM_H -#define __LINUX_SPARC_WIM_H - -#ifdef __LINUX_SPARC_V8 /* register doesn't exist on the V9 */ - -/* The Window Invalid Register %wim, holds a set of which register - windows are 'valid' at this point in time. - - ------------------------------------------------------------ - |W31|W30|W29|W28|W27|W26|W25|W24|W23|....|W5|W4|W3|W2|W1|W0| - ------------------------------------------------------------ - - Each register window on the chip gets one bit. If the bit is - set then the window is currently 'invalid' and hardware will - trap if that window is entered via a 'save', 'restore', or - 'rett' instruction. Privileged software is responsible for - updating this on trap fills/spills etc. Therefore if a 'save' - instruction is executed and it causes the Current Window - Pointer to equal a register window which has its bit set in - %wim we get a 'overflow' trap, a restore into such a register - invokes a window 'spill' trap. -*/ - -#define __LINUX_SPARC_HAS_WIM - -/* Macro to fine the %wim bit mask for the current window pointer */ -#define CWP_TO_WIM_MASK(cwp) (1<<(cwp)) - -/* Assembly version of above macro, 'cwp' and 'wimask' must be registers */ -#define ASM_CWP_TO_WIM_MASK(cwp,wimask) \ - or %g0, 0x1, wimask \ - sll wimask, cwp, wimask - -/* Assembly macro to find if the given window is set to invalid in the %wim. - Again 'window', 'result', and 'scratch' must be in registers. This leaves - a non-zero value in result if the window is indeed invalid. This routine - works because we keep exactly one window invalid at all times to maximize - register utilization, which means both kernel and user windows can be in - the register file at the same time in certain trap situations. -*/ -#define ASM_REG_WIN_INVAL(window,result,scratch) \ - rd %wim, result \ - or %g0, 0x1, scratch \ - sll scratch, window, scratch \ - and scratch, result, result - -#endif /* !(__LINUX_SPARC_V8) */ - -#endif /* !(__LINUX_SPARC_WIM_H) */ - diff --git a/include/asm-sparc/winmacro.h b/include/asm-sparc/winmacro.h new file mode 100644 index 000000000..e0cc5d3c9 --- /dev/null +++ b/include/asm-sparc/winmacro.h @@ -0,0 +1,129 @@ +/* $Id: winmacro.h,v 1.17 1996/09/19 20:27:44 davem Exp $ + * winmacro.h: Window loading-unloading macros. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_WINMACRO_H +#define _SPARC_WINMACRO_H + +#include <asm/ptrace.h> +#include <asm/psr.h> + +/* These are just handy. */ +#define _SV save %sp, -REGWIN_SZ, %sp +#define _RS restore + +#define FLUSH_ALL_KERNEL_WINDOWS \ + _SV; _SV; _SV; _SV; _SV; _SV; _SV; \ + _RS; _RS; _RS; _RS; _RS; _RS; _RS; + +/* Store the register window onto the 8-byte aligned area starting + * at %reg. It might be %sp, it might not, we don't care. + */ +#define STORE_WINDOW(reg) \ + std %l0, [%reg + RW_L0]; \ + std %l2, [%reg + RW_L2]; \ + std %l4, [%reg + RW_L4]; \ + std %l6, [%reg + RW_L6]; \ + std %i0, [%reg + RW_I0]; \ + std %i2, [%reg + RW_I2]; \ + std %i4, [%reg + RW_I4]; \ + std %i6, [%reg + RW_I6]; + +/* Load a register window from the area beginning at %reg. */ +#define LOAD_WINDOW(reg) \ + ldd [%reg + RW_L0], %l0; \ + ldd [%reg + RW_L2], %l2; \ + ldd [%reg + RW_L4], %l4; \ + ldd [%reg + RW_L6], %l6; \ + ldd [%reg + RW_I0], %i0; \ + ldd [%reg + RW_I2], %i2; \ + ldd [%reg + RW_I4], %i4; \ + ldd [%reg + RW_I6], %i6; + +/* Loading and storing struct pt_reg trap frames. */ +#define LOAD_PT_INS(base_reg) \ + ldd [%base_reg + REGWIN_SZ + PT_I0], %i0; \ + ldd [%base_reg + REGWIN_SZ + PT_I2], %i2; \ + ldd [%base_reg + REGWIN_SZ + PT_I4], %i4; \ + ldd [%base_reg + REGWIN_SZ + PT_I6], %i6; + +#define LOAD_PT_GLOBALS(base_reg) \ + ld [%base_reg + REGWIN_SZ + PT_G1], %g1; \ + ldd [%base_reg + REGWIN_SZ + PT_G2], %g2; \ + ldd [%base_reg + REGWIN_SZ + PT_G4], %g4; \ + ldd [%base_reg + REGWIN_SZ + PT_G6], %g6; + +#define LOAD_PT_YREG(base_reg, scratch) \ + ld [%base_reg + REGWIN_SZ + PT_Y], %scratch; \ + wr %scratch, 0x0, %y; + +#define LOAD_PT_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ + ld [%base_reg + REGWIN_SZ + PT_PSR], %pt_psr; \ + ld [%base_reg + REGWIN_SZ + PT_PC], %pt_pc; \ + ld [%base_reg + REGWIN_SZ + PT_NPC], %pt_npc; + +#define LOAD_PT_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \ + LOAD_PT_YREG(base_reg, scratch) \ + LOAD_PT_INS(base_reg) \ + LOAD_PT_GLOBALS(base_reg) \ + LOAD_PT_PRIV(base_reg, pt_psr, pt_pc, pt_npc) + +#define STORE_PT_INS(base_reg) \ + std %i0, [%base_reg + REGWIN_SZ + PT_I0]; \ + std %i2, [%base_reg + REGWIN_SZ + PT_I2]; \ + std %i4, [%base_reg + REGWIN_SZ + PT_I4]; \ + std %i6, [%base_reg + REGWIN_SZ + PT_I6]; + +#define STORE_PT_GLOBALS(base_reg) \ + st %g1, [%base_reg + REGWIN_SZ + PT_G1]; \ + std %g2, [%base_reg + REGWIN_SZ + PT_G2]; \ + std %g4, [%base_reg + REGWIN_SZ + PT_G4]; \ + std %g6, [%base_reg + REGWIN_SZ + PT_G6]; + +#define STORE_PT_YREG(base_reg, scratch) \ + rd %y, %scratch; \ + st %scratch, [%base_reg + REGWIN_SZ + PT_Y]; + +#define STORE_PT_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ + st %pt_psr, [%base_reg + REGWIN_SZ + PT_PSR]; \ + st %pt_pc, [%base_reg + REGWIN_SZ + PT_PC]; \ + st %pt_npc, [%base_reg + REGWIN_SZ + PT_NPC]; + +#define STORE_PT_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \ + STORE_PT_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \ + STORE_PT_GLOBALS(base_reg) \ + STORE_PT_YREG(base_reg, g_scratch) \ + STORE_PT_INS(base_reg) + +#define SAVE_BOLIXED_USER_STACK(cur_reg, scratch) \ + ld [%cur_reg + THREAD_W_SAVED], %scratch; \ + sll %scratch, 2, %scratch; \ + add %scratch, %cur_reg, %scratch; \ + st %sp, [%scratch + THREAD_STACK_PTRS]; \ + sub %scratch, %cur_reg, %scratch; \ + sll %scratch, 4, %scratch; \ + add %scratch, %cur_reg, %scratch; \ + STORE_WINDOW(scratch + THREAD_REG_WINDOW); \ + sub %scratch, %cur_reg, %scratch; \ + srl %scratch, 6, %scratch; \ + add %scratch, 1, %scratch; \ + st %scratch, [%cur_reg + THREAD_W_SAVED]; + +#ifdef __SMP__ +#define LOAD_CURRENT(dest_reg, idreg) \ + rd %tbr, %idreg; \ + srl %idreg, 10, %idreg; \ + and %idreg, 0xc, %idreg; \ + sethi %hi(C_LABEL(current_set)), %dest_reg; \ + or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \ + add %dest_reg, %idreg, %idreg; \ + ld [%idreg], %dest_reg; +#else +#define LOAD_CURRENT(dest_reg, idreg) \ + sethi %hi(C_LABEL(current_set)), %idreg; \ + ld [%idreg + %lo(C_LABEL(current_set))], %dest_reg; +#endif + +#endif /* !(_SPARC_WINMACRO_H) */ diff --git a/include/linux/a.out.h b/include/linux/a.out.h index ce141e011..172664afa 100644 --- a/include/linux/a.out.h +++ b/include/linux/a.out.h @@ -5,17 +5,7 @@ #ifndef __STRUCT_EXEC_OVERRIDE__ -struct exec -{ - unsigned long a_info; /* Use macros N_MAGIC, etc for access */ - unsigned a_text; /* length of text, in bytes */ - unsigned a_data; /* length of data, in bytes */ - unsigned a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned a_syms; /* length of symbol table data in file, in bytes */ - unsigned a_entry; /* start address */ - unsigned a_trsize; /* length of relocation info for text, in bytes */ - unsigned a_drsize; /* length of relocation info for data, in bytes */ -}; +#include <asm/a.out.h> #endif /* __STRUCT_EXEC_OVERRIDE__ */ @@ -104,15 +94,15 @@ enum machine_type { #endif #if !defined (N_DRELOFF) -#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize) +#define N_DRELOFF(x) (N_TRELOFF(x) + N_TRSIZE(x)) #endif #if !defined (N_SYMOFF) -#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize) +#define N_SYMOFF(x) (N_DRELOFF(x) + N_DRSIZE(x)) #endif #if !defined (N_STROFF) -#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms) +#define N_STROFF(x) (N_SYMOFF(x) + N_SYMSIZE(x)) #endif /* Address of text segment in memory after it is loaded. */ @@ -139,7 +129,13 @@ enum machine_type { #ifdef linux #include <asm/page.h> +#if defined(__i386__) || defined(__mc68000__) #define SEGMENT_SIZE 1024 +#else +#ifndef SEGMENT_SIZE +#define SEGMENT_SIZE PAGE_SIZE +#endif +#endif #endif #define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1)) diff --git a/include/linux/acct.h b/include/linux/acct.h new file mode 100644 index 000000000..99fe14917 --- /dev/null +++ b/include/linux/acct.h @@ -0,0 +1,29 @@ +#ifndef __LINUX_ACCT_H +#define __LINUX_ACCT_H + +#define ACCT_COMM 16 + +struct acct +{ + char ac_comm[ACCT_COMM]; /* Accounting command name */ + time_t ac_utime; /* Accounting user time */ + time_t ac_stime; /* Accounting system time */ + time_t ac_etime; /* Accounting elapsed time */ + time_t ac_btime; /* Beginning time */ + uid_t ac_uid; /* Accounting user ID */ + gid_t ac_gid; /* Accounting group ID */ + dev_t ac_tty; /* controlling tty */ + char ac_flag; /* Accounting flag */ + long ac_minflt; /* Accounting minor pagefaults */ + long ac_majflt; /* Accounting major pagefaults */ + long ac_exitcode; /* Accounting process exitcode */ +}; + +#define AFORK 0001 /* has executed fork, but no exec */ +#define ASU 0002 /* used super-user privileges */ +#define ACORE 0004 /* dumped core */ +#define AXSIG 0010 /* killed by a signal */ + +#define AHZ 100 + +#endif diff --git a/include/linux/affs_fs.h b/include/linux/affs_fs.h new file mode 100644 index 000000000..0067552fc --- /dev/null +++ b/include/linux/affs_fs.h @@ -0,0 +1,112 @@ +#ifndef _AFFS_FS_H +#define _AFFS_FS_H +/* + * The affs filesystem constants/structures + */ + +#include <linux/types.h> + +#define AFFS_SUPER_MAGIC 0xadff + +/* Get the filesystem block size given an inode. */ +#define AFFS_I2BSIZE(inode) ((inode)->i_sb->s_blocksize) + +/* Get the filesystem hash table size given an inode. */ +#define AFFS_I2HSIZE(inode) ((inode)->i_sb->u.affs_sb.s_hashsize) + +/* Get the block number bits given an inode */ +#define AFFS_I2BITS(inode) ((inode)->i_sb->s_blocksize_bits) + +/* Get the fs type given an inode */ +#define AFFS_I2FSTYPE(inode) ((inode)->i_sb->u.affs_sb.s_flags & SF_INTL) + +struct DateStamp +{ + __u32 ds_Days; + __u32 ds_Minute; + __u32 ds_Tick; +}; + + +/* --- Prototypes ----------------------------------------------------------------------------- */ + +/* amigaffs.c */ + +extern int affs_get_key_entry(int bsize, void *data, int entry_pos); +extern int affs_find_next_hash_entry(int bsize, void *dir_data, int *hash_pos); +extern int affs_get_file_name(int bsize, void *fh_data, char **name); +extern unsigned int affs_checksum_block(int bsize, void *data, int *ptype, int *stype); +extern void affs_fix_checksum(int bsize, void *data, int cspos); +extern void secs_to_datestamp(int secs, struct DateStamp *ds); +extern int prot_to_mode(unsigned int prot); +extern unsigned int mode_to_prot(int mode); +extern int affs_fix_hash_pred(struct inode *startino, int startoffset, + int key, int newkey); +extern int affs_fix_link_pred(struct inode *startino, int key, int newkey); + +/* bitmap. c */ + +extern int affs_count_free_blocks(struct super_block *s); +extern int affs_count_free_bits(int blocksize, const char *data); +extern void affs_free_block(struct super_block *sb, int block); +extern int affs_new_header(struct inode *inode); +extern int affs_new_data(struct inode *inode); +extern void affs_make_zones(struct super_block *sb); + +/* namei.c */ + +extern int affs_hash_name(const char *name, int len, int intl, int hashsize); +extern int affs_lookup(struct inode *dir,const char *name, int len, + struct inode **result); +extern int affs_unlink(struct inode *dir, const char *name, int len); +extern int affs_create(struct inode *dir, const char *name, int len, int mode, + struct inode **result); +extern int affs_mkdir(struct inode *dir, const char *name, int len, int mode); +extern int affs_rmdir(struct inode *dir, const char *name, int len); +extern int affs_link(struct inode *oldinode, struct inode *dir, + const char *name, int len); +extern int affs_symlink(struct inode *dir, const char *name, int len, + const char *symname); +extern int affs_fixup(struct buffer_head *bh, struct inode *inode); +extern int affs_rename(struct inode *old_dir, const char *old_name, int old_len, + struct inode *new_dir, const char *new_name, int new_len, + int must_be_dir); + +/* inode.c */ + +extern struct buffer_head *affs_bread(kdev_t dev, int block, int size); +extern void affs_brelse(struct buffer_head *buf); +extern void affs_put_super(struct super_block *); +extern int affs_parent_ino(struct inode *dir); +extern struct super_block *affs_read_super(struct super_block *,void *, int); +extern void affs_statfs(struct super_block *, struct statfs *, int bufsiz); +extern void affs_read_inode(struct inode *); +extern void affs_write_inode(struct inode *); +extern int affs_notify_change(struct inode *inode, struct iattr *attr); +extern void affs_put_inode(struct inode *); +extern struct inode *affs_new_inode(const struct inode *dir); +extern int affs_add_entry(struct inode *dir, struct inode *link, struct inode *inode, + const char *name, int len, int type); + +/* file.c */ + +extern int affs_bmap(struct inode *inode, int block); +extern struct buffer_head *affs_getblock(struct inode *inode, int block); +extern void affs_truncate(struct inode *); +extern void affs_truncate_ofs(struct inode *); + +/* dir.c */ + +extern void affs_dir_truncate(struct inode *); + +/* jump tables */ + +extern struct inode_operations affs_file_inode_operations; +extern struct inode_operations affs_file_inode_operations_ofs; +extern struct inode_operations affs_dir_inode_operations; +extern struct inode_operations affs_symlink_inode_operations; +extern struct inode_operations affs_chrdev_inode_operations; +extern struct inode_operations affs_blkdev_inode_operations; + +extern int init_affs_fs(void); +#endif diff --git a/include/linux/affs_fs_i.h b/include/linux/affs_fs_i.h new file mode 100644 index 000000000..40b823909 --- /dev/null +++ b/include/linux/affs_fs_i.h @@ -0,0 +1,47 @@ +#ifndef _AFFS_FS_I +#define _AFFS_FS_I + +#include <linux/a.out.h> +#include <linux/time.h> + +#define AFFS_MAX_PREALLOC 16 /* MUST be a power of 2 */ +#define AFFS_KCSIZE 73 /* Allows for 1 extension block at 512 byte-blocks */ + +struct key_cache { + struct timeval kc_lru_time; /* Last time this cache was used */ + int kc_first; /* First cached key */ + int kc_last; /* Last cached key */ + int kc_this_key; /* Key of extension block this data block keys are from */ + int kc_this_seq; /* Sequence number of this extension block */ + int kc_next_key; /* Key of next extension block */ + int kc_keys[AFFS_KCSIZE]; /* Key cache */ +}; + +#define EC_SIZE (PAGE_SIZE - 4 * sizeof(struct key_cache) - 4) / 4 + +struct ext_cache { + struct key_cache kc[4]; /* The 4 key caches */ + __s32 ec[EC_SIZE]; /* Keys of assorted extension blocks */ + int max_ext; /* Index of last known extension block */ +}; + +/* + * affs fs inode data in memory + */ +struct affs_inode_info { + __u32 i_protect; /* unused attribute bits */ + __s32 i_parent; /* parent ino */ + __s32 i_original; /* if != 0, this is the key of the original */ + __s32 i_data[AFFS_MAX_PREALLOC]; /* preallocated blocks */ + struct ext_cache *i_ec; /* Cache gets allocated dynamically */ + int i_cache_users; /* Cache cannot be freed while > 0 */ + int i_lastblock; /* last allocated block */ + short i_pa_cnt; /* number of preallocated blocks */ + short i_pa_next; /* Index of next block in i_data[] */ + short i_pa_last; /* Index of next free slot in i_data[] */ + short i_zone; /* write zone */ + unsigned char i_hlink; /* This is a fake */ + unsigned char i_pad; +}; + +#endif diff --git a/include/linux/affs_fs_sb.h b/include/linux/affs_fs_sb.h new file mode 100644 index 000000000..0ff862d13 --- /dev/null +++ b/include/linux/affs_fs_sb.h @@ -0,0 +1,72 @@ +#ifndef _AFFS_FS_SB +#define _AFFS_FS_SB + +/* + * super-block data in memory + * + * Block numbers are adjusted for their actual size + * + */ + +#define MAX_ZONES 8 +#define AFFS_DATA_MIN_FREE 512 /* Number of free blocks in zone for data blocks */ +#define AFFS_HDR_MIN_FREE 128 /* Same for header blocks */ +#define AFFS_ZONE_SIZE 1024 /* Blocks per alloc zone, must be multiple of 32 */ + +struct affs_bm_info { + struct buffer_head *bm_bh; /* Buffer head if loaded (bm_count > 0) */ + int bm_firstblk; /* Block number of first bit in this map */ + int bm_key; /* Disk block number */ + int bm_count; /* Usage counter */ +}; + +struct affs_alloc_zone { + short az_size; /* Size of this allocation zone in double words */ + short az_count; /* Number of users */ + int az_free; /* Free blocks in here (no. of bits) */ +}; + +struct affs_zone { + unsigned long z_ino; /* Associated inode number */ + struct affs_bm_info *z_bm; /* Zone lies in this bitmap */ + int z_start; /* Index of first word in bitmap */ + int z_end; /* Index of last word in zone + 1 */ + int z_az_no; /* Zone number */ + unsigned long z_lru_time; /* Time of last usage */ +}; + +struct affs_sb_info { + int s_partition_size; /* Partition size in blocks. */ + int s_root_block; /* FFS root block number. */ + int s_hashsize; /* Size of hash table. */ + unsigned long s_flags; /* See below. */ + short s_uid; /* uid to override */ + short s_gid; /* gid to override */ + umode_t s_mode; /* mode to override */ + int s_reserved; /* Number of reserved blocks. */ + struct buffer_head *s_root_bh; /* Cached root block. */ + struct affs_bm_info *s_bitmap; /* Bitmap infos. */ + int s_bm_count; /* Number of bitmap blocks. */ + int s_nextzone; /* Next zone to look for free blocks. */ + int s_num_az; /* Total number of alloc zones. */ + struct affs_zone *s_zones; /* The zones themselves. */ + struct affs_alloc_zone *s_alloc;/* The allocation zones. */ + char *s_zonemap; /* Bitmap for allocation zones. */ + char *s_prefix; /* Prefix for volumes and assigns. */ + int s_prefix_len; /* Length of prefix. */ + char s_volume[32]; /* Volume prefix for absolute symlinks. */ +}; + +#define SF_INTL 0x0001 /* International filesystem. */ +#define SF_BM_VALID 0x0002 /* Bitmap is valid. */ +#define SF_IMMUTABLE 0x0004 /* Protection bits cannot be changed */ +#define SF_QUIET 0x0008 /* chmod errors will be not reported */ +#define SF_SETUID 0x0010 /* Ignore Amiga uid */ +#define SF_SETGID 0x0020 /* Ignore Amiga gid */ +#define SF_SETMODE 0x0040 /* Ignore Amiga protection bits */ +#define SF_MUFS 0x0100 /* Use MUFS uid/gid mapping */ +#define SF_OFS 0x0200 /* Old filesystem */ +#define SF_PREFIX 0x0400 /* Buffer for prefix is allocated */ +#define SF_VERBOSE 0x0800 /* Talk about fs when mounting */ + +#endif diff --git a/include/linux/affs_hardblocks.h b/include/linux/affs_hardblocks.h new file mode 100644 index 000000000..33315488d --- /dev/null +++ b/include/linux/affs_hardblocks.h @@ -0,0 +1,66 @@ +#ifndef AFFS_HARDBLOCKS_H +#define AFFS_HARDBLOCKS_H + +/* Just the needed definitions for the RDB of an Amiga HD. */ + +struct RigidDiskBlock { + __u32 rdb_ID; + __u32 rdb_SummedLongs; + __s32 rdb_ChkSum; + __u32 rdb_HostID; + __u32 rdb_BlockBytes; + __u32 rdb_Flags; + __u32 rdb_BadBlockList; + __u32 rdb_PartitionList; + __u32 rdb_FileSysHeaderList; + __u32 rdb_DriveInit; + __u32 rdb_Reserved1[6]; + __u32 rdb_Cylinders; + __u32 rdb_Sectors; + __u32 rdb_Heads; + __u32 rdb_Interleave; + __u32 rdb_Park; + __u32 rdb_Reserved2[3]; + __u32 rdb_WritePreComp; + __u32 rdb_ReducedWrite; + __u32 rdb_StepRate; + __u32 rdb_Reserved3[5]; + __u32 rdb_RDBBlocksLo; + __u32 rdb_RDBBlocksHi; + __u32 rdb_LoCylinder; + __u32 rdb_HiCylinder; + __u32 rdb_CylBlocks; + __u32 rdb_AutoParkSeconds; + __u32 rdb_HighRDSKBlock; + __u32 rdb_Reserved4; + char rdb_DiskVendor[8]; + char rdb_DiskProduct[16]; + char rdb_DiskRevision[4]; + char rdb_ControllerVendor[8]; + char rdb_ControllerProduct[16]; + char rdb_ControllerRevision[4]; + __u32 rdb_Reserved5[10]; +}; + +#define IDNAME_RIGIDDISK 0x5244534B /* "RDSK" */ + +struct PartitionBlock { + __u32 pb_ID; + __u32 pb_SummedLongs; + __s32 pb_ChkSum; + __u32 pb_HostID; + __u32 pb_Next; + __u32 pb_Flags; + __u32 pb_Reserved1[2]; + __u32 pb_DevFlags; + __u8 pb_DriveName[32]; + __u32 pb_Reserved2[15]; + __u32 pb_Environment[17]; + __u32 pb_EReserved[15]; +}; + +#define IDNAME_PARTITION 0x50415254 /* "PART" */ + +#define RDB_ALLOCATION_LIMIT 16 + +#endif /* AFFS_HARDBLOCKS_H */ diff --git a/include/linux/amigaffs.h b/include/linux/amigaffs.h new file mode 100644 index 000000000..679f333e5 --- /dev/null +++ b/include/linux/amigaffs.h @@ -0,0 +1,219 @@ +#ifndef AMIGAFFS_H +#define AMIGAFFS_H + +#include <asm/byteorder.h> +#include <linux/types.h> + +/* Ugly macros make the code more pretty. */ + +#define GET_END_PTR(st,p,sz) ((st *)((char *)(p)+((sz)-sizeof(st)))) +#define AFFS_GET_HASHENTRY(data,hashkey) htonl(((struct dir_front *)data)->hashtable[hashkey]) +#define AFFS_BLOCK(data,ino,blk) ((struct file_front *)data)->blocks[AFFS_I2HSIZE(ino)-1-(blk)] + +#define FILE_END(p,i) GET_END_PTR(struct file_end,p,AFFS_I2BSIZE(i)) +#define ROOT_END(p,i) GET_END_PTR(struct root_end,p,AFFS_I2BSIZE(i)) +#define DIR_END(p,i) GET_END_PTR(struct dir_end,p,AFFS_I2BSIZE(i)) +#define LINK_END(p,i) GET_END_PTR(struct hlink_end,p,AFFS_I2BSIZE(i)) +#define ROOT_END_S(p,s) GET_END_PTR(struct root_end,p,(s)->s_blocksize) +#define DATA_FRONT(bh) ((struct data_front *)(bh)->b_data) + +/* Only for easier debugging if need be */ +#define affs_bread bread +#define affs_brelse brelse + +#ifdef __LITTLE_ENDIAN +#define BO_EXBITS 0x18UL +#elif defined(__BIG_ENDIAN) +#define BO_EXBITS 0x00UL +#else +#error Endianness must be known for affs to work. +#endif + +#define FS_OFS 0x444F5300 +#define FS_FFS 0x444F5301 +#define FS_INTLOFS 0x444F5302 +#define FS_INTLFFS 0x444F5303 +#define FS_DCOFS 0x444F5304 +#define FS_DCFFS 0x444F5305 +#define MUFS_FS 0x6d754653 /* 'muFS' */ +#define MUFS_OFS 0x6d754600 /* 'muF\0' */ +#define MUFS_FFS 0x6d754601 /* 'muF\1' */ +#define MUFS_INTLOFS 0x6d754602 /* 'muF\2' */ +#define MUFS_INTLFFS 0x6d754603 /* 'muF\3' */ +#define MUFS_DCOFS 0x6d754604 /* 'muF\4' */ +#define MUFS_DCFFS 0x6d754605 /* 'muF\5' */ + +#define T_SHORT 2 +#define T_LIST 16 +#define T_DATA 8 + +#define ST_LINKFILE -4 +#define ST_FILE -3 +#define ST_ROOT 1 +#define ST_USERDIR 2 +#define ST_SOFTLINK 3 +#define ST_LINKDIR 4 + +struct root_front +{ + __s32 primary_type; + __s32 spare1[2]; + __s32 hash_size; + __s32 spare2; + __u32 checksum; + __s32 hashtable[0]; +}; + +struct root_end +{ + __s32 bm_flag; + __s32 bm_keys[25]; + __s32 bm_extend; + struct DateStamp dir_altered; + __u8 disk_name[40]; + struct DateStamp disk_altered; + struct DateStamp disk_made; + __s32 spare1[3]; + __s32 secondary_type; +}; + +struct dir_front +{ + __s32 primary_type; + __s32 own_key; + __s32 spare1[3]; + __u32 checksum; + __s32 hashtable[0]; +}; + +struct dir_end +{ + __s32 spare1; + __s16 owner_uid; + __s16 owner_gid; + __u32 protect; + __s32 spare2; + __u8 comment[92]; + struct DateStamp created; + __u8 dir_name[32]; + __s32 spare3[2]; + __s32 link_chain; + __s32 spare4[5]; + __s32 hash_chain; + __s32 parent; + __s32 spare5; + __s32 secondary_type; +}; + +struct file_front +{ + __s32 primary_type; + __s32 own_key; + __s32 block_count; + __s32 unknown1; + __s32 first_data; + __u32 checksum; + __s32 blocks[0]; +}; + +struct file_end +{ + __s32 spare1; + __s16 owner_uid; + __s16 owner_gid; + __u32 protect; + __s32 byte_size; + __u8 comment[92]; + struct DateStamp created; + __u8 file_name[32]; + __s32 spare2; + __s32 original; /* not really in file_end */ + __s32 link_chain; + __s32 spare3[5]; + __s32 hash_chain; + __s32 parent; + __s32 extension; + __s32 secondary_type; +}; + +struct hlink_front +{ + __s32 primary_type; + __s32 own_key; + __s32 spare1[3]; + __u32 checksum; +}; + +struct hlink_end +{ + __s32 spare1; + __s16 owner_uid; + __s16 owner_gid; + __u32 protect; + __u8 comment[92]; + struct DateStamp created; + __u8 link_name[32]; + __s32 spare2; + __s32 original; + __s32 link_chain; + __s32 spare3[5]; + __s32 hash_chain; + __s32 parent; + __s32 spare4; + __s32 secondary_type; +}; + +struct slink_front +{ + __s32 primary_type; + __s32 own_key; + __s32 spare1[3]; + __s32 checksum; + __u8 symname[288]; /* depends on block size */ +}; + +struct data_front +{ + __s32 primary_type; + __s32 header_key; + __s32 sequence_number; + __s32 data_size; + __s32 next_data; + __s32 checksum; + __u8 data[488]; /* depends on block size */ +}; + +/* Permission bits */ + +#define FIBF_OTR_READ 0x8000 +#define FIBF_OTR_WRITE 0x4000 +#define FIBF_OTR_EXECUTE 0x2000 +#define FIBF_OTR_DELETE 0x1000 +#define FIBF_GRP_READ 0x0800 +#define FIBF_GRP_WRITE 0x0400 +#define FIBF_GRP_EXECUTE 0x0200 +#define FIBF_GRP_DELETE 0x0100 + +#define FIBF_SCRIPT 0x0040 +#define FIBF_PURE 0x0020 /* no use under linux */ +#define FIBF_ARCHIVE 0x0010 /* never set, always cleared on write */ +#define FIBF_READ 0x0008 /* 0 means allowed */ +#define FIBF_WRITE 0x0004 /* 0 means allowed */ +#define FIBF_EXECUTE 0x0002 /* 0 means allowed, ignored under linux */ +#define FIBF_DELETE 0x0001 /* 0 means allowed */ + +#define FIBF_OWNER 0x000F /* Bits pertaining to owner */ + +#define AFFS_UMAYWRITE(prot) (((prot) & (FIBF_WRITE|FIBF_DELETE)) == (FIBF_WRITE|FIBF_DELETE)) +#define AFFS_UMAYREAD(prot) ((prot) & FIBF_READ) +#define AFFS_UMAYEXECUTE(prot) (((prot) & (FIBF_SCRIPT|FIBF_READ)) == (FIBF_SCRIPT|FIBF_READ)) +#define AFFS_GMAYWRITE(prot) (((prot)&(FIBF_GRP_WRITE|FIBF_GRP_DELETE))==\ + (FIBF_GRP_WRITE|FIBF_GRP_DELETE)) +#define AFFS_GMAYREAD(prot) ((prot) & FIBF_GRP_READ) +#define AFFS_GMAYEXECUTE(prot) (((prot)&(FIBF_SCRIPT|FIBF_GRP_READ))==(FIBF_SCRIPT|FIBF_GRP_READ)) +#define AFFS_OMAYWRITE(prot) (((prot)&(FIBF_OTR_WRITE|FIBF_OTR_DELETE))==\ + (FIBF_OTR_WRITE|FIBF_OTR_DELETE)) +#define AFFS_OMAYREAD(prot) ((prot) & FIBF_OTR_READ) +#define AFFS_OMAYEXECUTE(prot) (((prot)&(FIBF_SCRIPT|FIBF_OTR_READ))==(FIBF_SCRIPT|FIBF_OTR_READ)) + +#endif diff --git a/include/linux/apm_bios.h b/include/linux/apm_bios.h new file mode 100644 index 000000000..326445110 --- /dev/null +++ b/include/linux/apm_bios.h @@ -0,0 +1,141 @@ +#ifndef _LINUX_APM_H +#define _LINUX_APM_H + +/* + * Include file for the interface to an APM BIOS + * Copyright 1994, 1995 Stephen Rothwell (Stephen.Rothwell@pd.necisa.oz.au) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * $Id: apm_bios.h,v 0.9 1995/03/09 13:50:05 sfr Exp $ + */ + +typedef unsigned short apm_event_t; + +#ifdef __KERNEL__ + +#include <linux/tasks.h> /* for NR_TASKS */ +#include <linux/sched.h> /* for _TSS */ + +#define APM_CS _TSS(NR_TASKS) +#define APM_CS_16 (APM_CS + 8) +#define APM_DS (APM_CS_16 + 8) + +struct apm_bios_info { + unsigned short version; + unsigned short cseg; + unsigned long offset; + unsigned short cseg_16; + unsigned short dseg; + unsigned short flags; + unsigned short cseg_len; + unsigned short dseg_len; +}; + + /* Results of APM Installation Check */ +#define APM_16_BIT_SUPPORT 0x0001 +#define APM_32_BIT_SUPPORT 0x0002 +#define APM_IDLE_SLOWS_CLOCK 0x0004 +#define APM_BIOS_DISABLED 0x0008 +#define APM_BIOS_DISENGAGED 0x0010 + +/* + * Maximum number of events stored + */ +#define APM_MAX_EVENTS 20 + +/* + * The per-file APM data + */ +struct apm_bios_struct { + int magic; + struct apm_bios_struct * next; + int suser; + int suspends_pending; + int standbys_pending; + int suspends_read; + int standbys_read; + int event_head; + int event_tail; + apm_event_t events[APM_MAX_EVENTS]; +}; + +/* + * The magic number in apm_bios_struct + */ +#define APM_BIOS_MAGIC 0x4101 + +/* + * in init/main.c + */ +extern struct apm_bios_info apm_bios_info; + +extern void apm_bios_init(void); + +extern int apm_register_callback(int (*callback)(apm_event_t)); +extern void apm_unregister_callback(int (*callback)(apm_event_t)); + +extern int apm_set_power_state(ushort state); +extern int apm_display_blank(void); +extern int apm_display_unblank(void); + +#endif /* __KERNEL__ */ + +/* + * Power states + */ +#define APM_STATE_READY 0x0000 +#define APM_STATE_STANDBY 0x0001 +#define APM_STATE_SUSPEND 0x0002 +#define APM_STATE_OFF 0x0003 +#define APM_STATE_BUSY 0x0004 +#define APM_STATE_REJECT 0x0005 + +/* + * Events (results of Get PM Event) + */ +#define APM_SYS_STANDBY 0x0001 +#define APM_SYS_SUSPEND 0x0002 +#define APM_NORMAL_RESUME 0x0003 +#define APM_CRITICAL_RESUME 0x0004 +#define APM_LOW_BATTERY 0x0005 +#define APM_POWER_STATUS_CHANGE 0x0006 +#define APM_UPDATE_TIME 0x0007 +#define APM_CRITICAL_SUSPEND 0x0008 +#define APM_USER_STANDBY 0x0009 +#define APM_USER_SUSPEND 0x000a +#define APM_STANDBY_RESUME 0x000b + +/* + * Error codes + */ +#define APM_SUCCESS 0x00 +#define APM_DISABLED 0x01 +#define APM_CONNECTED 0x02 +#define APM_NOT_CONNECTED 0x03 +#define APM_16_CONNECTED 0x05 +#define APM_16_UNSUPPORTED 0x06 +#define APM_32_CONNECTED 0x07 +#define APM_32_UNSUPPORTED 0x08 +#define APM_BAD_DEVICE 0x09 +#define APM_BAD_PARAM 0x0a +#define APM_NOT_ENGAGED 0x0b +#define APM_BAD_STATE 0x60 +#define APM_NO_EVENTS 0x80 +#define APM_NOT_PRESENT 0x86 + +/* ioctl operations */ +#include <linux/ioctl.h> + +#define APM_IOC_STANDBY _IO('A', 1) +#define APM_IOC_SUSPEND _IO('A', 2) + +#endif /* LINUX_APM_H */ diff --git a/include/net/atalk.h b/include/linux/atalk.h index 08760cdac..9035ddbd8 100644 --- a/include/net/atalk.h +++ b/include/linux/atalk.h @@ -25,7 +25,7 @@ struct at_addr struct sockaddr_at { - short sat_family; + sa_family_t sat_family; __u8 sat_port; struct at_addr sat_addr; char sat_zero[ 8 ]; @@ -94,9 +94,9 @@ struct ddpehdr struct ddpshdr { /* FIXME for bigendians */ - __u8 dsh_sport; - __u8 dsh_dport; __u16 dsh_len:10, dsh_pad:6; + __u8 dsh_dport; + __u8 dsh_sport; /* And netatalk apps expect to stick the type in themselves */ }; @@ -140,5 +140,9 @@ extern struct atalk_iface *atalk_find_dev(struct device *dev); extern struct at_addr *atalk_find_dev_addr(struct device *dev); extern int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr); extern void aarp_send_probe(struct device *dev, struct at_addr *addr); +#ifdef MODULE +extern void aarp_cleanup_module(void); +#endif + #endif #endif diff --git a/include/linux/ax25.h b/include/linux/ax25.h index f6bce2787..7cf2c6410 100644 --- a/include/linux/ax25.h +++ b/include/linux/ax25.h @@ -1,16 +1,47 @@ +/* + * These are the public elements of the Linux kernel AX.25 code. A similar + * file netrom.h exists for the NET/ROM protocol. + */ + +#ifndef AX25_KERNEL_H +#define AX25_KERNEL_H + #define PF_AX25 AF_AX25 #define AX25_MTU 256 -#define AX25_MAX_DIGIS 8 +#define AX25_MAX_DIGIS 6 /* This is wrong, should be 8 */ -typedef struct -{ +#define AX25_WINDOW 1 +#define AX25_T1 2 +#define AX25_N2 3 +#define AX25_T3 4 +#define AX25_T2 5 +#define AX25_BACKOFF 6 +#define AX25_EXTSEQ 7 +#define AX25_HDRINCL 8 +#define AX25_IDLE 9 +#define AX25_PACLEN 10 +#define AX25_MAXQUEUE 11 + +#define AX25_KILL 99 + +#define SIOCAX25GETUID (SIOCPROTOPRIVATE+0) +#define SIOCAX25ADDUID (SIOCPROTOPRIVATE+1) +#define SIOCAX25DELUID (SIOCPROTOPRIVATE+2) +#define SIOCAX25NOUID (SIOCPROTOPRIVATE+3) +#define SIOCAX25OPTRT (SIOCPROTOPRIVATE+4) +#define SIOCAX25CTLCON (SIOCPROTOPRIVATE+5) + +#define AX25_SET_RT_IPMODE 2 + +#define AX25_NOUID_DEFAULT 0 +#define AX25_NOUID_BLOCK 1 + +typedef struct { char ax25_call[7]; /* 6 call + SSID (shifted ascii!) */ -} -ax25_address; +} ax25_address; -struct sockaddr_ax25 -{ - short sax25_family; +struct sockaddr_ax25 { + sa_family_t sax25_family; ax25_address sax25_call; int sax25_ndigis; /* Digipeater ax25_address sets follow */ @@ -18,22 +49,31 @@ struct sockaddr_ax25 #define sax25_uid sax25_ndigis -struct full_sockaddr_ax25 -{ +struct full_sockaddr_ax25 { struct sockaddr_ax25 fsa_ax25; ax25_address fsa_digipeater[AX25_MAX_DIGIS]; }; -#define AX25_WINDOW 1 -#define AX25_T1 2 -#define AX25_N2 3 -#define AX25_T3 4 -#define AX25_T2 5 +struct ax25_routes_struct { + ax25_address port_addr; + ax25_address dest_addr; + unsigned char digi_count; + ax25_address digi_addr[AX25_MAX_DIGIS]; +}; -#define SIOCAX25GETUID (SIOCPROTOPRIVATE) -#define SIOCAX25ADDUID (SIOCPROTOPRIVATE+1) -#define SIOCAX25DELUID (SIOCPROTOPRIVATE+2) -#define SIOCAX25NOUID (SIOCPROTOPRIVATE+3) +struct ax25_route_opt_struct { + ax25_address port_addr; + ax25_address dest_addr; + int cmd; + int arg; +}; -#define AX25_NOUID_DEFAULT 0 -#define AX25_NOUID_BLOCK 1 +struct ax25_ctl_struct { + ax25_address port_addr; + ax25_address source_addr; + ax25_address dest_addr; + unsigned int cmd; + unsigned long arg; +}; + +#endif diff --git a/include/linux/aztcd.h b/include/linux/aztcd.h index b85f37ee8..71fe5a0df 100644 --- a/include/linux/aztcd.h +++ b/include/linux/aztcd.h @@ -1,4 +1,5 @@ -/* $Id: aztcd.h,v 1.0 1995/03/25 08:27:19 root Exp $ +/* $Id: aztcd.h,v 2.50 1996/05/17 16:15:43 root Exp root $ + * * Definitions for a AztechCD268 CD-ROM interface * Copyright (C) 1994, 1995 Werner Zimmermann * @@ -22,14 +23,41 @@ * October 1994 Email: zimmerma@rz.fht-esslingen.de */ -/* *** change this to set the I/O port address */ +/* *** change this to set the I/O port address of your CD-ROM drive*/ #define AZT_BASE_ADDR 0x320 -/* Comment this out to prevent tray from locking */ +/* Uncomment this, if your CDROM is connected to a Soundwave32-soundcard + and configure AZT_BASE_ADDR and AZT_SW32_BASE_ADDR */ +/*#define AZT_SW32 1 +*/ + +#ifdef AZT_SW32 +#define AZT_SW32_BASE_ADDR 0x220 /*I/O port base address of your soundcard*/ +#endif + +/* Set this to 1, if you want your tray to be locked, set to 0 to prevent tray + from locking */ #define AZT_ALLOW_TRAY_LOCK 1 -/* use incompatible ioctls for reading in raw and cooked mode */ -#define AZT_PRIVATE_IOCTLS +/*Set this to 1 to allow auto-eject when unmounting a disk, set to 0, if you + don't want the auto-eject feature*/ +#define AZT_AUTO_EJECT 0 + +/*Set this to 1, if you want to use incompatible ioctls for reading in raw and + cooked mode */ +#define AZT_PRIVATE_IOCTLS 1 + +/*Set this to 1, if you want multisession support by the ISO fs. Even if you set + this value to '0' you can use multisession CDs. In that case the drive's firm- + ware will do the appropriate redirection automatically. The CD will then look + like a single session CD (but nevertheless all data may be read). Please read + chapter '5.1 Multisession support' in README.aztcd for details. Normally it's + uncritical to leave this setting untouched */ +#define AZT_MULTISESSION 1 + +/*---------------------------------------------------------------------------*/ +/*-----nothing to be configured for normal applications below this line------*/ + /* Increase this if you get lots of timeouts; if you get kernel panic, replace STEN_LOW_WAIT by STEN_LOW in the source code */ @@ -45,12 +73,18 @@ #define DATA_PORT azt_port #define STATUS_PORT azt_port+1 #define MODE_PORT azt_port+2 +#ifdef AZT_SW32 + #define AZT_SW32_INIT (unsigned int) (0xFF00 & (AZT_BASE_ADDR*16)) + #define AZT_SW32_CONFIG_REG AZT_SW32_BASE_ADDR+0x16 /*Soundwave32 Config. Register*/ + #define AZT_SW32_ID_REG AZT_SW32_BASE_ADDR+0x04 /*Soundwave32 ID Version Register*/ +#endif /* status bits */ -#define AST_CMD_CHECK 0x80 /* command error */ -#define AST_DSK_CHG 0x20 /* disk removed or changed */ -#define AST_NOT_READY 0x02 /* no disk in the drive */ -#define AST_DOOR_OPEN 0x40 /* door is open */ +#define AST_CMD_CHECK 0x80 /* 1 = command error */ +#define AST_DOOR_OPEN 0x40 /* 1 = door is open */ +#define AST_NOT_READY 0x20 /* 1 = no disk in the drive */ +#define AST_DSK_CHG 0x02 /* 1 = disk removed or changed */ +#define AST_MODE 0x01 /* 0=MODE1, 1=MODE2 */ #define AST_MODE_BITS 0x1C /* Mode Bits */ #define AST_INITIAL 0x0C /* initial, only valid ... */ #define AST_BUSY 0x04 /* now playing, only valid @@ -68,7 +102,8 @@ /* commands */ #define ACMD_SOFT_RESET 0x10 /* reset drive */ #define ACMD_PLAY_READ 0x20 /* read data track in cooked mode */ -#define ACMD_DATA_READ_RAW 0x21 /* reading in raw mode*/ +#define ACMD_PLAY_READ_RAW 0x21 /* reading in raw mode*/ +#define ACMD_SEEK 0x30 /* seek msf address*/ #define ACMD_SEEK_TO_LEADIN 0x31 /* seek to leadin track*/ #define ACMD_GET_ERROR 0x40 /* get error code */ #define ACMD_GET_STATUS 0x41 /* get status */ @@ -82,14 +117,7 @@ #define ACMD_PLAY_AUDIO 0x90 /* play audio track */ #define ACMD_SET_VOLUME 0x93 /* set audio level */ #define ACMD_GET_VERSION 0xA0 /* get firmware version */ -#define ACMD_SET_MODE 0xA1 /* set drive mode */ - -#define SET_TIMER(func, jifs) \ - delay_timer.expires = jifs; \ - delay_timer.function = (void *) func; \ - add_timer(&delay_timer); - -#define CLEAR_TIMER del_timer(&delay_timer) +#define ACMD_SET_DISK_TYPE 0xA1 /* set disk data mode */ #define MAX_TRACKS 104 @@ -106,9 +134,15 @@ struct azt_Play_msf { struct azt_DiskInfo { unsigned char first; + unsigned char next; unsigned char last; struct msf diskLength; struct msf firstTrack; + unsigned char multi; + struct msf nextSession; + struct msf lastSession; + unsigned char xa; + unsigned char audio; }; struct azt_Toc { diff --git a/include/linux/baycom.h b/include/linux/baycom.h new file mode 100644 index 000000000..b4108d1df --- /dev/null +++ b/include/linux/baycom.h @@ -0,0 +1,62 @@ +/* + * The Linux BAYCOM driver for the Baycom serial 1200 baud modem + * and the parallel 9600 baud modem + * (C) 1996 by Thomas Sailer, HB9JNX + */ + +#ifndef _BAYCOM_H +#define _BAYCOM_H + +#include <linux/sockios.h> +#include <linux/if_ether.h> + +/* -------------------------------------------------------------------- */ +/* + * structs for the IOCTL commands + */ + +struct baycom_debug_data { + unsigned long debug1; + unsigned long debug2; + long debug3; +}; + +struct baycom_modem_type { + unsigned char modem_type; + unsigned int options; +}; + +struct baycom_ioctl { + int cmd; + union { + struct baycom_modem_type mt; + struct baycom_debug_data dbg; + } data; +}; + +/* -------------------------------------------------------------------- */ + +/* + * modem types + */ +#define BAYCOM_MODEM_INVALID 0 +#define BAYCOM_MODEM_SER12 1 +#define BAYCOM_MODEM_PAR96 2 + +/* + * modem options; bit mask + */ +#define BAYCOM_OPTIONS_SOFTDCD 1 + +/* + * ioctl values change for baycom_net + */ +#define BAYCOMCTL_GETMODEMTYPE 0x90 +#define BAYCOMCTL_SETMODEMTYPE 0x91 +#define BAYCOMCTL_GETDEBUG 0x92 + +/* -------------------------------------------------------------------- */ + +#endif /* _BAYCOM_H */ + +/* --------------------------------------------------------------------- */ diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 832bde64c..6c424fbe9 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -6,7 +6,7 @@ /* * MAX_ARG_PAGES defines the number of pages allocated for arguments * and envelope for the new program. 32 should suffice, this gives - * a maximum env+arg of 128kB ! + * a maximum env+arg of 128kB w/4KB pages! */ #define MAX_ARG_PAGES 32 @@ -18,10 +18,13 @@ struct linux_binprm{ unsigned long page[MAX_ARG_PAGES]; unsigned long p; int sh_bang; + int java; /* Java binary, prevent recursive invocation */ struct inode * inode; int e_uid, e_gid; int argc, envc; - char * filename; /* Name of binary */ + char * filename; /* Name of binary */ + unsigned long loader, exec; + int dont_iput; /* binfmt handler has put inode */ }; /* @@ -30,7 +33,7 @@ struct linux_binprm{ */ struct linux_binfmt { struct linux_binfmt * next; - int *use_count; + long *use_count; int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); int (*load_shlib)(int fd); int (*core_dump)(long signr, struct pt_regs * regs); @@ -40,13 +43,20 @@ extern int register_binfmt(struct linux_binfmt *); extern int unregister_binfmt(struct linux_binfmt *); extern int read_exec(struct inode *inode, unsigned long offset, - char * addr, unsigned long count); + char * addr, unsigned long count, int to_kmem); extern int open_inode(struct inode * inode, int mode); +extern int init_elf_binfmt(void); +extern int init_aout_binfmt(void); +extern int init_script_binfmt(void); +extern int init_java_binfmt(void); + +extern int prepare_binprm(struct linux_binprm *); +extern void remove_arg_zero(struct linux_binprm *); +extern int search_binary_handler(struct linux_binprm *,struct pt_regs *); extern void flush_old_exec(struct linux_binprm * bprm); -extern unsigned long setup_arg_pages(unsigned long text_size,unsigned long * page); -extern unsigned long * create_tables(char * p,int argc,int envc,int ibcs); +extern unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm); extern unsigned long copy_strings(int argc,char ** argv,unsigned long *page, unsigned long p, int from_kmem); diff --git a/include/linux/bios32.h b/include/linux/bios32.h index ee8f862ea..d3632092a 100644 --- a/include/linux/bios32.h +++ b/include/linux/bios32.h @@ -9,11 +9,11 @@ * PCI System Design Guide * * PCI Special Interest Group - * M/S HF3-15A - * 5200 N.E. Elam Young Parkway - * Hillsboro, Oregon 97124-6497 - * +1 (503) 696-2000 - * +1 (800) 433-5177 + * P.O. Box 14070 + * Portland, OR 97214 + * U. S. A. + * Phone: 800-433-5177 / +1-503-797-4207 + * Fax: +1-503-234-6762 * * Manuals are $25 each or $50 for all three, plus $7 shipping * within the United States, $35 abroad. @@ -24,7 +24,7 @@ /* * Error values that may be returned by the PCI bios. Use - * pci_strbioserr() to convert to a printable string. + * pcibios_strerror() to convert to a printable string. */ #define PCIBIOS_SUCCESSFUL 0x00 #define PCIBIOS_FUNC_NOT_SUPPORTED 0x81 @@ -56,5 +56,6 @@ extern int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn, unsigned char where, unsigned short val); extern pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn, unsigned char where, unsigned int val); -extern char *pcibios_strerror (int error); +extern const char *pcibios_strerror (int error); + #endif /* BIOS32_H */ diff --git a/include/linux/blk.h b/include/linux/blk.h new file mode 100644 index 000000000..cd8eb09b3 --- /dev/null +++ b/include/linux/blk.h @@ -0,0 +1,432 @@ +#ifndef _BLK_H +#define _BLK_H + +#include <linux/blkdev.h> +#include <linux/locks.h> +#include <linux/config.h> + +/* + * NR_REQUEST is the number of entries in the request-queue. + * NOTE that writes may use only the low 2/3 of these: reads + * take precedence. + */ +#define NR_REQUEST 64 + +/* + * This is used in the elevator algorithm. We don't prioritise reads + * over writes any more --- although reads are more time-critical than + * writes, by treating them equally we increase filesystem throughput. + * This turns out to give better overall performance. -- sct + */ +#define IN_ORDER(s1,s2) \ +((s1)->rq_dev < (s2)->rq_dev || (((s1)->rq_dev == (s2)->rq_dev && \ +(s1)->sector < (s2)->sector))) + +/* + * These will have to be changed to be aware of different buffer + * sizes etc.. It actually needs a major cleanup. + */ +#if defined(IDE_DRIVER) || defined(MD_DRIVER) +#define SECTOR_MASK ((BLOCK_SIZE >> 9) - 1) +#else +#define SECTOR_MASK (blksize_size[MAJOR_NR] && \ + blksize_size[MAJOR_NR][MINOR(CURRENT->rq_dev)] ? \ + ((blksize_size[MAJOR_NR][MINOR(CURRENT->rq_dev)] >> 9) - 1) : \ + ((BLOCK_SIZE >> 9) - 1)) +#endif /* IDE_DRIVER */ + +#define SUBSECTOR(block) (CURRENT->current_nr_sectors > 0) + +#ifdef CONFIG_CDU31A +extern int cdu31a_init(void); +#endif CONFIG_CDU31A +#ifdef CONFIG_MCD +extern int mcd_init(void); +#endif CONFIG_MCD +#ifdef CONFIG_MCDX +extern int mcdx_init(void); +#endif CONFIG_MCDX +#ifdef CONFIG_SBPCD +extern int sbpcd_init(void); +#endif CONFIG_SBPCD +#ifdef CONFIG_AZTCD +extern int aztcd_init(void); +#endif CONFIG_AZTCD +#ifdef CONFIG_CDU535 +extern int sony535_init(void); +#endif CONFIG_CDU535 +#ifdef CONFIG_GSCD +extern int gscd_init(void); +#endif CONFIG_GSCD +#ifdef CONFIG_CM206 +extern int cm206_init(void); +#endif CONFIG_CM206 +#ifdef CONFIG_OPTCD +extern int optcd_init(void); +#endif CONFIG_OPTCD +#ifdef CONFIG_SJCD +extern int sjcd_init(void); +#endif CONFIG_SJCD +#ifdef CONFIG_CDI_INIT +extern int cdi_init(void); +#endif CONFIG_CDI_INIT +#ifdef CONFIG_BLK_DEV_HD +extern int hd_init(void); +#endif +#ifdef CONFIG_BLK_DEV_IDE +extern int ide_init(void); +#endif +#ifdef CONFIG_BLK_DEV_XD +extern int xd_init(void); +#endif +#ifdef CONFIG_BLK_DEV_LOOP +extern int loop_init(void); +#endif +#ifdef CONFIG_BLK_DEV_MD +extern int md_init(void); +#endif CONFIG_BLK_DEV_MD + +extern void set_device_ro(kdev_t dev,int flag); +void add_blkdev_randomness(int major); + +extern int floppy_init(void); +extern void rd_load(void); +extern int rd_init(void); +extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ +extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ +extern int rd_image_start; /* starting block # of image */ + +#ifdef CONFIG_BLK_DEV_INITRD + +#define INITRD_MINOR 250 /* shouldn't collide with /dev/ram* too soon ... */ + +extern unsigned long initrd_start,initrd_end; +extern int mount_initrd; /* zero if initrd should not be mounted */ +void initrd_init(void); + +#endif + +#define RO_IOCTLS(dev,where) \ + case BLKROSET: { int __val; if (!suser()) return -EACCES; \ + if (get_user(__val, (int *)(where))) return -EFAULT; \ + set_device_ro((dev),__val); return 0; } \ + case BLKROGET: { int __val = (is_read_only(dev) != 0) ; \ + return put_user(__val,(int *) (where)); } + +#if defined(MAJOR_NR) || defined(IDE_DRIVER) + +/* + * Add entries as needed. + */ + +#ifdef IDE_DRIVER + +#define DEVICE_NR(device) (MINOR(device) >> PARTN_BITS) +#define DEVICE_ON(device) /* nothing */ +#define DEVICE_OFF(device) /* nothing */ + +#elif (MAJOR_NR == RAMDISK_MAJOR) + +/* ram disk */ +#define DEVICE_NAME "ramdisk" +#define DEVICE_REQUEST rd_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) +#define DEVICE_NO_RANDOM + +#elif (MAJOR_NR == FLOPPY_MAJOR) + +static void floppy_off(unsigned int nr); + +#define DEVICE_NAME "floppy" +#define DEVICE_INTR do_floppy +#define DEVICE_REQUEST do_fd_request +#define DEVICE_NR(device) ( (MINOR(device) & 3) | ((MINOR(device) & 0x80 ) >> 5 )) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) floppy_off(DEVICE_NR(device)) + +#elif (MAJOR_NR == HD_MAJOR) + +/* harddisk: timeout is 6 seconds.. */ +#define DEVICE_NAME "harddisk" +#define DEVICE_INTR do_hd +#define DEVICE_TIMEOUT HD_TIMER +#define TIMEOUT_VALUE (6*HZ) +#define DEVICE_REQUEST do_hd_request +#define DEVICE_NR(device) (MINOR(device)>>6) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == SCSI_DISK_MAJOR) + +#define DEVICE_NAME "scsidisk" +#define DEVICE_INTR do_sd +#define TIMEOUT_VALUE (2*HZ) +#define DEVICE_REQUEST do_sd_request +#define DEVICE_NR(device) (MINOR(device) >> 4) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +/* Kludge to use the same number for both char and block major numbers */ +#elif (MAJOR_NR == MD_MAJOR) && defined(MD_DRIVER) + +#define DEVICE_NAME "Multiple devices driver" +#define DEVICE_REQUEST do_md_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == SCSI_TAPE_MAJOR) + +#define DEVICE_NAME "scsitape" +#define DEVICE_INTR do_st +#define DEVICE_NR(device) (MINOR(device) & 0x7f) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == SCSI_CDROM_MAJOR) + +#define DEVICE_NAME "CD-ROM" +#define DEVICE_INTR do_sr +#define DEVICE_REQUEST do_sr_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == XT_DISK_MAJOR) + +#define DEVICE_NAME "xt disk" +#define DEVICE_REQUEST do_xd_request +#define DEVICE_NR(device) (MINOR(device) >> 6) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == CDU31A_CDROM_MAJOR) + +#define DEVICE_NAME "CDU31A" +#define DEVICE_REQUEST do_cdu31a_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == MITSUMI_CDROM_MAJOR) + +#define DEVICE_NAME "Mitsumi CD-ROM" +/* #define DEVICE_INTR do_mcd */ +#define DEVICE_REQUEST do_mcd_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == MITSUMI_X_CDROM_MAJOR) + +#define DEVICE_NAME "Mitsumi CD-ROM" +/* #define DEVICE_INTR do_mcdx */ +#define DEVICE_REQUEST do_mcdx_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == MATSUSHITA_CDROM_MAJOR) + +#define DEVICE_NAME "Matsushita CD-ROM controller #1" +#define DEVICE_REQUEST do_sbpcd_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == MATSUSHITA_CDROM2_MAJOR) + +#define DEVICE_NAME "Matsushita CD-ROM controller #2" +#define DEVICE_REQUEST do_sbpcd2_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == MATSUSHITA_CDROM3_MAJOR) + +#define DEVICE_NAME "Matsushita CD-ROM controller #3" +#define DEVICE_REQUEST do_sbpcd3_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == MATSUSHITA_CDROM4_MAJOR) + +#define DEVICE_NAME "Matsushita CD-ROM controller #4" +#define DEVICE_REQUEST do_sbpcd4_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == AZTECH_CDROM_MAJOR) + +#define DEVICE_NAME "Aztech CD-ROM" +#define DEVICE_REQUEST do_aztcd_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == CDU535_CDROM_MAJOR) + +#define DEVICE_NAME "SONY-CDU535" +#define DEVICE_INTR do_cdu535 +#define DEVICE_REQUEST do_cdu535_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == GOLDSTAR_CDROM_MAJOR) + +#define DEVICE_NAME "Goldstar R420" +#define DEVICE_REQUEST do_gscd_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == CM206_CDROM_MAJOR) +#define DEVICE_NAME "Philips/LMS cd-rom cm206" +#define DEVICE_REQUEST do_cm206_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == OPTICS_CDROM_MAJOR) + +#define DEVICE_NAME "DOLPHIN 8000AT CD-ROM" +#define DEVICE_REQUEST do_optcd_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#elif (MAJOR_NR == SANYO_CDROM_MAJOR) + +#define DEVICE_NAME "Sanyo H94A CD-ROM" +#define DEVICE_REQUEST do_sjcd_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#endif /* MAJOR_NR == whatever */ + +#if (MAJOR_NR != SCSI_TAPE_MAJOR) +#if !defined(IDE_DRIVER) + +#ifndef CURRENT +#define CURRENT (blk_dev[MAJOR_NR].current_request) +#endif + +#define CURRENT_DEV DEVICE_NR(CURRENT->rq_dev) + +#ifdef DEVICE_INTR +static void (*DEVICE_INTR)(void) = NULL; +#endif +#ifdef DEVICE_TIMEOUT + +#define SET_TIMER \ +((timer_table[DEVICE_TIMEOUT].expires = jiffies + TIMEOUT_VALUE), \ +(timer_active |= 1<<DEVICE_TIMEOUT)) + +#define CLEAR_TIMER \ +timer_active &= ~(1<<DEVICE_TIMEOUT) + +#define SET_INTR(x) \ +if ((DEVICE_INTR = (x)) != NULL) \ + SET_TIMER; \ +else \ + CLEAR_TIMER; + +#else + +#define SET_INTR(x) (DEVICE_INTR = (x)) + +#endif /* DEVICE_TIMEOUT */ + +static void (DEVICE_REQUEST)(void); + +#ifdef DEVICE_INTR +#define CLEAR_INTR SET_INTR(NULL) +#else +#define CLEAR_INTR +#endif + +#define INIT_REQUEST \ + if (!CURRENT) {\ + CLEAR_INTR; \ + return; \ + } \ + if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \ + panic(DEVICE_NAME ": request list destroyed"); \ + if (CURRENT->bh) { \ + if (!buffer_locked(CURRENT->bh)) \ + panic(DEVICE_NAME ": block not locked"); \ + } + +#endif /* !defined(IDE_DRIVER) */ + +/* end_request() - SCSI devices have their own version */ +/* - IDE drivers have their own copy too */ + +#if ! SCSI_BLK_MAJOR(MAJOR_NR) + +#if defined(IDE_DRIVER) && !defined(_IDE_C) /* shared copy for IDE modules */ +void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup); +#else + +#ifdef IDE_DRIVER +void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup) { + struct request *req = hwgroup->rq; +#else +static void end_request(int uptodate) { + struct request *req = CURRENT; +#endif /* IDE_DRIVER */ + struct buffer_head * bh; + + req->errors = 0; + if (!uptodate) { + printk("end_request: I/O error, dev %s, sector %lu\n", + kdevname(req->rq_dev), req->sector); + req->nr_sectors--; + req->nr_sectors &= ~SECTOR_MASK; + req->sector += (BLOCK_SIZE / 512); + req->sector &= ~SECTOR_MASK; + } + + if ((bh = req->bh) != NULL) { + req->bh = bh->b_reqnext; + bh->b_reqnext = NULL; + mark_buffer_uptodate(bh, uptodate); + unlock_buffer(bh); + if ((bh = req->bh) != NULL) { + req->current_nr_sectors = bh->b_size >> 9; + if (req->nr_sectors < req->current_nr_sectors) { + req->nr_sectors = req->current_nr_sectors; + printk("end_request: buffer-list destroyed\n"); + } + req->buffer = bh->b_data; + return; + } + } +#ifndef DEVICE_NO_RANDOM + add_blkdev_randomness(MAJOR(req->rq_dev)); +#endif +#ifdef IDE_DRIVER + blk_dev[MAJOR(req->rq_dev)].current_request = req->next; + hwgroup->rq = NULL; +#else + DEVICE_OFF(req->rq_dev); + CURRENT = req->next; +#endif /* IDE_DRIVER */ + if (req->sem != NULL) + up(req->sem); + req->rq_status = RQ_INACTIVE; + wake_up(&wait_for_request); +} +#endif /* defined(IDE_DRIVER) && !defined(_IDE_C) */ +#endif /* ! SCSI_BLK_MAJOR(MAJOR_NR) */ +#endif /* (MAJOR_NR != SCSI_TAPE_MAJOR) */ + +#endif /* defined(MAJOR_NR) || defined(IDE_DRIVER) */ + +#endif /* _BLK_H */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 1e0b17c81..e0f578f9b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -4,6 +4,7 @@ #include <linux/major.h> #include <linux/sched.h> #include <linux/genhd.h> +#include <linux/tqueue.h> /* * Ok, this is an expanded form so that we can use the same @@ -12,7 +13,14 @@ * for read/write completion. */ struct request { - int dev; /* -1 if no request */ + volatile int rq_status; /* should split this into a few status bits */ +#define RQ_INACTIVE (-1) +#define RQ_ACTIVE 1 +#define RQ_SCSI_BUSY 0xffff +#define RQ_SCSI_DONE 0xfffe +#define RQ_SCSI_DISCONNECTING 0xffe0 + + kdev_t rq_dev; int cmd; /* READ or WRITE */ int errors; unsigned long sector; @@ -28,6 +36,8 @@ struct request { struct blk_dev_struct { void (*request_fn)(void); struct request * current_request; + struct request plug; + struct tq_struct plug_tq; }; struct sec_size { @@ -39,6 +49,10 @@ extern struct sec_size * blk_sec[MAX_BLKDEV]; extern struct blk_dev_struct blk_dev[MAX_BLKDEV]; extern struct wait_queue * wait_for_request; extern void resetup_one_dev(struct gendisk *dev, int drive); +extern void unplug_device(void * data); + +/* md needs this function to remap requests */ +extern int md_map (int minor, kdev_t *rdev, unsigned long *rsector, unsigned long size); extern int * blk_size[MAX_BLKDEV]; diff --git a/include/linux/bpqether.h b/include/linux/bpqether.h new file mode 100644 index 000000000..cc7d35831 --- /dev/null +++ b/include/linux/bpqether.h @@ -0,0 +1,41 @@ +#ifndef __BPQETHER_H +#define __BPQETHER_H + +/* + * Defines for the BPQETHER pseudo device driver + */ + +#ifndef __LINUX_IF_ETHER_H +#include <linux/if_ether.h> +#endif + +#define SIOCSBPQETHOPT (SIOCDEVPRIVATE+0) /* reserved */ +#define SIOCSBPQETHADDR (SIOCDEVPRIVATE+1) + +struct bpq_ethaddr { + unsigned char destination[ETH_ALEN]; + unsigned char accept[ETH_ALEN]; +}; + +/* + * For SIOCSBPQETHOPT - this is compatible with PI2/PacketTwin card drivers, + * currently not implemented, though. If someone wants to hook a radio + * to his ethernet card he may find this useful... ;-) + */ + +#define SIOCGBPQETHPARAM 0x5000 /* get Level 1 parameters */ +#define SIOCSBPQETHPARAM 0x5001 /* set */ + +struct bpq_req { + int cmd; + int speed; /* unused */ + int clockmode; /* unused */ + int txdelay; + unsigned char persist; /* unused */ + int slotime; /* unused */ + int squeldelay; + int dmachan; /* unused */ + int irq; /* unused */ +}; + +#endif diff --git a/include/linux/busmouse.h b/include/linux/busmouse.h index 33c6ec7a9..eb71550d3 100644 --- a/include/linux/busmouse.h +++ b/include/linux/busmouse.h @@ -2,7 +2,7 @@ #define _LINUX_BUSMOUSE_H /* - * linux/include/linux/mouse.h: header file for Logitech Bus Mouse driver + * linux/include/linux/busmouse.h: header file for Logitech Bus Mouse driver * by James Banks * * based on information gleamed from various mouse drivers on the net @@ -33,11 +33,13 @@ /*--------- LOGITECH BUSMOUSE ITEMS -------------*/ +#define LOGIBM_BASE 0x23c #define MSE_DATA_PORT 0x23c #define MSE_SIGNATURE_PORT 0x23d #define MSE_CONTROL_PORT 0x23e -#define MSE_INTERRUPT_PORT 0x23e +#define MSE_INTERRUPT_PORT 0x23e #define MSE_CONFIG_PORT 0x23f +#define LOGIBM_EXTENT 0x4 #define MSE_ENABLE_INTERRUPTS 0x00 #define MSE_DISABLE_INTERRUPTS 0x10 @@ -59,10 +61,12 @@ /*--------- MICROSOFT BUSMOUSE ITEMS -------------*/ +#define MSBM_BASE 0x23d #define MS_MSE_DATA_PORT 0x23d #define MS_MSE_SIGNATURE_PORT 0x23e #define MS_MSE_CONTROL_PORT 0x23c #define MS_MSE_CONFIG_PORT 0x23f +#define MSBM_EXTENT 0x3 #define MS_MSE_ENABLE_INTERRUPTS 0x11 #define MS_MSE_DISABLE_INTERRUPTS 0x10 @@ -91,10 +95,10 @@ struct mouse_status { int ready; int active; struct wait_queue *wait; + struct fasync_struct *fasyncptr; }; /* Function Prototypes */ -extern long mouse_init(long); #endif diff --git a/include/linux/cd1400.h b/include/linux/cd1400.h new file mode 100644 index 000000000..b6e5b667b --- /dev/null +++ b/include/linux/cd1400.h @@ -0,0 +1,291 @@ +/*****************************************************************************/ + +/* + * cd1400.h -- cd1400 UART hardware info. + * + * Copyright (C) 1994-1996 Greg Ungerer (gerg@stallion.oz.au). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*****************************************************************************/ +#ifndef _CD1400_H +#define _CD1400_H +/*****************************************************************************/ + +/* + * Define the number of async ports per cd1400 uart chip. + */ +#define CD1400_PORTS 4 + +/* + * Define the cd1400 uarts internal FIFO sizes. + */ +#define CD1400_TXFIFOSIZE 12 +#define CD1400_RXFIFOSIZE 12 + +/* + * Local RX FIFO thresh hold level. Also define the RTS thresh hold + * based on the RX thresh hold. + */ +#define FIFO_RXTHRESHOLD 6 +#define FIFO_RTSTHRESHOLD 7 + +/*****************************************************************************/ + +/* + * Define the cd1400 register addresses. These are all the valid + * registers with the cd1400. Some are global, some virtual, some + * per port. + */ +#define GFRCR 0x40 +#define CAR 0x68 +#define GCR 0x4b +#define SVRR 0x67 +#define RICR 0x44 +#define TICR 0x45 +#define MICR 0x46 +#define RIR 0x6b +#define TIR 0x6a +#define MIR 0x69 +#define PPR 0x7e + +#define RIVR 0x43 +#define TIVR 0x42 +#define MIVR 0x41 +#define TDR 0x63 +#define RDSR 0x62 +#define MISR 0x4c +#define EOSRR 0x60 + +#define LIVR 0x18 +#define CCR 0x05 +#define SRER 0x06 +#define COR1 0x08 +#define COR2 0x09 +#define COR3 0x0a +#define COR4 0x1e +#define COR5 0x1f +#define CCSR 0x0b +#define RDCR 0x0e +#define SCHR1 0x1a +#define SCHR2 0x1b +#define SCHR3 0x1c +#define SCHR4 0x1d +#define SCRL 0x22 +#define SCRH 0x23 +#define LNC 0x24 +#define MCOR1 0x15 +#define MCOR2 0x16 +#define RTPR 0x21 +#define MSVR1 0x6c +#define MSVR2 0x6d +#define PSVR 0x6f +#define RBPR 0x78 +#define RCOR 0x7c +#define TBPR 0x72 +#define TCOR 0x76 + +/*****************************************************************************/ + +/* + * Define the set of baud rate clock divisors. + */ +#define CD1400_CLK0 8 +#define CD1400_CLK1 32 +#define CD1400_CLK2 128 +#define CD1400_CLK3 512 +#define CD1400_CLK4 2048 + +#define CD1400_NUMCLKS 5 + +/*****************************************************************************/ + +/* + * Define the clock pre-scalar value to be a 5 ms clock. This should be + * OK for now. It would probably be better to make it 10 ms, but we + * can't fit that divisor into 8 bits! + */ +#define PPR_SCALAR 244 + +/*****************************************************************************/ + +/* + * Define values used to set character size options. + */ +#define COR1_CHL5 0x00 +#define COR1_CHL6 0x01 +#define COR1_CHL7 0x02 +#define COR1_CHL8 0x03 + +/* + * Define values used to set the number of stop bits. + */ +#define COR1_STOP1 0x00 +#define COR1_STOP15 0x04 +#define COR1_STOP2 0x08 + +/* + * Define values used to set the parity scheme in use. + */ +#define COR1_PARNONE 0x00 +#define COR1_PARFORCE 0x20 +#define COR1_PARENB 0x40 +#define COR1_PARIGNORE 0x10 + +#define COR1_PARODD 0x80 +#define COR1_PAREVEN 0x00 + +#define COR2_IXM 0x80 +#define COR2_TXIBE 0x40 +#define COR2_ETC 0x20 +#define COR2_LLM 0x10 +#define COR2_RLM 0x08 +#define COR2_RTSAO 0x04 +#define COR2_CTSAE 0x02 + +#define COR3_SCDRNG 0x80 +#define COR3_SCD34 0x40 +#define COR3_FCT 0x20 +#define COR3_SCD12 0x10 + +/* + * Define values used by COR4. + */ +#define COR4_BRKINT 0x08 +#define COR4_IGNBRK 0x18 + +/*****************************************************************************/ + +/* + * Define the modem control register values. + * Note that the actual hardware is a little different to the conventional + * pin names on the cd1400. + */ +#define MSVR1_DTR 0x01 +#define MSVR1_DSR 0x10 +#define MSVR1_RI 0x20 +#define MSVR1_CTS 0x40 +#define MSVR1_DCD 0x80 + +#define MSVR2_RTS 0x02 +#define MSVR2_DSR 0x10 +#define MSVR2_RI 0x20 +#define MSVR2_CTS 0x40 +#define MSVR2_DCD 0x80 + +#define MCOR1_DCD 0x80 +#define MCOR1_CTS 0x40 +#define MCOR1_RI 0x20 +#define MCOR1_DSR 0x10 + +#define MCOR2_DCD 0x80 +#define MCOR2_CTS 0x40 +#define MCOR2_RI 0x20 +#define MCOR2_DSR 0x10 + +/*****************************************************************************/ + +/* + * Define the bits used with the service (interrupt) enable register. + */ +#define SRER_NNDT 0x01 +#define SRER_TXEMPTY 0x02 +#define SRER_TXDATA 0x04 +#define SRER_RXDATA 0x10 +#define SRER_MODEM 0x80 + +/*****************************************************************************/ + +/* + * Define operational commands for the command register. + */ +#define CCR_RESET 0x80 +#define CCR_CORCHANGE 0x4e +#define CCR_SENDCH 0x20 +#define CCR_CHANCTRL 0x10 + +#define CCR_TXENABLE (CCR_CHANCTRL | 0x08) +#define CCR_TXDISABLE (CCR_CHANCTRL | 0x04) +#define CCR_RXENABLE (CCR_CHANCTRL | 0x02) +#define CCR_RXDISABLE (CCR_CHANCTRL | 0x01) + +#define CCR_SENDSCHR1 (CCR_SENDCH | 0x01) +#define CCR_SENDSCHR2 (CCR_SENDCH | 0x02) +#define CCR_SENDSCHR3 (CCR_SENDCH | 0x03) +#define CCR_SENDSCHR4 (CCR_SENDCH | 0x04) + +#define CCR_RESETCHAN (CCR_RESET | 0x00) +#define CCR_RESETFULL (CCR_RESET | 0x01) +#define CCR_TXFLUSHFIFO (CCR_RESET | 0x02) + +#define CCR_MAXWAIT 10000 + +/*****************************************************************************/ + +/* + * Define the valid acknowledgement types (for hw ack cycle). + */ +#define ACK_TYPMASK 0x07 +#define ACK_TYPTX 0x02 +#define ACK_TYPMDM 0x01 +#define ACK_TYPRXGOOD 0x03 +#define ACK_TYPRXBAD 0x07 + +#define SVRR_RX 0x01 +#define SVRR_TX 0x02 +#define SVRR_MDM 0x04 + +#define ST_OVERRUN 0x01 +#define ST_FRAMING 0x02 +#define ST_PARITY 0x04 +#define ST_BREAK 0x08 +#define ST_SCHAR1 0x10 +#define ST_SCHAR2 0x20 +#define ST_SCHAR3 0x30 +#define ST_SCHAR4 0x40 +#define ST_RANGE 0x70 +#define ST_SCHARMASK 0x70 +#define ST_TIMEOUT 0x80 + +#define MISR_DCD 0x80 +#define MISR_CTS 0x40 +#define MISR_RI 0x20 +#define MISR_DSR 0x10 + +/*****************************************************************************/ + +/* + * Defines for the CCSR status register. + */ +#define CCSR_RXENABLED 0x80 +#define CCSR_RXFLOWON 0x40 +#define CCSR_RXFLOWOFF 0x20 +#define CCSR_TXENABLED 0x08 +#define CCSR_TXFLOWON 0x04 +#define CCSR_TXFLOWOFF 0x02 + +/*****************************************************************************/ + +/* + * Define the embedded commands. + */ +#define ETC_CMD 0x00 +#define ETC_STARTBREAK 0x81 +#define ETC_DELAY 0x82 +#define ETC_STOPBREAK 0x83 + +/*****************************************************************************/ +#endif diff --git a/include/linux/cdk.h b/include/linux/cdk.h new file mode 100644 index 000000000..a3d016791 --- /dev/null +++ b/include/linux/cdk.h @@ -0,0 +1,481 @@ +/*****************************************************************************/ + +/* + * cdk.h -- CDK interface definitions. + * + * Copyright (C) 1994-1996 Greg Ungerer (gerg@stallion.oz.au). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*****************************************************************************/ +#ifndef _CDK_H +#define _CDK_H +/*****************************************************************************/ + +#pragma pack(2) + +/* + * The following set of definitions is used to communicate with the + * shared memory interface of the Stallion intelligent multiport serial + * boards. The definitions in this file are taken directly from the + * document titled "Generic Stackable Interface, Downloader and + * Communications Development Kit". + */ + +/* + * Define the set of important shared memory addresses. These are + * required to initialize the board and get things started. All of these + * addresses are relative to the start of the shared memory. + */ +#define CDK_SIGADDR 0x200 +#define CDK_FEATADDR 0x280 +#define CDK_CDKADDR 0x300 +#define CDK_RDYADDR 0x262 + +#define CDK_ALIVEMARKER 13 + +/* + * On hardware power up the ROMs located on the EasyConnection 8/64 will + * fill out the following signature information into shared memory. This + * way the host system can quickly determine that the board is present + * and is operational. + */ +typedef struct cdkecpsig { + unsigned long magic; + unsigned short romver; + unsigned short cputype; + unsigned char panelid[8]; +} cdkecpsig_t; + +#define ECP_MAGIC 0x21504345 + +/* + * On hardware power up the ROMs located on the ONboard, Stallion and + * Brumbys will fill out the following signature information into shared + * memory. This way the host system can quickly determine that the board + * is present and is operational. + */ +typedef struct cdkonbsig { + unsigned short magic0; + unsigned short magic1; + unsigned short magic2; + unsigned short magic3; + unsigned short romver; + unsigned short memoff; + unsigned short memseg; + unsigned short amask0; + unsigned short pic; + unsigned short status; + unsigned short btype; + unsigned short clkticks; + unsigned short clkspeed; + unsigned short amask1; + unsigned short amask2; +} cdkonbsig_t; + +#define ONB_MAGIC0 0xf2a7 +#define ONB_MAGIC1 0xa149 +#define ONB_MAGIC2 0x6352 +#define ONB_MAGIC3 0xf121 + +/* + * Define the feature area structure. The feature area is the set of + * startup parameters used by the slave image when it starts executing. + * They allow for the specification of buffer sizes, debug trace, etc. + */ +typedef struct cdkfeature { + unsigned long debug; + unsigned long banner; + unsigned long etype; + unsigned long nrdevs; + unsigned long brdspec; + unsigned long txrqsize; + unsigned long rxrqsize; + unsigned long flags; +} cdkfeature_t; + +#define ETYP_DDK 0 +#define ETYP_CDK 1 + +/* + * Define the CDK header structure. This is the info that the slave + * environment sets up after it has been downloaded and started. It + * essentially provides a memory map for the shared memory interface. + */ +typedef struct cdkhdr { + unsigned short command; + unsigned short status; + unsigned short port; + unsigned short mode; + unsigned long cmd_buf[14]; + unsigned short alive_cnt; + unsigned short intrpt_mode; + unsigned char intrpt_id[8]; + unsigned char ver_release; + unsigned char ver_modification; + unsigned char ver_fix; + unsigned char deadman_restart; + unsigned short deadman; + unsigned short nrdevs; + unsigned long memp; + unsigned long hostp; + unsigned long slavep; + unsigned char hostreq; + unsigned char slavereq; + unsigned char cmd_reserved[30]; +} cdkhdr_t; + +#define MODE_DDK 0 +#define MODE_CDK 1 + +#define IMD_INTR 0x0 +#define IMD_PPINTR 0x1 +#define IMD_POLL 0xff + +/* + * Define the memory mapping structure. This structure is pointed to by + * the memp field in the stlcdkhdr struct. As many as these structures + * as required are layed out in shared memory to define how the rest of + * shared memory is divided up. There will be one for each port. + */ +typedef struct cdkmem { + unsigned short dtype; + unsigned long offset; +} cdkmem_t; + +#define TYP_UNDEFINED 0x0 +#define TYP_ASYNCTRL 0x1 +#define TYP_ASYNC 0x20 +#define TYP_PARALLEL 0x40 +#define TYP_SYNCX21 0x60 + +/*****************************************************************************/ + +/* + * Following is a set of defines and structures used to actually deal + * with the serial ports on the board. Firstly is the set of commands + * that can be applied to ports. + */ +#define ASYCMD (((unsigned long) 'a') << 8) + +#define A_NULL (ASYCMD | 0) +#define A_FLUSH (ASYCMD | 1) +#define A_BREAK (ASYCMD | 2) +#define A_GETPORT (ASYCMD | 3) +#define A_SETPORT (ASYCMD | 4) +#define A_SETPORTF (ASYCMD | 5) +#define A_SETPORTFTX (ASYCMD | 6) +#define A_SETPORTFRX (ASYCMD | 7) +#define A_GETSIGNALS (ASYCMD | 8) +#define A_SETSIGNALS (ASYCMD | 9) +#define A_SETSIGNALSF (ASYCMD | 10) +#define A_SETSIGNALSFTX (ASYCMD | 11) +#define A_SETSIGNALSFRX (ASYCMD | 12) +#define A_GETNOTIFY (ASYCMD | 13) +#define A_SETNOTIFY (ASYCMD | 14) +#define A_NOTIFY (ASYCMD | 15) +#define A_PORTCTRL (ASYCMD | 16) +#define A_GETSTATS (ASYCMD | 17) +#define A_RQSTATE (ASYCMD | 18) +#define A_FLOWSTATE (ASYCMD | 19) +#define A_CLEARSTATS (ASYCMD | 20) + +/* + * Define those arguments used for simple commands. + */ +#define FLUSHRX 0x1 +#define FLUSHTX 0x2 + +#define BREAKON -1 +#define BREAKOFF -2 + +/* + * Define the port setting structure, and all those defines that go along + * with it. Basically this structure defines the characteristics of this + * port: baud rate, chars, parity, input/output char cooking etc. + */ +typedef struct asyport { + unsigned long baudout; + unsigned long baudin; + unsigned long iflag; + unsigned long oflag; + unsigned long lflag; + unsigned long pflag; + unsigned long flow; + unsigned long spare1; + unsigned short vtime; + unsigned short vmin; + unsigned short txlo; + unsigned short txhi; + unsigned short rxlo; + unsigned short rxhi; + unsigned short rxhog; + unsigned short spare2; + unsigned char csize; + unsigned char stopbs; + unsigned char parity; + unsigned char stopin; + unsigned char startin; + unsigned char stopout; + unsigned char startout; + unsigned char parmark; + unsigned char brkmark; + unsigned char cc[11]; +} asyport_t; + +#define PT_STOP1 0x0 +#define PT_STOP15 0x1 +#define PT_STOP2 0x2 + +#define PT_NOPARITY 0x0 +#define PT_ODDPARITY 0x1 +#define PT_EVENPARITY 0x2 +#define PT_MARKPARITY 0x3 +#define PT_SPACEPARITY 0x4 + +#define F_NONE 0x0 +#define F_IXON 0x1 +#define F_IXOFF 0x2 +#define F_IXANY 0x4 +#define F_IOXANY 0x8 +#define F_RTSFLOW 0x10 +#define F_CTSFLOW 0x20 +#define F_DTRFLOW 0x40 +#define F_DCDFLOW 0x80 +#define F_DSROFLOW 0x100 +#define F_DSRIFLOW 0x200 + +#define FI_NORX 0x1 +#define FI_RAW 0x2 +#define FI_ISTRIP 0x4 +#define FI_UCLC 0x8 +#define FI_INLCR 0x10 +#define FI_ICRNL 0x20 +#define FI_IGNCR 0x40 +#define FI_IGNBREAK 0x80 +#define FI_DSCRDBREAK 0x100 +#define FI_1MARKBREAK 0x200 +#define FI_2MARKBREAK 0x400 +#define FI_XCHNGBREAK 0x800 +#define FI_IGNRXERRS 0x1000 +#define FI_DSCDRXERRS 0x2000 +#define FI_1MARKRXERRS 0x4000 +#define FI_2MARKRXERRS 0x8000 +#define FI_XCHNGRXERRS 0x10000 +#define FI_DSCRDNULL 0x20000 + +#define FO_OLCUC 0x1 +#define FO_ONLCR 0x2 +#define FO_OOCRNL 0x4 +#define FO_ONOCR 0x8 +#define FO_ONLRET 0x10 +#define FO_ONL 0x20 +#define FO_OBS 0x40 +#define FO_OVT 0x80 +#define FO_OFF 0x100 +#define FO_OTAB1 0x200 +#define FO_OTAB2 0x400 +#define FO_OTAB3 0x800 +#define FO_OCR1 0x1000 +#define FO_OCR2 0x2000 +#define FO_OCR3 0x4000 +#define FO_OFILL 0x8000 +#define FO_ODELL 0x10000 + +#define P_RTSLOCK 0x1 +#define P_CTSLOCK 0x2 +#define P_MAPRTS 0x4 +#define P_MAPCTS 0x8 +#define P_LOOPBACK 0x10 +#define P_DTRFOLLOW 0x20 +#define P_FAKEDCD 0x40 + +/* + * Define a structure to communicate serial port signal and data state + * information. + */ +typedef struct asysigs { + unsigned long data; + unsigned long signal; + unsigned long sigvalue; +} asysigs_t; + +#define DT_TXBUSY 0x1 +#define DT_TXEMPTY 0x2 +#define DT_TXLOW 0x4 +#define DT_TXHIGH 0x8 +#define DT_TXFULL 0x10 +#define DT_TXHOG 0x20 +#define DT_TXFLOWED 0x40 +#define DT_TXBREAK 0x80 + +#define DT_RXBUSY 0x100 +#define DT_RXEMPTY 0x200 +#define DT_RXLOW 0x400 +#define DT_RXHIGH 0x800 +#define DT_RXFULL 0x1000 +#define DT_RXHOG 0x2000 +#define DT_RXFLOWED 0x4000 +#define DT_RXBREAK 0x8000 + +#define SG_DTR 0x1 +#define SG_DCD 0x2 +#define SG_RTS 0x4 +#define SG_CTS 0x8 +#define SG_DSR 0x10 +#define SG_RI 0x20 + +/* + * Define the notification setting structure. This is used to tell the + * port what events we want to be informed about. Fields here use the + * same defines as for the asysigs structure above. + */ +typedef struct asynotify { + unsigned long ctrl; + unsigned long data; + unsigned long signal; + unsigned long sigvalue; +} asynotify_t; + +/* + * Define the port control structure. It is used to do fine grain + * control operations on the port. + */ +typedef struct { + unsigned long rxctrl; + unsigned long txctrl; + char rximdch; + char tximdch; + char spare1; + char spare2; +} asyctrl_t; + +#define CT_ENABLE 0x1 +#define CT_DISABLE 0x2 +#define CT_STOP 0x4 +#define CT_START 0x8 +#define CT_STARTFLOW 0x10 +#define CT_STOPFLOW 0x20 +#define CT_SENDCHR 0x40 + +/* + * Define the stats structure kept for each port. This is a useful set + * of data collected for each port on the slave. The A_GETSTATS command + * is used to retrieve this data from the slave. + */ +typedef struct asystats { + unsigned long opens; + unsigned long txchars; + unsigned long rxchars; + unsigned long txringq; + unsigned long rxringq; + unsigned long txmsgs; + unsigned long rxmsgs; + unsigned long txflushes; + unsigned long rxflushes; + unsigned long overruns; + unsigned long framing; + unsigned long parity; + unsigned long ringover; + unsigned long lost; + unsigned long rxstart; + unsigned long rxstop; + unsigned long txstart; + unsigned long txstop; + unsigned long dcdcnt; + unsigned long dtrcnt; + unsigned long ctscnt; + unsigned long rtscnt; + unsigned long dsrcnt; + unsigned long ricnt; + unsigned long txbreaks; + unsigned long rxbreaks; + unsigned long signals; + unsigned long state; + unsigned long hwid; +} asystats_t; + +/*****************************************************************************/ + +/* + * All command and control communication with a device on the slave is + * via a control block in shared memory. Each device has its own control + * block, defined by the following structure. The control block allows + * the host to open, close and control the device on the slave. + */ +typedef struct cdkctrl { + unsigned char open; + unsigned char close; + unsigned long openarg; + unsigned long closearg; + unsigned long cmd; + unsigned long status; + unsigned long args[32]; +} cdkctrl_t; + +/* + * Each device on the slave passes data to and from the host via a ring + * queue in shared memory. Define a ring queue structure to hold the + * vital information about each ring queue. Two ring queues will be + * allocated for each port, one for receive data and one for transmit + * data. + */ +typedef struct cdkasyrq { + unsigned long offset; + unsigned short size; + unsigned short head; + unsigned short tail; +} cdkasyrq_t; + +/* + * Each asynchronous port is defined in shared memory by the following + * structure. It contains a control block to command a device, and also + * the necessary data channel information as well. + */ +typedef struct cdkasy { + cdkctrl_t ctrl; + unsigned short notify; + asynotify_t changed; + unsigned short receive; + cdkasyrq_t rxq; + unsigned short transmit; + cdkasyrq_t txq; +} cdkasy_t; + +#pragma pack() + +/*****************************************************************************/ + +/* + * Define the set of ioctls used by the driver to do special things + * to the board. These include interrupting it, and initializing + * the driver after board startup and shutdown. + */ +#include <linux/ioctl.h> + +#define STL_BINTR _IO('s',20) +#define STL_BSTART _IO('s',21) +#define STL_BSTOP _IO('s',22) +#define STL_BRESET _IO('s',23) + +/* + * Define a set of ioctl extensions, used to get at special stuff. + */ +#define STL_GETPFLAG _IO('s',80) +#define STL_SETPFLAG _IO('s',81) + +/*****************************************************************************/ +#endif diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index 1cd8cbeda..aba1458c3 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -1,12 +1,10 @@ -/**************************************************************************************** - * * - * general (not only SCSI) header library for linux CDROM drivers * - * (C) 1992 David Giller rafetmad@oxy.edu * - * 1994 Eberhard Moenkeberg emoenke@gwdg.de ("read audio" and some other stuff) * - * * - * <linux/cdrom.h> -- CD-ROM IOCTLs and structs * - * * - ****************************************************************************************/ +/* + * -- <linux/cdrom.h> + * general (not only SCSI) header library for linux CDROM drivers + * (C) 1992 David Giller rafetmad@oxy.edu + * 1994, 1995 Eberhard Moenkeberg emoenke@gwdg.de + * + */ #ifndef _LINUX_CDROM_H #define _LINUX_CDROM_H @@ -14,229 +12,114 @@ /* * some fix numbers */ -#define CD_MINS 74 /* max. minutes per CD */ -#define CD_SECS 60 /* seconds per minute */ -#define CD_FRAMES 75 /* frames per second */ -#define CD_CHUNK_SIZE 24 /* lowest-level "data bytes piece" */ -#define CD_NUM_OF_CHUNKS 98 /* chunks per frame */ -#define CD_FRAMESIZE 2048 /* bytes per frame, cooked mode */ -#define CD_FRAMESIZE_RAW0 2336 /* bytes per frame, "raw" mode */ -#define CD_FRAMESIZE_XA 2340 /* bytes per frame, "xa" mode */ -#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */ -#define CD_FRAMESIZE_SUB 96 /* subchannel data size */ -#define CD_BLOCK_OFFSET 150 /* offset of first logical frame */ -#define CD_XA_HEAD 12 /* header size of XA frame */ -#define CD_XA_TAIL 280 /* tail size of XA frame */ +#define CD_MINS 74 /* max. minutes per CD, not really a limit */ +#define CD_SECS 60 /* seconds per minute */ +#define CD_FRAMES 75 /* frames per second */ + +#define CD_SYNC_SIZE 12 /* 12 sync bytes per raw data frame, not transfered by the drive */ +#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */ +#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */ +#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */ +#define CD_XA_SYNC_HEAD (CD_SYNC_SIZE+CD_XA_HEAD)/* sync bytes + header of XA frame */ + +#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ +#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */ +/* most drives don't deliver everything: */ +#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /* 2340 */ +#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /* 2336 */ +/* Optics drive also has a 'read all' mode: */ +#define CD_FRAMESIZE_RAWER 2646 /* bytes per frame */ + +#define CD_EDC_SIZE 4 /* bytes EDC per most raw data frame types */ +#define CD_ZERO_SIZE 8 /* bytes zero per yellow book mode 1 frame */ +#define CD_ECC_SIZE 276 /* bytes ECC per most raw data frame types */ +#define CD_XA_TAIL (CD_EDC_SIZE+CD_ECC_SIZE) /* "after data" part of raw XA frame */ + +#define CD_FRAMESIZE_SUB 96 /* subchannel data "frame" size */ +#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */ + +#define CD_CHUNK_SIZE 24 /* lowest-level "data bytes piece" */ +#define CD_NUM_OF_CHUNKS 98 /* chunks per frame */ + +#define CD_FRAMESIZE_XA CD_FRAMESIZE_RAW1 /* obsolete name */ +#define CD_BLOCK_OFFSET CD_MSF_OFFSET /* obsolete name */ /* + * the raw frame layout: * - * For IOCTL calls, we will commandeer byte 0x53, or 'S'. + * - audio (red): | audio_sample_bytes | + * | 2352 | * + * - data (yellow, mode1): | sync - head - data - EDC - zero - ECC | + * | 12 - 4 - 2048 - 4 - 8 - 276 | + * + * - data (yellow, mode2): | sync - head - data | + * | 12 - 4 - 2336 | + * + * - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC | + * | 12 - 4 - 8 - 2048 - 4 - 276 | + * + * - XA data (green, mode2 form2): | sync - head - sub - data - EDC | + * | 12 - 4 - 8 - 2324 - 4 | */ /* - * CD-ROM-specific SCSI command opcodes - */ - -/* - * Group 2 (10-byte). All of these are called 'optional' by SCSI-II. - */ - -#define SCMD_READ_TOC 0x43 /* read table of contents */ -#define SCMD_PLAYAUDIO_MSF 0x47 /* play data at time offset */ -#define SCMD_PLAYAUDIO_TI 0x48 /* play data at track/index */ -#define SCMD_PAUSE_RESUME 0x4B /* pause/resume audio */ -#define SCMD_READ_SUBCHANNEL 0x42 /* read SC info on playing disc */ -#define SCMD_PLAYAUDIO10 0x45 /* play data at logical block */ -#define SCMD_READ_HEADER 0x44 /* read TOC header */ - -/* - * Group 5 - */ - -#define SCMD_PLAYAUDIO12 0xA5 /* play data at logical block */ -#define SCMD_PLAYTRACK_REL12 0xA9 /* play track at relative offset*/ - -/* - * Group 6 Commands - */ - -#define SCMD_CD_PLAYBACK_CONTROL 0xC9 /* Sony vendor-specific audio */ -#define SCMD_CD_PLAYBACK_STATUS 0xC4 /* control opcodes. info please!*/ - -/* - * CD-ROM capacity structure. - */ - -struct scsi_capacity - { - u_long capacity; - u_long lbasize; - }; - -/* - * CD-ROM MODE_SENSE/MODE_SELECT parameters - */ - -#define ERR_RECOVERY_PARMS 0x01 -#define DISCO_RECO_PARMS 0x02 -#define FORMAT_PARMS 0x03 -#define GEOMETRY_PARMS 0x04 -#define CERTIFICATION_PARMS 0x06 -#define CACHE_PARMS 0x38 - -/* - * standard mode-select header prepended to all mode-select commands - */ - -struct ccs_modesel_head - { - u_char _r1; /* reserved */ - u_char medium; /* device-specific medium type */ - u_char _r2; /* reserved */ - u_char block_desc_length; /* block descriptor length */ - u_char density; /* device-specific density code */ - u_char number_blocks_hi; /* number of blocks in this block desc */ - u_char number_blocks_med; - u_char number_blocks_lo; - u_char _r3; - u_char block_length_hi; /* block length for blocks in this desc */ - u_short block_length; - }; - -/* - * error recovery parameters - */ - -struct ccs_err_recovery - { - u_char _r1 : 2; /* reserved */ - u_char page_code : 6; /* page code */ - u_char page_length; /* page length */ - u_char awre : 1; /* auto write realloc enabled */ - u_char arre : 1; /* auto read realloc enabled */ - u_char tb : 1; /* transfer block */ - u_char rc : 1; /* read continuous */ - u_char eec : 1; /* enable early correction */ - u_char per : 1; /* post error */ - u_char dte : 1; /* disable transfer on error */ - u_char dcr : 1; /* disable correction */ - u_char retry_count; /* error retry count */ - u_char correction_span; /* largest recov. to be attempted, bits */ - u_char head_offset_count; /* head offset (2's C) for each retry */ - u_char strobe_offset_count; /* data strobe " */ - u_char recovery_time_limit; /* time limit on recovery attempts */ -}; - -/* - * disco/reco parameters + * CDROM IOCTL structures */ -struct ccs_disco_reco - { - u_char _r1 : 2; /* reserved */ - u_char page_code : 6; /* page code */ - u_char page_length; /* page length */ - u_char buffer_full_ratio; /* write buffer reconnect threshold */ - u_char buffer_empty_ratio; /* read " */ - u_short bus_inactivity_limit; /* limit on bus inactivity time */ - u_short disconnect_time_limit; /* minimum disconnect time */ - u_short connect_time_limit; /* minimum connect time */ - u_short _r2; /* reserved */ +struct cdrom_blk +{ + unsigned from; + unsigned short len; }; -/* - * drive geometry parameters - */ - -struct ccs_geometry - { - u_char _r1 : 2; /* reserved */ - u_char page_code : 6; /* page code */ - u_char page_length; /* page length */ - u_char cyl_ub; /* #cyls */ - u_char cyl_mb; - u_char cyl_lb; - u_char heads; /* #heads */ - u_char precomp_cyl_ub; /* precomp start */ - u_char precomp_cyl_mb; - u_char precomp_cyl_lb; - u_char current_cyl_ub; /* reduced current start */ - u_char current_cyl_mb; - u_char current_cyl_lb; - u_short step_rate; /* stepping motor rate */ - u_char landing_cyl_ub; /* landing zone */ - u_char landing_cyl_mb; - u_char landing_cyl_lb; - u_char _r2; - u_char _r3; - u_char _r4; - }; - -/* - * cache parameters - */ - -struct ccs_cache - { - u_char _r1 : 2; /* reserved */ - u_char page_code : 6; /* page code */ - u_char page_length; /* page length */ - u_char mode; /* cache control byte */ - u_char threshold; /* prefetch threshold */ - u_char max_prefetch; /* maximum prefetch size */ - u_char max_multiplier; /* maximum prefetch multiplier */ - u_char min_prefetch; /* minimum prefetch size */ - u_char min_multiplier; /* minimum prefetch multiplier */ - u_char _r2[8]; - }; - -/* - * CDROM IOCTL structures - */ struct cdrom_msf - { - u_char cdmsf_min0; /* start minute */ - u_char cdmsf_sec0; /* start second */ - u_char cdmsf_frame0; /* start frame */ - u_char cdmsf_min1; /* end minute */ - u_char cdmsf_sec1; /* end second */ - u_char cdmsf_frame1; /* end frame */ - }; +{ + u_char cdmsf_min0; /* start minute */ + u_char cdmsf_sec0; /* start second */ + u_char cdmsf_frame0; /* start frame */ + u_char cdmsf_min1; /* end minute */ + u_char cdmsf_sec1; /* end second */ + u_char cdmsf_frame1; /* end frame */ +}; struct cdrom_ti - { - u_char cdti_trk0; /* start track */ - u_char cdti_ind0; /* start index */ - u_char cdti_trk1; /* end track */ - u_char cdti_ind1; /* end index */ - }; +{ + u_char cdti_trk0; /* start track */ + u_char cdti_ind0; /* start index */ + u_char cdti_trk1; /* end track */ + u_char cdti_ind1; /* end index */ +}; struct cdrom_tochdr - { - u_char cdth_trk0; /* start track */ - u_char cdth_trk1; /* end track */ - }; +{ + u_char cdth_trk0; /* start track */ + u_char cdth_trk1; /* end track */ +}; + +struct cdrom_msf0 /* address in MSF format */ +{ + u_char minute; + u_char second; + u_char frame; +}; + +union cdrom_addr /* address in either MSF or logical format */ +{ + struct cdrom_msf0 msf; + int lba; +}; struct cdrom_tocentry - { +{ u_char cdte_track; u_char cdte_adr :4; u_char cdte_ctrl :4; u_char cdte_format; - union - { - struct - { - u_char minute; - u_char second; - u_char frame; - } msf; - int lba; - } cdte_addr; + union cdrom_addr cdte_addr; u_char cdte_datamode; - }; +}; /* * CD-ROM address types (cdrom_tocentry.cdte_format) @@ -245,94 +128,67 @@ struct cdrom_tocentry #define CDROM_MSF 0x02 /* "minute-second-frame": binary, not bcd here! */ /* - * bit to tell whether track is data or audio + * bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) */ - #define CDROM_DATA_TRACK 0x04 /* * The leadout track is always 0xAA, regardless of # of tracks on disc */ - #define CDROM_LEADOUT 0xAA struct cdrom_subchnl - { +{ u_char cdsc_format; u_char cdsc_audiostatus; u_char cdsc_adr: 4; u_char cdsc_ctrl: 4; u_char cdsc_trk; u_char cdsc_ind; - union - { - struct - { - u_char minute; - u_char second; - u_char frame; - } msf; - int lba; - } cdsc_absaddr; - union - { - struct - { - u_char minute; - u_char second; - u_char frame; - } msf; - int lba; - } cdsc_reladdr; - }; + union cdrom_addr cdsc_absaddr; + union cdrom_addr cdsc_reladdr; +}; + +struct cdrom_mcn { + u_char medium_catalog_number[14]; /* 13 ASCII digits, null-terminated */ +}; /* - * return value from READ SUBCHANNEL DATA + * audio states (from SCSI-2, but seen with other drives, too) */ - -#define CDROM_AUDIO_INVALID 0x00 /* audio status not supported */ -#define CDROM_AUDIO_PLAY 0x11 /* audio play operation in progress */ -#define CDROM_AUDIO_PAUSED 0x12 /* audio play operation paused */ -#define CDROM_AUDIO_COMPLETED 0x13 /* audio play successfully completed */ -#define CDROM_AUDIO_ERROR 0x14 /* audio play stopped due to error */ -#define CDROM_AUDIO_NO_STATUS 0x15 /* no current audio status to return */ +#define CDROM_AUDIO_INVALID 0x00 /* audio status not supported */ +#define CDROM_AUDIO_PLAY 0x11 /* audio play operation in progress */ +#define CDROM_AUDIO_PAUSED 0x12 /* audio play operation paused */ +#define CDROM_AUDIO_COMPLETED 0x13 /* audio play successfully completed */ +#define CDROM_AUDIO_ERROR 0x14 /* audio play stopped due to error */ +#define CDROM_AUDIO_NO_STATUS 0x15 /* no current audio status to return */ struct cdrom_volctrl - { +{ u_char channel0; u_char channel1; u_char channel2; u_char channel3; - }; +}; struct cdrom_read - { +{ int cdread_lba; caddr_t cdread_bufaddr; int cdread_buflen; - }; +}; /* - * preliminary extensions for transferring audio frames - * currently used by sbpcd.c - * (still may change if other drivers will use it, too): + * extensions for transferring audio frames + * currently used by sbpcd.c, cdu31a.c, ide-cd.c */ struct cdrom_read_audio - { - union - { - struct - { - u_char minute; - u_char second; - u_char frame; - } msf; - int lba; - } addr; /* frame address */ - u_char addr_format; /* CDROM_LBA or CDROM_MSF */ - int nframes; /* number of 2352-byte-frames to read at once, limited by the drivers */ - u_char *buf; /* frame buffer (size: nframes*2352 bytes) */ - }; +{ + union cdrom_addr addr; /* frame address */ + u_char addr_format; /* CDROM_LBA or CDROM_MSF */ + int nframes; /* number of 2352-byte-frames to read at once, limited by the drivers */ + u_char *buf; /* frame buffer (size: nframes*2352 bytes) */ +}; /* * this has to be the "arg" of the CDROMMULTISESSION ioctl @@ -340,20 +196,11 @@ struct cdrom_read_audio * The returned "addr" is valid only if "xa_flag" is true. */ struct cdrom_multisession - { - union - { - struct - { - u_char minute; - u_char second; - u_char frame; - } msf; - int lba; - } addr; /* frame address: start-of-last-session (not the new "frame 16"!)*/ - u_char xa_flag; /* 1: "is XA disk" */ - u_char addr_format; /* CDROM_LBA or CDROM_MSF */ - }; +{ + union cdrom_addr addr; /* frame address: start-of-last-session (not the new "frame 16"!)*/ + u_char xa_flag; /* 1: "is XA disk" */ + u_char addr_format; /* CDROM_LBA or CDROM_MSF */ +}; #ifdef FIVETWELVE #define CDROM_MODE1_SIZE 512 @@ -364,54 +211,235 @@ struct cdrom_multisession /* * CD-ROM IOCTL commands + * For IOCTL calls, we will commandeer byte 0x53, or 'S'. */ -#define CDROMPAUSE 0x5301 /* pause */ -#define CDROMRESUME 0x5302 /* resume */ +#define CDROMPAUSE 0x5301 +#define CDROMRESUME 0x5302 +#define CDROMPLAYMSF 0x5303 /* (struct cdrom_msf) */ +#define CDROMPLAYTRKIND 0x5304 /* (struct cdrom_ti) */ -#define CDROMPLAYMSF 0x5303 /* (struct cdrom_msf) */ - /* SCMD_PLAY_AUDIO_MSF */ +#define CDROMREADTOCHDR 0x5305 /* (struct cdrom_tochdr) */ +#define CDROMREADTOCENTRY 0x5306 /* (struct cdrom_tocentry) */ -#define CDROMPLAYTRKIND 0x5304 /* (struct cdrom_ti) */ - /* SCMD_PLAY_AUDIO_TI */ +#define CDROMSTOP 0x5307 /* stop the drive motor */ +#define CDROMSTART 0x5308 /* turn the motor on */ -#define CDROMREADTOCHDR 0x5305 /* (struct cdrom_tochdr) */ - /* read the TOC header */ -#define CDROMREADTOCENTRY 0x5306 /* (struct cdrom_tocentry) */ - /* read a TOC entry */ +#define CDROMEJECT 0x5309 /* eject CD-ROM media */ -#define CDROMSTOP 0x5307 /* stop the drive motor */ -#define CDROMSTART 0x5308 /* turn the motor on */ +#define CDROMVOLCTRL 0x530a /* (struct cdrom_volctrl) */ -#define CDROMEJECT 0x5309 /* eject CD-ROM media */ +#define CDROMSUBCHNL 0x530b /* (struct cdrom_subchnl) */ -#define CDROMVOLCTRL 0x530a /* (struct cdrom_volctrl) */ - /* volume control */ +#define CDROMREADMODE2 0x530c /* (struct cdrom_read) */ + /* read type-2 data */ -#define CDROMSUBCHNL 0x530b /* (struct cdrom_subchnl) */ - /* read Q sub-channel data */ +#define CDROMREADMODE1 0x530d /* (struct cdrom_read) */ + /* read type-1 data */ -#define CDROMREADMODE2 0x530c /* (struct cdrom_read) */ - /* read type-2 data (not suppt) */ +#define CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */ -#define CDROMREADMODE1 0x530d /* (struct cdrom_read) */ - /* read type-1 data */ -/* - * preliminary extension for transferring audio frames - * currently used by cdu31a.c and sbpcd.c - * (still may change if other drivers will use it, too): - */ -#define CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */ /* - * preliminary extension for enable (1) / disable (0) auto-ejecting - * currently used by sbpcd.c - * (still may change if other drivers will use it, too): + * enable (1) / disable (0) auto-ejecting */ -#define CDROMEJECT_SW 0x530f /* arg: 0 or 1 */ +#define CDROMEJECT_SW 0x530f /* arg: 0 or 1 */ /* * obtain the start-of-last-session address of multi session disks */ -#define CDROMMULTISESSION 0x5310 /* (struct cdrom_multisession) */ +#define CDROMMULTISESSION 0x5310 /* (struct cdrom_multisession) */ + +/* + * obtain the "universal product code" number + * (only some data disks have it coded) + */ +#define CDROM_GET_UPC 0x5311 /* 8 bytes returned */ + +#define CDROMRESET 0x5312 /* hard-reset the drive */ +#define CDROMVOLREAD 0x5313 /* let the drive tell its volume setting */ + /* (struct cdrom_volctrl) */ + +/* + * these ioctls are used in aztcd.c and optcd.c + */ +#define CDROMREADRAW 0x5314 /* read data in raw mode */ +#define CDROMREADCOOKED 0x5315 /* read data in cooked mode */ +#define CDROMSEEK 0x5316 /* seek msf address */ + +/* + * for playing audio in logical block addressing mode + */ +#define CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */ + +/* + * these ioctls are used in optcd.c + */ +#define CDROMREADALL 0x5318 /* read all 2646 bytes */ +#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ + + +/* + * CD-ROM-specific SCSI command opcodes + */ + +/* + * Group 2 (10-byte). All of these are called 'optional' by SCSI-II. + */ +#define SCMD_READ_TOC 0x43 /* read table of contents */ +#define SCMD_PLAYAUDIO_MSF 0x47 /* play data at time offset */ +#define SCMD_PLAYAUDIO_TI 0x48 /* play data at track/index */ +#define SCMD_PAUSE_RESUME 0x4B /* pause/resume audio */ +#define SCMD_READ_SUBCHANNEL 0x42 /* read SC info on playing disc */ +#define SCMD_PLAYAUDIO10 0x45 /* play data at logical block */ +#define SCMD_READ_HEADER 0x44 /* read TOC header */ + +/* + * Group 5 + */ +#define SCMD_PLAYAUDIO12 0xA5 /* play data at logical block */ +#define SCMD_PLAYTRACK_REL12 0xA9 /* play track at relative offset */ + +/* + * Group 6 Commands + */ +#define SCMD_CD_PLAYBACK_CONTROL 0xC9 /* Sony vendor-specific audio */ +#define SCMD_CD_PLAYBACK_STATUS 0xC4 /* control opcodes */ + +/* + * CD-ROM capacity structure. + */ +struct scsi_capacity +{ + u_long capacity; + u_long lbasize; +}; + +/* + * CD-ROM MODE_SENSE/MODE_SELECT parameters + */ +#define ERR_RECOVERY_PARMS 0x01 +#define DISCO_RECO_PARMS 0x02 +#define FORMAT_PARMS 0x03 +#define GEOMETRY_PARMS 0x04 +#define CERTIFICATION_PARMS 0x06 +#define CACHE_PARMS 0x38 + +/* + * standard mode-select header prepended to all mode-select commands + */ +struct ccs_modesel_head +{ + u_char _r1; /* reserved */ + u_char medium; /* device-specific medium type */ + u_char _r2; /* reserved */ + u_char block_desc_length; /* block descriptor length */ + u_char density; /* device-specific density code */ + u_char number_blocks_hi; /* number of blocks in this block desc */ + u_char number_blocks_med; + u_char number_blocks_lo; + u_char _r3; + u_char block_length_hi; /* block length for blocks in this desc */ + u_short block_length; +}; + +/* + * error recovery parameters + */ +struct ccs_err_recovery +{ + u_char _r1 : 2; /* reserved */ + u_char page_code : 6; /* page code */ + u_char page_length; /* page length */ + u_char awre : 1; /* auto write realloc enabled */ + u_char arre : 1; /* auto read realloc enabled */ + u_char tb : 1; /* transfer block */ + u_char rc : 1; /* read continuous */ + u_char eec : 1; /* enable early correction */ + u_char per : 1; /* post error */ + u_char dte : 1; /* disable transfer on error */ + u_char dcr : 1; /* disable correction */ + u_char retry_count; /* error retry count */ + u_char correction_span; /* largest recov. to be attempted, bits */ + u_char head_offset_count; /* head offset (2's C) for each retry */ + u_char strobe_offset_count; /* data strobe */ + u_char recovery_time_limit; /* time limit on recovery attempts */ +}; + +/* + * disco/reco parameters + */ +struct ccs_disco_reco +{ + u_char _r1 : 2; /* reserved */ + u_char page_code : 6; /* page code */ + u_char page_length; /* page length */ + u_char buffer_full_ratio; /* write buffer reconnect threshold */ + u_char buffer_empty_ratio; /* read */ + u_short bus_inactivity_limit; /* limit on bus inactivity time */ + u_short disconnect_time_limit; /* minimum disconnect time */ + u_short connect_time_limit; /* minimum connect time */ + u_short _r2; /* reserved */ +}; + +/* + * drive geometry parameters + */ +struct ccs_geometry +{ + u_char _r1 : 2; /* reserved */ + u_char page_code : 6; /* page code */ + u_char page_length; /* page length */ + u_char cyl_ub; /* #cyls */ + u_char cyl_mb; + u_char cyl_lb; + u_char heads; /* #heads */ + u_char precomp_cyl_ub; /* precomp start */ + u_char precomp_cyl_mb; + u_char precomp_cyl_lb; + u_char current_cyl_ub; /* reduced current start */ + u_char current_cyl_mb; + u_char current_cyl_lb; + u_short step_rate; /* stepping motor rate */ + u_char landing_cyl_ub; /* landing zone */ + u_char landing_cyl_mb; + u_char landing_cyl_lb; + u_char _r2; + u_char _r3; + u_char _r4; +}; + +/* + * cache parameters + */ +struct ccs_cache +{ + u_char _r1 : 2; /* reserved */ + u_char page_code : 6; /* page code */ + u_char page_length; /* page length */ + u_char mode; /* cache control byte */ + u_char threshold; /* prefetch threshold */ + u_char max_prefetch; /* maximum prefetch size */ + u_char max_multiplier; /* maximum prefetch multiplier */ + u_char min_prefetch; /* minimum prefetch size */ + u_char min_multiplier; /* minimum prefetch multiplier */ + u_char _r2[8]; +}; #endif _LINUX_CDROM_H +/*==========================================================================*/ +/* + * 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-indent-level: 8 + * c-brace-imaginary-offset: 0 + * c-brace-offset: -8 + * c-argdecl-indent: 8 + * c-label-offset: -8 + * c-continued-statement-offset: 8 + * c-continued-brace-offset: 0 + * End: + */ diff --git a/include/linux/cdu31a.h b/include/linux/cdu31a.h index fc1150fef..269e7b614 100644 --- a/include/linux/cdu31a.h +++ b/include/linux/cdu31a.h @@ -66,16 +66,16 @@ #define LOG_START_OFFSET 150 /* Offset of first logical sector */ -#define SONY_DETECT_TIMEOUT 80 /* Maximum amount of time +#define SONY_DETECT_TIMEOUT (8*HZ/10) /* Maximum amount of time that drive detection code will wait for response from drive (in 1/100th's of seconds). */ -#define SONY_JIFFIES_TIMEOUT 1000 /* Maximum number of times the +#define SONY_JIFFIES_TIMEOUT 1000 /* Maximum number of times the drive will wait/try for an operation */ -#define SONY_RESET_TIMEOUT 100 /* Maximum number of times the +#define SONY_RESET_TIMEOUT 100 /* Maximum number of times the drive will wait/try a reset operation */ #define SONY_READY_RETRIES 20000 /* How many times to retry a @@ -134,6 +134,13 @@ #define SONY_SD_AUTO_SPIN_DOWN_TIME 0x06 /* + * The following are parameter bits for the mechanical control command + */ +#define SONY_AUTO_SPIN_UP_BIT 0x01 +#define SONY_AUTO_EJECT_BIT 0x02 +#define SONY_DOUBLE_SPEED_BIT 0x04 + +/* * The following extract information from the drive configuration about * the drive itself. */ diff --git a/include/linux/cm206.h b/include/linux/cm206.h new file mode 100644 index 000000000..671a46f31 --- /dev/null +++ b/include/linux/cm206.h @@ -0,0 +1,177 @@ +/* cm206.h Header file for cm206.c. + Copyright (c) 1995 David van Leeuwen +*/ + +#ifndef LINUX_CM206_H +#define LINUX_CM206_H + +#include <linux/ioctl.h> + +/* First, the cm260 stuff */ +/* The ports and irq used. Although CM206_BASE and CM206_IRQ are defined + below, the values are not used unless autoprobing is turned off and + no LILO boot options or module command line options are given. Change + these values to your own as last resort if autoprobing and options + don't work. */ + +#define CM206_BASE 0x340 +#define CM206_IRQ 11 + +#define r_data_status (cm206_base) +#define r_uart_receive (cm206_base+0x2) +#define r_fifo_output_buffer (cm206_base+0x4) +#define r_line_status (cm206_base+0x6) +#define r_data_control (cm206_base+0x8) +#define r_uart_transmit (cm206_base+0xa) +#define r_test_clock (cm206_base+0xc) +#define r_test_control (cm206_base+0xe) + +/* the data_status flags */ +#define ds_ram_size 0x4000 +#define ds_toc_ready 0x2000 +#define ds_fifo_empty 0x1000 +#define ds_sync_error 0x800 +#define ds_crc_error 0x400 +#define ds_data_error 0x200 +#define ds_fifo_overflow 0x100 +#define ds_data_ready 0x80 + +/* the line_status flags */ +#define ls_attention 0x10 +#define ls_parity_error 0x8 +#define ls_overrun 0x4 +#define ls_receive_buffer_full 0x2 +#define ls_transmitter_buffer_empty 0x1 + +/* the data control register flags */ +#define dc_read_q_channel 0x4000 +#define dc_mask_sync_error 0x2000 +#define dc_toc_enable 0x1000 +#define dc_no_stop_on_error 0x800 +#define dc_break 0x400 +#define dc_initialize 0x200 +#define dc_mask_transmit_ready 0x100 +#define dc_flag_enable 0x80 + +/* Define the default data control register flags here */ +#define dc_normal (dc_mask_sync_error | dc_no_stop_on_error | \ + dc_mask_transmit_ready) + +/* now some constants related to the cm206 */ +/* another drive status byte, echoed by the cm206 on most commands */ + +#define dsb_error_condition 0x1 +#define dsb_play_in_progress 0x4 +#define dsb_possible_media_change 0x8 +#define dsb_disc_present 0x10 +#define dsb_drive_not_ready 0x20 +#define dsb_tray_locked 0x40 +#define dsb_tray_not_closed 0x80 + +#define dsb_not_useful (dsb_drive_not_ready | dsb_tray_not_closed) + +/* the cm206 command set */ + +#define c_close_tray 0 +#define c_lock_tray 0x01 +#define c_unlock_tray 0x04 +#define c_open_tray 0x05 +#define c_seek 0x10 +#define c_read_data 0x20 +#define c_force_1x 0x21 +#define c_force_2x 0x22 +#define c_auto_mode 0x23 +#define c_play 0x30 +#define c_set_audio_mode 0x31 +#define c_read_current_q 0x41 +#define c_stream_q 0x42 +#define c_drive_status 0x50 +#define c_disc_status 0x51 +#define c_audio_status 0x52 +#define c_drive_configuration 0x53 +#define c_read_upc 0x60 +#define c_stop 0x70 +#define c_calc_checksum 0xe5 + +#define c_gimme 0xf8 + +/* finally, the (error) condition that the drive can be in * + * OK, this is not always an error, but let's prefix it with e_ */ + +#define e_none 0 +#define e_illegal_command 0x01 +#define e_sync 0x02 +#define e_seek 0x03 +#define e_parity 0x04 +#define e_focus 0x05 +#define e_header_sync 0x06 +#define e_code_incompatibility 0x07 +#define e_reset_done 0x08 +#define e_bad_parameter 0x09 +#define e_radial 0x0a +#define e_sub_code 0x0b +#define e_no_data_track 0x0c +#define e_scan 0x0d +#define e_tray_open 0x0f +#define e_no_disc 0x10 +#define e_tray stalled 0x11 + +/* drive configuration masks */ + +#define dcf_revision_code 0x7 +#define dcf_transfer_rate 0x60 +#define dcf_motorized_tray 0x80 + +/* disc status byte */ + +#define cds_multi_session 0x2 +#define cds_all_audio 0x8 +#define cds_xa_mode 0xf0 + +/* finally some ioctls for the driver */ + +#define CM206CTL_GET_STAT _IO( 0x20, 0 ) +#define CM206CTL_GET_LAST_STAT _IO( 0x20, 1 ) + +/* for kernel 1.2.n */ +#if !defined(CDROM_GET_UPC) +#define CDROM_GET_UPC _IO( 'S', 0x11 ) +#define CDROMRESET _IO( 'S', 0x12 ) +#endif + +#ifdef STATISTICS + +/* This is an ugly way to guarantee that the names of the statistics + * are the same in the code and in the diagnostics program. */ + +#ifdef __KERNEL__ +#define x(a) st_ ## a +#define y enum +#else +#define x(a) #a +#define y char * stats_name[] = +#endif + +y {x(interrupt), x(data_ready), x(fifo_overflow), x(data_error), + x(crc_error), x(sync_error), x(lost_intr), x(echo), + x(write_timeout), x(receive_timeout), x(read_timeout), + x(dsb_timeout), x(stop_0xff), x(back_read_timeout), + x(sector_transferred), x(read_restarted), x(read_background), + x(bh), x(open), x(ioctl_multisession), x(attention) +#ifdef __KERNEL__ + , x(last_entry) +#endif + }; + +#ifdef __KERNEL__ +#define NR_STATS st_last_entry +#else +#define NR_STATS (sizeof(stats_name)/sizeof(char*)) +#endif + +#undef y +#undef x + +#endif STATISTICS + +#endif LINUX_CM206_H diff --git a/include/linux/comstats.h b/include/linux/comstats.h new file mode 100644 index 000000000..8f7591f38 --- /dev/null +++ b/include/linux/comstats.h @@ -0,0 +1,118 @@ +/*****************************************************************************/ + +/* + * comstats.h -- Serial Port Stats. + * + * Copyright (C) 1994-1996 Greg Ungerer (gerg@stallion.oz.au). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*****************************************************************************/ +#ifndef _COMSTATS_H +#define _COMSTATS_H +/*****************************************************************************/ + +/* + * Serial port stats structure. The structure itself is UART + * independent, but some fields may be UART/driver specific (for + * example state). + */ + +typedef struct { + unsigned long brd; + unsigned long panel; + unsigned long port; + unsigned long hwid; + unsigned long type; + unsigned long txtotal; + unsigned long rxtotal; + unsigned long txbuffered; + unsigned long rxbuffered; + unsigned long rxoverrun; + unsigned long rxparity; + unsigned long rxframing; + unsigned long rxlost; + unsigned long txbreaks; + unsigned long rxbreaks; + unsigned long txxon; + unsigned long txxoff; + unsigned long rxxon; + unsigned long rxxoff; + unsigned long txctson; + unsigned long txctsoff; + unsigned long rxrtson; + unsigned long rxrtsoff; + unsigned long modem; + unsigned long state; + unsigned long flags; + unsigned long ttystate; + unsigned long cflags; + unsigned long iflags; + unsigned long oflags; + unsigned long lflags; + unsigned long signals; +} comstats_t; + + +/* + * Board stats structure. Returns useful info about the board. + */ + +#define COM_MAXPANELS 8 + +typedef struct { + unsigned long panel; + unsigned long type; + unsigned long hwid; + unsigned long nrports; +} companel_t; + +typedef struct { + unsigned long brd; + unsigned long type; + unsigned long hwid; + unsigned long state; + unsigned long ioaddr; + unsigned long ioaddr2; + unsigned long memaddr; + unsigned long irq; + unsigned long nrpanels; + unsigned long nrports; + companel_t panels[COM_MAXPANELS]; +} combrd_t; + + +/* + * Define the ioctl operations for stats stuff. + */ +#include <linux/ioctl.h> + +#define COM_GETPORTSTATS _IO('c',30) +#define COM_CLRPORTSTATS _IO('c',31) +#define COM_GETBRDSTATS _IO('c',32) + + +/* + * Define the set of ioctls that give user level access to the + * private port, panel and board structures. The argument required + * will be driver dependent! + */ +#define COM_READPORT _IO('c',40) +#define COM_READBOARD _IO('c',41) +#define COM_READPANEL _IO('c',42) + +/*****************************************************************************/ +#endif diff --git a/include/linux/config.h b/include/linux/config.h index a54cdff20..790cff448 100644 --- a/include/linux/config.h +++ b/include/linux/config.h @@ -27,7 +27,9 @@ * in linux/version.h, and should only be used by linux/version.c */ -/* Don't touch these, unless you really know what your doing. */ +/* Shouldn't these be defined somewhere in an i386 definition? */ + +/* Don't touch these, unless you really know what you're doing. */ #define DEF_INITSEG 0x9000 #define DEF_SYSSEG 0x1000 #define DEF_SETUPSEG 0x9020 diff --git a/include/linux/console.h b/include/linux/console.h new file mode 100644 index 000000000..80a1c5e69 --- /dev/null +++ b/include/linux/console.h @@ -0,0 +1,124 @@ +/* + * linux/include/linux/console.h + * + * Copyright (C) 1993 Hamish Macdonald + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Changed: + * 10-Mar-94: Arno Griffioen: Conversion for vt100 emulator port from PC LINUX + */ + +#ifndef _LINUX_CONSOLE_H_ +#define _LINUX_CONSOLE_H_ 1 + +#define NPAR 16 + +struct vc_data { + unsigned long vc_screenbuf_size; + unsigned short vc_num; /* Console number */ + unsigned short vc_video_erase_char; /* Background erase character */ + unsigned char vc_attr; /* Current attributes */ + unsigned char vc_def_color; /* Default colors */ + unsigned char vc_color; /* Foreground & background */ + unsigned char vc_s_color; /* Saved foreground & background */ + unsigned char vc_ulcolor; /* Colour for underline mode */ + unsigned char vc_halfcolor; /* Colour for half intensity mode */ + unsigned long vc_origin; /* Used for EGA/VGA fast scroll */ + unsigned long vc_scr_end; /* Used for EGA/VGA fast scroll */ + unsigned short *vc_pos; + unsigned long vc_x,vc_y; + unsigned long vc_top,vc_bottom; + unsigned long vc_rows,vc_cols; + unsigned long vc_size_row; + unsigned long vc_state; + unsigned long vc_npar,vc_par[NPAR]; + unsigned short *vc_video_mem_start; + unsigned long vc_video_mem_end; /* End of video RAM (sort of) */ + unsigned long vc_saved_x; + unsigned long vc_saved_y; + /* mode flags */ + unsigned long vc_charset : 1; /* Character set G0 / G1 */ + unsigned long vc_s_charset : 1; /* Saved character set */ + unsigned long vc_disp_ctrl : 1; /* Display chars < 32? */ + unsigned long vc_toggle_meta : 1; /* Toggle high bit? */ + unsigned long vc_decscnm : 1; /* Screen Mode */ + unsigned long vc_decom : 1; /* Origin Mode */ + unsigned long vc_decawm : 1; /* Autowrap Mode */ + unsigned long vc_deccm : 1; /* Cursor Visible */ + unsigned long vc_decim : 1; /* Insert Mode */ + unsigned long vc_deccolm : 1; /* 80/132 Column Mode */ + /* attribute flags */ + unsigned long vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */ + unsigned long vc_underline : 1; + unsigned long vc_blink : 1; + unsigned long vc_reverse : 1; + unsigned long vc_s_intensity : 2; /* saved rendition */ + unsigned long vc_s_underline : 1; + unsigned long vc_s_blink : 1; + unsigned long vc_s_reverse : 1; + /* misc */ + unsigned long vc_ques : 1; + unsigned long vc_need_wrap : 1; + unsigned long vc_can_do_color : 1; + unsigned long vc_has_scrolled : 1; /* Info for unblank_screen */ + unsigned long vc_kmalloced : 1; /* kfree_s() needed */ + unsigned long vc_report_mouse : 2; + unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */ + unsigned char vc_utf_count; + unsigned long vc_utf_char; + unsigned long vc_tab_stop[5]; /* Tab stops. 160 columns. */ + unsigned short *vc_translate; + unsigned char vc_G0_charset; + unsigned char vc_G1_charset; + unsigned char vc_saved_G0; + unsigned char vc_saved_G1; + unsigned int vc_bell_pitch; /* Console bell pitch */ + unsigned int vc_bell_duration; /* Console bell duration */ + struct consw *vc_sw; + /* additional information is in vt_kern.h */ +}; + +/* + * this is what the terminal answers to a ESC-Z or csi0c query. + */ +#define VT100ID "\033[?1;2c" +#define VT102ID "\033[?6c" + +/* DPC: 1994-04-13 !!! con_putcs is new entry !!! */ + +struct consw { + unsigned long (*con_startup)(unsigned long, char **); + void (*con_init)(struct vc_data *); + int (*con_deinit)(struct vc_data *); + int (*con_clear)(struct vc_data *, int, int, int, int); + int (*con_putc)(struct vc_data *, int, int, int); + int (*con_putcs)(struct vc_data *, const char *, int, int, int); + int (*con_cursor)(struct vc_data *, int); + int (*con_scroll)(struct vc_data *, int, int, int, int); + int (*con_bmove)(struct vc_data *, int, int, int, int, int, int); + int (*con_switch)(struct vc_data *); + int (*con_blank)(int); + int (*con_get_font)(struct vc_data *, int *, int *, char *); + int (*con_set_font)(struct vc_data *, int, int, char *); +}; + +extern struct consw *conswitchp; + +/* flag bits */ +#define CON_INITED (1) + +/* scroll */ +#define SM_UP (1) +#define SM_DOWN (2) +#define SM_LEFT (3) +#define SM_RIGHT (4) + +/* cursor */ +#define CM_DRAW (1) +#define CM_ERASE (2) +#define CM_MOVE (3) + +#endif /* linux/console.h */ diff --git a/include/linux/ctype.h b/include/linux/ctype.h index 838ef933d..bac58b52f 100644 --- a/include/linux/ctype.h +++ b/include/linux/ctype.h @@ -1,6 +1,11 @@ #ifndef _LINUX_CTYPE_H #define _LINUX_CTYPE_H +/* + * NOTE! This ctype does not handle EOF like the standarc C + * library is required to. + */ + #define _U 0x01 /* upper */ #define _L 0x02 /* lower */ #define _D 0x04 /* digit */ @@ -11,24 +16,39 @@ #define _SP 0x80 /* hard space (0x20) */ extern unsigned char _ctype[]; -extern char _ctmp; - -#define isalnum(c) ((_ctype+1)[c]&(_U|_L|_D)) -#define isalpha(c) ((_ctype+1)[c]&(_U|_L)) -#define iscntrl(c) ((_ctype+1)[c]&(_C)) -#define isdigit(c) ((_ctype+1)[c]&(_D)) -#define isgraph(c) ((_ctype+1)[c]&(_P|_U|_L|_D)) -#define islower(c) ((_ctype+1)[c]&(_L)) -#define isprint(c) ((_ctype+1)[c]&(_P|_U|_L|_D|_SP)) -#define ispunct(c) ((_ctype+1)[c]&(_P)) -#define isspace(c) ((_ctype+1)[c]&(_S)) -#define isupper(c) ((_ctype+1)[c]&(_U)) -#define isxdigit(c) ((_ctype+1)[c]&(_D|_X)) - -#define isascii(c) (((unsigned) c)<=0x7f) -#define toascii(c) (((unsigned) c)&0x7f) - -#define tolower(c) (_ctmp=c,isupper(_ctmp)?_ctmp-('A'-'a'):_ctmp) -#define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp-('a'-'A'):_ctmp) + +#define __ismask(x) (_ctype[(int)(unsigned char)(x)]) + +#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) +#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) +#define iscntrl(c) ((__ismask(c)&(_C)) != 0) +#define isdigit(c) ((__ismask(c)&(_D)) != 0) +#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) +#define islower(c) ((__ismask(c)&(_L)) != 0) +#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) +#define ispunct(c) ((__ismask(c)&(_P)) != 0) +#define isspace(c) ((__ismask(c)&(_S)) != 0) +#define isupper(c) ((__ismask(c)&(_U)) != 0) +#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) + +#define isascii(c) (((unsigned char)(c))<=0x7f) +#define toascii(c) (((unsigned char)(c))&0x7f) + +static inline unsigned char __tolower(unsigned char c) +{ + if (isupper(c)) + c -= 'A'-'a'; + return c; +} + +static inline unsigned char __toupper(unsigned char c) +{ + if (islower(c)) + c -= 'a'-'A'; + return c; +} + +#define tolower(c) __tolower(c) +#define toupper(c) __toupper(c) #endif diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h index 73f01e26a..efed32b4d 100644 --- a/include/linux/cyclades.h +++ b/include/linux/cyclades.h @@ -1,13 +1,20 @@ -struct cyclades_card { - int base_addr; - int irq; - int num_chips; /* implies card type, 0 if card is absent */ - int first_line; /* line number of first channel of first chip on card */ -}; +/* + * linux/include/linux/cyclades.h + * + * This file is maintained by Marcio Saito <marcio@cyclades.com> and + * Randolph Bentson <bentson@grieg.seaslug.org>. + * + * This file contains the general definitions for the cyclades.c driver + *$Log: cyclades.h,v $ + * Revision 1.5 1995/11/13 21:13:31 bentson + * changes suggested by Michael Chastain <mec@duracef.shout.net> + * to support use of this file in non-kernel applications + * + * + */ -struct cyclades_chip { - int filler; -}; +#ifndef _LINUX_CYCLADES_H +#define _LINUX_CYCLADES_H struct cyclades_monitor { unsigned long int_count; @@ -16,6 +23,34 @@ struct cyclades_monitor { unsigned long char_last; }; +#define CYCLADES_MAGIC 0x4359 + +#define CYGETMON 0x435901 +#define CYGETTHRESH 0x435902 +#define CYSETTHRESH 0x435903 +#define CYGETDEFTHRESH 0x435904 +#define CYSETDEFTHRESH 0x435905 +#define CYGETTIMEOUT 0x435906 +#define CYSETTIMEOUT 0x435907 +#define CYGETDEFTIMEOUT 0x435908 +#define CYSETDEFTIMEOUT 0x435909 + +#ifdef __KERNEL__ + +/* Per card data structure */ + +struct cyclades_card { + int base_addr; + int irq; + int num_chips; /* 0 if card is absent */ + int first_line; /* minor number of first channel on card */ + int bus_index; /* address shift - 0 for ISA, 1 for PCI */ +}; + +struct cyclades_chip { + int filler; +}; + /* * This is our internal structure for each serial port's state. * @@ -62,18 +97,6 @@ struct cyclades_port { struct cyclades_monitor mon; }; -#define CYCLADES_MAGIC 0x4359 - -#define CYGETMON 0x435901 -#define CYGETTHRESH 0x435902 -#define CYSETTHRESH 0x435903 -#define CYGETDEFTHRESH 0x435904 -#define CYSETDEFTHRESH 0x435905 -#define CYGETTIMEOUT 0x435906 -#define CYSETTIMEOUT 0x435907 -#define CYGETDEFTIMEOUT 0x435908 -#define CYSETDEFTIMEOUT 0x435909 - /* * Events are used to schedule things to happen at timer-interrupt * time, instead of at cy interrupt time. @@ -93,6 +116,7 @@ struct cyclades_port { #define CyRegSize 0x0400 #define Cy_HwReset 0x1400 #define Cy_ClrIntr 0x1800 +#define Cy_EpldRev 0x1e00 /* Global Registers */ @@ -255,3 +279,6 @@ struct cyclades_port { #define CyMAX_CHAR_FIFO 12 /***************************************************************************/ + +#endif /* __KERNEL__ */ +#endif /* _LINUX_CYCLADES_H */ diff --git a/include/linux/debugreg.h b/include/linux/debugreg.h index ba93e10c6..d954a54ca 100644 --- a/include/linux/debugreg.h +++ b/include/linux/debugreg.h @@ -21,7 +21,7 @@ /* Now define a bunch of things for manipulating the control register. The top two bytes of the control register consist of 4 fields of 4 - bytes - each field corresponds to one of the four debug registers, + bits - each field corresponds to one of the four debug registers, and indicates what types of access we trap on, and how large the data field is that we are looking at */ diff --git a/include/linux/dirent.h b/include/linux/dirent.h index 219faf1cb..a18f7e463 100644 --- a/include/linux/dirent.h +++ b/include/linux/dirent.h @@ -1,13 +1,11 @@ #ifndef _LINUX_DIRENT_H #define _LINUX_DIRENT_H -#include <linux/limits.h> - struct dirent { long d_ino; - off_t d_off; + __kernel_off_t d_off; unsigned short d_reclen; - char d_name[NAME_MAX+1]; + char d_name[256]; /* We must not include limits.h! */ }; #endif diff --git a/include/linux/elf.h b/include/linux/elf.h index 52dedbda4..3487041ba 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -1,6 +1,8 @@ #ifndef _LINUX_ELF_H #define _LINUX_ELF_H +#include <asm/elf.h> + typedef unsigned long Elf32_Addr; typedef unsigned short Elf32_Half; typedef unsigned long Elf32_Off; @@ -54,6 +56,25 @@ typedef unsigned long Elf32_Word; #define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */ #define EM_PARISC 15 +#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ + +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ + +#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */ + +#define EM_PARISC 15 /* HPPA */ + +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ + +#define EM_PPC 20 /* PowerPC */ + +/* + * This is an interim value that we will use until the committee comes + * up with a final number. + */ +#define EM_ALPHA 0x9026 + + /* This is the info that is needed to parse the dynamic section of the file */ #define DT_NULL 0 #define DT_NEEDED 1 @@ -115,6 +136,23 @@ typedef unsigned long Elf32_Word; #define ELF32_ST_BIND(x) ((x) >> 4) #define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) +/* Symbolic values for the entries in the auxiliary table + put on the initial stack */ +#define AT_NULL 0 /* end of vector */ +#define AT_IGNORE 1 /* entry should be ignored */ +#define AT_EXECFD 2 /* file descriptor of program */ +#define AT_PHDR 3 /* program headers for program */ +#define AT_PHENT 4 /* size of program header entry */ +#define AT_PHNUM 5 /* number of program headers */ +#define AT_PAGESZ 6 /* system page size */ +#define AT_BASE 7 /* base address of interpreter */ +#define AT_FLAGS 8 /* flags */ +#define AT_ENTRY 9 /* entry point of program */ +#define AT_NOTELF 10 /* program is not ELF */ +#define AT_UID 11 /* real uid */ +#define AT_EUID 12 /* effective uid */ +#define AT_GID 13 /* real gid */ +#define AT_EGID 14 /* effective gid */ typedef struct dynamic{ @@ -125,7 +163,13 @@ typedef struct dynamic{ } d_un; } Elf32_Dyn; -extern Elf32_Dyn _DYNAMIC []; +typedef struct { + unsigned long long d_tag; /* entry tag value */ + union { + unsigned long long d_val; + unsigned long long d_ptr; + } d_un; +} Elf64_Dyn; /* The following are used with relocations */ #define ELF32_R_SYM(x) ((x) >> 8) @@ -168,28 +212,53 @@ extern Elf32_Dyn _DYNAMIC []; #define R_MIPS_GOT_DISP 19 #define R_MIPS_GOT_PAGE 20 #define R_MIPS_GOT_OFST 21 -#define R_MIPS_GOT_HI16 22 -#define R_MIPS_GOT_LO16 23 +/* + * The following two relocation types are specified in the the MIPS ABI + * conformance guide version 1.2 but not yet in the psABI. + */ +#define R_MIPS_GOTHI16 22 +#define R_MIPS_GOTLO16 23 #define R_MIPS_SUB 24 #define R_MIPS_INSERT_A 25 #define R_MIPS_INSERT_B 26 #define R_MIPS_DELETE 27 #define R_MIPS_HIGHER 28 #define R_MIPS_HIGHEST 29 -#define R_MIPS_CALL_HI16 30 -#define R_MIPS_CALL_LO16 31 +/* + * The following two relocation types are specified in the the MIPS ABI + * conformance guide version 1.2 but not yet in the psABI. + */ +#define R_MIPS_CALLHI16 30 +#define R_MIPS_CALLLO16 31 +/* + * This range is reserved for vendor specific relocations. + */ +#define R_MIPS_LOVENDOR 100 +#define R_MIPS_HIVENDOR 127 + typedef struct elf32_rel { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel; +typedef struct elf64_rel { + unsigned long long r_offset; /* Location at which to apply the action */ + unsigned long long r_info; /* index and type of relocation */ +} Elf64_Rel; + typedef struct elf32_rela{ Elf32_Addr r_offset; Elf32_Word r_info; Elf32_Sword r_addend; } Elf32_Rela; +typedef struct elf64_rela { + unsigned long long r_offset; /* Location at which to apply the action */ + unsigned long long r_info; /* index and type of relocation */ + unsigned long long r_addend; /* Constant addend used to compute value */ +} Elf64_Rela; + typedef struct elf32_sym{ Elf32_Word st_name; Elf32_Addr st_value; @@ -199,10 +268,19 @@ typedef struct elf32_sym{ Elf32_Half st_shndx; } Elf32_Sym; +typedef struct elf64_sym { + unsigned int st_name; /* Symbol name, index in string tbl */ + unsigned char st_info; /* Type and binding attributes */ + unsigned char st_other; /* No defined meaning, 0 */ + unsigned short st_shndx; /* Associated section index */ + unsigned long long st_value; /* Value of the symbol */ + unsigned long long st_size; /* Associated symbol size */ +} Elf64_Sym; + #define EI_NIDENT 16 -typedef struct elfhdr{ +typedef struct elf32_hdr{ unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; @@ -219,13 +297,30 @@ typedef struct elfhdr{ Elf32_Half e_shstrndx; } Elf32_Ehdr; +typedef struct elf64_hdr { + unsigned char e_ident[16]; /* ELF "magic number" */ + short int e_type; + short unsigned int e_machine; + int e_version; + unsigned long long e_entry; /* Entry point virtual address */ + unsigned long long e_phoff; /* Program header table file offset */ + unsigned long long e_shoff; /* Section header table file offset */ + int e_flags; + short int e_ehsize; + short int e_phentsize; + short int e_phnum; + short int e_shentsize; + short int e_shnum; + short int e_shstrndx; +} Elf64_Ehdr; + /* These constants define the permissions on sections in the program header, p_flags. */ #define PF_R 0x4 #define PF_W 0x2 #define PF_X 0x1 -typedef struct elf_phdr{ +typedef struct elf32_phdr{ Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; @@ -236,6 +331,17 @@ typedef struct elf_phdr{ Elf32_Word p_align; } Elf32_Phdr; +typedef struct elf64_phdr { + int p_type; + int p_flags; + unsigned long long p_offset; /* Segment file offset */ + unsigned long long p_vaddr; /* Segment virtual address */ + unsigned long long p_paddr; /* Segment physical address */ + unsigned long long p_filesz; /* Segment size in file */ + unsigned long long p_memsz; /* Segment size in memory */ + unsigned long long p_align; /* Segment alignment, file & memory */ +} Elf64_Phdr; + /* sh_type */ #define SHT_NULL 0 #define SHT_PROGBITS 1 @@ -289,6 +395,19 @@ typedef struct { Elf32_Word sh_entsize; } Elf32_Shdr; +typedef struct elf64_shdr { + unsigned int sh_name; /* Section name, index in string tbl */ + unsigned int sh_type; /* Type of section */ + unsigned long long sh_flags; /* Miscellaneous section attributes */ + unsigned long long sh_addr; /* Section virtual addr at execution */ + unsigned long long sh_offset; /* Section file offset */ + unsigned long long sh_size; /* Size of section in bytes */ + unsigned int sh_link; /* Index of another section */ + unsigned int sh_info; /* Additional section information */ + unsigned long long sh_addralign; /* Section alignment */ + unsigned long long sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + #define EI_MAG0 0 /* e_ident[] indexes */ #define EI_MAG1 1 #define EI_MAG2 2 @@ -325,12 +444,41 @@ typedef struct { #define NT_TASKSTRUCT 4 /* Note header in a PT_NOTE section */ -typedef struct elf_note { +typedef struct elf32_note { Elf32_Word n_namesz; /* Name size */ Elf32_Word n_descsz; /* Content size */ Elf32_Word n_type; /* Content type */ } Elf32_Nhdr; +/* Note header in a PT_NOTE section */ +/* + * For now we use the 32 bit version of the structure until we figure + * out whether we need anything better. Note - on the Alpha, "unsigned int" + * is only 32 bits. + */ +typedef struct elf64_note { + unsigned int n_namesz; /* Name size */ + unsigned int n_descsz; /* Content size */ + unsigned int n_type; /* Content type */ +} Elf64_Nhdr; + #define ELF_START_MMAP 0x80000000 +#if ELF_CLASS == ELFCLASS32 + +extern Elf32_Dyn _DYNAMIC []; +#define elfhdr elf32_hdr +#define elf_phdr elf32_phdr +#define elf_note elf32_note + +#else + +extern Elf64_Dyn _DYNAMIC []; +#define elfhdr elf64_hdr +#define elf_phdr elf64_phdr +#define elf_note elf64_note + +#endif + + #endif /* _LINUX_ELF_H */ diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h new file mode 100644 index 000000000..2fe53ca3d --- /dev/null +++ b/include/linux/elfcore.h @@ -0,0 +1,88 @@ +#ifndef _LINUX_ELFCORE_H +#define _LINUX_ELFCORE_H + +#include <linux/types.h> +#include <linux/signal.h> +#include <linux/time.h> +#include <linux/ptrace.h> +#include <linux/user.h> + +struct elf_siginfo +{ + int si_signo; /* signal number */ + int si_code; /* extra code */ + int si_errno; /* errno */ +}; + +#include <asm/elf.h> + +#ifndef __KERNEL__ +typedef elf_greg_t greg_t; +typedef elf_gregset_t gregset_t; +typedef elf_fpregset_t fpregset_t; +#define NGREG ELF_NGREG +#endif + +/* + * Definitions to generate Intel SVR4-like core files. + * These mostly have the same names as the SVR4 types with "elf_" + * tacked on the front to prevent clashes with linux definitions, + * and the typedef forms have been avoided. This is mostly like + * the SVR4 structure, but more Linuxy, with things that Linux does + * not support and which gdb doesn't really use excluded. + * Fields present but not used are marked with "XXX". + */ +struct elf_prstatus +{ +#if 0 + long pr_flags; /* XXX Process flags */ + short pr_why; /* XXX Reason for process halt */ + short pr_what; /* XXX More detailed reason */ +#endif + struct elf_siginfo pr_info; /* Info associated with signal */ + short pr_cursig; /* Current signal */ + sigset_t pr_sigpend; /* Set of pending signals */ + sigset_t pr_sighold; /* Set of held signals */ +#if 0 + struct sigaltstack pr_altstack; /* Alternate stack info */ + struct sigaction pr_action; /* Signal action for current sig */ +#endif + pid_t pr_pid; + pid_t pr_ppid; + pid_t pr_pgrp; + pid_t pr_sid; + struct timeval pr_utime; /* User time */ + struct timeval pr_stime; /* System time */ + struct timeval pr_cutime; /* Cumulative user time */ + struct timeval pr_cstime; /* Cumulative system time */ +#if 0 + long pr_instr; /* Current instruction */ +#endif + elf_gregset_t pr_reg; /* GP registers */ + int pr_fpvalid; /* True if math co-processor being used. */ +}; + +#define ELF_PRARGSZ (80) /* Number of chars for args */ + +struct elf_prpsinfo +{ + char pr_state; /* numeric process state */ + char pr_sname; /* char for pr_state */ + char pr_zomb; /* zombie */ + char pr_nice; /* nice val */ + unsigned long pr_flag; /* flags */ + uid_t pr_uid; + gid_t pr_gid; + pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* filename of executable */ + char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ +}; + +#ifndef __KERNEL__ +typedef struct elf_prstatus prstatus_t; +typedef struct elf_prpsinfo prpsinfo_t; +#define PRARGSZ ELF_PRARGSZ +#endif + +#endif /* _LINUX_ELFCORE_H */ diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 41073fcba..9f8b97ccf 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -28,13 +28,18 @@ #include <linux/if_ether.h> #ifdef __KERNEL__ -extern int eth_header(unsigned char *buff, struct device *dev, +extern int eth_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, - void *saddr, unsigned len, - struct sk_buff *skb); + void *saddr, unsigned len); extern int eth_rebuild_header(void *buff, struct device *dev, - unsigned long raddr, struct sk_buff *skb); + unsigned long dst, struct sk_buff *skb); extern unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev); +extern void eth_header_cache_bind(struct hh_cache ** hhp, struct device *dev, + unsigned short htype, __u32 daddr); +extern void eth_header_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr); +extern void eth_copy_and_sum(struct sk_buff *dest, + unsigned char *src, int length, int base); +extern struct device * init_etherdev(struct device *, int); #endif diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h index c96a04dc3..bd87ebcf5 100644 --- a/include/linux/ext2_fs.h +++ b/include/linux/ext2_fs.h @@ -28,21 +28,6 @@ #undef EXT2FS_DEBUG /* - * Define EXT2FS_DEBUG_CACHE to produce cache debug messages - */ -#undef EXT2FS_DEBUG_CACHE - -/* - * Define EXT2FS_CHECK_CACHE to add some checks to the name cache code - */ -#undef EXT2FS_CHECK_CACHE - -/* - * Define EXT2FS_PRE_02B_COMPAT to convert ext 2 fs prior to 0.2b - */ -#undef EXT2FS_PRE_02B_COMPAT - -/* * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files */ #define EXT2_PREALLOCATE @@ -50,8 +35,8 @@ /* * The second extended file system version */ -#define EXT2FS_DATE "95/03/19" -#define EXT2FS_VERSION "0.5a" +#define EXT2FS_DATE "95/08/09" +#define EXT2FS_VERSION "0.5b" /* * Debug code @@ -75,12 +60,13 @@ #define EXT2_ACL_DATA_INO 4 /* ACL inode */ #define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ #define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ -#define EXT2_FIRST_INO 11 /* First non reserved inode */ + +/* First non-reserved inode for old ext2 filesystems */ +#define EXT2_GOOD_OLD_FIRST_INO 11 /* * The second extended file system magic number */ -#define EXT2_PRE_02B_MAGIC 0xEF51 #define EXT2_SUPER_MAGIC 0xEF53 /* @@ -102,11 +88,22 @@ #define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry)) #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) #ifdef __KERNEL__ -# define EXT2_BLOCK_SIZE_BITS(s) ((s)->u.ext2_sb.s_es->s_log_block_size + 10) +# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) #else # define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) #endif -#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_inode)) +#ifdef __KERNEL__ +#define EXT2_ADDR_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_addr_per_block_bits) +#define EXT2_INODE_SIZE(s) ((s)->u.ext2_sb.s_inode_size) +#define EXT2_FIRST_INO(s) ((s)->u.ext2_sb.s_first_ino) +#else +#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ + EXT2_GOOD_OLD_INODE_SIZE : \ + (s)->s_inode_size) +#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ + EXT2_GOOD_OLD_FIRST_INO : \ + (s)->s_first_ino) +#endif /* * Macro-instructions used to manage fragments @@ -147,15 +144,6 @@ struct ext2_acl_entry /* Access Control List Entry */ /* * Structure of a blocks group descriptor */ -struct ext2_old_group_desc -{ - __u32 bg_block_bitmap; /* Blocks bitmap block */ - __u32 bg_inode_bitmap; /* Inodes bitmap block */ - __u32 bg_inode_table; /* Inodes table block */ - __u16 bg_free_blocks_count; /* Free blocks count */ - __u16 bg_free_inodes_count; /* Free inodes count */ -}; - struct ext2_group_desc { __u32 bg_block_bitmap; /* Blocks bitmap block */ @@ -175,6 +163,7 @@ struct ext2_group_desc # define EXT2_BLOCKS_PER_GROUP(s) ((s)->u.ext2_sb.s_blocks_per_group) # define EXT2_DESC_PER_BLOCK(s) ((s)->u.ext2_sb.s_desc_per_block) # define EXT2_INODES_PER_GROUP(s) ((s)->u.ext2_sb.s_inodes_per_group) +# define EXT2_DESC_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_desc_per_block_bits) #else # define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) # define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) @@ -200,7 +189,8 @@ struct ext2_group_desc #define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */ #define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */ #define EXT2_NODUMP_FL 0x00000040 /* do not dump file */ - +#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ + /* * ioctl commands */ @@ -347,22 +337,58 @@ struct ext2_super_block { __u16 s_magic; /* Magic signature */ __u16 s_state; /* File system state */ __u16 s_errors; /* Behaviour when detecting errors */ - __u16 s_pad; + __u16 s_minor_rev_level; /* minor revision level */ __u32 s_lastcheck; /* time of last check */ __u32 s_checkinterval; /* max. time between checks */ __u32 s_creator_os; /* OS */ __u32 s_rev_level; /* Revision level */ __u16 s_def_resuid; /* Default uid for reserved blocks */ __u16 s_def_resgid; /* Default gid for reserved blocks */ - __u32 s_reserved[235]; /* Padding to the end of the block */ + /* + * These fields are for EXT2_DYNAMIC_REV superblocks only. + * + * Note: the difference between the compatible feature set and + * the incompatible feature set is that if there is a bit set + * in the incompatible feature set that the kernel doesn't + * know about, it should refuse to mount the filesystem. + * + * e2fsck's requirements are more strict; if it doesn't know + * about a feature in either the compatible or incompatible + * feature set, it must abort and not try to meddle with + * things it doesn't understand... + */ + __u32 s_first_ino; /* First non-reserved inode */ + __u16 s_inode_size; /* size of inode structure */ + __u16 s_block_group_nr; /* block group # of this superblock */ + __u32 s_feature_compat; /* compatible feature set */ + __u32 s_feature_incompat; /* incompatible feature set */ + __u32 s_feature_ro_compat; /* readonly-compatible feature set */ + __u32 s_reserved[230]; /* Padding to the end of the block */ }; +/* + * Codes for operating systems + */ #define EXT2_OS_LINUX 0 #define EXT2_OS_HURD 1 #define EXT2_OS_MASIX 2 +#define EXT2_OS_FREEBSD 3 +#define EXT2_OS_LITES 4 + +/* + * Revision levels + */ +#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */ +#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ -#define EXT2_CURRENT_REV 0 +#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV +#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV +#define EXT2_GOOD_OLD_INODE_SIZE 128 + +/* + * Default values for user and/or group using reserved blocks + */ #define EXT2_DEF_RESUID 0 #define EXT2_DEF_RESGID 0 @@ -388,6 +414,13 @@ struct ext2_dir_entry { #define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ ~EXT2_DIR_ROUND) +/* + * Feature set definitions --- none are defined as of now + */ +#define EXT2_FEATURE_COMPAT_SUPP 0 +#define EXT2_FEATURE_INCOMPAT_SUPP 0 +#define EXT2_FEATURE_RO_COMPAT_SUPP 0 + #ifdef __KERNEL__ /* * Function prototypes @@ -397,23 +430,17 @@ struct ext2_dir_entry { * Ok, these declarations are also in <linux/kernel.h> but none of the * ext2 source programs needs to include it so they are duplicated here. */ -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -# define NORET_TYPE __volatile__ -# define ATTRIB_NORET /**/ -# define NORET_AND /**/ -#else # define NORET_TYPE /**/ # define ATTRIB_NORET __attribute__((noreturn)) # define NORET_AND noreturn, -#endif /* acl.c */ extern int ext2_permission (struct inode *, int); /* balloc.c */ -extern int ext2_new_block (struct super_block *, unsigned long, - __u32 *, __u32 *); -extern void ext2_free_blocks (struct super_block *, unsigned long, +extern int ext2_new_block (const struct inode *, unsigned long, + __u32 *, __u32 *, int *); +extern void ext2_free_blocks (const struct inode *, unsigned long, unsigned long); extern unsigned long ext2_count_free_blocks (struct super_block *); extern void ext2_check_blocks_bitmap (struct super_block *); @@ -422,7 +449,7 @@ extern void ext2_check_blocks_bitmap (struct super_block *); extern unsigned long ext2_count_free (struct buffer_head *, unsigned); /* dir.c */ -extern int ext2_check_dir_entry (char *, struct inode *, +extern int ext2_check_dir_entry (const char *, struct inode *, struct ext2_dir_entry *, struct buffer_head *, unsigned long); @@ -434,7 +461,7 @@ extern int ext2_write (struct inode *, struct file *, char *, int); extern int ext2_sync_file (struct inode *, struct file *); /* ialloc.c */ -extern struct inode * ext2_new_inode (const struct inode *, int); +extern struct inode * ext2_new_inode (const struct inode *, int, int *); extern void ext2_free_inode (struct inode *); extern unsigned long ext2_count_free_inodes (struct super_block *); extern void ext2_check_inodes_bitmap (struct super_block *); @@ -468,7 +495,7 @@ extern int ext2_symlink (struct inode *, const char *, int, const char *); extern int ext2_link (struct inode *, struct inode *, const char *, int); extern int ext2_mknod (struct inode *, const char *, int, int, int); extern int ext2_rename (struct inode *, const char *, int, - struct inode *, const char *, int); + struct inode *, const char *, int, int); /* super.c */ extern void ext2_error (struct super_block *, const char *, const char *, ...) @@ -482,6 +509,7 @@ extern void ext2_put_super (struct super_block *); extern void ext2_write_super (struct super_block *); extern int ext2_remount (struct super_block *, int *, char *); extern struct super_block * ext2_read_super (struct super_block *,void *,int); +extern int init_ext2_fs(void); extern void ext2_statfs (struct super_block *, struct statfs *, int); /* truncate.c */ diff --git a/include/linux/ext2_fs_i.h b/include/linux/ext2_fs_i.h index f3eca4480..7df902135 100644 --- a/include/linux/ext2_fs_i.h +++ b/include/linux/ext2_fs_i.h @@ -35,6 +35,7 @@ struct ext2_inode_info { __u32 i_next_alloc_goal; __u32 i_prealloc_block; __u32 i_prealloc_count; + int i_new_inode:1; /* Is a freshly allocated inode */ }; #endif /* _LINUX_EXT2_FS_I */ diff --git a/include/linux/ext2_fs_sb.h b/include/linux/ext2_fs_sb.h index 685efeb34..dd064b86a 100644 --- a/include/linux/ext2_fs_sb.h +++ b/include/linux/ext2_fs_sb.h @@ -16,6 +16,8 @@ #ifndef _LINUX_EXT2_FS_SB #define _LINUX_EXT2_FS_SB +#include <linux/ext2_fs.h> + /* * The following is not needed anymore since the descriptors buffer * heads are now dynamically allocated @@ -53,6 +55,11 @@ struct ext2_sb_info { unsigned short s_resuid; unsigned short s_resgid; unsigned short s_mount_state; + unsigned short s_pad; + int s_addr_per_block_bits; + int s_desc_per_block_bits; + int s_inode_size; + int s_first_ino; }; #endif /* _LINUX_EXT2_FS_SB */ diff --git a/include/linux/ext_fs.h b/include/linux/ext_fs.h index 52ab5413f..9bca72b0b 100644 --- a/include/linux/ext_fs.h +++ b/include/linux/ext_fs.h @@ -63,7 +63,7 @@ struct ext_dir_entry { extern int ext_open(struct inode * inode, struct file * filp); extern void ext_release(struct inode * inode, struct file * filp); extern int ext_lookup(struct inode * dir,const char * name, int len, - struct inode ** result); + struct inode ** result); extern int ext_create(struct inode * dir,const char * name, int len, int mode, struct inode ** result); extern int ext_mkdir(struct inode * dir, const char * name, int len, int mode); @@ -74,7 +74,7 @@ extern int ext_symlink(struct inode * inode, const char * name, int len, extern int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int len); extern int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev); extern int ext_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len); + struct inode * new_dir, const char * new_name, int new_len, int must_be_dir); extern struct inode * ext_new_inode(const struct inode * dir); extern void ext_free_inode(struct inode * inode); extern unsigned long ext_count_free_inodes(struct super_block *sb); @@ -91,6 +91,7 @@ extern void ext_truncate(struct inode *); extern void ext_put_super(struct super_block *); extern void ext_write_super(struct super_block *); extern struct super_block *ext_read_super(struct super_block *,void *,int); +extern int init_ext_fs(void); extern void ext_read_inode(struct inode *); extern void ext_write_inode(struct inode *); extern void ext_put_inode(struct inode *); diff --git a/include/linux/fb.h b/include/linux/fb.h new file mode 100644 index 000000000..f97a313c6 --- /dev/null +++ b/include/linux/fb.h @@ -0,0 +1,288 @@ +#ifndef _LINUX_FB_H +#define _LINUX_FB_H + +/* Definitions of frame buffers */ + +/* ioctls + 0x46 is 'F' */ +#define FBIOGET_VSCREENINFO 0x4600 +#define FBIOPUT_VSCREENINFO 0x4601 +#define FBIOGET_FSCREENINFO 0x4602 +#define FBIOGETCMAP 0x4604 +#define FBIOPUTCMAP 0x4605 +#define FBIOPAN_DISPLAY 0x4606 + +#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ +#define FB_TYPE_PLANES 1 /* Non interleaved planes */ +#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */ + +#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */ +#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */ +#define FB_VISUAL_TRUECOLOR 2 /* True color */ +#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */ +#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */ +#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */ +#define FB_VISUAL_STATIC_DIRECTCOLOR 6 /* Direct color readonly */ + +struct fb_fix_screeninfo { + char id[16]; /* identification string eg "TT Builtin" */ + unsigned long smem_start; /* Start of frame buffer mem */ + unsigned long smem_len; /* Length of frame buffer mem */ + int type; /* see FB_TYPE_* */ + int type_aux; /* Interleave for interleaved Planes */ + int visual; /* see FB_VISUAL_* */ + u_short xpanstep; /* zero if no hardware panning */ + u_short ypanstep; /* zero if no hardware panning */ + u_short ywrapstep; /* zero if no hardware ywrap */ + u_long line_length; /* length of a line in bytes */ + short reserved[9]; /* Reserved for future compatibility */ +}; + +struct fb_bitfield { + int offset; /* beginning of bitfield */ + int length; /* length of bitfield */ + int msb_right; /* != 0 : Most significant bit is */ + /* right */ +}; + +#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */ + +#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/ +#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */ +#define FB_ACTIVATE_TEST 2 /* don't set, round up impossible */ +#define FB_ACTIVATE_MASK 15 + /* values */ +#define FB_ACTIVATE_VBL 16 /* activate values on next vbl */ +#define FB_CHANGE_CMAP_VBL 32 /* change colormap on vbl */ + +#define FB_ACCEL_NONE 0 /* no hardware accelerator */ +#define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */ +#define FB_ACCEL_AMIGABLITT 2 /* Amiga Blitter */ +#define FB_ACCEL_CYBERVISION 3 /* Cybervision64 (S3 Trio64) */ + +#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */ +#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */ +#define FB_SYNC_EXT 4 /* external sync */ +#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */ +#define FB_SYNC_BROADCAST 16 /* broadcast video timings */ + /* vtotal = 144d/288n/576i => PAL */ + /* vtotal = 121d/242n/484i => NTSC */ + +#define FB_VMODE_NONINTERLACED 0 /* non interlaced */ +#define FB_VMODE_INTERLACED 1 /* interlaced */ +#define FB_VMODE_DOUBLE 2 /* double scan */ +#define FB_VMODE_MASK 255 + +#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */ +#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ +#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */ + +struct fb_var_screeninfo { + int xres; /* visible resolution */ + int yres; + int xres_virtual; /* virtual resolution */ + int yres_virtual; + int xoffset; /* offset from virtual to visible */ + int yoffset; /* resolution */ + + int bits_per_pixel; /* guess what */ + int grayscale; /* != 0 Graylevels instead of colors */ + + struct fb_bitfield red; /* bitfield in fb mem if true color, */ + struct fb_bitfield green; /* else only length is significant */ + struct fb_bitfield blue; + struct fb_bitfield transp; /* transparency */ + + int nonstd; /* != 0 Non standard pixel format */ + + int activate; /* see FB_ACTIVATE_* */ + + int height; /* height of picture in mm */ + int width; /* width of picture in mm */ + + int accel; /* see FB_ACCEL_* */ + + /* Timing: All values in pixclocks, except pixclock (of course) */ + unsigned long pixclock; /* pixel clock in ps (pico seconds) */ + unsigned long left_margin; /* time from sync to picture */ + unsigned long right_margin; /* time from picture to sync */ + unsigned long upper_margin; /* time from sync to picture */ + unsigned long lower_margin; + unsigned long hsync_len; /* length of horizontal sync */ + unsigned long vsync_len; /* length of vertical sync */ + int sync; /* see FB_SYNC_* */ + int vmode; /* see FB_VMODE_* */ + int reserved[6]; /* Reserved for future compatibility */ +}; + +struct fb_cmap { + int start; /* First entry */ + int len; /* Number of entries */ + unsigned short *red; /* Red values */ + unsigned short *green; + unsigned short *blue; + unsigned short *transp; /* transparency, can be NULL */ +}; + +#ifdef __KERNEL__ + +#include <linux/fs.h> + +struct fb_ops { + /* get non settable parameters */ + int (*fb_get_fix) (struct fb_fix_screeninfo *, int); + /* get settable parameters */ + int (*fb_get_var) (struct fb_var_screeninfo *, int); + /* set settable parameters */ + int (*fb_set_var) (struct fb_var_screeninfo *, int); + /* get colormap */ + int (*fb_get_cmap) (struct fb_cmap *, int, int); + /* set colormap */ + int (*fb_set_cmap) (struct fb_cmap *, int, int); + /* pan display */ + int (*fb_pan_display) (struct fb_var_screeninfo *, int); + /* perform fb specific ioctl */ + int (*fb_ioctl)(struct inode *, struct file *, unsigned int, + unsigned long, int); +}; + +int register_framebuffer(char *, int *, struct fb_ops *, int, + struct fb_var_screeninfo *); +int unregister_framebuffer(int); + + /* + * This is the interface between the low-level console driver and the + * low-level frame buffer device + */ + +struct display { + /* Filled in by the frame buffer device */ + + struct fb_var_screeninfo var; /* variable infos. yoffset and vmode */ + /* are updated by fbcon.c */ + struct fb_cmap cmap; /* colormap */ + u_char *screen_base; /* pointer to top of virtual screen */ + int visual; + int type; /* see FB_TYPE_* */ + int type_aux; /* Interleave for interleaved Planes */ + u_short ypanstep; /* zero if no hardware ypan */ + u_short ywrapstep; /* zero if no hardware ywrap */ + u_long line_length; /* length of a line in bytes */ + u_short can_soft_blank; /* zero if no hardware blanking */ + u_short inverse; /* != 0 text black on white as default */ + +#if 0 + struct fb_fix_cursorinfo fcrsr; + struct fb_var_cursorinfo *vcrsr; + struct fb_cursorstate crsrstate; +#endif + + /* Filled in by the low-level console driver */ + + struct vc_data *conp; /* pointer to console data */ + int vrows; /* number of virtual rows */ + int cursor_x; /* current cursor position */ + int cursor_y; + int fgcol; /* text colors */ + int bgcol; + u_long next_line; /* offset to one line below */ + u_long next_plane; /* offset to next plane */ + u_char *fontdata; /* Font associated to this display */ + int fontheight; + int fontwidth; + int userfont; /* != 0 if fontdata kmalloc()ed */ + struct display_switch *dispsw; /* low level operations */ + u_short scrollmode; /* Scroll Method */ + short yscroll; /* Hardware scrolling */ +}; + + +struct fb_info { + char modename[40]; /* at boottime detected video mode */ + struct display *disp; /* pointer to display variables */ + char fontname[40]; /* default font name */ + int (*changevar)(int); /* tell console var has changed */ + int (*switch_con)(int); /* tell fb to switch consoles */ + int (*updatevar)(int); /* tell fb to update the vars */ + void (*blank)(int); /* tell fb to (un)blank the screen */ +}; + +#endif /* __KERNEL__ */ + +#if 1 + +#define FBCMD_GET_CURRENTPAR 0xDEAD0005 +#define FBCMD_SET_CURRENTPAR 0xDEAD8005 + +#endif + + +#if 1 /* Preliminary */ + + /* + * Hardware Cursor + */ + +#define FBIOGET_FCURSORINFO 0x4607 +#define FBIOGET_VCURSORINFO 0x4608 +#define FBIOPUT_VCURSORINFO 0x4609 +#define FBIOGET_CURSORSTATE 0x460A +#define FBIOPUT_CURSORSTATE 0x460B + + +struct fb_fix_cursorinfo { + u_short crsr_width; /* width and height of the cursor in */ + u_short crsr_height; /* pixels (zero if no cursor) */ + u_short crsr_xsize; /* cursor size in display pixels */ + u_short crsr_ysize; + u_short crsr_color1; /* colormap entry for cursor color1 */ + u_short crsr_color2; /* colormap entry for cursor color2 */ +}; + +struct fb_var_cursorinfo { + u_short width; + u_short height; + u_short xspot; + u_short yspot; + u_char data[1]; /* field with [height][width] */ +}; + +struct fb_cursorstate { + short xoffset; + short yoffset; + u_short mode; +}; + +#define FB_CURSOR_OFF 0 +#define FB_CURSOR_ON 1 +#define FB_CURSOR_FLASH 2 + +#define FBCMD_DRAWLINE 0x4621 +#define FBCMD_MOVE 0x4622 + +#define FB_LINE_XOR 1 +#define FB_LINE_BOX 2 +#define FB_LINE_FILLED 4 + +struct fb_line { + int start_x; + int start_y; + int end_x; + int end_y; + int color; + int option; +}; + +struct fb_move { + int src_x; + int src_y; + int dest_x; + int dest_y; + int height; + int width; +}; + +#endif /* Preliminary */ + + +#endif /* _LINUX_FB_H */ diff --git a/include/linux/fd.h b/include/linux/fd.h index 044f0bace..a05cf3900 100644 --- a/include/linux/fd.h +++ b/include/linux/fd.h @@ -1,52 +1,26 @@ #ifndef _LINUX_FD_H #define _LINUX_FD_H -#define FDCLRPRM 0 /* clear user-defined parameters */ -#define FDSETPRM 1 /* set user-defined parameters for current media */ -#define FDSETMEDIAPRM 1 -#define FDDEFPRM 2 /* set user-defined parameters until explicitly cleared */ -#define FDDEFMEDIAPRM 2 -#define FDGETPRM 3 /* get disk parameters */ -#define FDGETMEDIAPRM 3 -#define FDMSGON 4 /* issue kernel messages on media type change */ -#define FDMSGOFF 5 /* don't issue kernel messages on media type change */ -#define FDFMTBEG 6 /* begin formatting a disk */ -#define FDFMTTRK 7 /* format the specified track */ -#define FDFMTEND 8 /* end formatting a disk */ -#define FDSETEMSGTRESH 10 /* set fdc error reporting threshold */ -#define FDFLUSH 11 /* flush buffers for media; either for verifying media, or for - handling a media change without closing the file - descriptor */ -#define FDSETMAXERRS 12 /* set abortion and read_track threshold */ -#define FDGETMAXERRS 14 /* get abortion and read_track threshold */ -#define FDGETDRVTYP 16 /* get drive type: 5 1/4 or 3 1/2 */ - -#define FDSETDRVPRM 20 /* set drive parameters */ -#define FDGETDRVPRM 21 /* get drive parameters */ -#define FDGETDRVSTAT 22 /* get drive state */ -#define FDPOLLDRVSTAT 23 /* get drive state */ -#define FDRESET 24 /* reset FDC */ - -#define FD_RESET_IF_NEEDED 0 -#define FD_RESET_IF_RAWCMD 1 -#define FD_RESET_ALWAYS 2 - -#define FDGETFDCSTAT 25 /* get fdc state */ -#define FDWERRORCLR 27 /* clear write error and badness information */ -#define FDWERRORGET 28 /* get write error and badness information */ - -#define FDRAWCMD 30 /* send a raw command to the fdc */ - -#define FDTWADDLE 40 /* flicker motor-on bit before reading a sector */ +#include <linux/ioctl.h> + +/* New file layout: Now the ioctl definitions immediately follow the + * definitions of the structures that they use */ /* - * Maximum number of sectors in a track buffer. Track buffering is disabled - * if tracks are bigger. + * Geometry */ -#define MAX_BUFFER_SECTORS 24 /* was 18 -bb */ +struct floppy_struct { + unsigned int size, /* nr of sectors total */ + sect, /* sectors per track */ + head, /* nr of heads */ + track, /* nr of tracks */ + stretch; /* !=0 means double track steps */ +#define FD_STRETCH 1 +#define FD_SWAPSIDES 2 -#define FD_FILL_BYTE 0xF6 /* format fill byte */ + unsigned char gap, /* gap1 size */ + rate, /* data rate. |= 0x40 for perpendicular */ #define FD_2M 0x4 #define FD_SIZECODEMASK 0x38 #define FD_SIZECODE(floppy) (((((floppy)->rate&FD_SIZECODEMASK)>> 3)+ 2) %8) @@ -54,27 +28,56 @@ 512 : 128 << FD_SIZECODE(floppy) ) #define FD_PERP 0x40 -#ifndef __ASSEMBLY__ -/* the following structure is used by FDSETPRM, FDDEFPRM and FDGETPRM */ -struct floppy_struct { - unsigned int size, /* nr of sectors total */ - sect, /* sectors per track */ - head, /* nr of heads */ - track, /* nr of tracks */ - stretch; /* !=0 means double track steps */ - unsigned char gap, /* gap1 size */ - rate, /* data rate. |= 0x40 for perpendicular */ spec1, /* stepping rate, head unload time */ fmt_gap; /* gap2 size */ - char * name; /* used only for predefined formats */ + const char * name; /* used only for predefined formats */ }; + +/* commands needing write access have 0x40 set */ +/* commands needing super user access have 0x80 set */ + +#define FDCLRPRM _IO(2, 0x41) +/* clear user-defined parameters */ + +#define FDSETPRM _IOW(2, 0x42, struct floppy_struct) +#define FDSETMEDIAPRM FDSETPRM +/* set user-defined parameters for current media */ + +#define FDDEFPRM _IOW(2, 0x43, struct floppy_struct) +#define FDGETPRM _IOR(2, 0x04, struct floppy_struct) +#define FDDEFMEDIAPRM FDDEFPRM +#define FDGETMEDIAPRM FDGETPRM +/* set/get disk parameters */ + + +#define FDMSGON _IO(2,0x45) +#define FDMSGOFF _IO(2,0x46) +/* issue/don't issue kernel messages on media type change */ + + +/* + * Formatting (obsolete) + */ +#define FD_FILL_BYTE 0xF6 /* format fill byte. */ + struct format_descr { unsigned int device,head,track; }; +#define FDFMTBEG _IO(2,0x47) +/* begin formatting a disk */ +#define FDFMTTRK _IOW(2,0x48, struct format_descr) +/* format the specified track */ +#define FDFMTEND _IO(2,0x49) +/* end formatting a disk */ + + +/* + * Error thresholds + */ struct floppy_max_errors { - unsigned int + unsigned int abort, /* number of errors to be reached before aborting */ read_track, /* maximal number of errors permitted to read an * entire track at once */ @@ -91,32 +94,55 @@ struct floppy_max_errors { }; -/* the following structure is used by FDSETDRVPRM and FDGETDRVPRM */ +#define FDSETEMSGTRESH _IO(2,0x4a) +/* set fdc error reporting threshold */ + +#define FDFLUSH _IO(2,0x4b) +/* flush buffers for media; either for verifying media, or for + * handling a media change without closing the file descriptor */ + +#define FDSETMAXERRS _IOW(2, 0x4c, struct floppy_max_errors) +#define FDGETMAXERRS _IOR(2, 0x0e, struct floppy_max_errors) +/* set/get abortion and read_track threshold. See also floppy_drive_params + * structure */ + + +typedef char floppy_drive_name[16]; +#define FDGETDRVTYP _IOR(2, 0x0f, floppy_drive_name) +/* get drive type: 5 1/4 or 3 1/2 */ + + +/* + * Drive parameters (user modifiable) + */ struct floppy_drive_params { - char cmos; /* cmos type */ - - /* Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms etc) - * and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA). - */ - unsigned long max_dtr; /* Step rate, usec */ - unsigned long hlt; /* Head load/settle time, msec */ - unsigned long hut; /* Head unload time (remnant of 8" drives) */ - unsigned long srt; /* Step rate, usec */ - - unsigned long spinup; /* time needed for spinup ( in jiffies) */ - unsigned long spindown; /* timeout needed for spindown */ - unsigned char spindown_offset;/* decides in which position the disk - * will stop */ - unsigned char select_delay; /* delay to wait after select */ - unsigned char rps; /* rotations per second */ - unsigned char tracks; /* maximum number of tracks */ - unsigned long timeout; /* timeout for interrupt requests */ - - unsigned char interleave_sect;/* if there are more sectors, use interleave */ - - struct floppy_max_errors max_errors; - - char flags; /* various flags, including ftd_msg */ + char cmos; /* cmos type */ + + /* Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms + * etc) and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA). + */ + unsigned long max_dtr; /* Step rate, usec */ + unsigned long hlt; /* Head load/settle time, msec */ + unsigned long hut; /* Head unload time (remnant of + * 8" drives) */ + unsigned long srt; /* Step rate, usec */ + + unsigned long spinup; /* time needed for spinup (expressed + * in jiffies) */ + unsigned long spindown; /* timeout needed for spindown */ + unsigned char spindown_offset; /* decides in which position the disk + * will stop */ + unsigned char select_delay; /* delay to wait after select */ + unsigned char rps; /* rotations per second */ + unsigned char tracks; /* maximum number of tracks */ + unsigned long timeout; /* timeout for interrupt requests */ + + unsigned char interleave_sect; /* if there are more sectors, use + * interleave */ + + struct floppy_max_errors max_errors; + + char flags; /* various flags, including ftd_msg */ /* * Announce successful media type detection and media information loss after * disk changes. @@ -129,29 +155,40 @@ struct floppy_drive_params { #define FD_SILENT_DCL_CLEAR 0x4 #define FD_INVERTED_DCL 0x80 - char read_track; /* use readtrack during probing? */ + char read_track; /* use readtrack during probing? */ /* * Auto-detection. Each drive type has eight formats which are * used in succession to try to read the disk. If the FDC cannot lock onto * the disk, the next format is tried. This uses the variable 'probing'. */ - short autodetect[8]; /* autodetected formats */ - - int checkfreq; /* how often should the drive be checked for disk changes */ - int native_format; /* native format of this drive */ + short autodetect[8]; /* autodetected formats */ + + int checkfreq; /* how often should the drive be checked for disk + * changes */ + int native_format; /* native format of this drive */ }; enum { -FD_NEED_TWADDLE_BIT, /* more magic */ -FD_VERIFY_BIT, /* inquire for write protection */ -FD_DISK_NEWCHANGE_BIT, /* change detected, and no action undertaken yet to - clear media change status */ -FD_UNUSED_BIT, -FD_DISK_CHANGED_BIT, /* disk has been changed since last i/o */ -FD_DISK_WRITABLE_BIT /* disk is writable */ + FD_NEED_TWADDLE_BIT, /* more magic */ + FD_VERIFY_BIT, /* inquire for write protection */ + FD_DISK_NEWCHANGE_BIT, /* change detected, and no action undertaken yet + * to clear media change status */ + FD_UNUSED_BIT, + FD_DISK_CHANGED_BIT, /* disk has been changed since last i/o */ + FD_DISK_WRITABLE_BIT /* disk is writable */ }; +#define FDSETDRVPRM _IOW(2, 0x90, struct floppy_drive_params) +#define FDGETDRVPRM _IOR(2, 0x11, struct floppy_drive_params) +/* set/get drive parameters */ + + +/* + * Current drive state (not directly modifiable by user, readonly) + */ +struct floppy_drive_struct { + signed char flags; /* values for these flags */ #define FD_NEED_TWADDLE (1 << FD_NEED_TWADDLE_BIT) #define FD_VERIFY (1 << FD_VERIFY_BIT) @@ -159,93 +196,182 @@ FD_DISK_WRITABLE_BIT /* disk is writable */ #define FD_DISK_CHANGED (1 << FD_DISK_CHANGED_BIT) #define FD_DISK_WRITABLE (1 << FD_DISK_WRITABLE_BIT) -#define FD_DRIVE_PRESENT 0 /* keep fdpatch utils compiling */ - -struct floppy_drive_struct { - signed char flags; - unsigned long spinup_date; - unsigned long select_date; - unsigned long first_read_date; - short probed_format; - short track; /* current track */ - short maxblock; /* id of highest block read */ - short maxtrack; /* id of highest half track read */ - int generation; /* how many diskchanges? */ + unsigned long spinup_date; + unsigned long select_date; + unsigned long first_read_date; + short probed_format; + short track; /* current track */ + short maxblock; /* id of highest block read */ + short maxtrack; /* id of highest half track read */ + int generation; /* how many diskchanges? */ /* * (User-provided) media information is _not_ discarded after a media change * if the corresponding keep_data flag is non-zero. Positive values are * decremented after each probe. */ - int keep_data; + int keep_data; + + /* Prevent "aliased" accesses. */ + int fd_ref; + int fd_device; + int last_checked; /* when was the drive last checked for a disk + * change? */ + + char *dmabuf; + int bufblocks; +}; - /* Prevent "aliased" accesses. */ - int fd_ref; - int fd_device; - int last_checked; /* when was the drive last checked for a disk change? */ +#define FDGETDRVSTAT _IOR(2, 0x12, struct floppy_drive_struct) +#define FDPOLLDRVSTAT _IOR(2, 0x13, struct floppy_drive_struct) +/* get drive state: GET returns the cached state, POLL polls for new state */ +/* + * reset FDC + */ +enum reset_mode { + FD_RESET_IF_NEEDED, /* reset only if the reset flags is set */ + FD_RESET_IF_RAWCMD, /* obsolete */ + FD_RESET_ALWAYS /* reset always */ }; +#define FDRESET _IO(2, 0x54) -struct floppy_write_errors { - /* Write error logging. - * - * These fields can be cleared with the FDWERRORCLR ioctl. - * Only writes that were attempted but failed due to a physical media - * error are logged. write(2) calls that fail and return an error code - * to the user process are not counted. - */ - - unsigned int write_errors; /* number of physical write errors encountered */ - - /* position of first and last write errors */ - unsigned long first_error_sector; - int first_error_generation; - unsigned long last_error_sector; - int last_error_generation; - - unsigned int badness; /* highest retry count for a read or write operation */ -}; +/* + * FDC state + */ struct floppy_fdc_state { - int spec1; /* spec1 value last used */ - int spec2; /* spec2 value last used */ + int spec1; /* spec1 value last used */ + int spec2; /* spec2 value last used */ int dtr; unsigned char version; /* FDC version code */ unsigned char dor; - unsigned int address; /* io address */ + int address; /* io address */ unsigned int rawcmd:2; unsigned int reset:1; unsigned int need_configure:1; unsigned int perp_mode:2; unsigned int has_fifo:1; + unsigned int driver_version; /* version code for floppy driver */ +#define FD_DRIVER_VERSION 0x100 +/* user programs using the floppy API should use floppy_fdc_state to + * get the version number of the floppy driver that they are running + * on. If this version number is bigger than the one compiled into the + * user program (the FD_DRIVER_VERSION define), it should be prepared + * to bigger structures + */ + + unsigned char track[4]; + /* Position of the heads of the 4 units attached to this FDC, + * as stored on the FDC. In the future, the position as stored + * on the FDC might not agree with the actual physical + * position of these drive heads. By allowing such + * disagreement, it will be possible to reset the FDC without + * incurring the expensive cost of repositioning all heads. + * Right now, these positions are hard wired to 0. */ + }; -struct floppy_raw_cmd { - void *data; - long length; - - unsigned char rate; - unsigned char flags; - unsigned char cmd_count; - unsigned char cmd[9]; - unsigned char reply_count; - unsigned char reply[7]; - int track; +#define FDGETFDCSTAT _IOR(2, 0x15, struct floppy_fdc_state) + + +/* + * Asynchronous Write error tracking + */ +struct floppy_write_errors { + /* Write error logging. + * + * These fields can be cleared with the FDWERRORCLR ioctl. + * Only writes that were attempted but failed due to a physical media + * error are logged. write(2) calls that fail and return an error code + * to the user process are not counted. + */ + + unsigned int write_errors; /* number of physical write errors + * encountered */ + + /* position of first and last write errors */ + unsigned long first_error_sector; + int first_error_generation; + unsigned long last_error_sector; + int last_error_generation; + + unsigned int badness; /* highest retry count for a read or write + * operation */ }; -#endif -/* meaning of the various bytes */ +#define FDWERRORCLR _IO(2, 0x56) +/* clear write error and badness information */ +#define FDWERRORGET _IOR(2, 0x17, struct floppy_write_errors) +/* get write error and badness information */ + + +/* + * Raw commands + */ +/* new interface flag: now we can do them in batches */ +#define FDHAVEBATCHEDRAWCMD -/* flags */ +struct floppy_raw_cmd { + unsigned int flags; #define FD_RAW_READ 1 #define FD_RAW_WRITE 2 #define FD_RAW_NO_MOTOR 4 -#define FD_RAW_DISK_CHANGE 4 -#define FD_RAW_INTR 8 -#define FD_RAW_SPIN 16 -#define FD_RAW_NO_MOTOR_AFTER 32 -#define FD_RAW_NEED_DISK 64 -#define FD_RAW_NEED_SEEK 128 +#define FD_RAW_DISK_CHANGE 4 /* out: disk change flag was set */ +#define FD_RAW_INTR 8 /* wait for an interrupt */ +#define FD_RAW_SPIN 0x10 /* spin up the disk for this command */ +#define FD_RAW_NO_MOTOR_AFTER 0x20 /* switch the motor off after command + * completion */ +#define FD_RAW_NEED_DISK 0x40 /* this command needs a disk to be present */ +#define FD_RAW_NEED_SEEK 0x80 /* this command uses an implied seek (soft) */ + +/* more "in" flags */ +#define FD_RAW_MORE 0x100 /* more records follow */ +#define FD_RAW_STOP_IF_FAILURE 0x200 /* stop if we encounter a failure */ +#define FD_RAW_STOP_IF_SUCCESS 0x400 /* stop if command successful */ +#define FD_RAW_SOFTFAILURE 0x800 /* consider the return value for failure + * detection too */ + +/* more "out" flags */ +#define FD_RAW_FAILURE 0x10000 /* command sent to fdc, fdc returned error */ +#define FD_RAW_HARDFAILURE 0x20000 /* fdc had to be reset, or timed out */ + + void *data; + char *kernel_data; /* location of data buffer in the kernel */ + struct floppy_raw_cmd *next; /* used for chaining of raw cmd's + * within the kernel */ + long length; /* in: length of dma transfer. out: remaining bytes */ + long phys_length; /* physical length, if different from dma length */ + int buffer_length; /* length of allocated buffer */ + + unsigned char rate; + unsigned char cmd_count; + unsigned char cmd[16]; + unsigned char reply_count; + unsigned char reply[16]; + int track; + int resultcode; + + int reserved1; + int reserved2; +}; + +#define FDRAWCMD _IO(2, 0x58) +/* send a raw command to the fdc. Structure size not included, because of + * batches */ + +#define FDTWADDLE _IO(2, 0x59) +/* flicker motor-on bit before reading a sector. Experimental */ + + +#define FDEJECT _IO(2, 0x5a) +/* eject the disk */ + + +#ifdef __KERNEL__ +/* eject the boot floppy (if we need the drive for a different root floppy) */ +void floppy_eject(void); +#endif #endif diff --git a/include/linux/fddidevice.h b/include/linux/fddidevice.h new file mode 100644 index 000000000..bb0b298ee --- /dev/null +++ b/include/linux/fddidevice.h @@ -0,0 +1,42 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the FDDI handlers. + * + * Version: @(#)fddidevice.h 1.0.0 08/12/96 + * + * Author: Lawrence V. Stefani, <stefani@lkg.dec.com> + * + * fddidevice.h is based on previous trdevice.h work by + * Ross Biro, <bir7@leland.Stanford.Edu> + * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * Alan Cox, <gw4pts@gw4pts.ampr.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _LINUX_FDDIDEVICE_H +#define _LINUX_FDDIDEVICE_H + +#include <linux/if_fddi.h> + +#ifdef __KERNEL__ +extern int fddi_header(struct sk_buff *skb, + struct device *dev, + unsigned short type, + void *daddr, + void *saddr, + unsigned len); +extern int fddi_rebuild_header(void *buff, + struct device *dev, + unsigned long dest, + struct sk_buff *skb); +extern unsigned short fddi_type_trans(struct sk_buff *skb, + struct device *dev); +#endif + +#endif /* _LINUX_FDDIDEVICE_H */ diff --git a/include/linux/fdreg.h b/include/linux/fdreg.h index 245647bbf..1d9026eed 100644 --- a/include/linux/fdreg.h +++ b/include/linux/fdreg.h @@ -44,7 +44,7 @@ #define ST0_DS 0x03 /* drive select mask */ #define ST0_HA 0x04 /* Head (Address) */ #define ST0_NR 0x08 /* Not Ready */ -#define ST0_ECE 0x10 /* Equipment chech error */ +#define ST0_ECE 0x10 /* Equipment check error */ #define ST0_SE 0x20 /* Seek end */ #define ST0_INTR 0xC0 /* Interrupt code mask */ @@ -92,18 +92,52 @@ #define FD_RSEEK_OUT 0x8f /* seek out (i.e. to lower tracks) */ #define FD_RSEEK_IN 0xcf /* seek in (i.e. to higher tracks) */ +/* the following commands are new in the 82078. They are not used in the + * floppy driver, except the first three. These commands may be useful for apps + * which use the FDRAWCMD interface. For doc, get the 82078 spec sheets at + * http://www-techdoc.intel.com/docs/periph/fd_contr/datasheets/ */ + +#define FD_PARTID 0x18 /* part id ("extended" version cmd) */ +#define FD_SAVE 0x2e /* save fdc regs for later restore */ +#define FD_DRIVESPEC 0x8e /* drive specification: Access to the + * 2 Mbps data transfer rate for tape + * drives */ + +#define FD_RESTORE 0x4e /* later restore */ +#define FD_POWERDOWN 0x27 /* configure FDC's powersave features */ +#define FD_FORMAT_N_WRITE 0xef /* format and write in one go. */ +#define FD_OPTION 0x33 /* ISO format (which is a clean way to + * pack more sectors on a track) */ + /* DMA commands */ #define DMA_READ 0x46 #define DMA_WRITE 0x4A /* FDC version return types */ #define FDC_NONE 0x00 -#define FDC_UNKNOWN 0x10 +#define FDC_UNKNOWN 0x10 /* DO NOT USE THIS TYPE EXCEPT IF IDENTIFICATION + FAILS EARLY */ #define FDC_8272A 0x20 /* Intel 8272a, NEC 765 */ #define FDC_765ED 0x30 /* Non-Intel 1MB-compatible FDC, can't detect */ #define FDC_82072 0x40 /* Intel 82072; 8272a + FIFO + DUMPREGS */ -#define FDC_82077_ORIG 0x50 /* Original version of 82077AA, sans LOCK */ +#define FDC_82072A 0x45 /* 82072A (on Sparcs) */ +#define FDC_82077_ORIG 0x51 /* Original version of 82077AA, sans LOCK */ #define FDC_82077 0x52 /* 82077AA-1 */ +#define FDC_82078_UNKN 0x5f /* Unknown 82078 variant */ +#define FDC_82078 0x60 /* 44pin 82078 or 64pin 82078SL */ +#define FDC_82078_1 0x61 /* 82078-1 (2Mbps fdc) */ +#define FDC_S82078B 0x62 /* S82078B (first seen on Adaptec AVA-2825 VLB + * SCSI/EIDE/Floppy controller) */ +#define FDC_87306 0x63 /* National Semiconductor PC 87306 */ + +/* + * Beware: the fdc type list is roughly sorted by increasing features. + * Presence of features is tested by comparing the FDC version id with the + * "oldest" version that has the needed feature. + * If during FDC detection, an obscure test fails late in the sequence, don't + * assign FDC_UNKNOWN. Else the FDC will be treated as a dumb 8272a, or worse. + * This is especially true if the tests are unneeded. + */ #define FD_RESET_DELAY 20 #endif diff --git a/include/linux/file.h b/include/linux/file.h new file mode 100644 index 000000000..a3297909d --- /dev/null +++ b/include/linux/file.h @@ -0,0 +1,25 @@ +#ifndef __LINUX_FILE_H +#define __LINUX_FILE_H + +extern inline struct file * fget(unsigned long fd) +{ + struct file * file = NULL; + if (fd < NR_OPEN) { + file = current->files->fd[fd]; + if (file) + file->f_count++; + } + return file; +} + +extern void __fput(struct file *, struct inode *); + +extern inline void fput(struct file *file, struct inode *inode) +{ + int count = file->f_count-1; + if (!count) + __fput(file, inode); + file->f_count = count; +} + +#endif diff --git a/include/linux/firewall.h b/include/linux/firewall.h new file mode 100644 index 000000000..e2d1f25e3 --- /dev/null +++ b/include/linux/firewall.h @@ -0,0 +1,41 @@ +#ifndef __LINUX_FIREWALL_H +#define __LINUX_FIREWALL_H + +/* + * Definitions for loadable firewall modules + */ + +#define FW_BLOCK 0 +#define FW_ACCEPT 1 +#define FW_REJECT (-1) +#define FW_REDIRECT 2 +#define FW_MASQUERADE 3 +#define FW_SKIP 4 + +struct firewall_ops +{ + struct firewall_ops *next; + int (*fw_forward)(struct firewall_ops *this, int pf, + struct device *dev, void *phdr, void *arg); + int (*fw_input)(struct firewall_ops *this, int pf, + struct device *dev, void *phdr, void *arg); + int (*fw_output)(struct firewall_ops *this, int pf, + struct device *dev, void *phdr, void *arg); + /* Data falling in the second 486 cache line isn't used directly + during a firewall call and scan, only by insert/delete and other + unusual cases + */ + int fw_pf; /* Protocol family */ + int fw_priority; /* Priority of chosen firewalls */ +}; + +#ifdef __KERNEL__ +extern int register_firewall(int pf, struct firewall_ops *fw); +extern int unregister_firewall(int pf, struct firewall_ops *fw); +extern int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg); +extern int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg); +extern int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg); +extern void fwchain_init(void); +#endif + +#endif diff --git a/include/linux/fs.h b/include/linux/fs.h index 617a11a41..0c64ed100 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -6,12 +6,15 @@ * structures etc. */ +#include <linux/config.h> #include <linux/linkage.h> #include <linux/limits.h> #include <linux/wait.h> #include <linux/types.h> #include <linux/vfs.h> #include <linux/net.h> +#include <linux/kdev_t.h> +#include <linux/ioctl.h> /* * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix @@ -21,34 +24,32 @@ * Some programs (notably those using select()) may have to be * recompiled to take full advantage of the new limits.. */ + +/* Fixed constants first: */ #undef NR_OPEN #define NR_OPEN 256 -#define NR_INODE 2048 /* this should be bigger than NR_FILE */ -#define NR_FILE 1024 /* this can well be larger on a larger system */ -#define NR_SUPER 32 -#define NR_IHASH 131 +#define NR_SUPER 64 #define BLOCK_SIZE 1024 #define BLOCK_SIZE_BITS 10 +/* And dynamically-tunable limits and defaults: */ +extern int max_inodes, nr_inodes; +extern int max_files, nr_files; +#define NR_INODE 3072 /* this should be bigger than NR_FILE */ +#define NR_FILE 1024 /* this can well be larger on a larger system */ + #define MAY_EXEC 1 #define MAY_WRITE 2 #define MAY_READ 4 +#define FMODE_READ 1 +#define FMODE_WRITE 2 + #define READ 0 #define WRITE 1 -#define READA 2 /* read-ahead - don't pause */ -#define WRITEA 3 /* "write-ahead" - silly, but somewhat useful */ - -extern void buffer_init(void); -extern unsigned long inode_init(unsigned long start, unsigned long end); -extern unsigned long file_table_init(unsigned long start, unsigned long end); -extern unsigned long name_cache_init(unsigned long start, unsigned long end); - -#define MAJOR(a) (int)((unsigned short)(a) >> 8) -#define MINOR(a) (int)((unsigned short)(a) & 0xFF) -#define MKDEV(a,b) ((int)((((a) & 0xff) << 8) | ((b) & 0xff))) -#define NODEV MKDEV(0,0) +#define READA 2 /* read-ahead - don't block if no resources */ +#define WRITEA 3 /* write-ahead - don't block if no resources */ #ifndef NULL #define NULL ((void *) 0) @@ -62,26 +63,27 @@ extern unsigned long name_cache_init(unsigned long start, unsigned long end); /* * These are the fs-independent mount-flags: up to 16 flags are supported */ -#define MS_RDONLY 1 /* mount read-only */ -#define MS_NOSUID 2 /* ignore suid and sgid bits */ -#define MS_NODEV 4 /* disallow access to device special files */ -#define MS_NOEXEC 8 /* disallow program execution */ -#define MS_SYNCHRONOUS 16 /* writes are synced at once */ -#define MS_REMOUNT 32 /* alter flags of a mounted FS */ - -#define S_APPEND 256 /* append-only file */ -#define S_IMMUTABLE 512 /* immutable file */ +#define MS_RDONLY 1 /* Mount read-only */ +#define MS_NOSUID 2 /* Ignore suid and sgid bits */ +#define MS_NODEV 4 /* Disallow access to device special files */ +#define MS_NOEXEC 8 /* Disallow program execution */ +#define MS_SYNCHRONOUS 16 /* Writes are synced at once */ +#define MS_REMOUNT 32 /* Alter flags of a mounted FS */ +#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ +#define S_WRITE 128 /* Write on file/directory/symlink */ +#define S_APPEND 256 /* Append-only file */ +#define S_IMMUTABLE 512 /* Immutable file */ /* * Flags that can be altered by MS_REMOUNT */ -#define MS_RMT_MASK (MS_RDONLY) +#define MS_RMT_MASK (MS_RDONLY|MS_MANDLOCK) /* * Magic mount flag number. Has to be or-ed to the flag values. */ -#define MS_MGC_VAL 0xC0ED0000 /* magic flag number to indicate "new" flags */ -#define MS_MGC_MSK 0xffff0000 /* magic flag number mask */ +#define MS_MGC_VAL 0xC0ED0000 /* magic flag number to indicate "new" flags */ +#define MS_MGC_MSK 0xffff0000 /* magic flag number mask */ /* * Note that read-only etc flags are inode-specific: setting some file-system @@ -96,61 +98,125 @@ extern unsigned long name_cache_init(unsigned long start, unsigned long end); #define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV) #define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC) #define IS_SYNC(inode) ((inode)->i_flags & MS_SYNCHRONOUS) +#define IS_MANDLOCK(inode) ((inode)->i_flags & MS_MANDLOCK) +#define IS_WRITABLE(inode) ((inode)->i_flags & S_WRITE) #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) /* the read-only stuff doesn't really belong here, but any other place is probably as bad and I don't want to create yet another include file. */ -#define BLKROSET 4701 /* set device read-only (0 = read-write) */ -#define BLKROGET 4702 /* get read-only status (0 = read_write) */ -#define BLKRRPART 4703 /* re-read partition table */ -#define BLKGETSIZE 4704 /* return device size */ -#define BLKFLSBUF 4705 /* flush buffer cache */ -#define BLKRASET 4706 /* Set read ahead for block device */ -#define BLKRAGET 4707 /* get current read ahead setting */ - -/* These are a few other constants only used by scsi devices */ - -#define SCSI_IOCTL_GET_IDLUN 0x5382 +#define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */ +#define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */ +#define BLKRRPART _IO(0x12,95) /* re-read partition table */ +#define BLKGETSIZE _IO(0x12,96) /* return device size */ +#define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */ +#define BLKRASET _IO(0x12,98) /* Set read ahead for block device */ +#define BLKRAGET _IO(0x12,99) /* get current read ahead setting */ -/* Used to turn on and off tagged queuing for scsi devices */ +#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ +#define FIBMAP _IO(0x00,1) /* bmap access */ +#define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */ -#define SCSI_IOCTL_TAGGED_ENABLE 0x5383 -#define SCSI_IOCTL_TAGGED_DISABLE 0x5384 +#ifdef __KERNEL__ +#include <asm/semaphore.h> +#include <asm/byteorder.h> +#include <asm/bitops.h> -#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ -#define FIBMAP 1 /* bmap access */ -#define FIGETBSZ 2 /* get the block size used for bmap */ +extern void buffer_init(void); +extern unsigned long inode_init(unsigned long start, unsigned long end); +extern unsigned long file_table_init(unsigned long start, unsigned long end); +extern unsigned long name_cache_init(unsigned long start, unsigned long end); typedef char buffer_block[BLOCK_SIZE]; +/* bh state bits */ +#define BH_Uptodate 0 /* 1 if the buffer contains valid data */ +#define BH_Dirty 1 /* 1 if the buffer is dirty */ +#define BH_Lock 2 /* 1 if the buffer is locked */ +#define BH_Req 3 /* 0 if the buffer has been invalidated */ +#define BH_Touched 4 /* 1 if the buffer has been touched (aging) */ +#define BH_Has_aged 5 /* 1 if the buffer has been aged (aging) */ +#define BH_Protected 6 /* 1 if the buffer is protected */ +#define BH_FreeOnIO 7 /* 1 to discard the buffer_head after IO */ + +/* + * Try to keep the most commonly used fields in single cache lines (16 + * bytes) to improve performance. This ordering should be + * particularly beneficial on 32-bit processors. + * + * We use the first 16 bytes for the data which is used in searches + * over the block hash lists (ie. getblk(), find_buffer() and + * friends). + * + * The second 16 bytes we use for lru buffer scans, as used by + * sync_buffers() and refill_freelist(). -- sct + */ struct buffer_head { - char * b_data; /* pointer to data block (1024 bytes) */ - unsigned long b_size; /* block size */ + /* First cache line: */ unsigned long b_blocknr; /* block number */ - dev_t b_dev; /* device (0 = free) */ - unsigned short b_count; /* users using this block */ - unsigned char b_uptodate; - unsigned char b_dirt; /* 0-clean,1-dirty */ - unsigned char b_lock; /* 0 - ok, 1 -locked */ - unsigned char b_req; /* 0 if the buffer has been invalidated */ - unsigned char b_list; /* List that this buffer appears */ - unsigned char b_retain; /* Expected number of times this will - be used. Put on freelist when 0 */ - unsigned long b_flushtime; /* Time when this (dirty) buffer should be written */ - unsigned long b_lru_time; /* Time when this buffer was last used. */ + kdev_t b_dev; /* device (B_FREE = free) */ + kdev_t b_rdev; /* Real device */ + unsigned long b_rsector; /* Real buffer location on disk */ + struct buffer_head * b_next; /* Hash queue list */ + struct buffer_head * b_this_page; /* circular list of buffers in one page */ + + /* Second cache line: */ + unsigned long b_state; /* buffer state bitmap (see above) */ + struct buffer_head * b_next_free; + unsigned int b_count; /* users using this block */ + unsigned long b_size; /* block size */ + + /* Non-performance-critical data follows. */ + char * b_data; /* pointer to data block (1024 bytes) */ + unsigned int b_list; /* List that this buffer appears */ + unsigned long b_flushtime; /* Time when this (dirty) buffer + * should be written */ + unsigned long b_lru_time; /* Time when this buffer was + * last used. */ struct wait_queue * b_wait; struct buffer_head * b_prev; /* doubly linked list of hash-queue */ - struct buffer_head * b_next; struct buffer_head * b_prev_free; /* doubly linked list of buffers */ - struct buffer_head * b_next_free; - struct buffer_head * b_this_page; /* circular list of buffers in one page */ struct buffer_head * b_reqnext; /* request queue */ }; +static inline int buffer_uptodate(struct buffer_head * bh) +{ + return test_bit(BH_Uptodate, &bh->b_state); +} + +static inline int buffer_dirty(struct buffer_head * bh) +{ + return test_bit(BH_Dirty, &bh->b_state); +} + +static inline int buffer_locked(struct buffer_head * bh) +{ + return test_bit(BH_Lock, &bh->b_state); +} + +static inline int buffer_req(struct buffer_head * bh) +{ + return test_bit(BH_Req, &bh->b_state); +} + +static inline int buffer_touched(struct buffer_head * bh) +{ + return test_bit(BH_Touched, &bh->b_state); +} + +static inline int buffer_has_aged(struct buffer_head * bh) +{ + return test_bit(BH_Has_aged, &bh->b_state); +} + +static inline int buffer_protected(struct buffer_head * bh) +{ + return test_bit(BH_Protected, &bh->b_state); +} + #include <linux/pipe_fs_i.h> #include <linux/minix_fs_i.h> #include <linux/ext_fs_i.h> @@ -162,8 +228,8 @@ struct buffer_head { #include <linux/nfs_fs_i.h> #include <linux/xia_fs_i.h> #include <linux/sysv_fs_i.h> - -#ifdef __KERNEL__ +#include <linux/affs_fs_i.h> +#include <linux/ufs_fs_i.h> /* * Attribute flags. These should be or-ed together to figure out what @@ -178,6 +244,7 @@ struct buffer_head { #define ATTR_CTIME 64 #define ATTR_ATIME_SET 128 #define ATTR_MTIME_SET 256 +#define ATTR_FORCE 512 /* Not a change, but a change it */ /* * This is the Inode Attributes structure, used for notify_change(). It @@ -199,14 +266,16 @@ struct iattr { time_t ia_ctime; }; +#include <linux/quota.h> + struct inode { - dev_t i_dev; + kdev_t i_dev; unsigned long i_ino; umode_t i_mode; nlink_t i_nlink; uid_t i_uid; gid_t i_gid; - dev_t i_rdev; + kdev_t i_rdev; off_t i_size; time_t i_atime; time_t i_mtime; @@ -214,18 +283,20 @@ struct inode { unsigned long i_blksize; unsigned long i_blocks; unsigned long i_version; + unsigned long i_nrpages; struct semaphore i_sem; - struct inode_operations * i_op; - struct super_block * i_sb; - struct wait_queue * i_wait; - struct file_lock * i_flock; - struct vm_area_struct * i_mmap; - struct inode * i_next, * i_prev; - struct inode * i_hash_next, * i_hash_prev; - struct inode * i_bound_to, * i_bound_by; - struct inode * i_mount; + struct inode_operations *i_op; + struct super_block *i_sb; + struct wait_queue *i_wait; + struct file_lock *i_flock; + struct vm_area_struct *i_mmap; + struct page *i_pages; + struct dquot *i_dquot[MAXQUOTAS]; + struct inode *i_next, *i_prev; + struct inode *i_hash_next, *i_hash_prev; + struct inode *i_bound_to, *i_bound_by; + struct inode *i_mount; unsigned short i_count; - unsigned short i_wcount; unsigned short i_flags; unsigned char i_lock; unsigned char i_dirt; @@ -233,6 +304,7 @@ struct inode { unsigned char i_sock; unsigned char i_seek; unsigned char i_update; + unsigned short i_writecount; union { struct pipe_inode_info pipe_i; struct minix_inode_info minix_i; @@ -245,6 +317,8 @@ struct inode { struct nfs_inode_info nfs_i; struct xiafs_inode_info xiafs_i; struct sysv_inode_info sysv_i; + struct affs_inode_info affs_i; + struct ufs_inode_info ufs_i; struct socket socket_i; void * generic_ip; } u; @@ -255,7 +329,7 @@ struct file { loff_t f_pos; unsigned short f_flags; unsigned short f_count; - off_t f_reada; + unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin; struct file *f_next, *f_prev; int f_owner; /* pid or -pgrp where SIGIO should be sent */ struct inode * f_inode; @@ -264,20 +338,66 @@ struct file { void *private_data; /* needed for tty driver, and maybe others */ }; +#define FL_POSIX 1 +#define FL_FLOCK 2 +#define FL_BROKEN 4 /* broken flock() emulation */ +#define FL_ACCESS 8 /* for processes suspended by mandatory locking */ + struct file_lock { struct file_lock *fl_next; /* singly linked list for this inode */ struct file_lock *fl_nextlink; /* doubly linked list of all locks */ struct file_lock *fl_prevlink; /* used to simplify lock removal */ - struct file_lock *fl_block; + struct file_lock *fl_nextblock; /* circular list of blocked processes */ + struct file_lock *fl_prevblock; struct task_struct *fl_owner; struct wait_queue *fl_wait; struct file *fl_file; - char fl_flags; - char fl_type; + unsigned char fl_flags; + unsigned char fl_type; off_t fl_start; off_t fl_end; }; +#include <linux/fcntl.h> + +extern int fcntl_getlk(unsigned int fd, struct flock *l); +extern int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l); +extern void locks_remove_locks(struct task_struct *task, struct file *filp); + +#include <linux/stat.h> + +#define FLOCK_VERIFY_READ 1 +#define FLOCK_VERIFY_WRITE 2 + +extern int locks_mandatory_locked(struct inode *inode); +extern int locks_mandatory_area(int read_write, struct inode *inode, + struct file *filp, unsigned int offset, + unsigned int count); + +extern inline int locks_verify_locked(struct inode *inode) +{ + /* Candidates for mandatory locking have the setgid bit set + * but no group execute bit - an otherwise meaningless combination. + */ + if (IS_MANDLOCK(inode) && + (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) + return (locks_mandatory_locked(inode)); + return (0); +} +extern inline int locks_verify_area(int read_write, struct inode *inode, + struct file *filp, unsigned int offset, + unsigned int count) +{ + /* Candidates for mandatory locking have the setgid bit set + * but no group execute bit - an otherwise meaningless combination. + */ + if (IS_MANDLOCK(inode) && + (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) + return (locks_mandatory_area(read_write, inode, filp, offset, + count)); + return (0); +} + struct fasync_struct { int magic; struct fasync_struct *fa_next; /* singly linked list */ @@ -286,6 +406,8 @@ struct fasync_struct { #define FASYNC_MAGIC 0x4601 +extern int fasync_helper(struct inode *, struct file *, int, struct fasync_struct **); + #include <linux/minix_fs_sb.h> #include <linux/ext_fs_sb.h> #include <linux/ext2_fs_sb.h> @@ -295,9 +417,11 @@ struct fasync_struct { #include <linux/nfs_fs_sb.h> #include <linux/xia_fs_sb.h> #include <linux/sysv_fs_sb.h> +#include <linux/affs_fs_sb.h> +#include <linux/ufs_fs_sb.h> struct super_block { - dev_t s_dev; + kdev_t s_dev; unsigned long s_blocksize; unsigned char s_blocksize_bits; unsigned char s_lock; @@ -305,6 +429,7 @@ struct super_block { unsigned char s_dirt; struct file_system_type *s_type; struct super_operations *s_op; + struct dquot_operations *dq_op; unsigned long s_flags; unsigned long s_magic; unsigned long s_time; @@ -321,6 +446,8 @@ struct super_block { struct nfs_sb_info nfs_sb; struct xiafs_sb_info xiafs_sb; struct sysv_sb_info sysv_sb; + struct affs_sb_info affs_sb; + struct ufs_sb_info ufs_sb; void *generic_sbp; } u; }; @@ -331,12 +458,12 @@ struct super_block { * This allows the kernel to read directories into kernel space or * to have different dirent layouts depending on the binary type. */ -typedef int (*filldir_t)(void *, char *, int, off_t, ino_t); +typedef int (*filldir_t)(void *, const char *, int, off_t, ino_t); struct file_operations { - int (*lseek) (struct inode *, struct file *, off_t, int); - int (*read) (struct inode *, struct file *, char *, int); - int (*write) (struct inode *, struct file *, char *, int); + long long (*llseek) (struct inode *, struct file *, long long, int); + long (*read) (struct inode *, struct file *, char *, unsigned long); + long (*write) (struct inode *, struct file *, const char *, unsigned long); int (*readdir) (struct inode *, struct file *, void *, filldir_t); int (*select) (struct inode *, struct file *, int, select_table *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); @@ -345,8 +472,8 @@ struct file_operations { void (*release) (struct inode *, struct file *); int (*fsync) (struct inode *, struct file *); int (*fasync) (struct inode *, struct file *, int); - int (*check_media_change) (dev_t dev); - int (*revalidate) (dev_t dev); + int (*check_media_change) (kdev_t dev); + int (*revalidate) (kdev_t dev); }; struct inode_operations { @@ -359,9 +486,11 @@ struct inode_operations { int (*mkdir) (struct inode *,const char *,int,int); int (*rmdir) (struct inode *,const char *,int); int (*mknod) (struct inode *,const char *,int,int,int); - int (*rename) (struct inode *,const char *,int,struct inode *,const char *,int); + int (*rename) (struct inode *,const char *,int,struct inode *,const char *,int, int); int (*readlink) (struct inode *,char *,int); int (*follow_link) (struct inode *,struct inode *,int,int,struct inode **); + int (*readpage) (struct inode *, struct page *); + int (*writepage) (struct inode *, struct page *); int (*bmap) (struct inode *,int); void (*truncate) (struct inode *); int (*permission) (struct inode *, int); @@ -379,9 +508,19 @@ struct super_operations { int (*remount_fs) (struct super_block *, int *, char *); }; +struct dquot_operations { + void (*initialize) (struct inode *, short); + void (*drop) (struct inode *); + int (*alloc_block) (const struct inode *, unsigned long); + int (*alloc_inode) (const struct inode *, unsigned long); + void (*free_block) (const struct inode *, unsigned long); + void (*free_inode) (const struct inode *, unsigned long); + int (*transfer) (struct inode *, struct iattr *, char); +}; + struct file_system_type { struct super_block *(*read_super) (struct super_block *, void *, int); - char *name; + const char *name; int requires_dev; struct file_system_type * next; }; @@ -396,10 +535,11 @@ extern void kill_fasync(struct fasync_struct *fa, int sig); extern int getname(const char * filename, char **result); extern void putname(char * name); - +extern int do_truncate(struct inode *, unsigned long); extern int register_blkdev(unsigned int, const char *, struct file_operations *); extern int unregister_blkdev(unsigned int major, const char * name); extern int blkdev_open(struct inode * inode, struct file * filp); +extern void blkdev_release (struct inode * inode); extern struct file_operations def_blk_fops; extern struct inode_operations blkdev_inode_operations; @@ -410,6 +550,7 @@ extern struct file_operations def_chr_fops; extern struct inode_operations chrdev_inode_operations; extern void init_fifo(struct inode * inode); +extern struct inode_operations fifo_inode_operations; extern struct file_operations connecting_fifo_fops; extern struct file_operations read_fifo_fops; @@ -419,22 +560,20 @@ extern struct file_operations read_pipe_fops; extern struct file_operations write_pipe_fops; extern struct file_operations rdwr_pipe_fops; -extern struct file_system_type *get_fs_type(char *name); +extern struct file_system_type *get_fs_type(const char *name); -extern int fs_may_mount(dev_t dev); -extern int fs_may_umount(dev_t dev, struct inode * mount_root); -extern int fs_may_remount_ro(dev_t dev); +extern int fs_may_mount(kdev_t dev); +extern int fs_may_umount(kdev_t dev, struct inode * mount_root); +extern int fs_may_remount_ro(kdev_t dev); extern struct file *first_file; -extern int nr_files; extern struct super_block super_blocks[NR_SUPER]; -extern int shrink_buffers(unsigned int priority); extern void refile_buffer(struct buffer_head * buf); extern void set_writetime(struct buffer_head * buf, int flag); extern void refill_freelist(int size); +extern int try_to_free_buffer(struct buffer_head*, struct buffer_head**, int); -extern struct buffer_head ** buffer_pages; extern int nr_buffers; extern int buffermem; extern int nr_buffer_heads; @@ -447,39 +586,52 @@ extern int nr_buffer_heads; #define BUF_SHARED 5 /* Buffers shared */ #define NR_LIST 6 +void mark_buffer_uptodate(struct buffer_head * bh, int on); + extern inline void mark_buffer_clean(struct buffer_head * bh) { - if(bh->b_dirt) { - bh->b_dirt = 0; - if(bh->b_list == BUF_DIRTY) refile_buffer(bh); - } + if (clear_bit(BH_Dirty, &bh->b_state)) { + if (bh->b_list == BUF_DIRTY) + refile_buffer(bh); + } } extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag) { - if(!bh->b_dirt) { - bh->b_dirt = 1; - set_writetime(bh, flag); - if(bh->b_list != BUF_DIRTY) refile_buffer(bh); - } + if (!set_bit(BH_Dirty, &bh->b_state)) { + set_writetime(bh, flag); + if (bh->b_list != BUF_DIRTY) + refile_buffer(bh); + } } - -extern int check_disk_change(dev_t dev); -extern void invalidate_inodes(dev_t dev); -extern void invalidate_buffers(dev_t dev); +extern int check_disk_change(kdev_t dev); +extern void invalidate_inodes(kdev_t dev); +extern void invalidate_inode_pages(struct inode *); +extern void invalidate_buffers(kdev_t dev); extern int floppy_is_wp(int minor); -extern void sync_inodes(dev_t dev); -extern void sync_dev(dev_t dev); -extern int fsync_dev(dev_t dev); -extern void sync_supers(dev_t dev); +extern void sync_inodes(kdev_t dev); +extern void sync_dev(kdev_t dev); +extern int fsync_dev(kdev_t dev); +extern void sync_supers(kdev_t dev); extern int bmap(struct inode * inode,int block); extern int notify_change(struct inode *, struct iattr *); +extern int _namei(const char * pathname, struct inode * base, + int follow_links, struct inode ** res_inode); extern int namei(const char * pathname, struct inode ** res_inode); +/* + * knamei() is the same as namei() except that it doesn't attempt + * to copy the pathname from userspace to kernelspace. So it + * can be used for names in kernelspace. + */ +extern inline int knamei(const char *pathname, struct inode **res_inode) +{ + return _namei(pathname, NULL, 1, res_inode); +} extern int lnamei(const char * pathname, struct inode ** res_inode); extern int permission(struct inode * inode,int mask); -extern int get_write_access(struct inode * inode); -extern void put_write_access(struct inode * inode); +extern int get_write_access(struct inode *inode); +extern void put_write_access(struct inode *inode); extern int open_namei(const char * pathname, int flag, int mode, struct inode ** res_inode, struct inode * base); extern int do_mknod(const char * filename, int mode, dev_t dev); @@ -490,34 +642,58 @@ extern struct inode * get_empty_inode(void); extern void insert_inode_hash(struct inode *); extern void clear_inode(struct inode *); extern struct inode * get_pipe_inode(void); +extern int get_unused_fd(void); +extern void put_unused_fd(int); extern struct file * get_empty_filp(void); -extern struct buffer_head * get_hash_table(dev_t dev, int block, int size); -extern struct buffer_head * getblk(dev_t dev, int block, int size); +extern int close_fp(struct file *filp); +extern struct buffer_head * get_hash_table(kdev_t dev, int block, int size); +extern struct buffer_head * getblk(kdev_t dev, int block, int size); extern void ll_rw_block(int rw, int nr, struct buffer_head * bh[]); -extern void ll_rw_page(int rw, int dev, unsigned long nr, char * buffer); -extern void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buffer); -extern int is_read_only(int dev); -extern void brelse(struct buffer_head * buf); -extern void set_blocksize(dev_t dev, int size); -extern struct buffer_head * bread(dev_t dev, int block, int size); -extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int no_share); -extern struct buffer_head * breada(dev_t dev,int block, int size, +extern void ll_rw_page(int rw, kdev_t dev, unsigned long nr, char * buffer); +extern void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buffer); +extern int is_read_only(kdev_t dev); +extern void __brelse(struct buffer_head *buf); +extern inline void brelse(struct buffer_head *buf) +{ + if (buf) + __brelse(buf); +} +extern void __bforget(struct buffer_head *buf); +extern inline void bforget(struct buffer_head *buf) +{ + if (buf) + __bforget(buf); +} +extern void set_blocksize(kdev_t dev, int size); +extern struct buffer_head * bread(kdev_t dev, int block, int size); +extern struct buffer_head * breada(kdev_t dev,int block, int size, unsigned int pos, unsigned int filesize); -extern void put_super(dev_t dev); -unsigned long generate_cluster(dev_t dev, int b[], int size); -extern dev_t ROOT_DEV; + +extern int brw_page(int, struct page *, kdev_t, int [], int, int); + +extern int generic_readpage(struct inode *, struct page *); +extern int generic_file_mmap(struct inode *, struct file *, struct vm_area_struct *); +extern long generic_file_read(struct inode *, struct file *, char *, unsigned long); + +extern void put_super(kdev_t dev); +unsigned long generate_cluster(kdev_t dev, int b[], int size); +unsigned long generate_cluster_swab32(kdev_t dev, int b[], int size); +extern kdev_t ROOT_DEV; extern void show_buffers(void); extern void mount_root(void); -extern int char_read(struct inode *, struct file *, char *, int); -extern int block_read(struct inode *, struct file *, char *, int); -extern int read_ahead[]; +#ifdef CONFIG_BLK_DEV_INITRD +extern kdev_t real_root_dev; +extern int change_root(kdev_t new_root_dev,const char *put_old); +#endif -extern int char_write(struct inode *, struct file *, char *, int); -extern int block_write(struct inode *, struct file *, char *, int); +extern long char_read(struct inode *, struct file *, char *, unsigned long); +extern long block_read(struct inode *, struct file *, char *, unsigned long); +extern int read_ahead[]; -extern int generic_mmap(struct inode *, struct file *, struct vm_area_struct *); +extern long char_write(struct inode *, struct file *, const char *, unsigned long); +extern long block_write(struct inode *, struct file *, const char *, unsigned long); extern int block_fsync(struct inode *, struct file *); extern int file_fsync(struct inode *, struct file *); @@ -530,9 +706,13 @@ extern void inode_setattr(struct inode *, struct iattr *); extern inline struct inode * iget(struct super_block * sb,int nr) { - return __iget(sb,nr,1); + return __iget(sb, nr, 1); } +/* kludge to get SCSI modules working */ +#include <linux/minix_fs.h> +#include <linux/minix_fs_sb.h> + #endif /* __KERNEL__ */ #endif diff --git a/include/linux/ftape.h b/include/linux/ftape.h new file mode 100644 index 000000000..0ce7a1c4b --- /dev/null +++ b/include/linux/ftape.h @@ -0,0 +1,70 @@ +#ifndef _FTAPE_H +#define _FTAPE_H + +/* + * Copyright (C) 1994-1995 Bas Laarhoven. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + * + $Source: /home/bas/distr/ftape-2.03b/RCS/ftape.h,v $ + $Author: bas $ + * + $Revision: 1.18 $ + $Date: 1995/05/06 16:11:53 $ + $State: Beta $ + * + * This file contains global definitions, typedefs and macro's + * for the QIC-40/80 floppy-tape driver for Linux. + */ + +#include <linux/sched.h> +#include <linux/mm.h> + +#define SECTOR(x) (x+1) /* sector offset into real sector */ +#define SECTOR_SIZE (1024) +#define SECTORS_PER_SEGMENT (32) +#define BUFF_SIZE (SECTORS_PER_SEGMENT * SECTOR_SIZE) +#define FTAPE_UNIT (ftape_unit & 3) +#define RQM_DELAY (12) +#define MILLISECOND (1) +#define SECOND (1000) +#define FOREVER (-1) +#ifndef HZ +# error "HZ undefined." +#endif +#define MSPT (SECOND / HZ) /* milliseconds per tick */ + +/* This defines the number of retries that the driver will allow + * before giving up (and letting a higher level handle the error). + */ +#ifdef TESTING +# define SOFT_RETRIES 1 /* number of low level retries */ +# define RETRIES_ON_ECC_ERROR 3 /* ecc error when correcting segment */ +#else +# define SOFT_RETRIES 6 /* number of low level retries (triple) */ +# define RETRIES_ON_ECC_ERROR 3 /* ecc error when correcting segment */ +#endif +/* some useful macro's + */ +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#define NR_ITEMS(x) (sizeof(x)/ sizeof(*x)) + +typedef unsigned char byte; + +extern int ftape_init(void); + +#endif + diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 8ff890e48..535cdefdc 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -8,8 +8,28 @@ * * <drew@colorado.edu> */ - -#define EXTENDED_PARTITION 5 + +#include <linux/config.h> + +#define CONFIG_MSDOS_PARTITION 1 + +#ifdef __alpha__ +#define CONFIG_OSF_PARTITION 1 +#endif + +#if defined(__sparc__) || defined(CONFIG_SMD_DISKLABEL) +#define CONFIG_SUN_PARTITION 1 +#endif + +/* These two have identical behaviour; use the second one if DOS fdisk gets + confused about extended/logical partitions starting past cylinder 1023. */ +#define DOS_EXTENDED_PARTITION 5 +#define LINUX_EXTENDED_PARTITION 0x85 + +#define DM6_PARTITION 0x54 /* has DDO: use xlated geom & offset */ +#define EZD_PARTITION 0x55 /* EZ-DRIVE: same as DM6 (we think) */ +#define DM6_AUX1PARTITION 0x51 /* no DDO: use xlated geom */ +#define DM6_AUX3PARTITION 0x53 /* no DDO: use xlated geom */ struct partition { unsigned char boot_ind; /* 0x80 - active */ @@ -31,22 +51,84 @@ struct hd_struct { struct gendisk { int major; /* major number of driver */ - char *major_name; /* name of major driver */ + const char *major_name; /* name of major driver */ int minor_shift; /* number of times minor is shifted to get real minor */ int max_p; /* maximum partitions per device */ int max_nr; /* maximum number of real devices */ - void (*init)(void); /* Initialization called before we do our thing */ + void (*init)(struct gendisk *); /* Initialization called before we do our thing */ struct hd_struct *part; /* partition table */ - int *sizes; /* size of device in blocks */ + int *sizes; /* device size in blocks, copied to blk_size[] */ int nr_real; /* number of real devices */ void *real_devices; /* internal use */ struct gendisk *next; }; -extern int NR_GENDISKS; /* total */ +#ifdef CONFIG_BSD_DISKLABEL +/* + * BSD disklabel support by Yossi Gottlieb <yogo@math.tau.ac.il> + */ + +#define BSD_PARTITION 0xa5 /* Partition ID */ + +#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ +#define BSD_MAXPARTITIONS 8 +#define BSD_FS_UNUSED 0 /* disklabel unused partition entry ID */ +struct bsd_disklabel { + __u32 d_magic; /* the magic number */ + __s16 d_type; /* drive type */ + __s16 d_subtype; /* controller/d_type specific */ + char d_typename[16]; /* type name, e.g. "eagle" */ + char d_packname[16]; /* pack identifier */ + __u32 d_secsize; /* # of bytes per sector */ + __u32 d_nsectors; /* # of data sectors per track */ + __u32 d_ntracks; /* # of tracks per cylinder */ + __u32 d_ncylinders; /* # of data cylinders per unit */ + __u32 d_secpercyl; /* # of data sectors per cylinder */ + __u32 d_secperunit; /* # of data sectors per unit */ + __u16 d_sparespertrack; /* # of spare sectors per track */ + __u16 d_sparespercyl; /* # of spare sectors per cylinder */ + __u32 d_acylinders; /* # of alt. cylinders per unit */ + __u16 d_rpm; /* rotational speed */ + __u16 d_interleave; /* hardware sector interleave */ + __u16 d_trackskew; /* sector 0 skew, per track */ + __u16 d_cylskew; /* sector 0 skew, per cylinder */ + __u32 d_headswitch; /* head switch time, usec */ + __u32 d_trkseek; /* track-to-track seek, usec */ + __u32 d_flags; /* generic flags */ +#define NDDATA 5 + __u32 d_drivedata[NDDATA]; /* drive-type specific information */ +#define NSPARE 5 + __u32 d_spare[NSPARE]; /* reserved for future use */ + __u32 d_magic2; /* the magic number (again) */ + __u16 d_checksum; /* xor of data incl. partitions */ + + /* filesystem and partition information: */ + __u16 d_npartitions; /* number of partitions in following */ + __u32 d_bbsize; /* size of boot area at sn0, bytes */ + __u32 d_sbsize; /* max size of fs superblock, bytes */ + struct bsd_partition { /* the partition table */ + __u32 p_size; /* number of sectors in partition */ + __u32 p_offset; /* starting sector */ + __u32 p_fsize; /* filesystem basic fragment size */ + __u8 p_fstype; /* filesystem type, see below */ + __u8 p_frag; /* filesystem fragments per block */ + __u16 p_cpg; /* filesystem cylinders per group */ + } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ +}; + +#endif /* CONFIG_BSD_DISKLABEL */ + extern struct gendisk *gendisk_head; /* linked list of disks */ +/* + * disk_name() is used by genhd.c and md.c. + * It formats the devicename of the indicated disk + * into the supplied buffer, and returns a pointer + * to that same buffer (for convenience). + */ +char *disk_name (struct gendisk *hd, int minor, char *buf); + #endif diff --git a/include/linux/gscd.h b/include/linux/gscd.h new file mode 100644 index 000000000..fccc742a5 --- /dev/null +++ b/include/linux/gscd.h @@ -0,0 +1,110 @@ +/* + * Definitions for a GoldStar R420 CD-ROM interface + * + * Copyright (C) 1995 Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de> + * Eberhard Moenkeberg <emoenke@gwdg.de> + * + * Published under the GPL. + * + */ + + +/* The Interface Card default address is 0x340. This will work for most + applications. Address selection is accomplished by jumpers PN801-1 to + PN801-4 on the GoldStar Interface Card. + Appropriate settings are: 0x300, 0x310, 0x320, 0x330, 0x340, 0x350, 0x360 + 0x370, 0x380, 0x390, 0x3A0, 0x3B0, 0x3C0, 0x3D0, 0x3E0, 0x3F0 */ + +/* insert here the I/O port address */ +#define GSCD_BASE_ADDR 0x340 + +/* change this to set the dma-channel */ +#define GSCD_DMA_CHANNEL 3 /* not used */ + +/************** nothing to set up below here *********************/ + +/* port access macro */ +#define GSCDPORT(x) (gscd_port + (x)) + +/* + * commands + * the lower nibble holds the command length + */ +#define CMD_STATUS 0x01 +#define CMD_READSUBQ 0x02 /* 1: ?, 2: UPC, 5: ? */ +#define CMD_SEEK 0x05 /* read_mode M-S-F */ +#define CMD_READ 0x07 /* read_mode M-S-F nsec_h nsec_l */ +#define CMD_RESET 0x11 +#define CMD_SETMODE 0x15 +#define CMD_PLAY 0x17 /* M-S-F M-S-F */ +#define CMD_LOCK_CTL 0x22 /* 0: unlock, 1: lock */ +#define CMD_IDENT 0x31 +#define CMD_SETSPEED 0x32 /* 0: auto */ /* ??? */ +#define CMD_GETMODE 0x41 +#define CMD_PAUSE 0x51 +#define CMD_READTOC 0x61 +#define CMD_DISKINFO 0x71 +#define CMD_TRAY_CTL 0x81 + +/* + * disk_state: + */ +#define ST_PLAYING 0x80 +#define ST_UNLOCKED 0x40 +#define ST_NO_DISK 0x20 +#define ST_DOOR_OPEN 0x10 +#define ST_x08 0x08 +#define ST_x04 0x04 +#define ST_INVALID 0x02 +#define ST_x01 0x01 + +/* + * cmd_type: + */ +#define TYPE_INFO 0x01 +#define TYPE_DATA 0x02 + +/* + * read_mode: + */ +#define MOD_POLLED 0x80 +#define MOD_x08 0x08 +#define MOD_RAW 0x04 + +#define READ_DATA(port, buf, nr) insb(port, buf, nr) + +#define SET_TIMER(func, jifs) \ + ((timer_table[GSCD_TIMER].expires = jiffies + jifs), \ + (timer_table[GSCD_TIMER].fn = func), \ + (timer_active |= 1<<GSCD_TIMER)) + +#define CLEAR_TIMER timer_active &= ~(1<<GSCD_TIMER) + +#define MAX_TRACKS 104 + +struct msf { + unsigned char min; + unsigned char sec; + unsigned char frame; +}; + +struct gscd_Play_msf { + struct msf start; + struct msf end; +}; + +struct gscd_DiskInfo { + unsigned char first; + unsigned char last; + struct msf diskLength; + struct msf firstTrack; +}; + +struct gscd_Toc { + unsigned char ctrl_addr; + unsigned char track; + unsigned char pointIndex; + struct msf trackTime; + struct msf diskTime; +}; + diff --git a/include/linux/hdlcdrv.h b/include/linux/hdlcdrv.h new file mode 100644 index 000000000..82a35d06d --- /dev/null +++ b/include/linux/hdlcdrv.h @@ -0,0 +1,326 @@ +/* + * hdlcdrv.h -- HDLC packet radio network driver. + * The Linux soundcard driver for 1200 baud and 9600 baud packet radio + * (C) 1996 by Thomas Sailer, HB9JNX/AE4WA + */ + +#ifndef _HDLCDRV_H +#define _HDLCDRV_H + +#include <linux/sockios.h> +#include <linux/if_ether.h> +#include <linux/netdevice.h> + +/* -------------------------------------------------------------------- */ +/* + * structs for the IOCTL commands + */ + +struct hdlcdrv_params { + int iobase; + int irq; + int dma; + int seriobase; + int pariobase; + int midiiobase; +}; + +struct hdlcdrv_channel_params { + int tx_delay; /* the transmitter keyup delay in 10ms units */ + int tx_tail; /* the transmitter keyoff delay in 10ms units */ + int slottime; /* the slottime in 10ms; usually 10 = 100ms */ + int ppersist; /* the p-persistence 0..255 */ + int fulldup; /* some driver do not support full duplex, setting */ + /* this just makes them send even if DCD is on */ +}; + +struct hdlcdrv_channel_state { + int ptt; + int dcd; + int ptt_keyed; + struct enet_statistics stats; +}; + +struct hdlcdrv_ioctl { + int cmd; + union { + struct hdlcdrv_params mp; + struct hdlcdrv_channel_params cp; + struct hdlcdrv_channel_state cs; + unsigned int calibrate; + unsigned char bits; + } data; +}; + +/* -------------------------------------------------------------------- */ + +/* + * ioctl values + */ +#define HDLCDRVCTL_GETMODEMPAR 0 +#define HDLCDRVCTL_SETMODEMPAR 1 +#define HDLCDRVCTL_GETCHANNELPAR 2 +#define HDLCDRVCTL_SETCHANNELPAR 3 +#define HDLCDRVCTL_GETSTAT 4 +#define HDLCDRVCTL_CALIBRATE 5 + +/* + * these are mainly for debugging purposes + */ +#define HDLCDRVCTL_GETSAMPLES 10 +#define HDLCDRVCTL_GETBITS 11 + +/* -------------------------------------------------------------------- */ + +#ifdef __KERNEL__ + +#define HDLCDRV_MAGIC 0x5ac6e778 +#define HDLCDRV_IFNAMELEN 6 +#define HDLCDRV_HDLCBUFFER 16 /* should be a power of 2 for speed reasons */ +#define HDLCDRV_BITBUFFER 256 /* should be a power of 2 for speed reasons */ +#undef HDLCDRV_LOOPBACK /* define for HDLC debugging purposes */ +#undef HDLCDRV_DEBUG + +/* maximum packet length, excluding CRC */ +#define HDLCDRV_MAXFLEN 400 + + +struct hdlcdrv_hdlcbuffer { + unsigned rd, wr; + unsigned short buf[HDLCDRV_HDLCBUFFER]; +}; + +#ifdef HDLCDRV_DEBUG +struct hdlcdrv_bitbuffer { + unsigned int rd; + unsigned int wr; + unsigned int shreg; + unsigned char buffer[HDLCDRV_BITBUFFER]; +}; + +extern inline void hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer *buf, + unsigned int bit) +{ + unsigned char new; + + new = buf->shreg & 1; + buf->shreg >>= 1; + buf->shreg |= (!!bit) << 7; + if (new) { + buf->buffer[buf->wr] = buf->shreg; + buf->wr = (buf->wr+1) % sizeof(buf->buffer); + buf->shreg = 0x80; + } +} + +extern inline void hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer *buf, + unsigned int bits) +{ + buf->buffer[buf->wr] = bits & 0xff; + buf->wr = (buf->wr+1) % sizeof(buf->buffer); + buf->buffer[buf->wr] = (bits >> 8) & 0xff; + buf->wr = (buf->wr+1) % sizeof(buf->buffer); + +} +#endif /* HDLCDRV_DEBUG */ + +/* -------------------------------------------------------------------- */ +/* + * Information that need to be kept for each driver. + */ + +struct hdlcdrv_ops { + /* + * first some informations needed by the hdlcdrv routines + */ + int bitrate; + /* + * the routines called by the hdlcdrv routines + */ + int (*open)(struct device *); + int (*close)(struct device *); + int (*ioctl)(struct device *, struct ifreq *, int); +}; + +struct hdlcdrv_state { + int magic; + + char ifname[HDLCDRV_IFNAMELEN]; + + const struct hdlcdrv_ops *ops; + + struct hdlcdrv_pttoutput { + int seriobase; + int pariobase; + int midiiobase; + unsigned int flags; + } ptt_out; + + struct hdlcdrv_channel_params ch_params; + + struct hdlcdrv_hdlcrx { + struct hdlcdrv_hdlcbuffer hbuf; + int in_hdlc_rx; + /* 0 = sync hunt, != 0 receiving */ + int rx_state; + unsigned int bitstream; + unsigned int bitbuf; + int numbits; + unsigned char dcd; + + int len; + unsigned char *bp; + unsigned char buffer[HDLCDRV_MAXFLEN+2]; + } hdlcrx; + + struct hdlcdrv_hdlctx { + struct hdlcdrv_hdlcbuffer hbuf; + int in_hdlc_tx; + /* + * 0 = send flags + * 1 = send txtail (flags) + * 2 = send packet + */ + int tx_state; + int numflags; + unsigned int bitstream; + unsigned char ptt; + int calibrate; + int slotcnt; + + unsigned int bitbuf; + int numbits; + + int len; + unsigned char *bp; + unsigned char buffer[HDLCDRV_MAXFLEN+2]; + } hdlctx; + +#ifdef HDLCDRV_DEBUG + struct hdlcdrv_bitbuffer bitbuf_channel; + struct hdlcdrv_bitbuffer bitbuf_hdlc; +#endif /* HDLCDRV_DEBUG */ + + struct enet_statistics stats; + int ptt_keyed; + + struct sk_buff_head send_queue; /* Packets awaiting transmission */ +}; + + +/* -------------------------------------------------------------------- */ + +extern inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb) +{ + return !((HDLCDRV_HDLCBUFFER - 1 + hb->rd - hb->wr) + % HDLCDRV_HDLCBUFFER); +} + +/* -------------------------------------------------------------------- */ + +extern inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb) +{ + return hb->rd == hb->wr; +} + +/* -------------------------------------------------------------------- */ + +extern inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb) +{ + unsigned newr; + unsigned short val; + unsigned long flags; + + if (hb->rd == hb->wr) + return 0; + save_flags(flags); + cli(); + newr = (hb->rd+1) % HDLCDRV_HDLCBUFFER; + val = hb->buf[hb->rd]; + hb->rd = newr; + restore_flags(flags); + return val; +} + +/* -------------------------------------------------------------------- */ + +extern inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb, + unsigned short val) +{ + unsigned newp; + unsigned long flags; + + save_flags(flags); + cli(); + newp = (hb->wr+1) % HDLCDRV_HDLCBUFFER; + if (newp != hb->rd) { + hb->buf[hb->wr] = val & 0xffff; + hb->wr = newp; + } + restore_flags(flags); +} + +/* -------------------------------------------------------------------- */ + +extern void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits) +{ + hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits); +} + +extern unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s) +{ + unsigned int ret; + + if (hdlcdrv_hbuf_empty(&s->hdlctx.hbuf)) { + if (s->hdlctx.calibrate > 0) + s->hdlctx.calibrate--; + else + s->hdlctx.ptt = 0; + ret = 0; + } else + ret = hdlcdrv_hbuf_get(&s->hdlctx.hbuf); +#ifdef HDLCDRV_LOOPBACK + hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, ret); +#endif /* HDLCDRV_LOOPBACK */ + return ret; +} + +extern void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit) +{ +#ifdef HDLCDRV_DEBUG + hdlcdrv_add_bitbuffer(&s->bitbuf_channel, bit); +#endif /* HDLCDRV_DEBUG */ +} + +extern void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd) +{ + s->hdlcrx.dcd = !!dcd; +} + +extern int hdlcdrv_ptt(struct hdlcdrv_state *s) +{ + return s->hdlctx.ptt || (s->hdlctx.calibrate > 0); +} + +/* -------------------------------------------------------------------- */ + +void hdlcdrv_receiver(struct device *, struct hdlcdrv_state *); +void hdlcdrv_transmitter(struct device *, struct hdlcdrv_state *); +void hdlcdrv_arbitrate(struct device *, struct hdlcdrv_state *); +int hdlcdrv_register_hdlcdrv(struct device *dev, const struct hdlcdrv_ops *ops, + unsigned int privsize, char *ifname, + unsigned int baseaddr, unsigned int irq, + unsigned int dma); +int hdlcdrv_unregister_hdlcdrv(struct device *dev); + +/* -------------------------------------------------------------------- */ + + + +#endif /* __KERNEL__ */ + +/* -------------------------------------------------------------------- */ + +#endif /* _HDLCDRV_H */ + +/* -------------------------------------------------------------------- */ diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h index 1640a3beb..ba4b62648 100644 --- a/include/linux/hdreg.h +++ b/include/linux/hdreg.h @@ -1,16 +1,16 @@ #ifndef _LINUX_HDREG_H #define _LINUX_HDREG_H -#include <linux/config.h> - /* * This file contains some defines for the AT-hd-controller. - * Various sources. Check out some definitions (see comments with - * a ques). + * Various sources. */ +#define HD_IRQ 14 /* the standard disk interrupt */ + +/* ide.c has its own port definitions in "ide.h" */ + /* Hd controller regs. Ref: IBM AT Bios-listing */ -/* For a second IDE interface, xor all addresses with 0x80 */ #define HD_DATA 0x1f0 /* _CTL when writing */ #define HD_ERROR 0x1f1 /* see err-bits */ #define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ @@ -26,6 +26,8 @@ #define HD_CMD 0x3f6 /* used for resets */ #define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ +/* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */ + /* Bits of HD_STATUS */ #define ERR_STAT 0x01 #define INDEX_STAT 0x02 @@ -45,16 +47,25 @@ #define WIN_INIT 0x60 #define WIN_SEEK 0x70 #define WIN_DIAGNOSE 0x90 -#define WIN_SPECIFY 0x91 +#define WIN_SPECIFY 0x91 /* set drive geometry translation */ #define WIN_SETIDLE1 0xE3 #define WIN_SETIDLE2 0x97 -#define WIN_PIDENTIFY 0xA1 /* identify ATA-PI device */ -#define WIN_MULTREAD 0xC4 /* read multiple sectors */ -#define WIN_MULTWRITE 0xC5 /* write multiple sectors */ -#define WIN_SETMULT 0xC6 /* enable read multiple */ +#define WIN_DOORLOCK 0xde /* lock door on removable drives */ +#define WIN_DOORUNLOCK 0xdf /* unlock door on removable drives */ + +#define WIN_MULTREAD 0xC4 /* read sectors using multiple mode */ +#define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */ +#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */ #define WIN_IDENTIFY 0xEC /* ask drive to identify itself */ -#define WIN_SETFEATURES 0xEF /* set special drive features */ +#define WIN_SETFEATURES 0xEF /* set special drive features */ +#define WIN_READDMA 0xc8 /* read sectors using DMA transfers */ +#define WIN_WRITEDMA 0xca /* write sectors using DMA transfers */ + +/* Additional drive command codes used by ATAPI devices. */ +#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */ +#define WIN_SRST 0x08 /* ATAPI soft reset command */ +#define WIN_PACKETCMD 0xa0 /* Send a packet command. */ /* Bits for HD_ERROR */ #define MARK_ERR 0x01 /* Bad address mark */ @@ -71,21 +82,26 @@ struct hd_geometry { unsigned long start; }; -/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x30n/0x31n */ -#define HDIO_GETGEO 0x301 /* get device geometry */ -#define HDIO_REQ HDIO_GETGEO /* obsolete, use HDIO_GETGEO */ -#define HDIO_GET_UNMASKINTR 0x302 /* get current unmask setting */ -#define HDIO_GET_MULTCOUNT 0x304 /* get current IDE blockmode setting */ -#define HDIO_GET_IDENTITY 0x307 /* get IDE identification info */ -#define HDIO_GET_KEEPSETTINGS 0x308 /* get keep-settings-on-reset flag */ -#define HDIO_GET_CHIPSET 0x309 /* get current interface type setting */ -#define HDIO_DRIVE_CMD 0x31f /* execute a special drive command */ - -/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x32n/0x33n */ -#define HDIO_SET_MULTCOUNT 0x321 /* set IDE blockmode */ -#define HDIO_SET_UNMASKINTR 0x322 /* permit other irqs during I/O */ -#define HDIO_SET_KEEPSETTINGS 0x323 /* keep ioctl settings on reset */ -#define HDIO_SET_CHIPSET 0x324 /* optimise driver for interface type */ +/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */ +#define HDIO_GETGEO 0x0301 /* get device geometry */ +#define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */ +#define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */ +#define HDIO_GET_IDENTITY 0x0307 /* get IDE identification info */ +#define HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */ +#define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */ +#define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */ +#define HDIO_GET_DMA 0x030b /* get use-dma flag */ +#define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */ + +/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */ +#define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */ +#define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */ +#define HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */ +#define HDIO_SET_32BIT 0x0324 /* change io_32bit flags */ +#define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */ +#define HDIO_SET_DMA 0x0326 /* change use-dma flag */ +#define HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */ +#define HDIO_SCAN_HWIF 0x0328 /* register and (re)scan interface */ /* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */ struct hd_driveid { @@ -138,18 +154,25 @@ struct hd_driveid { /* unsigned short reservedyy[96];*/ /* reserved (words 160-255) */ }; +#ifdef __KERNEL__ /* * These routines are used for kernel command line parameters from main.c: */ +#include <linux/config.h> + #ifdef CONFIG_BLK_DEV_HD void hd_setup(char *, int *); #endif /* CONFIG_BLK_DEV_HD */ + #ifdef CONFIG_BLK_DEV_IDE -void ide_setup(char *, int *); -void hda_setup(char *, int *); -void hdb_setup(char *, int *); -void hdc_setup(char *, int *); -void hdd_setup(char *, int *); +void ide_setup(char *); #endif /* CONFIG_BLK_DEV_IDE */ +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +int ide_register(int io_port, int ctl_port, int irq); +void ide_unregister(unsigned int); +#endif /* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */ + +#endif /* __KERNEL__ */ + #endif /* _LINUX_HDREG_H */ diff --git a/include/linux/hpfs_fs.h b/include/linux/hpfs_fs.h index 0094c359c..2b7926aba 100644 --- a/include/linux/hpfs_fs.h +++ b/include/linux/hpfs_fs.h @@ -8,5 +8,6 @@ /* The entry point for a VFS */ extern struct super_block *hpfs_read_super (struct super_block *, void *, int); +extern int init_hpfs_fs(void); #endif diff --git a/include/linux/icmp.h b/include/linux/icmp.h index ca1e8c6bf..611c41da8 100644 --- a/include/linux/icmp.h +++ b/include/linux/icmp.h @@ -46,6 +46,10 @@ #define ICMP_HOST_ANO 10 #define ICMP_NET_UNR_TOS 11 #define ICMP_HOST_UNR_TOS 12 +#define ICMP_PKT_FILTERED 13 /* Packet filtered */ +#define ICMP_PREC_VIOLATION 14 /* Precedence violation */ +#define ICMP_PREC_CUTOFF 15 /* Precedence cut off */ +#define NR_ICMP_UNREACH 15 /* instead of hardcoding immediate value */ /* Codes for REDIRECT. */ #define ICMP_REDIR_NET 0 /* Redirect Net */ @@ -59,15 +63,15 @@ struct icmphdr { - unsigned char type; - unsigned char code; - unsigned short checksum; + __u8 type; + __u8 code; + __u16 checksum; union { struct { - unsigned short id; - unsigned short sequence; + __u16 id; + __u16 sequence; } echo; - unsigned long gateway; + __u32 gateway; } un; }; diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h new file mode 100644 index 000000000..d600403c8 --- /dev/null +++ b/include/linux/icmpv6.h @@ -0,0 +1,142 @@ +#ifndef _LINUX_ICMPV6_H +#define _LINUX_ICMPV6_H + +#include <asm/byteorder.h> + +struct icmpv6hdr { + + __u8 type; + __u8 code; + __u16 checksum; + + + union { + struct icmpv6_echo { + __u16 identifier; + __u16 sequence; + } u_echo; + __u32 pointer; + __u32 mtu; + __u32 unused; + + struct icmpv6_nd_advt { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u32 reserved:5, + override:1, + solicited:1, + router:1, + reserved2:24; +#elif defined(__BIG_ENDIAN_BITFIELD) + __u32 router:1, + solicited:1, + override:1, + reserved:29; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } u_nd_advt; + + struct icmpv6_nd_ra { + __u8 hop_limit; +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 reserved:6, + other:1, + managed:1; + +#elif defined(__BIG_ENDIAN_BITFIELD) + __u8 managed:1, + other:1, + reserved:6; +#else +#error "Please fix <asm/byteorder.h>" +#endif + __u16 rt_lifetime; + } u_nd_ra; + + } u; + +#define icmp6_identifier u.u_echo.identifier +#define icmp6_sequence u.u_echo.sequence +#define icmp6_pointer u.pointer +#define icmp6_mtu u.mtu +#define icmp6_unused u.unused +#define icmp6_router u.u_nd_advt.router +#define icmp6_solicited u.u_nd_advt.solicited +#define icmp6_override u.u_nd_advt.override +#define icmp6_ndiscreserved u.u_nd_advt.reserved +#define icmp6_hop_limit u.u_nd_ra.hop_limit +#define icmp6_addrconf_managed u.u_nd_ra.managed +#define icmp6_addrconf_other u.u_nd_ra.other +#define icmp6_rt_lifetime u.u_nd_ra.rt_lifetime +}; + + +#define ICMPV6_DEST_UNREACH 1 +#define ICMPV6_PKT_TOOBIG 2 +#define ICMPV6_TIME_EXCEEDED 3 +#define ICMPV6_PARAMETER_PROB 4 + +#define ICMPV6_ECHO_REQUEST 128 +#define ICMPV6_ECHO_REPLY 129 +#define ICMPV6_MEMBERSHIP_QUERY 130 +#define ICMPV6_MEMBERSHIP_REPORT 131 +#define ICMPV6_MEMBERSHIP_REDUCTION 132 + +/* + * Codes for Destination Unreachable + */ +#define ICMPV6_NOROUTE 0 +#define ICMPV6_ADM_PROHIBITED 1 +#define ICMPV6_NOT_NEIGHBOUR 2 +#define ICMPV6_ADDR_UNREACH 3 +#define ICMPV6_PORT_UNREACH 4 + +/* + * Codes for Time Exceeded + */ +#define ICMPV6_EXC_HOPLIMIT 0 +#define ICMPV6_EXC_FRAGTIME 1 + +/* + * Codes for Parameter Problem + */ +#define ICMPV6_HDR_FIELD 0 +#define ICMPV6_UNK_NEXTHDR 1 +#define ICMPV6_UNK_OPTION 2 + +/* + * constants for (set|get)sockopt + */ + +#define ICMPV6_FILTER 1 + +/* + * ICMPV6 filter + */ + +#define ICMPV6_FILTER_BLOCK 1 +#define ICMPV6_FILTER_PASS 2 +#define ICMPV6_FILTER_BLOCKOTHERS 3 +#define ICMPV6_FILTER_PASSONLY 4 + +struct icmp6_filter { + __u32 data[8]; +}; + +#ifdef __KERNEL__ + +#include <linux/netdevice.h> +#include <linux/skbuff.h> + + +extern void icmpv6_send(struct sk_buff *skb, + int type, int code, + __u32 info, + struct device *dev); + +extern void icmpv6_init(struct proto_ops *ops); +extern int icmpv6_err_convert(int type, int code, + int *err); +#endif + +#endif diff --git a/include/linux/if.h b/include/linux/if.h index 13af3bb7e..ffa226a62 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -97,7 +97,6 @@ struct ifreq union { char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - char ifrn_hwaddr[IFHWADDRLEN]; /* Obsolete */ } ifr_ifrn; union { @@ -107,7 +106,7 @@ struct ifreq struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short ifru_flags; - int ifru_metric; + int ifru_ivalue; int ifru_mtu; struct ifmap ifru_map; char ifru_slave[IFNAMSIZ]; /* Just fits the size */ @@ -116,18 +115,18 @@ struct ifreq }; #define ifr_name ifr_ifrn.ifrn_name /* interface name */ -#define old_ifr_hwaddr ifr_ifrn.ifrn_hwaddr /* interface hardware */ #define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ #define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ #define ifr_flags ifr_ifru.ifru_flags /* flags */ -#define ifr_metric ifr_ifru.ifru_metric /* metric */ +#define ifr_metric ifr_ifru.ifru_ivalue /* metric */ #define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ #define ifr_map ifr_ifru.ifru_map /* device map */ #define ifr_slave ifr_ifru.ifru_slave /* slave device */ #define ifr_data ifr_ifru.ifru_data /* for use by interface */ +#define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */ /* * Structure used in SIOCGIFCONF request. @@ -148,9 +147,4 @@ struct ifconf #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ #define ifc_req ifc_ifcu.ifcu_req /* array of structures */ - -/* BSD UNIX expects to find these here, so here we go: */ -#include <linux/if_arp.h> -#include <linux/route.h> - #endif /* _LINUX_IF_H */ diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index 75f86b616..fffb67990 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -11,7 +11,8 @@ * Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source. * Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> - * Florian La Roche. + * Florian La Roche, + * Jonathan Layes <layes@loran.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -21,6 +22,8 @@ #ifndef _LINUX_IF_ARP_H #define _LINUX_IF_ARP_H +#include <linux/netdevice.h> + /* ARP protocol HARDWARE identifiers. */ #define ARPHRD_NETROM 0 /* from KA9Q: NET/ROM pseudo */ #define ARPHRD_ETHER 1 /* Ethernet 10Mbps */ @@ -28,9 +31,12 @@ #define ARPHRD_AX25 3 /* AX.25 Level 2 */ #define ARPHRD_PRONET 4 /* PROnet token ring */ #define ARPHRD_CHAOS 5 /* Chaosnet */ -#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet- huh? */ +#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */ #define ARPHRD_ARCNET 7 /* ARCnet */ #define ARPHRD_APPLETLK 8 /* APPLEtalk */ +#define ARPHRD_DLCI 15 /* Frame Relay DLCI */ +#define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */ + /* Dummy types for non ARP hardware */ #define ARPHRD_SLIP 256 #define ARPHRD_CSLIP 257 @@ -38,8 +44,18 @@ #define ARPHRD_CSLIP6 259 #define ARPHRD_RSRVD 260 /* Notional KISS type */ #define ARPHRD_ADAPT 264 +#define ARPHRD_ROSE 270 +#define ARPHRD_X25 271 /* CCITT X.25 */ #define ARPHRD_PPP 512 + #define ARPHRD_TUNNEL 768 /* IPIP tunnel */ +#define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel */ +#define ARPHRD_FRAD 770 /* Frame Relay Access Device */ +#define ARPHRD_SKIP 771 /* SKIP vif */ +#define ARPHRD_LOOPBACK 772 /* Loopback device */ +#define ARPHRD_LOCALTLK 773 /* Localtalk device */ +#define ARPHRD_FDDI 774 /* FDDI interfaces */ +#define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4 */ /* ARP protocol opcodes. */ #define ARPOP_REQUEST 1 /* ARP request */ @@ -54,6 +70,14 @@ struct arpreq { struct sockaddr arp_ha; /* hardware address */ int arp_flags; /* flags */ struct sockaddr arp_netmask; /* netmask (only for proxy arps) */ + char arp_dev[16]; +}; + +struct arpreq_old { + struct sockaddr arp_pa; /* protocol address */ + struct sockaddr arp_ha; /* hardware address */ + int arp_flags; /* flags */ + struct sockaddr arp_netmask; /* netmask (only for proxy arps) */ }; /* ARP Flag values. */ @@ -88,4 +112,20 @@ struct arphdr }; +/* Support for the user space arp daemon, arpd */ + +#define ARPD_UPDATE 0x01 +#define ARPD_LOOKUP 0x02 +#define ARPD_FLUSH 0x03 + +struct arpd_request +{ + unsigned short req; /* request type */ + __u32 ip; /* ip address of entry */ + unsigned long dev; /* Device entry is tied to */ + unsigned long stamp; + unsigned long updated; + unsigned char ha[MAX_ADDR_LEN]; /* Hardware address */ +}; + #endif /* _LINUX_IF_ARP_H */ diff --git a/include/linux/if_eql.h b/include/linux/if_eql.h index 5a03f21c8..320dbebf1 100644 --- a/include/linux/if_eql.h +++ b/include/linux/if_eql.h @@ -2,7 +2,7 @@ * Equalizer Load-balancer for serial network interfaces. * * (c) Copyright 1995 Simon "Guru Aleph-Null" Janes - * NCM: Network and Communications Mangement, Inc. + * NCM: Network and Communications Management, Inc. * * * This software may be used and distributed according to the terms @@ -19,6 +19,8 @@ #ifndef _LINUX_IF_EQL_H #define _LINUX_IF_EQL_H +#include <linux/timer.h> + #define EQL_DEFAULT_SLAVE_PRIORITY 28800 #define EQL_DEFAULT_MAX_SLAVES 4 #define EQL_DEFAULT_MTU 576 diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index eb6a07cce..dd09d8352 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -9,73 +9,111 @@ * * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Donald Becker, <becker@super.org> + * Alan Cox, <alan@cymru.net> + * Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ + #ifndef _LINUX_IF_ETHER_H #define _LINUX_IF_ETHER_H +/* + * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble + * and FCS/CRC (frame check sequence). + */ -/* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble - and FCS/CRC (frame check sequence). */ #define ETH_ALEN 6 /* Octets in one ethernet addr */ #define ETH_HLEN 14 /* Total octets in header. */ #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ #define ETH_DATA_LEN 1500 /* Max. octets in payload */ #define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ +/* + * These are the defined Ethernet Protocol ID's. + */ -/* These are the defined Ethernet Protocol ID's. */ #define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ #define ETH_P_ECHO 0x0200 /* Ethernet Echo packet */ #define ETH_P_PUP 0x0400 /* Xerox PUP packet */ #define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define ETH_P_X25 0x0805 /* CCITT X.25 */ #define ETH_P_ARP 0x0806 /* Address Resolution packet */ +#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ +#define ETH_P_DEC 0x6000 /* DEC Assigned proto */ +#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ +#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ +#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ +#define ETH_P_LAT 0x6004 /* DEC LAT */ +#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ +#define ETH_P_CUST 0x6006 /* DEC Customer use */ +#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ #define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ -#define ETH_P_X25 0x0805 /* CCITT X.25 */ #define ETH_P_ATALK 0x809B /* Appletalk DDP */ #define ETH_P_AARP 0x80F3 /* Appletalk AARP */ #define ETH_P_IPX 0x8137 /* IPX over DIX */ +#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ + +/* + * Non DIX types. Won't clash for 1500 types. + */ + #define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ #define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ #define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ #define ETH_P_802_2 0x0004 /* 802.2 frames */ #define ETH_P_SNAP 0x0005 /* Internal only */ -/* This is an Ethernet frame header. */ -struct ethhdr { - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - unsigned short h_proto; /* packet type ID field */ +#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ +#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ +#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ +#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ +#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ +#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */ + +/* + * This is an Ethernet frame header. + */ + +struct ethhdr +{ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ }; -/* Ethernet statistics collection data. */ -struct enet_statistics{ - int rx_packets; /* total packets received */ - int tx_packets; /* total packets transmitted */ - int rx_errors; /* bad packets received */ - int tx_errors; /* packet transmit problems */ - int rx_dropped; /* no space in linux buffers */ - int tx_dropped; /* no space available in linux */ - int multicast; /* multicast packets received */ - int collisions; +/* + * Ethernet statistics collection data. + */ + +struct enet_statistics +{ + int rx_packets; /* total packets received */ + int tx_packets; /* total packets transmitted */ + int rx_errors; /* bad packets received */ + int tx_errors; /* packet transmit problems */ + int rx_dropped; /* no space in linux buffers */ + int tx_dropped; /* no space available in linux */ + int multicast; /* multicast packets received */ + int collisions; - /* detailed rx_errors: */ - int rx_length_errors; - int rx_over_errors; /* receiver ring buff overflow */ - int rx_crc_errors; /* recved pkt with crc error */ - int rx_frame_errors; /* recv'd frame alignment error */ - int rx_fifo_errors; /* recv'r fifo overrun */ - int rx_missed_errors; /* receiver missed packet */ + /* detailed rx_errors: */ + int rx_length_errors; + int rx_over_errors; /* receiver ring buff overflow */ + int rx_crc_errors; /* recved pkt with crc error */ + int rx_frame_errors; /* recv'd frame alignment error */ + int rx_fifo_errors; /* recv'r fifo overrun */ + int rx_missed_errors; /* receiver missed packet */ - /* detailed tx_errors */ - int tx_aborted_errors; - int tx_carrier_errors; - int tx_fifo_errors; - int tx_heartbeat_errors; - int tx_window_errors; + /* detailed tx_errors */ + int tx_aborted_errors; + int tx_carrier_errors; + int tx_fifo_errors; + int tx_heartbeat_errors; + int tx_window_errors; }; + #endif /* _LINUX_IF_ETHER_H */ diff --git a/include/linux/if_fddi.h b/include/linux/if_fddi.h new file mode 100644 index 000000000..6db6745b6 --- /dev/null +++ b/include/linux/if_fddi.h @@ -0,0 +1,202 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Global definitions for the ANSI FDDI interface. + * + * Version: @(#)if_fddi.h 1.0.1 09/16/96 + * + * Author: Lawrence V. Stefani, <stefani@lkg.dec.com> + * + * if_fddi.h is based on previous if_ether.h and if_tr.h work by + * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * Donald Becker, <becker@super.org> + * Alan Cox, <alan@cymru.net> + * Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk> + * Peter De Schrijver, <stud11@cc4.kuleuven.ac.be> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _LINUX_IF_FDDI_H +#define _LINUX_IF_FDDI_H + +/* + * Define max and min legal sizes. The frame sizes do not include + * 4 byte FCS/CRC (frame check sequence). + */ +#define FDDI_K_ALEN 6 /* Octets in one FDDI address */ +#define FDDI_K_8022_HLEN 16 /* Total octets in 802.2 header */ +#define FDDI_K_SNAP_HLEN 21 /* Total octets in 802.2 SNAP header */ +#define FDDI_K_8022_ZLEN 16 /* Min octets in 802.2 frame sans FCS */ +#define FDDI_K_SNAP_ZLEN 21 /* Min octets in 802.2 SNAP frame sans FCS */ +#define FDDI_K_8022_DLEN 4475 /* Max octets in 802.2 payload */ +#define FDDI_K_SNAP_DLEN 4470 /* Max octets in 802.2 SNAP payload */ +#define FDDI_K_LLC_ZLEN 13 /* Min octets in LLC frame sans FCS */ +#define FDDI_K_LLC_LEN 4491 /* Max octets in LLC frame sans FCS */ + +/* Define FDDI Frame Control (FC) Byte values */ +#define FDDI_FC_K_VOID 0x00 +#define FDDI_FC_K_NON_RESTRICTED_TOKEN 0x80 +#define FDDI_FC_K_RESTRICTED_TOKEN 0xC0 +#define FDDI_FC_K_SMT_MIN 0x41 +#define FDDI_FC_K_SMT_MAX 0x4F +#define FDDI_FC_K_MAC_MIN 0xC1 +#define FDDI_FC_K_MAC_MAX 0xCF +#define FDDI_FC_K_ASYNC_LLC_MIN 0x50 +#define FDDI_FC_K_ASYNC_LLC_DEF 0x54 +#define FDDI_FC_K_ASYNC_LLC_MAX 0x5F +#define FDDI_FC_K_SYNC_LLC_MIN 0xD0 +#define FDDI_FC_K_SYNC_LLC_MAX 0xD7 +#define FDDI_FC_K_IMPLEMENTOR_MIN 0x60 +#define FDDI_FC_K_IMPLEMENTOR_MAX 0x6F +#define FDDI_FC_K_RESERVED_MIN 0x70 +#define FDDI_FC_K_RESERVED_MAX 0x7F + +/* Define LLC and SNAP constants */ +#define FDDI_EXTENDED_SAP 0xAA +#define FDDI_UI_CMD 0x03 + +/* Define 802.2 Type 1 header */ +struct fddi_8022_1_hdr + { + __u8 dsap; /* destination service access point */ + __u8 ssap; /* source service access point */ + __u8 ctrl; /* control byte #1 */ + } __attribute__ ((packed)); + +/* Define 802.2 Type 2 header */ +struct fddi_8022_2_hdr + { + __u8 dsap; /* destination service access point */ + __u8 ssap; /* source service access point */ + __u8 ctrl_1; /* control byte #1 */ + __u8 ctrl_2; /* control byte #2 */ + } __attribute__ ((packed)); + +/* Define 802.2 SNAP header */ +#define FDDI_K_OUI_LEN 3 +struct fddi_snap_hdr + { + __u8 dsap; /* always 0xAA */ + __u8 ssap; /* always 0xAA */ + __u8 ctrl; /* always 0x03 */ + __u8 oui[FDDI_K_OUI_LEN]; /* organizational universal id */ + __u16 ethertype; /* packet type ID field */ + } __attribute__ ((packed)); + +/* Define FDDI LLC frame header */ +struct fddihdr + { + __u8 fc; /* frame control */ + __u8 daddr[FDDI_K_ALEN]; /* destination address */ + __u8 saddr[FDDI_K_ALEN]; /* source address */ + union + { + struct fddi_8022_1_hdr llc_8022_1; + struct fddi_8022_2_hdr llc_8022_2; + struct fddi_snap_hdr llc_snap; + } hdr; + } __attribute__ ((packed)); + +/* Define FDDI statistics structure */ +struct fddi_statistics + { + __u32 rx_packets; /* total packets received */ + __u32 tx_packets; /* total packets transmitted */ + __u32 rx_errors; /* bad packets received */ + __u32 tx_errors; /* packet transmit problems */ + __u32 rx_dropped; /* no space in linux buffers */ + __u32 tx_dropped; /* no space available in linux */ + __u32 multicast; /* multicast packets received */ + __u32 transmit_collision; /* always 0 for FDDI */ + + /* Detailed FDDI statistics. Adopted from RFC 1512 */ + + __u8 smt_station_id[8]; + __u32 smt_op_version_id; + __u32 smt_hi_version_id; + __u32 smt_lo_version_id; + __u8 smt_user_data[32]; + __u32 smt_mib_version_id; + __u32 smt_mac_cts; + __u32 smt_non_master_cts; + __u32 smt_master_cts; + __u32 smt_available_paths; + __u32 smt_config_capabilities; + __u32 smt_config_policy; + __u32 smt_connection_policy; + __u32 smt_t_notify; + __u32 smt_stat_rpt_policy; + __u32 smt_trace_max_expiration; + __u32 smt_bypass_present; + __u32 smt_ecm_state; + __u32 smt_cf_state; + __u32 smt_remote_disconnect_flag; + __u32 smt_station_status; + __u32 smt_peer_wrap_flag; + __u32 smt_time_stamp; + __u32 smt_transition_time_stamp; + __u32 mac_frame_status_functions; + __u32 mac_t_max_capability; + __u32 mac_tvx_capability; + __u32 mac_available_paths; + __u32 mac_current_path; + __u8 mac_upstream_nbr[FDDI_K_ALEN]; + __u8 mac_downstream_nbr[FDDI_K_ALEN]; + __u8 mac_old_upstream_nbr[FDDI_K_ALEN]; + __u8 mac_old_downstream_nbr[FDDI_K_ALEN]; + __u32 mac_dup_address_test; + __u32 mac_requested_paths; + __u32 mac_downstream_port_type; + __u8 mac_smt_address[FDDI_K_ALEN]; + __u32 mac_t_req; + __u32 mac_t_neg; + __u32 mac_t_max; + __u32 mac_tvx_value; + __u32 mac_frame_cts; + __u32 mac_copied_cts; + __u32 mac_transmit_cts; + __u32 mac_error_cts; + __u32 mac_lost_cts; + __u32 mac_frame_error_threshold; + __u32 mac_frame_error_ratio; + __u32 mac_rmt_state; + __u32 mac_da_flag; + __u32 mac_una_da_flag; + __u32 mac_frame_error_flag; + __u32 mac_ma_unitdata_available; + __u32 mac_hardware_present; + __u32 mac_ma_unitdata_enable; + __u32 path_tvx_lower_bound; + __u32 path_t_max_lower_bound; + __u32 path_max_t_req; + __u32 path_configuration[8]; + __u32 port_my_type[2]; + __u32 port_neighbor_type[2]; + __u32 port_connection_policies[2]; + __u32 port_mac_indicated[2]; + __u32 port_current_path[2]; + __u8 port_requested_paths[3*2]; + __u32 port_mac_placement[2]; + __u32 port_available_paths[2]; + __u32 port_pmd_class[2]; + __u32 port_connection_capabilities[2]; + __u32 port_bs_flag[2]; + __u32 port_lct_fail_cts[2]; + __u32 port_ler_estimate[2]; + __u32 port_lem_reject_cts[2]; + __u32 port_lem_cts[2]; + __u32 port_ler_cutoff[2]; + __u32 port_ler_alarm[2]; + __u32 port_connect_state[2]; + __u32 port_pcm_state[2]; + __u32 port_pc_withhold[2]; + __u32 port_ler_flag[2]; + __u32 port_hardware_present[2]; + }; + +#endif /* _LINUX_IF_FDDI_H */ diff --git a/include/linux/if_frad.h b/include/linux/if_frad.h new file mode 100644 index 000000000..6dcbed815 --- /dev/null +++ b/include/linux/if_frad.h @@ -0,0 +1,194 @@ +/* + * DLCI/FRAD Definitions for Frame Relay Access Devices. DLCI devices are + * created for each DLCI associated with a FRAD. The FRAD driver + * is not truly a network device, but the lower level device + * handler. This allows other FRAD manufacturers to use the DLCI + * code, including its RFC1490 encapsulation alongside the current + * implementation for the Sangoma cards. + * + * Version: @(#)if_ifrad.h 0.15 31 Mar 96 + * + * Author: Mike McLagan <mike.mclagan@linux.org> + * + * Changes: + * 0.15 Mike McLagan changed structure defs (packed) + * re-arranged flags + * added DLCI_RET vars + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _FRAD_H_ +#define _FRAD_H_ + +#include <linux/if.h> + +/* Structures and constants associated with the DLCI device driver */ + +struct dlci_add +{ + char devname[IFNAMSIZ]; + short dlci; +}; + +#define DLCI_GET_CONF (SIOCDEVPRIVATE + 2) +#define DLCI_SET_CONF (SIOCDEVPRIVATE + 3) + +/* + * These are related to the Sangoma SDLA and should remain in order. + * Code within the SDLA module is based on the specifics of this + * structure. Change at your own peril. + */ +struct dlci_conf { + short flags; + short CIR_fwd; + short Bc_fwd; + short Be_fwd; + short CIR_bwd; + short Bc_bwd; + short Be_bwd; + +/* these are part of the status read */ + short Tc_fwd; + short Tc_bwd; + short Tf_max; + short Tb_max; + +/* add any new fields here above is a mirror of sdla_dlci_conf */ +}; + +#define DLCI_GET_SLAVE (SIOCDEVPRIVATE + 4) + +/* configuration flags for DLCI */ +#define DLCI_IGNORE_CIR_OUT 0x0001 +#define DLCI_ACCOUNT_CIR_IN 0x0002 +#define DLCI_BUFFER_IF 0x0008 + +#define DLCI_VALID_FLAGS 0x000B + +/* FRAD driver uses these to indicate what it did with packet */ +#define DLCI_RET_OK 0x00 +#define DLCI_RET_ERR 0x01 +#define DLCI_RET_DROP 0x02 + +/* defines for the actual Frame Relay hardware */ +#define FRAD_GET_CONF (SIOCDEVPRIVATE) +#define FRAD_SET_CONF (SIOCDEVPRIVATE + 1) + +#define FRAD_LAST_IOCTL FRAD_SET_CONF + +/* + * Based on the setup for the Sangoma SDLA. If changes are + * necessary to this structure, a routine will need to be + * added to that module to copy fields. + */ +struct frad_conf +{ + short station; + short flags; + short kbaud; + short clocking; + short mtu; + short T391; + short T392; + short N391; + short N392; + short N393; + short CIR_fwd; + short Bc_fwd; + short Be_fwd; + short CIR_bwd; + short Bc_bwd; + short Be_bwd; + +/* Add new fields here, above is a mirror of the sdla_conf */ + +}; + +#define FRAD_STATION_CPE 0x0000 +#define FRAD_STATION_NODE 0x0001 + +#define FRAD_TX_IGNORE_CIR 0x0001 +#define FRAD_RX_ACCOUNT_CIR 0x0002 +#define FRAD_DROP_ABORTED 0x0004 +#define FRAD_BUFFERIF 0x0008 +#define FRAD_STATS 0x0010 +#define FRAD_MCI 0x0100 +#define FRAD_AUTODLCI 0x8000 +#define FRAD_VALID_FLAGS 0x811F + +#define FRAD_CLOCK_INT 0x0001 +#define FRAD_CLOCK_EXT 0x0000 + +#ifdef __KERNEL__ + +/* these are the fields of an RFC 1490 header */ +struct frhdr +{ + unsigned char control __attribute__((packed)); + + /* for IP packets, this can be the NLPID */ + unsigned char pad __attribute__((packed)); + + unsigned char NLPID __attribute__((packed)); + unsigned char OUI[3] __attribute__((packed)); + unsigned short PID __attribute__((packed)); + +#define IP_NLPID pad +}; + +/* see RFC 1490 for the definition of the following */ +#define FRAD_I_UI 0x03 + +#define FRAD_P_PADDING 0x00 +#define FRAD_P_Q933 0x08 +#define FRAD_P_SNAP 0x80 +#define FRAD_P_CLNP 0x81 +#define FRAD_P_IP 0xCC + +struct dlci_local +{ + struct enet_statistics stats; + struct device *slave; + struct dlci_conf config; + int configured; + + /* callback function */ + void (*receive)(struct sk_buff *skb, struct device *); +}; + +struct frad_local +{ + struct enet_statistics stats; + + /* devices which this FRAD is slaved to */ + struct device *master[CONFIG_DLCI_MAX]; + short dlci[CONFIG_DLCI_MAX]; + + struct frad_conf config; + int configured; /* has this device been configured */ + int initialized; /* mem_start, port, irq set ? */ + + /* callback functions */ + int (*activate)(struct device *, struct device *); + int (*deactivate)(struct device *, struct device *); + int (*assoc)(struct device *, struct device *); + int (*deassoc)(struct device *, struct device *); + int (*dlci_conf)(struct device *, struct device *, int get); + + /* fields that are used by the Sangoma SDLA cards */ + struct timer_list timer; + int type; /* adapter type */ + int state; /* state of the S502/8 control latch */ + int buffer; /* current buffer for S508 firmware */ +}; + +int register_frad(const char *name); +int unregister_frad(const char *name); + +#endif __KERNEL__ + +#endif diff --git a/include/linux/if_packet.h b/include/linux/if_packet.h new file mode 100644 index 000000000..5f6d3e9d5 --- /dev/null +++ b/include/linux/if_packet.h @@ -0,0 +1,11 @@ +#ifndef __LINUX_IF_PACKET_H +#define __LINUX_IF_PACKET_H + +struct sockaddr_pkt +{ + unsigned short spkt_family; + unsigned char spkt_device[14]; + unsigned short spkt_protocol; +}; + +#endif diff --git a/include/linux/if_ppp.h b/include/linux/if_ppp.h index 51389df71..1d3a750d8 100644 --- a/include/linux/if_ppp.h +++ b/include/linux/if_ppp.h @@ -1,237 +1,151 @@ -#ifndef _LINUX_IF_PPP_H -#define _LINUX_IF_PPP_H - -/* definitions for kernel PPP module - Michael Callahan <callahan@maths.ox.ac.uk> - Nov. 4 1993 */ - -/* how many PPP units? */ -#ifdef CONFIG_PPP_LOTS -#define PPP_NRUNIT 16 -#else -#define PPP_NRUNIT 4 +/* $Id: if_ppp.h,v 1.3 1995/06/12 11:36:50 paulus Exp $ */ + +/* + * if_ppp.h - Point-to-Point Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +/* + * ==FILEVERSION 960109== + * + * NOTE TO MAINTAINERS: + * If you modify this file at all, please set the above date. + * if_ppp.h is shipped with a PPP distribution as well as with the kernel; + * if everyone increases the FILEVERSION number above, then scripts + * can do the right thing when deciding whether to install a new if_ppp.h + * file. Don't change the format of that line otherwise, so the + * installation script can recognize it. + */ + +#ifndef _IF_PPP_H_ +#define _IF_PPP_H_ + +#if defined(__linux__) +#include <linux/if.h> +#include <linux/ioctl.h> +#include <linux/ppp_defs.h> #endif -#define PPP_VERSION "0.2.7" - -/* line discipline number */ -#define N_PPP 3 - -/* Magic value for the ppp structure */ -#define PPP_MAGIC 0x5002 - -#define PPPIOCGFLAGS 0x5490 /* get configuration flags */ -#define PPPIOCSFLAGS 0x5491 /* set configuration flags */ -#define PPPIOCGASYNCMAP 0x5492 /* get async map */ -#define PPPIOCSASYNCMAP 0x5493 /* set async map */ -#define PPPIOCGUNIT 0x5494 /* get ppp unit number */ -#define PPPIOCSINPSIG 0x5495 /* set input ready signal */ -#define PPPIOCSDEBUG 0x5497 /* set debug level */ -#define PPPIOCGDEBUG 0x5498 /* get debug level */ -#define PPPIOCGSTAT 0x5499 /* read PPP statistic information */ -#define PPPIOCGTIME 0x549A /* read time delta information */ -#define PPPIOCGXASYNCMAP 0x549B /* get async table */ -#define PPPIOCSXASYNCMAP 0x549C /* set async table */ -#define PPPIOCSMRU 0x549D /* set receive unit size for PPP */ -#define PPPIOCRASYNCMAP 0x549E /* set receive async map */ -#define PPPIOCSMAXCID 0x549F /* set the maximum compression slot id */ - -/* special characters in the framing protocol */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7E /* frame delimiter -- marks frame boundaries */ -#define PPP_ADDRESS 0xFF /* first character of frame <-- (may be */ -#define PPP_CONTROL 0x03 /* second character of frame <-- compressed)*/ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ -#define PPP_ESC 0x7d /* escape character -- next character is - data, and the PPP_TRANS bit should be - toggled. PPP_ESC PPP_FLAG is illegal */ - -/* protocol numbers */ -#define PROTO_IP 0x0021 -#define PROTO_VJCOMP 0x002d -#define PROTO_VJUNCOMP 0x002f - -/* FCS support */ -#define PPP_FCS_INIT 0xffff -#define PPP_FCS_GOOD 0xf0b8 - -/* initial MTU */ -#define PPP_MTU 1500 - -/* initial MRU */ -#define PPP_MRU PPP_MTU - -/* flags */ +/* + * Packet sizes + */ + +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#define PPP_MAXMRU 65000 /* Largest MRU we allow */ +#define PPP_VERSION "2.2.0" +#define PPP_MAGIC 0x5002 /* Magic value for the ppp structure */ +#define PROTO_IPX 0x002b /* protocol numbers */ +#define PROTO_DNA_RT 0x0027 /* DNA Routing */ + + +/* + * Bit definitions for flags. + */ + #define SC_COMP_PROT 0x00000001 /* protocol compression (output) */ #define SC_COMP_AC 0x00000002 /* header compression (output) */ #define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */ #define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */ #define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */ #define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */ +#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */ +#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */ #define SC_ENABLE_IP 0x00000100 /* IP packets may be exchanged */ -#define SC_IP_DOWN 0x00000200 /* give ip frames to pppd */ -#define SC_IP_FLUSH 0x00000400 /* "next time" flag for IP_DOWN */ +#define SC_COMP_RUN 0x00001000 /* compressor has been inited */ +#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */ #define SC_DEBUG 0x00010000 /* enable debug messages */ #define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */ #define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */ #define SC_LOG_RAWIN 0x00080000 /* log all chars received */ #define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ +#define SC_MASK 0x0fE0ffff /* bits that user can change */ -/* Flag bits to determine state of input characters */ -#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */ -#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 0 */ -#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */ -#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */ - -#define SC_MASK 0x0fffffff /* bits that user can change */ - -/* flag for doing transmitter lockout */ +/* state bits */ +#define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */ +#define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */ +#define SC_VJ_RESET 0x20000000 /* Need to reset the VJ decompressor */ #define SC_XMIT_BUSY 0x10000000 /* ppp_write_wakeup is active */ +#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */ +#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */ +#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */ +#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */ +#define SC_DC_FERROR 0x00800000 /* fatal decomp error detected */ +#define SC_DC_ERROR 0x00400000 /* non-fatal decomp error detected */ /* - * This is the format of the data buffer of a LQP packet. The packet data - * is sent/received to the peer. - */ - -struct ppp_lqp_packet_hdr { - unsigned long LastOutLQRs; /* Copied from PeerOutLQRs */ - unsigned long LastOutPackets; /* Copied from PeerOutPackets */ - unsigned long LastOutOctets; /* Copied from PeerOutOctets */ - unsigned long PeerInLQRs; /* Copied from SavedInLQRs */ - unsigned long PeerInPackets; /* Copied from SavedInPackets */ - unsigned long PeerInDiscards; /* Copied from SavedInDiscards */ - unsigned long PeerInErrors; /* Copied from SavedInErrors */ - unsigned long PeerInOctets; /* Copied from SavedInOctets */ - unsigned long PeerOutLQRs; /* Copied from OutLQRs, plus 1 */ - unsigned long PeerOutPackets; /* Current ifOutUniPackets, + 1 */ - unsigned long PeerOutOctets; /* Current ifOutOctets + LQR */ - }; - -/* - * This data is not sent to the remote. It is updated by the driver when - * a packet is received. + * Ioctl definitions. */ -struct ppp_lqp_packet_trailer { - unsigned long SaveInLQRs; /* Current InLQRs on reception */ - unsigned long SaveInPackets; /* Current ifInUniPackets */ - unsigned long SaveInDiscards; /* Current ifInDiscards */ - unsigned long SaveInErrors; /* Current ifInErrors */ - unsigned long SaveInOctets; /* Current ifInOctects */ +struct npioctl { + int protocol; /* PPP protocol, e.g. PPP_IP */ + enum NPmode mode; }; -/* - * PPP LQP packet. The packet is changed by the driver immediately prior - * to transmission and updated upon reception with the current values. - * So, it must be known to the driver as well as the pppd software. - */ - -struct ppp_lpq_packet { - unsigned long magic; /* current magic value */ - struct ppp_lqp_packet_hdr hdr; /* Header fields for structure */ - struct ppp_lqp_packet_trailer tail; /* Trailer fields (not sent) */ +/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ +struct ppp_option_data { + __u8 *ptr; + __u32 length; + int transmit; }; -/* - * PPP interface statistics. (used by LQP / pppstats) - */ - -struct ppp_stats { - unsigned long rbytes; /* bytes received */ - unsigned long rcomp; /* compressed packets received */ - unsigned long runcomp; /* uncompressed packets received */ - unsigned long rothers; /* non-ip frames received */ - unsigned long rerrors; /* received errors */ - unsigned long roverrun; /* "buffer overrun" counter */ - unsigned long tossed; /* packets discarded */ - unsigned long runts; /* frames too short to process */ - unsigned long rgiants; /* frames too large to process */ - unsigned long sbytes; /* bytes sent */ - unsigned long scomp; /* compressed packets sent */ - unsigned long suncomp; /* uncompressed packets sent */ - unsigned long sothers; /* non-ip frames sent */ - unsigned long serrors; /* transmitter errors */ - unsigned long sbusy; /* "transmitter busy" counter */ +struct ifpppstatsreq { + struct ifreq b; + struct ppp_stats stats; /* statistic information */ }; -/* - * Demand dial fields - */ - -struct ppp_ddinfo { - unsigned long ip_sjiffies; /* time when last IP frame sent */ - unsigned long ip_rjiffies; /* time when last IP frame recvd*/ - unsigned long nip_sjiffies; /* time when last NON-IP sent */ - unsigned long nip_rjiffies; /* time when last NON-IP recvd */ +struct ifpppcstatsreq { + struct ifreq b; + struct ppp_comp_stats stats; }; -#ifdef __KERNEL__ - -struct ppp { - int magic; /* magic value for structure */ - - /* Bitmapped flag fields. */ - char inuse; /* are we allocated? */ - char sending; /* "channel busy" indicator */ - char escape; /* 0x20 if prev char was PPP_ESC*/ - char toss; /* toss this frame */ - - unsigned int flags; /* miscellany */ - - unsigned long xmit_async_map[8]; /* 1 bit means that given control - character is quoted on output*/ - - unsigned long recv_async_map; /* 1 bit means that given control - character is ignored on input*/ - int mtu; /* maximum xmit frame size */ - int mru; /* maximum receive frame size */ - unsigned short fcs; /* FCS field of current frame */ - - /* Various fields. */ - int line; /* PPP channel number */ - struct tty_struct *tty; /* ptr to TTY structure */ - struct device *dev; /* easy for intr handling */ - struct slcompress *slcomp; /* for header compression */ - unsigned long last_xmit; /* time of last transmission */ - - /* These are pointers to the malloc()ed frame buffers. - These buffers are used while processing a packet. If a packet - has to hang around for the user process to read it, it lingers in - the user buffers below. */ - unsigned char *rbuff; /* receiver buffer */ - unsigned char *xbuff; /* transmitter buffer */ - unsigned char *cbuff; /* compression buffer */ - - /* These are the various pointers into the buffers. */ - unsigned char *rhead; /* RECV buffer pointer (head) */ - unsigned char *rend; /* RECV buffer pointer (end) */ - int rcount; /* PPP receive counter */ - unsigned char *xhead; /* XMIT buffer pointer (head) */ - unsigned char *xtail; /* XMIT buffer pointer (end) */ - - /* Structures for interfacing with the user process. */ -#define RBUFSIZE 4000 - unsigned char *us_rbuff; /* circular incoming packet buf.*/ - unsigned char *us_rbuff_end; /* end of allocated space */ - unsigned char *us_rbuff_head; /* head of waiting packets */ - unsigned char *us_rbuff_tail; /* tail of waiting packets */ - unsigned char us_rbuff_lock; /* lock: bit 0 head bit 1 tail */ - int inp_sig; /* input ready signal for pgrp */ - int inp_sig_pid; /* process to get notified */ - - /* items to support the select() function */ - struct wait_queue *write_wait; /* queue for reading processes */ - struct wait_queue *read_wait; /* queue for writing processes */ - - /* PPP interface statistics. */ - struct ppp_stats stats; /* statistic information */ - - /* PPP demand dial information. */ - struct ppp_ddinfo ddinfo; /* demand dial information */ -}; +#define ifr__name b.ifr_ifrn.ifrn_name +#define stats_ptr b.ifr_ifru.ifru_data -#endif /* __KERNEL__ */ -#endif /* _LINUX_PPP_H */ +/* + * Ioctl definitions. + */ +#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */ +#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */ +#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */ +#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */ +#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */ +#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */ +#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */ +#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */ +#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */ +#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */ +#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */ +#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */ +#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */ +#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data) +#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */ +#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */ +#define PPPIOCGDEBUG _IOR('t', 65, int) /* Read debug level */ +#define PPPIOCSDEBUG _IOW('t', 64, int) /* Set debug level */ +#define PPPIOCGIDLE _IOR('t', 63, struct ppp_idle) /* get idle time */ + +#define SIOCGPPPSTATS (SIOCDEVPRIVATE + 0) +#define SIOCGPPPVER (SIOCDEVPRIVATE + 1) /* NEVER change this!! */ +#define SIOCGPPPCSTATS (SIOCDEVPRIVATE + 2) + +#if !defined(ifr_mtu) +#define ifr_mtu ifr_ifru.ifru_metric +#endif +#endif /* _IF_PPP_H_ */ diff --git a/include/linux/if_pppvar.h b/include/linux/if_pppvar.h new file mode 100644 index 000000000..1c7eb4f6d --- /dev/null +++ b/include/linux/if_pppvar.h @@ -0,0 +1,157 @@ +/* $Id: if_pppvar.h,v 1.2 1995/06/12 11:36:51 paulus Exp $ */ +/* + * if_pppvar.h - private structures and declarations for PPP. + * + * Copyright (c) 1994 The Australian National University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, provided that the above copyright + * notice appears in all copies. This software is provided without any + * warranty, express or implied. The Australian National University + * makes no representations about the suitability of this software for + * any purpose. + * + * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY + * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO + * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, + * OR MODIFICATIONS. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * ==FILEVERSION 960302== + * + * NOTE TO MAINTAINERS: + * If you modify this file at all, please set the above date. + * if_pppvar.h is shipped with a PPP distribution as well as with the kernel; + * if everyone increases the FILEVERSION number above, then scripts + * can do the right thing when deciding whether to install a new if_pppvar.h + * file. Don't change the format of that line otherwise, so the + * installation script can recognize it. + */ + +/* + * Supported network protocols. These values are used for + * indexing sc_npmode. + */ + +#define NP_IP 0 /* Internet Protocol */ +#define NUM_NP 1 /* Number of NPs. */ + +/* + * Buffers for the PPP process have the following structure + */ + +#define RBUFSIZE 2048 /* MUST be a power of 2 and be <= 4095 */ + +struct ppp_buffer { + __s32 size; /* Size of the buffer area */ + __s32 count; /* Count of characters in bufr */ + __s32 head; /* index to head of list */ + __s32 tail; /* index to tail of list */ + __u32 locked; /* Buffer is being sent */ + __s32 type; /* Type of the buffer */ + /* =0, device read buffer */ + /* =1, device write buffer */ + /* =2, daemon write buffer */ + /* =3, daemon read buffer */ + __u16 fcs; /* Frame Check Sequence (CRC) */ + __u8 filler[4]; /* Extra space if needed */ +}; + +/* Given a pointer to the ppp_buffer then return base address of buffer */ +#define buf_base(buf) ((__u8 *) (&buf[1])) + +/* + * Structure describing each ppp unit. + */ + +struct ppp { + __s32 magic; /* magic value for structure */ + + /* Bitmapped flag fields. */ + __u8 inuse; /* are we allocated? */ + __u8 escape; /* 0x20 if prev char was PPP_ESC*/ + __u8 toss; /* toss this frame */ + + __u32 flags; /* miscellany */ + + __u32 xmit_async_map[8]; /* 1 bit means that given control + character is quoted on output*/ + + __u32 recv_async_map; /* 1 bit means that given control + character is ignored on input*/ + __s32 mtu; /* maximum xmit frame size */ + __s32 mru; /* maximum receive frame size */ + + /* Information about the current tty data */ + __s32 line; /* PPP channel number */ + struct tty_struct *tty; /* ptr to TTY structure */ + __s32 bytes_sent; /* Bytes sent on frame */ + __s32 bytes_rcvd; /* Bytes recvd on frame */ + + /* Interface to the network layer */ + struct device *dev; /* easy for intr handling */ + + /* VJ Header compression data */ + struct slcompress *slcomp; /* for header compression */ + + /* Transmission information */ + struct ppp_buffer *xbuf; /* Buffer currently being sent */ + struct ppp_buffer *s1buf; /* Pointer to daemon buffer */ + struct ppp_buffer *s2buf; /* Pointer to device buffer */ + + __u32 last_xmit; /* time of last transmission */ + + /* These are pointers to the malloc()ed frame buffers. + These buffers are used while processing a packet. If a packet + has to hang around for the user process to read it, it lingers in + the user buffers below. */ + + struct ppp_buffer *wbuf; /* Transmission information */ + struct ppp_buffer *tbuf; /* daemon transmission buffer */ + struct ppp_buffer *rbuf; /* Receive information */ + struct ppp_buffer *ubuf; /* User buffer information */ + struct ppp_buffer *cbuf; /* compression buffer */ + + /* Queues for select() functionality */ + struct wait_queue *write_wait; /* queue for reading processes */ + struct wait_queue *read_wait; /* queue for writing processes */ + + /* Statistic information */ + struct pppstat stats; /* statistic information */ + struct ppp_idle ddinfo; /* demand dial information */ + + /* PPP compression protocol information */ + __u32 sc_bytessent; /* count of octets sent */ + __u32 sc_bytesrcvd; /* count of octets received */ + enum NPmode sc_npmode[NUM_NP]; /* what to do with each NP */ + struct compressor *sc_xcomp; /* transmit compressor */ + void *sc_xc_state; /* transmit compressor state */ + struct compressor *sc_rcomp; /* receive decompressor */ + void *sc_rc_state; /* receive decompressor state */ + __s32 sc_xfer; /* PID of reserved PPP table */ +}; diff --git a/include/linux/if_slip.h b/include/linux/if_slip.h index 0cb7f71b8..5bd77e520 100644 --- a/include/linux/if_slip.h +++ b/include/linux/if_slip.h @@ -15,5 +15,14 @@ #define SL_OPT_SIXBIT 2 #define SL_OPT_ADAPTIVE 8 +/* + * VSV = ioctl for keepalive & outfill in SLIP driver + */ + +#define SIOCSKEEPALIVE (SIOCDEVPRIVATE) /* Set keepalive timeout in sec */ +#define SIOCGKEEPALIVE (SIOCDEVPRIVATE+1) /* Get keepalive timeout */ +#define SIOCSOUTFILL (SIOCDEVPRIVATE+2) /* Set outfill timeout */ +#define SIOCGOUTFILL (SIOCDEVPRIVATE+3) /* Get outfill timeout */ + #endif diff --git a/include/linux/if_strip.h b/include/linux/if_strip.h new file mode 100644 index 000000000..fb5c5c984 --- /dev/null +++ b/include/linux/if_strip.h @@ -0,0 +1,25 @@ +/* + * if_strip.h -- + * + * Definitions for the STRIP interface + * + * Copyright 1996 The Board of Trustees of The Leland Stanford + * Junior University. All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies. Stanford University + * makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +#ifndef __LINUX_STRIP_H +#define __LINUX_STRIP_H + +typedef struct { + __u8 c[6]; +} MetricomAddress; + +#endif diff --git a/include/linux/if_tr.h b/include/linux/if_tr.h index 61629332b..545f1b7f0 100644 --- a/include/linux/if_tr.h +++ b/include/linux/if_tr.h @@ -45,37 +45,36 @@ /* This is an Token-Ring frame header. */ struct trh_hdr { - unsigned char ac; /* access control field */ - unsigned char fc; /* frame control field */ - unsigned char daddr[TR_ALEN]; /* destination address */ - unsigned char saddr[TR_ALEN]; /* source address */ - unsigned short rcf; /* route control field */ - unsigned short rseg[8];/* routing registers */ + __u8 ac; /* access control field */ + __u8 fc; /* frame control field */ + __u8 daddr[TR_ALEN]; /* destination address */ + __u8 saddr[TR_ALEN]; /* source address */ + __u16 rcf; /* route control field */ + __u16 rseg[8]; /* routing registers */ }; /* This is an Token-Ring LLC structure */ struct trllc { - unsigned char dsap; /* destination SAP */ - unsigned char ssap; /* source SAP */ - unsigned char llc; /* LLC control field */ - unsigned char protid[3]; /* protocol id */ - unsigned short ethertype; /* ether type field */ + __u8 dsap; /* destination SAP */ + __u8 ssap; /* source SAP */ + __u8 llc; /* LLC control field */ + __u8 protid[3]; /* protocol id */ + __u16 ethertype; /* ether type field */ }; - /* Token-Ring statistics collection data. */ -struct tr_statistics{ - int rx_packets; /* total packets received */ - int tx_packets; /* total packets transmitted */ - int rx_errors; /* bad packets received */ - int tx_errors; /* packet transmit problems */ - int rx_dropped; /* no space in linux buffers */ - int tx_dropped; /* no space available in linux */ - int multicast; /* multicast packets received */ - int transmit_collision; +struct tr_statistics { + int rx_packets; /* total packets received */ + int tx_packets; /* total packets transmitted */ + int rx_errors; /* bad packets received */ + int tx_errors; /* packet transmit problems */ + int rx_dropped; /* no space in linux buffers */ + int tx_dropped; /* no space available in linux */ + int multicast; /* multicast packets received */ + int transmit_collision; - /* detailed Token-Ring errors. See IBM Token-Ring Network Architecture - for more info */ + /* detailed Token-Ring errors. See IBM Token-Ring Network + Architecture for more info */ int line_errors; int internal_errors; @@ -88,7 +87,6 @@ struct tr_statistics{ int frequency_errors; int token_errors; int dummy1; - }; /* source routing stuff */ diff --git a/include/linux/if_wic.h b/include/linux/if_wic.h new file mode 100644 index 000000000..cca15f85b --- /dev/null +++ b/include/linux/if_wic.h @@ -0,0 +1,102 @@ +#ifndef _LINUX_IF_WIC_H +#define _LINUX_IF_WIC_H + +#include <linux/sockios.h> + +#define SIOCDEVWIC SIOCDEVPRIVATE + +struct wicconf +{ + unsigned char pcmd; + unsigned char data[120]; + unsigned char len; +}; + +/* WIC host to controller commands */ + +#define WIC_AYT 0x10 /* test dki */ +#define WIC_RESET 0x11 /* reset controller */ +#define WIC_SETSN 0x21 /* set station name */ +#define WIC_SETPS 0x22 /* set power saving mode */ +#define WIC_SETAF 0x23 /* set announce filter */ +#define WIC_SETGPF 0x24 /* set GPSP filter */ +#define WIC_GETVERH 0x61 /* get interface controller version */ +#define WIC_GETNL 0x62 /* get neighbor list */ +#define WIC_GETSN 0x65 /* get station name */ +#define WIC_CLRSTATS 0x83 /* clear controller statistics */ +#define WIC_SETNET 0x84 /* set network configuration */ +#define WIC_SETSYS 0x85 /* set system configuration */ +#define WIC_GETSTATS 0xc1 /* get statistics */ +#define WIC_GETVERM 0xc3 /* get MAC version */ +#define WIC_GETNET 0xc4 /* get network configuration */ +#define WIC_GETSYS 0xc5 /* get system configuration */ + +/* + * structure used for the GETNET/SETNET command + */ + +struct wic_net { + unsigned char ula[6]; /* ula of interface */ + unsigned char mode; /* operating mode */ +#define NET_MODE_ME 0x01 /* receive my ula */ +#define NET_MODE_BCAST 0x02 /* receive bcasts */ +#define NET_MODE_MCAST 0x04 /* receive mcasts */ +#define NET_MODE_PROM 0x08 /* promiscuous */ +#define NET_MODE_HC 0x10 /* is a hop coordinator */ +#define NET_MODE_HC_VALID 0x20 /* hc address is valid */ +#define NET_MODE_HCAP 0x40 /* hc is also ap */ +#define NET_MODE_HC_KNOWN 0x80 /* hc is known */ + unsigned char rts_lo; /* rts threshold */ + unsigned char rts_hi; /* rts threshold */ + unsigned char retry; /* retry limit */ + unsigned char hc_ula[6]; /* ula of hc */ + unsigned char key[4]; /* network key */ + unsigned char dsl; /* direct send limit */ + unsigned char res1; /* reserved */ +}; + +/* + * structure used for the GETSYS/SETSYS command + */ + +struct wic_sys { + unsigned char mode; /* set operating mode */ +#define SYS_MODE_ANT_DIV 0x00 /* use antenna diversity */ +#define SYS_MODE_ANT_1 0x01 /* use ant 1 for tx */ +#define SYS_MODE_ANT_2 0x02 /* use ant 2 for tx */ +#define SYS_MODE_HC_LOCK 0x04 /* lock onto current hc */ +#define SYS_MODE_DEBUG 0x08 /* upload failed frames */ +#define SYS_MODE_IAM_AP 0x10 /* I am AP */ +#define SYS_MODE_IAM_HC 0x20 /* I am HC */ +#define SYS_MODE_USE_SKIP 0x40 /* use skipping mechanism */ +#define SYS_MODE_AUTO 0x80 /* station is in auto mode */ + unsigned char switches; /* radio/controller switches */ +#define SYS_SWITCH_STDBY 0x01 /* switch radio to standby */ +#define SYS_SWITCH_TXRX 0x02 /* 1 = tx, manual mode only */ +#define SYS_SWITCH_PA 0x04 /* 1 = enable PA on radio */ +#define SYS_SWITCH_PWR 0x10 /* 1 = hi, 0 = lo power output */ +#define SYS_SWITCH_RES1 0x20 /* reserved, must be 0 */ +#define SYS_SWITCH_LIGHTS 0x40 /* light for tx & rx */ +#define SYS_SWITCH_LIGHTS_HC 0x80 /* light for rx while coordinated */ + unsigned char hop_min; /* hop range */ + unsigned char hop_max; /* hop range */ + unsigned char pre_len; /* preamble length (bytes) */ + unsigned char pre_match; /* valid preamble match (bytes) */ + unsigned char mod; /* data mod: 1 = 8:1, 0 = none */ + unsigned char cca_mode; /* cca flags */ +#define CCA_PKT_DET_BSY 0x01 /* busy if packet is detected */ +#define CCA_VIRT_CARR 0x02 /* use virtual carrier */ +#define CCA_RSSI_BSY 0x04 /* busy if rssi > threshold */ +#define CCA_DATA_BSY 0x08 /* busy if valid data > XXX usec */ + unsigned char dwell_hi; /* dwell time */ + unsigned char dwell_lo; /* dwell time */ + unsigned char hc_timeout; /* HC timeout */ + unsigned char rssi; /* rssi threshold */ + unsigned char hc_rssi; /* rssi of last hc frame */ + unsigned char hc_rssi_chan; /* channel of hc rssi value */ +}; + + +#endif /* _LINUX_IF_WIC_H */ + + diff --git a/include/linux/igmp.h b/include/linux/igmp.h index b8ee985aa..82569a653 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -1,8 +1,10 @@ /* - * Linux NET3: Internet Gateway Management Protocol [IGMP] + * Linux NET3: Internet Group Management Protocol [IGMP] * * Authors: - * Alan Cox <Alan.Cox@linux.org> + * Alan Cox <Alan.Cox@linux.org> + * + * Extended to talk the BSD extended IGMP protocol of mrouted 3.6 * * * This program is free software; you can redistribute it and/or @@ -21,34 +23,56 @@ /* * Header in on cable format */ - + struct igmphdr { - unsigned char type; - unsigned char unused; - unsigned short csum; - unsigned long group; + __u8 type; + __u8 code; /* For newer IGMP */ + __u16 csum; + __u32 group; }; +#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */ +#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */ +#define IGMP_DVMRP 0x13 /* DVMRP routing */ +#define IGMP_PIM 0x14 /* PIM routing */ +#define IGMP_TRACE 0x15 /* CISCO trace */ +#define IGMP_HOST_NEW_MEMBERSHIP_REPORT 0x16 /* New version of 0x11 */ +#define IGMP_HOST_LEAVE_MESSAGE 0x17 /* An extra BSD seems to send */ + +#define IGMP_MTRACE_RESP 0x1e +#define IGMP_MTRACE 0x1f + + /* - * Header in host convenient format + * Use the BSD names for these for compatibility */ -struct igmp_header -{ - unsigned char type; - unsigned char unused; - unsigned short csum; - unsigned long group; -}; +#define IGMP_DELAYING_MEMBER 0x01 +#define IGMP_IDLE_MEMBER 0x02 +#define IGMP_LAZY_MEMBER 0x03 +#define IGMP_SLEEPING_MEMBER 0x04 +#define IGMP_AWAKENING_MEMBER 0x05 +#define IGMP_OLD_ROUTER 0x00 +#define IGMP_NEW_ROUTER 0x01 -#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */ -#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */ -#define IGMP_HOST_LEAVE_MESSAGE 0x17 /* An extra BSD seems to send */ +#define IGMP_MINLEN 8 + +#define IGMP_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */ + /* query (in seconds) */ + +#define IGMP_TIMER_SCALE 10 /* denotes that the igmphdr->timer field */ + /* specifies time in 10th of seconds */ + +#define IGMP_AGE_THRESHOLD 540 /* If this host don't hear any IGMP V1 */ + /* message in this period of time, */ + /* revert to IGMP v2 router. */ - /* 224.0.0.1 */ #define IGMP_ALL_HOSTS htonl(0xE0000001L) +#define IGMP_ALL_ROUTER htonl(0xE0000002L) +#define IGMP_LOCAL_GROUP htonl(0xE0000000L) +#define IGMP_LOCAL_GROUP_MASK htonl(0xFFFFFF00L) /* * struct for keeping the multicast list in @@ -61,24 +85,35 @@ struct ip_mc_socklist struct device *multidev[IP_MAX_MEMBERSHIPS]; }; -struct ip_mc_list +struct ip_mc_list { struct device *interface; unsigned long multiaddr; struct ip_mc_list *next; struct timer_list timer; - int tm_running; + short tm_running; + short reporter; int users; }; - + +struct ip_router_info +{ + struct device *dev; + int type; /* type of router which is querier on this interface */ + int time; /* # of slow timeouts since last old query */ + struct timer_list timer; + struct ip_router_info *next; +}; + extern struct ip_mc_list *ip_mc_head; -extern int igmp_rcv(struct sk_buff *, struct device *, struct options *, unsigned long, unsigned short, - unsigned long, int , struct inet_protocol *); -extern void ip_mc_drop_device(struct device *dev); +extern int igmp_rcv(struct sk_buff *, struct device *, struct options *, __u32, unsigned short, + __u32, int , struct inet_protocol *); +extern void ip_mc_drop_device(struct device *dev); extern int ip_mc_join_group(struct sock *sk, struct device *dev, unsigned long addr); extern int ip_mc_leave_group(struct sock *sk, struct device *dev,unsigned long addr); extern void ip_mc_drop_socket(struct sock *sk); +extern void ip_mr_init(void); #endif #endif diff --git a/include/linux/in.h b/include/linux/in.h index d811239d6..61566713f 100644 --- a/include/linux/in.h +++ b/include/linux/in.h @@ -18,12 +18,13 @@ #ifndef _LINUX_IN_H #define _LINUX_IN_H +#include <linux/types.h> /* Standard well-defined IP protocols. */ enum { IPPROTO_IP = 0, /* Dummy protocol for TCP */ IPPROTO_ICMP = 1, /* Internet Control Message Protocol */ - IPPROTO_IGMP = 2, /* Internet Gateway Management Protocol */ + IPPROTO_IGMP = 2, /* Internet Group Management Protocol */ IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */ IPPROTO_TCP = 6, /* Transmission Control Protocol */ IPPROTO_EGP = 8, /* Exterior Gateway Protocol */ @@ -31,14 +32,17 @@ enum { IPPROTO_UDP = 17, /* User Datagram Protocol */ IPPROTO_IDP = 22, /* XNS IDP protocol */ - IPPROTO_RAW = 255, /* Raw IP packets */ + IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */ + IPPROTO_ICMPV6 = 58, /* ICMPv6 */ + + IPPROTO_RAW = 255, /* Raw IP packets */ IPPROTO_MAX }; /* Internet address. */ struct in_addr { - unsigned long int s_addr; + __u32 s_addr; }; /* Request struct for multicast socket ops */ @@ -53,7 +57,7 @@ struct ip_mreq /* Structure describing an Internet (IP) socket address. */ #define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */ struct sockaddr_in { - short int sin_family; /* Address family */ + sa_family_t sin_family; /* Address family */ unsigned short int sin_port; /* Port number */ struct in_addr sin_addr; /* Internet address */ @@ -100,21 +104,29 @@ struct sockaddr_in { #define INADDR_BROADCAST ((unsigned long int) 0xffffffff) /* Address indicating an error return. */ -#define INADDR_NONE 0xffffffff +#define INADDR_NONE ((unsigned long int) 0xffffffff) /* Network number for local host loopback. */ #define IN_LOOPBACKNET 127 /* Address to loopback in software to local host. */ #define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */ +#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000) /* Defines for Multicast INADDR */ #define INADDR_UNSPEC_GROUP 0xe0000000 /* 224.0.0.0 */ #define INADDR_ALLHOSTS_GROUP 0xe0000001 /* 224.0.0.1 */ #define INADDR_MAX_LOCAL_GROUP 0xe00000ff /* 224.0.0.255 */ -/* <asm/byteorder.h> contains the htonl type stuff.. */ +/* <asm/byteorder.h> contains the htonl type stuff.. */ #include <asm/byteorder.h> +#ifdef __KERNEL__ +/* Some random defines to make it easier in the kernel.. */ +#define LOOPBACK(x) (((x) & htonl(0xff000000)) == htonl(0x7f000000)) +#define MULTICAST(x) (((x) & htonl(0xf0000000)) == htonl(0xe0000000)) + +#endif + #endif /* _LINUX_IN_H */ diff --git a/include/linux/in6.h b/include/linux/in6.h new file mode 100644 index 000000000..781d7339d --- /dev/null +++ b/include/linux/in6.h @@ -0,0 +1,114 @@ +/* + * Types and definitions for AF_INET6 + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * Sources: + * IPv6 Program Interfaces for BSD Systems + * <draft-ietf-ipngwg-bsd-api-05.txt> + * + * Advanced Sockets API for IPv6 + * <draft-stevens-advanced-api-00.txt> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _LINUX_IN6_H +#define _LINUX_IN6_H + + +/* + * IPv6 address structure + */ + +struct in6_addr +{ + union + { + __u8 u6_addr8[16]; + __u32 u6_addr32[4]; +#if (~0UL) > 0xffffffff + __u64 u6_addr64[2]; +#endif + } in6_u; +#define s6_addr in6_u.u6_addr8 +#define s6_addr32 in6_u.u6_addr32 +#define s6_addr64 in6_u.u6_addr64 +}; + +struct sockaddr_in6 { + unsigned short int sin6_family; /* AF_INET6 */ + __u16 sin6_port; /* Transport layer port # */ + __u32 sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ +}; + + +struct ipv6_mreq { + /* IPv6 multicast address of group */ + struct in6_addr ipv6mr_multiaddr; + + /* local IPv6 address of interface */ + int ipv6mr_ifindex; +}; + +/* + * Bitmask constant declarations to help applications select out the + * flow label and priority fields. + * + * Note that this are in host byte order while the flowinfo field of + * sockaddr_in6 is in network byte order. + */ + +#define IPV6_FLOWINFO_FLOWLABEL 0x00ff +#define IPV6_FLOWINFO_PRIORITY 0x0f00 + +#define IPV6_PRIORITY_UNCHARACTERIZED 0x0000 +#define IPV6_PRIORITY_FILLER 0x0100 +#define IPV6_PRIORITY_UNATTENDED 0x0200 +#define IPV6_PRIORITY_RESERVED1 0x0300 +#define IPV6_PRIORITY_BULK 0x0400 +#define IPV6_PRIORITY_RESERVED2 0x0500 +#define IPV6_PRIORITY_INTERACTIVE 0x0600 +#define IPV6_PRIORITY_CONTROL 0x0700 +#define IPV6_PRIORITY_8 0x0800 +#define IPV6_PRIORITY_9 0x0900 +#define IPV6_PRIORITY_10 0x0a00 +#define IPV6_PRIORITY_11 0x0b00 +#define IPV6_PRIORITY_12 0x0c00 +#define IPV6_PRIORITY_13 0x0d00 +#define IPV6_PRIORITY_14 0x0e00 +#define IPV6_PRIORITY_15 0x0f00 + +/* + * IPV6 socket options + */ + +#define IPV6_ADDRFORM 1 +#define IPV6_RXINFO 2 +#define IPV6_RXHOPOPTS 3 +#define IPV6_RXDSTOPTS 4 +#define IPV6_RXSRCRT 5 +#define IPV6_PKTOPTIONS 6 +#define IPV6_CHECKSUM 7 + +/* + * Alternative names + */ +#define IPV6_TXINFO IPV6_RXINFO +#define SCM_SRCINFO IPV6_TXINFO +#define SCM_SRCRT IPV6_RXSRCRT + +#define IPV6_UNICAST_HOPS 16 +#define IPV6_MULTICAST_IF 17 +#define IPV6_MULTICAST_HOPS 18 +#define IPV6_MULTICAST_LOOP 19 +#define IPV6_ADD_MEMBERSHIP 20 +#define IPV6_DROP_MEMBERSHIP 21 + +#endif diff --git a/include/linux/inet.h b/include/linux/inet.h index 4a7a9f654..9bd28d56e 100644 --- a/include/linux/inet.h +++ b/include/linux/inet.h @@ -46,7 +46,7 @@ extern void inet_proto_init(struct net_proto *pro); extern char *in_ntoa(unsigned long in); -extern unsigned long in_aton(char *str); +extern unsigned long in_aton(const char *str); #endif #endif /* _LINUX_INET_H */ diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 4c4edc82c..77cd07c8f 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -2,17 +2,24 @@ #ifndef _LINUX_INTERRUPT_H #define _LINUX_INTERRUPT_H -#include <linux/linkage.h> +#include <linux/kernel.h> #include <asm/bitops.h> -struct bh_struct { - void (*routine)(void *); - void *data; +struct irqaction { + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + unsigned long mask; + const char *name; + void *dev_id; + struct irqaction *next; }; +extern unsigned long intr_count; + +extern int bh_mask_count[32]; extern unsigned long bh_active; extern unsigned long bh_mask; -extern struct bh_struct bh_base[32]; +extern void (*bh_base[32])(void); asmlinkage void do_bottom_half(void); @@ -23,37 +30,57 @@ enum { TIMER_BH = 0, CONSOLE_BH, TQUEUE_BH, + DIGI_BH, SERIAL_BH, + RISCOM8_BH, NET_BH, IMMEDIATE_BH, KEYBOARD_BH, - CYCLADES_BH + CYCLADES_BH, + CM206_BH }; +extern inline void init_bh(int nr, void (*routine)(void)) +{ + bh_base[nr] = routine; + bh_mask_count[nr] = 0; + bh_mask |= 1 << nr; +} + extern inline void mark_bh(int nr) { set_bit(nr, &bh_active); } +/* + * These use a mask count to correctly handle + * nested disable/enable calls + */ extern inline void disable_bh(int nr) { - clear_bit(nr, &bh_mask); + bh_mask &= ~(1 << nr); + bh_mask_count[nr]++; } extern inline void enable_bh(int nr) { - set_bit(nr, &bh_mask); + if (!--bh_mask_count[nr]) + bh_mask |= 1 << nr; } +/* + * start_bh_atomic/end_bh_atomic also nest + * naturally by using a counter + */ extern inline void start_bh_atomic(void) { intr_count++; + barrier(); } extern inline void end_bh_atomic(void) { - if (intr_count == 1 && (bh_active & bh_mask)) - do_bottom_half(); + barrier(); intr_count--; } @@ -77,14 +104,14 @@ extern inline void end_bh_atomic(void) * 7. service the device to clear its pending interrupt. * 8. loop again if paranoia is required. * - * probe_irq_on() returns a mask of snarfed irq's. + * probe_irq_on() returns a mask of allocated irq's. * * probe_irq_off() takes the mask as a parameter, * and returns the irq number which occurred, * or zero if none occurred, or a negative irq number * if more than one irq occurred. */ -extern unsigned int probe_irq_on(void); /* returns 0 on failure */ -extern int probe_irq_off(unsigned int); /* returns 0 or negative on failure */ +extern unsigned long probe_irq_on(void); /* returns 0 on failure */ +extern int probe_irq_off(unsigned long); /* returns 0 or negative on failure */ #endif diff --git a/include/linux/ioctl.h b/include/linux/ioctl.h index e76bdb6e0..aa91eb395 100644 --- a/include/linux/ioctl.h +++ b/include/linux/ioctl.h @@ -1,53 +1,7 @@ -/* $Id: ioctl.h,v 1.5 1993/07/19 21:53:50 root Exp root $ - * - * linux/ioctl.h for Linux by H.H. Bergman. - */ - #ifndef _LINUX_IOCTL_H #define _LINUX_IOCTL_H - -/* ioctl command encoding: 32 bits total, command in lower 16 bits, - * size of the parameter structure in the lower 14 bits of the - * upper 16 bits. - * Encoding the size of the parameter structure in the ioctl request - * is useful for catching programs compiled with old versions - * and to avoid overwriting user space outside the user buffer area. - * The highest 2 bits are reserved for indicating the ``access mode''. - * NOTE: This limits the max parameter size to 16kB -1 ! - */ - -#define IOC_VOID 0x00000000 /* param in size field */ -#define IOC_IN 0x40000000 /* user --> kernel */ -#define IOC_OUT 0x80000000 /* kernel --> user */ -#define IOC_INOUT (IOC_IN | IOC_OUT) /* both */ -#define IOCSIZE_MASK 0x3fff0000 /* size (max 16k-1 bytes) */ -#define IOCSIZE_SHIFT 16 /* how to get the size */ -#define IOCSIZE_MAX ((PAGE_SIZE-1)&(IOCSIZE_MASK >> IOC_SHIFT)) -#define IOCCMD_MASK 0x0000ffff /* command code */ -#define IOCCMD_SHIFT 0 -#define IOCPARM_MASK IOCCMD_MASK -#define IOCPARM_SHIFT IOCCMD_SHIFT - -#define IOC_SIZE(cmd) (((cmd) & IOCSIZE_MASK) >> IOCSIZE_SHIFT) -#define IOCBASECMD(cmd) ((cmd) & ~IOCPARM_MASK) -#define IOCGROUP(cmd) (((cmd) >> 8) & 0xFF) - -/* _IO(magic, subcode); size field is zero and the - * subcode determines the command. - */ -#define _IO(c,d) (IOC_VOID | ((c)<<8) | (d)) /* param encoded */ - -/* _IOXX(magic, subcode, arg_t); where arg_t is the type of the - * (last) argument field in the ioctl call, if present. - */ -#define _IOW(c,d,t) (IOC_IN | ((sizeof(t)<<16) & IOCSIZE_MASK) | \ - ((c)<<8) | (d)) -#define _IOR(c,d,t) (IOC_OUT | ((sizeof(t)<<16) & IOCSIZE_MASK) | \ - ((c)<<8) | (d)) -/* WR rather than RW to avoid conflict with stdio.h */ -#define _IOWR(c,d,t) (IOC_INOUT | ((sizeof(t)<<16) & IOCSIZE_MASK) | \ - ((c)<<8) | (d)) +#include <asm/ioctl.h> #endif /* _LINUX_IOCTL_H */ diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 8a019adb6..335e3b65f 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -13,12 +13,11 @@ #define HAVE_PORTRESERVE /* * Call check_region() before probing for your hardware. - * Once you have found you hardware, register it with snarf_region(). + * Once you have found you hardware, register it with request_region(). * If you unload the driver, use release_region to free ports. */ extern void reserve_setup(char *str, int *ints); extern int check_region(unsigned int from, unsigned int extent); -extern void snarf_region(unsigned int from, unsigned int extent); extern void request_region(unsigned int from, unsigned int extent,const char *name); extern void release_region(unsigned int from, unsigned int extent); extern int get_ioport_list(char *); @@ -26,7 +25,7 @@ extern int get_ioport_list(char *); #define HAVE_AUTOIRQ extern void *irq2dev_map[16]; /* Use only if you own the IRQ. */ -extern void autoirq_setup(int waittime); +extern int autoirq_setup(int waittime); extern int autoirq_report(int waittime); #endif /* _LINUX_PORTIO_H */ diff --git a/include/linux/ip.h b/include/linux/ip.h index d12b92b1e..74d0fa81a 100644 --- a/include/linux/ip.h +++ b/include/linux/ip.h @@ -33,18 +33,15 @@ struct timestamp { __u8 len; __u8 ptr; - union { -#if defined(LITTLE_ENDIAN_BITFIELD) +#if defined(__LITTLE_ENDIAN_BITFIELD) __u8 flags:4, overflow:4; -#elif defined(BIG_ENDIAN_BITFIELD) +#elif defined(__BIG_ENDIAN_BITFIELD) __u8 overflow:4, flags:4; #else #error "Please fix <asm/byteorder.h>" #endif - __u8 full_char; - } x; __u32 data[9]; }; @@ -57,25 +54,44 @@ struct route { unsigned long route[MAX_ROUTE]; }; +#define IPOPT_OPTVAL 0 +#define IPOPT_OLEN 1 +#define IPOPT_OFFSET 2 +#define IPOPT_MINOFF 4 +#define MAX_IPOPTLEN 40 +#define IPOPT_NOP IPOPT_NOOP +#define IPOPT_EOL IPOPT_END +#define IPOPT_TS IPOPT_TIMESTAMP + +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 2 /* specified modules only */ struct options { - struct route record_route; - struct route loose_route; - struct route strict_route; - struct timestamp tstamp; - unsigned short security; - unsigned short compartment; - unsigned short handling; - unsigned short stream; - unsigned tcc; + __u32 faddr; /* Saved first hop address */ + unsigned char optlen; + unsigned char srr; + unsigned char rr; + unsigned char ts; + unsigned char is_setbyuser:1, /* Set by setsockopt? */ + is_data:1, /* Options in __data, rather than skb */ + is_strictroute:1, /* Strict source route */ + srr_is_hit:1, /* Packet destination addr was our one */ + is_changed:1, /* IP checksum more not valid */ + rr_needaddr:1, /* Need to record addr of outgoing dev */ + ts_needtime:1, /* Need to record timestamp */ + ts_needaddr:1; /* Need to record addr of outgoing dev */ + unsigned char __pad1; + unsigned char __pad2; + unsigned char __pad3; + unsigned char __data[0]; }; - struct iphdr { -#if defined(LITTLE_ENDIAN_BITFIELD) +#if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; -#elif defined (BIG_ENDIAN_BITFIELD) +#elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else @@ -93,5 +109,4 @@ struct iphdr { /*The options start here. */ }; - #endif /* _LINUX_IP_H */ diff --git a/include/linux/ip_fw.h b/include/linux/ip_fw.h index 29bafa34f..3a33555f7 100644 --- a/include/linux/ip_fw.h +++ b/include/linux/ip_fw.h @@ -16,6 +16,13 @@ * * Fixes: * Pauline Middelink : Added masquerading. + * Jos Vos : Separate input and output firewall + * chains, new "insert" and "append" + * commands to replace "add" commands, + * add ICMP header to struct ip_fwpkt. + * Jos Vos : Add support for matching device names. + * Willy Konynenberg : Add transparent proxying support. + * Jos Vos : Add options for input/output accounting. * * All the real work was done by ..... */ @@ -45,12 +52,19 @@ #ifndef _IP_FW_H #define _IP_FW_H +#include <linux/icmp.h> +#include <linux/in.h> +#include <linux/ip.h> +#include <linux/tcp.h> +#include <linux/udp.h> + struct ip_fw { struct ip_fw *fw_next; /* Next firewall on chain */ struct in_addr fw_src, fw_dst; /* Source and destination IP addr */ struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */ struct in_addr fw_via; /* IP address of interface "via" */ + struct device *fw_viadev; /* device of interface "via" */ unsigned short fw_flg; /* Flags word */ unsigned short fw_nsp, fw_ndp; /* N'of src ports and # of dst ports */ /* in ports array (dst ports follow */ @@ -59,35 +73,42 @@ struct ip_fw #define IP_FW_MAX_PORTS 10 /* A reasonable maximum */ unsigned short fw_pts[IP_FW_MAX_PORTS]; /* Array of port numbers to match */ unsigned long fw_pcnt,fw_bcnt; /* Packet and byte counters */ + unsigned char fw_tosand, fw_tosxor; /* Revised packet priority */ + char fw_vianame[IFNAMSIZ]; /* name of interface "via" */ }; /* * Values for "flags" field . */ -#define IP_FW_F_ALL 0x000 /* This is a universal packet firewall*/ -#define IP_FW_F_TCP 0x001 /* This is a TCP packet firewall */ -#define IP_FW_F_UDP 0x002 /* This is a UDP packet firewall */ -#define IP_FW_F_ICMP 0x003 /* This is a ICMP packet firewall */ -#define IP_FW_F_KIND 0x003 /* Mask to isolate firewall kind */ -#define IP_FW_F_ACCEPT 0x004 /* This is an accept firewall (as * +#define IP_FW_F_ALL 0x0000 /* This is a universal packet firewall*/ +#define IP_FW_F_TCP 0x0001 /* This is a TCP packet firewall */ +#define IP_FW_F_UDP 0x0002 /* This is a UDP packet firewall */ +#define IP_FW_F_ICMP 0x0003 /* This is a ICMP packet firewall */ +#define IP_FW_F_KIND 0x0003 /* Mask to isolate firewall kind */ +#define IP_FW_F_ACCEPT 0x0004 /* This is an accept firewall (as * * opposed to a deny firewall)* * */ -#define IP_FW_F_SRNG 0x008 /* The first two src ports are a min * +#define IP_FW_F_SRNG 0x0008 /* The first two src ports are a min * * and max range (stored in host byte * * order). * * */ -#define IP_FW_F_DRNG 0x010 /* The first two dst ports are a min * +#define IP_FW_F_DRNG 0x0010 /* The first two dst ports are a min * * and max range (stored in host byte * * order). * * (ports[0] <= port <= ports[1]) * * */ -#define IP_FW_F_PRN 0x020 /* In verbose mode print this firewall*/ -#define IP_FW_F_BIDIR 0x040 /* For bidirectional firewalls */ -#define IP_FW_F_TCPSYN 0x080 /* For tcp packets-check SYN only */ -#define IP_FW_F_ICMPRPL 0x100 /* Send back icmp unreachable packet */ -#define IP_FW_F_MASQ 0x200 /* Masquerading */ -#define IP_FW_F_MASK 0x3FF /* All possible flag bits mask */ +#define IP_FW_F_PRN 0x0020 /* In verbose mode print this firewall*/ +#define IP_FW_F_BIDIR 0x0040 /* For bidirectional firewalls */ +#define IP_FW_F_TCPSYN 0x0080 /* For tcp packets-check SYN only */ +#define IP_FW_F_ICMPRPL 0x0100 /* Send back icmp unreachable packet */ +#define IP_FW_F_MASQ 0x0200 /* Masquerading */ +#define IP_FW_F_TCPACK 0x0400 /* For tcp-packets match if ACK is set*/ +#define IP_FW_F_REDIR 0x0800 /* Redirect to local port fw_pts[n] */ +#define IP_FW_F_ACCTIN 0x1000 /* Account incoming packets only. */ +#define IP_FW_F_ACCTOUT 0x2000 /* Account outgoing packets only. */ + +#define IP_FW_F_MASK 0x3FFF /* All possible flag bits mask */ /* * New IP firewall options for [gs]etsockopt at the RAW IP level. @@ -95,25 +116,56 @@ struct ip_fw * a raw socket for this. Instead we check rights in the calls. */ -#define IP_FW_BASE_CTL 64 - -#define IP_FW_ADD_BLK (IP_FW_BASE_CTL) -#define IP_FW_ADD_FWD (IP_FW_BASE_CTL+1) -#define IP_FW_CHK_BLK (IP_FW_BASE_CTL+2) -#define IP_FW_CHK_FWD (IP_FW_BASE_CTL+3) -#define IP_FW_DEL_BLK (IP_FW_BASE_CTL+4) -#define IP_FW_DEL_FWD (IP_FW_BASE_CTL+5) -#define IP_FW_FLUSH_BLK (IP_FW_BASE_CTL+6) -#define IP_FW_FLUSH_FWD (IP_FW_BASE_CTL+7) -#define IP_FW_ZERO_BLK (IP_FW_BASE_CTL+8) -#define IP_FW_ZERO_FWD (IP_FW_BASE_CTL+9) -#define IP_FW_POLICY_BLK (IP_FW_BASE_CTL+10) -#define IP_FW_POLICY_FWD (IP_FW_BASE_CTL+11) - -#define IP_ACCT_ADD (IP_FW_BASE_CTL+16) -#define IP_ACCT_DEL (IP_FW_BASE_CTL+17) -#define IP_ACCT_FLUSH (IP_FW_BASE_CTL+18) -#define IP_ACCT_ZERO (IP_FW_BASE_CTL+19) +#define IP_FW_BASE_CTL 64 /* base for firewall socket options */ + +#define IP_FW_COMMAND 0x00FF /* mask for command without chain */ +#define IP_FW_TYPE 0x0300 /* mask for type (chain) */ +#define IP_FW_SHIFT 8 /* shift count for type (chain) */ + +#define IP_FW_FWD 0 +#define IP_FW_IN 1 +#define IP_FW_OUT 2 +#define IP_FW_ACCT 3 +#define IP_FW_CHAINS 4 /* total number of ip_fw chains */ + +#define IP_FW_INSERT (IP_FW_BASE_CTL) +#define IP_FW_APPEND (IP_FW_BASE_CTL+1) +#define IP_FW_DELETE (IP_FW_BASE_CTL+2) +#define IP_FW_FLUSH (IP_FW_BASE_CTL+3) +#define IP_FW_ZERO (IP_FW_BASE_CTL+4) +#define IP_FW_POLICY (IP_FW_BASE_CTL+5) +#define IP_FW_CHECK (IP_FW_BASE_CTL+6) +#define IP_FW_MASQ_TIMEOUTS (IP_FW_BASE_CTL+7) + +#define IP_FW_INSERT_FWD (IP_FW_INSERT | (IP_FW_FWD << IP_FW_SHIFT)) +#define IP_FW_APPEND_FWD (IP_FW_APPEND | (IP_FW_FWD << IP_FW_SHIFT)) +#define IP_FW_DELETE_FWD (IP_FW_DELETE | (IP_FW_FWD << IP_FW_SHIFT)) +#define IP_FW_FLUSH_FWD (IP_FW_FLUSH | (IP_FW_FWD << IP_FW_SHIFT)) +#define IP_FW_ZERO_FWD (IP_FW_ZERO | (IP_FW_FWD << IP_FW_SHIFT)) +#define IP_FW_POLICY_FWD (IP_FW_POLICY | (IP_FW_FWD << IP_FW_SHIFT)) +#define IP_FW_CHECK_FWD (IP_FW_CHECK | (IP_FW_FWD << IP_FW_SHIFT)) + +#define IP_FW_INSERT_IN (IP_FW_INSERT | (IP_FW_IN << IP_FW_SHIFT)) +#define IP_FW_APPEND_IN (IP_FW_APPEND | (IP_FW_IN << IP_FW_SHIFT)) +#define IP_FW_DELETE_IN (IP_FW_DELETE | (IP_FW_IN << IP_FW_SHIFT)) +#define IP_FW_FLUSH_IN (IP_FW_FLUSH | (IP_FW_IN << IP_FW_SHIFT)) +#define IP_FW_ZERO_IN (IP_FW_ZERO | (IP_FW_IN << IP_FW_SHIFT)) +#define IP_FW_POLICY_IN (IP_FW_POLICY | (IP_FW_IN << IP_FW_SHIFT)) +#define IP_FW_CHECK_IN (IP_FW_CHECK | (IP_FW_IN << IP_FW_SHIFT)) + +#define IP_FW_INSERT_OUT (IP_FW_INSERT | (IP_FW_OUT << IP_FW_SHIFT)) +#define IP_FW_APPEND_OUT (IP_FW_APPEND | (IP_FW_OUT << IP_FW_SHIFT)) +#define IP_FW_DELETE_OUT (IP_FW_DELETE | (IP_FW_OUT << IP_FW_SHIFT)) +#define IP_FW_FLUSH_OUT (IP_FW_FLUSH | (IP_FW_OUT << IP_FW_SHIFT)) +#define IP_FW_ZERO_OUT (IP_FW_ZERO | (IP_FW_OUT << IP_FW_SHIFT)) +#define IP_FW_POLICY_OUT (IP_FW_POLICY | (IP_FW_OUT << IP_FW_SHIFT)) +#define IP_FW_CHECK_OUT (IP_FW_CHECK | (IP_FW_OUT << IP_FW_SHIFT)) + +#define IP_ACCT_INSERT (IP_FW_INSERT | (IP_FW_ACCT << IP_FW_SHIFT)) +#define IP_ACCT_APPEND (IP_FW_APPEND | (IP_FW_ACCT << IP_FW_SHIFT)) +#define IP_ACCT_DELETE (IP_FW_DELETE | (IP_FW_ACCT << IP_FW_SHIFT)) +#define IP_ACCT_FLUSH (IP_FW_FLUSH | (IP_FW_ACCT << IP_FW_SHIFT)) +#define IP_ACCT_ZERO (IP_FW_ZERO | (IP_FW_ACCT << IP_FW_SHIFT)) struct ip_fwpkt { @@ -121,63 +173,47 @@ struct ip_fwpkt union { struct tcphdr fwp_tcph; /* TCP header or */ struct udphdr fwp_udph; /* UDP header */ + struct icmphdr fwp_icmph; /* ICMP header */ } fwp_protoh; struct in_addr fwp_via; /* interface address */ + char fwp_vianame[IFNAMSIZ]; /* interface name */ }; /* + * timeouts for ip masquerading + */ + +struct ip_fw_masq; + +/* * Main firewall chains definitions and global var's definitions. */ #ifdef __KERNEL__ -#include <linux/config.h> +/* Modes used in the ip_fw_chk() routine. */ +#define IP_FW_MODE_FW 0x00 /* kernel firewall check */ +#define IP_FW_MODE_ACCT_IN 0x01 /* accounting (incoming) */ +#define IP_FW_MODE_ACCT_OUT 0x02 /* accounting (outgoing) */ +#define IP_FW_MODE_CHK 0x04 /* check requested by user */ -#ifdef CONFIG_IP_MASQUERADE -struct ip_masq { - struct ip_masq *next; /* next member in list */ - struct timer_list timer; /* Expiration timer */ - __u16 protocol; /* Which protocol are we talking? */ - __u32 src, dst; /* Source and destination IP addresses */ - __u16 sport,dport; /* Source and destoination ports */ - __u16 mport; /* Masquaraded port */ - __u32 init_seq; /* Add delta from this seq. on */ - short delta; /* Delta in sequence numbers */ - char sawfin; /* Did we saw an FIN packet? */ -}; -extern struct ip_masq *ip_msq_hosts; -extern void ip_fw_masquerade(struct sk_buff **, struct device *); -extern int ip_fw_demasquerade(struct sk_buff *); -#endif +#include <linux/config.h> #ifdef CONFIG_IP_FIREWALL -extern struct ip_fw *ip_fw_blk_chain; +extern struct ip_fw *ip_fw_in_chain; +extern struct ip_fw *ip_fw_out_chain; extern struct ip_fw *ip_fw_fwd_chain; -extern int ip_fw_blk_policy; +extern int ip_fw_in_policy; +extern int ip_fw_out_policy; extern int ip_fw_fwd_policy; extern int ip_fw_ctl(int, void *, int); #endif #ifdef CONFIG_IP_ACCT extern struct ip_fw *ip_acct_chain; -extern void ip_acct_cnt(struct iphdr *, struct device *, struct ip_fw *); extern int ip_acct_ctl(int, void *, int); #endif -extern int ip_fw_chk(struct iphdr *, struct device *rif,struct ip_fw *, int, int); -#endif /* KERNEL */ - -#ifdef CONFIG_IP_MASQUERADE - -#undef DEBUG_MASQ -#define MASQUERADE_EXPIRE_TCP 15*60*HZ -#define MASQUERADE_EXPIRE_TCP_FIN 2*60*HZ -#define MASQUERADE_EXPIRE_UDP 5*60*HZ - -/* - * Linux ports don't normally get allocated above 32K. I used an extra 4K port-space - */ - -#define PORT_MASQ_BEGIN 60000 -#define PORT_MASQ_END (PORT_MASQ_BEGIN+4096) -#endif +extern int ip_fw_chk(struct iphdr *, struct device *, __u16 *, struct ip_fw *, int, int); +extern void ip_fw_init(void); +#endif /* KERNEL */ #endif /* _IP_FW_H */ diff --git a/include/linux/ipc.h b/include/linux/ipc.h index 3878e0203..9349f0f49 100644 --- a/include/linux/ipc.h +++ b/include/linux/ipc.h @@ -1,22 +1,21 @@ #ifndef _LINUX_IPC_H #define _LINUX_IPC_H + #include <linux/types.h> -typedef int key_t; /* should go in <types.h> type for IPC key */ -#define IPC_PRIVATE ((key_t) 0) +#define IPC_PRIVATE ((__kernel_key_t) 0) struct ipc_perm { - key_t key; - ushort uid; /* owner euid and egid */ - ushort gid; - ushort cuid; /* creator euid and egid */ - ushort cgid; - ushort mode; /* access modes see mode flags below */ - ushort seq; /* sequence number */ + __kernel_key_t key; + __kernel_uid_t uid; + __kernel_gid_t gid; + __kernel_uid_t cuid; + __kernel_gid_t cgid; + __kernel_mode_t mode; + unsigned short seq; }; - /* resource get request flags */ #define IPC_CREAT 00001000 /* create if key is nonexistent */ #define IPC_EXCL 00002000 /* fail if key exists */ @@ -38,28 +37,6 @@ struct ipc_perm #define IPC_UNUSED ((void *) -1) #define IPC_NOID ((void *) -2) /* being allocated/destroyed */ -/* - * These are used to wrap system calls. See ipc/util.c. - */ -struct ipc_kludge { - struct msgbuf *msgp; - long msgtyp; -}; - -#define SEMOP 1 -#define SEMGET 2 -#define SEMCTL 3 -#define MSGSND 11 -#define MSGRCV 12 -#define MSGGET 13 -#define MSGCTL 14 -#define SHMAT 21 -#define SHMDT 22 -#define SHMGET 23 -#define SHMCTL 24 - -#define IPCCALL(version,op) ((version)<<16 | (op)) - #endif /* __KERNEL__ */ #endif /* _LINUX_IPC_H */ diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h new file mode 100644 index 000000000..b8126a9f2 --- /dev/null +++ b/include/linux/ipv6.h @@ -0,0 +1,105 @@ +#ifndef _IPV6_H +#define _IPV6_H + +#include <linux/in6.h> +#include <asm/byteorder.h> + +/* + * IPv6 fixed header + */ + +struct ipv6hdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 priority:4, + version:4; +#elif defined(__BIG_ENDIAN_BITFIELD) + __u8 version:4, + priority:4; +#else +#error "Please fix <asm/byteorder.h>" +#endif + __u8 flow_lbl[3]; + + __u16 payload_len; + __u8 nexthdr; + __u8 hop_limit; + + struct in6_addr saddr; + struct in6_addr daddr; +}; + +struct in6_ifreq { + struct in6_addr addr; + __u32 prefix_len; + char devname[8]; +}; + +/* + * Advanced API + * source interface/address selection, source routing, etc... + * *under construction* + */ + + +struct in6_pktinfo { + struct in6_addr ipi6_addr; + int ipi6_ifindex; +}; + +#define IPV6_SRCRT_STRICT 0x01 /* this hop must be a neighbor */ +#define IPV6_SRCRT_TYPE_0 0 /* IPv6 type 0 Routing Header */ + +/* + * routing header + */ +struct ipv6_rt_hdr { + __u8 nexthdr; + __u8 hdrlen; + __u8 type; + __u8 segments_left; + + /* + * type specific data + * variable length field + */ +}; + +/* + * routing header type 0 (used in cmsghdr struct) + */ + +struct rt0_hdr { + struct ipv6_rt_hdr rt_hdr; + __u32 bitmap; /* strict/loose bit map */ + struct in6_addr addr[0]; + +#define rt0_type rt_hdr.type; +}; + +#ifdef __KERNEL__ + +/* + * The length of this struct cannot be greater than the length of + * the proto_priv field in a sk_buff which is currently + * defined to be 16 bytes. + * Pointers take upto 8 bytes (sizeof(void *) is 8 on the alpha). + */ +struct ipv6_options +{ + /* length of extension headers */ + + __u16 opt_flen; /* after fragment hdr */ + __u16 opt_nflen; /* before fragment hdr */ + + /* + * protocol options + * usualy carried in IPv6 extension headers + */ + + struct ipv6_rt_hdr *srcrt; /* Routing Header */ + +}; + +#endif + +#endif diff --git a/include/linux/ipv6_route.h b/include/linux/ipv6_route.h new file mode 100644 index 000000000..ef93e022b --- /dev/null +++ b/include/linux/ipv6_route.h @@ -0,0 +1,41 @@ +/* + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _LINUX_IPV6_ROUTE_H +#define _LINUX_IPV6_ROUTE_H + +#include <linux/route.h> + +#define RTI_DEVRT 0x00010000 /* route lookup, dev must match */ +#define RTI_ALLONLINK 0x00020000 /* all destinations on link */ +#define RTI_DCACHE RTF_DCACHE /* rt6_info is a dcache entry */ +#define RTI_INVALID RTF_INVALID /* invalid route/dcache entry */ + +#define RTI_DYNAMIC RTF_DYNAMIC /* rt6_info created dynamicly */ +#define RTI_GATEWAY RTF_GATEWAY +#define RTI_DYNMOD RTF_MODIFIED /* more specific route may exist*/ + +#define DCF_PMTU RTF_MSS /* dest cache has valid PMTU */ +#define DCF_INVALID RTF_INVALID + +struct in6_rtmsg { + struct in6_addr rtmsg_dst; + struct in6_addr rtmsg_gateway; + __u32 rtmsg_type; + __u16 rtmsg_prefixlen; + __u16 rtmsg_metric; + unsigned long rtmsg_info; + __u32 rtmsg_flags; + int rtmsg_ifindex; +}; + +#endif diff --git a/include/linux/ipx.h b/include/linux/ipx.h index d3bff83b6..a2d86a983 100644 --- a/include/linux/ipx.h +++ b/include/linux/ipx.h @@ -6,11 +6,11 @@ struct sockaddr_ipx { - short sipx_family; - short sipx_port; - unsigned long sipx_network; - unsigned char sipx_node[IPX_NODE_LEN]; - unsigned char sipx_type; + sa_family_t sipx_family; + __u16 sipx_port; + __u32 sipx_network; + unsigned char sipx_node[IPX_NODE_LEN]; + __u8 sipx_type; unsigned char sipx_zero; /* 16 byte fill */ }; @@ -40,6 +40,7 @@ typedef struct ipx_interface_definition #define IPX_FRAME_8022 2 #define IPX_FRAME_ETHERII 3 #define IPX_FRAME_8023 4 +#define IPX_FRAME_TR_8022 5 unsigned char ipx_special; #define IPX_SPECIAL_NONE 0 #define IPX_PRIMARY 1 diff --git a/include/linux/isdn.h b/include/linux/isdn.h new file mode 100644 index 000000000..1408407d9 --- /dev/null +++ b/include/linux/isdn.h @@ -0,0 +1,635 @@ +/* $Id: isdn.h,v 1.16 1996/08/12 16:20:56 hipp Exp $ + * + * Main header for the Linux ISDN subsystem (linklevel). + * + * Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg + * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: isdn.h,v $ + * Revision 1.16 1996/08/12 16:20:56 hipp + * renamed ppp_minor to ppp_slot + * + * Revision 1.15 1996/06/15 14:56:57 fritz + * Added version signatures for data structures used + * by userlevel programs. + * + * Revision 1.14 1996/06/06 21:24:23 fritz + * Started adding support for suspend/resume. + * + * Revision 1.13 1996/06/05 02:18:20 fritz + * Added DTMF decoding stuff. + * + * Revision 1.12 1996/06/03 19:55:08 fritz + * Fixed typos. + * + * Revision 1.11 1996/05/31 01:37:47 fritz + * Minor changes, due to changes in isdn_tty.c + * + * Revision 1.10 1996/05/18 01:37:18 fritz + * Added spelling corrections and some minor changes + * to stay in sync with kernel. + * + * Revision 1.9 1996/05/17 03:58:20 fritz + * Added flags for DLE handling. + * + * Revision 1.8 1996/05/11 21:49:55 fritz + * Removed queue management variables. + * Changed queue management to use sk_buffs. + * + * Revision 1.7 1996/05/07 09:10:06 fritz + * Reorganized tty-related structs. + * + * Revision 1.6 1996/05/06 11:38:27 hipp + * minor change in ippp struct + * + * Revision 1.5 1996/04/30 11:03:16 fritz + * Added Michael's ippp-bind patch. + * + * Revision 1.4 1996/04/29 23:00:02 fritz + * Added variables for voice-support. + * + * Revision 1.3 1996/04/20 16:54:58 fritz + * Increased maximum number of channels. + * Added some flags for isdn_net to handle callback more reliable. + * Fixed delay-definitions to be more accurate. + * Misc. typos + * + * Revision 1.2 1996/02/11 02:10:02 fritz + * Changed IOCTL-names + * Added rx_netdev, st_netdev, first_skb, org_hcb, and org_hcu to + * Netdevice-local struct. + * + * Revision 1.1 1996/01/10 20:55:07 fritz + * Initial revision + * + */ + +#ifndef isdn_h +#define isdn_h + +#include <linux/ioctl.h> + +#define ISDN_TTY_MAJOR 43 +#define ISDN_TTYAUX_MAJOR 44 +#define ISDN_MAJOR 45 + +/* The minor-devicenumbers for Channel 0 and 1 are used as arguments for + * physical Channel-Mapping, so they MUST NOT be changed without changing + * the correspondent code in isdn.c + */ + +#define ISDN_MAX_DRIVERS 32 +#define ISDN_MAX_CHANNELS 64 +#define ISDN_MINOR_B 0 +#define ISDN_MINOR_BMAX (ISDN_MAX_CHANNELS-1) +#define ISDN_MINOR_CTRL ISDN_MAX_CHANNELS +#define ISDN_MINOR_CTRLMAX (2*ISDN_MAX_CHANNELS-1) +#define ISDN_MINOR_PPP (2*ISDN_MAX_CHANNELS) +#define ISDN_MINOR_PPPMAX (3*ISDN_MAX_CHANNELS-1) +#define ISDN_MINOR_STATUS 255 + +/* New ioctl-codes */ +#define IIOCNETAIF _IO('I',1) +#define IIOCNETDIF _IO('I',2) +#define IIOCNETSCF _IO('I',3) +#define IIOCNETGCF _IO('I',4) +#define IIOCNETANM _IO('I',5) +#define IIOCNETDNM _IO('I',6) +#define IIOCNETGNM _IO('I',7) +#define IIOCGETSET _IO('I',8) +#define IIOCSETSET _IO('I',9) +#define IIOCSETVER _IO('I',10) +#define IIOCNETHUP _IO('I',11) +#define IIOCSETGST _IO('I',12) +#define IIOCSETBRJ _IO('I',13) +#define IIOCSIGPRF _IO('I',14) +#define IIOCGETPRF _IO('I',15) +#define IIOCSETPRF _IO('I',16) +#define IIOCGETMAP _IO('I',17) +#define IIOCSETMAP _IO('I',18) +#define IIOCNETASL _IO('I',19) +#define IIOCNETDIL _IO('I',20) +#define IIOCGETCPS _IO('I',21) +#define IIOCGETDVR _IO('I',22) + +#define IIOCNETALN _IO('I',32) +#define IIOCNETDLN _IO('I',33) + +#define IIOCDBGVAR _IO('I',127) + +#define IIOCDRVCTL _IO('I',128) + +/* Packet encapsulations for net-interfaces */ +#define ISDN_NET_ENCAP_ETHER 0 +#define ISDN_NET_ENCAP_RAWIP 1 +#define ISDN_NET_ENCAP_IPTYP 2 +#define ISDN_NET_ENCAP_CISCOHDLC 3 +#define ISDN_NET_ENCAP_SYNCPPP 4 +#define ISDN_NET_ENCAP_UIHDLC 5 + +/* Facility which currently uses an ISDN-channel */ +#define ISDN_USAGE_NONE 0 +#define ISDN_USAGE_RAW 1 +#define ISDN_USAGE_MODEM 2 +#define ISDN_USAGE_NET 3 +#define ISDN_USAGE_VOICE 4 +#define ISDN_USAGE_FAX 5 +#define ISDN_USAGE_MASK 7 /* Mask to get plain usage */ +#define ISDN_USAGE_EXCLUSIVE 64 /* This bit is set, if channel is exclusive */ +#define ISDN_USAGE_OUTGOING 128 /* This bit is set, if channel is outgoing */ + +#define ISDN_MODEM_ANZREG 21 /* Number of Modem-Registers */ +#define ISDN_MSNLEN 20 + +typedef struct { + char drvid[25]; + unsigned long arg; +} isdn_ioctl_struct; + +typedef struct { + unsigned long isdndev; + unsigned long atmodem[ISDN_MAX_CHANNELS]; + unsigned long info[ISDN_MAX_CHANNELS]; +} debugvar_addr; + +typedef struct { + char name[10]; + char phone[20]; + int outgoing; +} isdn_net_ioctl_phone; + +#define NET_DV 0x01 /* Data version for net_cfg */ +#define TTY_DV 0x01 /* Data version for iprofd etc. */ + +typedef struct { + char name[10]; /* Name of interface */ + char master[10]; /* Name of Master for Bundling */ + char slave[10]; /* Name of Slave for Bundling */ + char eaz[256]; /* EAZ/MSN */ + char drvid[25]; /* DriverId for Bindings */ + int onhtime; /* Hangup-Timeout */ + int charge; /* Charge-Units */ + int l2_proto; /* Layer-2 protocol */ + int l3_proto; /* Layer-3 protocol */ + int p_encap; /* Encapsulation */ + int exclusive; /* Channel, if bound exclusive */ + int dialmax; /* Dial Retry-Counter */ + int slavedelay; /* Delay until slave starts up */ + int cbdelay; /* Delay before Callback */ + int chargehup; /* Flag: Charge-Hangup */ + int ihup; /* Flag: Hangup-Timeout on incoming line */ + int secure; /* Flag: Secure */ + int callback; /* Flag: Callback */ + int cbhup; /* Flag: Reject Call before Callback */ + int pppbind; /* ippp device for bindings */ +} isdn_net_ioctl_cfg; + +#ifdef __KERNEL__ + +#ifndef STANDALONE +#include <linux/config.h> +#endif +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/major.h> +#include <asm/segment.h> +#include <asm/io.h> +#include <linux/kernel.h> +#include <linux/signal.h> +#include <linux/malloc.h> +#include <linux/mm.h> +#include <linux/timer.h> +#include <linux/wait.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> +#include <linux/serial_reg.h> +#include <linux/fcntl.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ip.h> +#include <linux/in.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <linux/tcp.h> + +#ifdef CONFIG_ISDN_PPP + +#ifdef CONFIG_ISDN_PPP_VJ +# include <net/slhc_vj.h> +#endif + +#include <linux/ppp_defs.h> +#include <linux/if_ppp.h> +#include <linux/if_pppvar.h> + +#include <linux/isdn_ppp.h> +#endif + +#include <linux/isdnif.h> + +#define ISDN_DRVIOCTL_MASK 0x7f /* Mask for Device-ioctl */ + +/* Until now unused */ +#define ISDN_SERVICE_VOICE 1 +#define ISDN_SERVICE_AB 1<<1 +#define ISDN_SERVICE_X21 1<<2 +#define ISDN_SERVICE_G4 1<<3 +#define ISDN_SERVICE_BTX 1<<4 +#define ISDN_SERVICE_DFUE 1<<5 +#define ISDN_SERVICE_X25 1<<6 +#define ISDN_SERVICE_TTX 1<<7 +#define ISDN_SERVICE_MIXED 1<<8 +#define ISDN_SERVICE_FW 1<<9 +#define ISDN_SERVICE_GTEL 1<<10 +#define ISDN_SERVICE_BTXN 1<<11 +#define ISDN_SERVICE_BTEL 1<<12 + +/* Macros checking plain usage */ +#define USG_NONE(x) ((x & ISDN_USAGE_MASK)==ISDN_USAGE_NONE) +#define USG_RAW(x) ((x & ISDN_USAGE_MASK)==ISDN_USAGE_RAW) +#define USG_MODEM(x) ((x & ISDN_USAGE_MASK)==ISDN_USAGE_MODEM) +#define USG_VOICE(x) ((x & ISDN_USAGE_MASK)==ISDN_USAGE_VOICE) +#define USG_NET(x) ((x & ISDN_USAGE_MASK)==ISDN_USAGE_NET) +#define USG_OUTGOING(x) ((x & ISDN_USAGE_OUTGOING)==ISDN_USAGE_OUTGOING) +#define USG_MODEMORVOICE(x) (((x & ISDN_USAGE_MASK)==ISDN_USAGE_MODEM) || \ + ((x & ISDN_USAGE_MASK)==ISDN_USAGE_VOICE) ) + +/* Timer-delays and scheduling-flags */ +#define ISDN_TIMER_RES 3 /* Main Timer-Resolution */ +#define ISDN_TIMER_02SEC (HZ/(ISDN_TIMER_RES+1)/5) /* Slow-Timer1 .2 sec */ +#define ISDN_TIMER_1SEC (HZ/(ISDN_TIMER_RES+1)) /* Slow-Timer2 1 sec */ +#define ISDN_TIMER_MODEMREAD 1 +#define ISDN_TIMER_MODEMPLUS 2 +#define ISDN_TIMER_MODEMRING 4 +#define ISDN_TIMER_MODEMXMIT 8 +#define ISDN_TIMER_NETDIAL 16 +#define ISDN_TIMER_NETHANGUP 32 +#define ISDN_TIMER_IPPP 64 +#define ISDN_TIMER_FAST (ISDN_TIMER_MODEMREAD | ISDN_TIMER_MODEMPLUS | \ + ISDN_TIMER_MODEMXMIT) +#define ISDN_TIMER_SLOW (ISDN_TIMER_MODEMRING | ISDN_TIMER_NETHANGUP | \ + ISDN_TIMER_NETDIAL) + +/* Timeout-Values for isdn_net_dial() */ +#define ISDN_TIMER_DTIMEOUT10 (10*HZ/(ISDN_TIMER_02SEC*(ISDN_TIMER_RES+1))) +#define ISDN_TIMER_DTIMEOUT15 (15*HZ/(ISDN_TIMER_02SEC*(ISDN_TIMER_RES+1))) + +/* GLOBAL_FLAGS */ +#define ISDN_GLOBAL_STOPPED 1 + +/*=================== Start of ip-over-ISDN stuff =========================*/ + +/* Feature- and status-flags for a net-interface */ +#define ISDN_NET_CONNECTED 0x01 /* Bound to ISDN-Channel */ +#define ISDN_NET_SECURE 0x02 /* Accept calls from phonelist only */ +#define ISDN_NET_CALLBACK 0x04 /* activate callback */ +#define ISDN_NET_CBHUP 0x08 /* hangup before callback */ +#define ISDN_NET_CBOUT 0x10 /* remote machine does callback */ +#if 0 +/* Unused??? */ +#define ISDN_NET_CLONE 0x08 /* clone a tmp interface when called */ +#define ISDN_NET_TMP 0x10 /* tmp interface until getting an IP */ +#define ISDN_NET_DYNAMIC 0x20 /* this link is dynamically allocated */ +#endif +#define ISDN_NET_MAGIC 0x49344C02 /* for paranoia-checking */ + +/* Phone-list-element */ +typedef struct { + void *next; + char num[20]; +} isdn_net_phone; + +/* Local interface-data */ +typedef struct isdn_net_local_s { + ulong magic; + char name[10]; /* Name of device */ + struct enet_statistics stats; /* Ethernet Statistics */ + int isdn_device; /* Index to isdn-device */ + int isdn_channel; /* Index to isdn-channel */ + int ppp_slot; /* PPPD device slot number */ + int pre_device; /* Preselected isdn-device */ + int pre_channel; /* Preselected isdn-channel */ + int exclusive; /* If non-zero idx to reserved chan.*/ + int flags; /* Connection-flags */ + int dialretry; /* Counter for Dialout-retries */ + int dialmax; /* Max. Number of Dial-retries */ + int cbdelay; /* Delay before Callback starts */ + int dtimer; /* Timeout-counter for dialing */ + char msn[ISDN_MSNLEN]; /* MSNs/EAZs for this interface */ + u_char cbhup; /* Flag: Reject Call before Callback*/ + u_char dialstate; /* State for dialing */ + u_char p_encap; /* Packet encapsulation */ + /* 0 = Ethernet over ISDN */ + /* 1 = RAW-IP */ + /* 2 = IP with type field */ + u_char l2_proto; /* Layer-2-protocol */ + /* See ISDN_PROTO_L2..-constants in */ + /* isdnif.h */ + /* 0 = X75/LAPB with I-Frames */ + /* 1 = X75/LAPB with UI-Frames */ + /* 2 = X75/LAPB with BUI-Frames */ + /* 3 = HDLC */ + u_char l3_proto; /* Layer-3-protocol */ + /* See ISDN_PROTO_L3..-constants in */ + /* isdnif.h */ + /* 0 = Transparent */ + int huptimer; /* Timeout-counter for auto-hangup */ + int charge; /* Counter for charging units */ + int chargetime; /* Timer for Charging info */ + int hupflags; /* Flags for charge-unit-hangup: */ + /* bit0: chargeint is invalid */ + /* bit1: Getting charge-interval */ + /* bit2: Do charge-unit-hangup */ + int outgoing; /* Flag: outgoing call */ + int onhtime; /* Time to keep link up */ + int chargeint; /* Interval between charge-infos */ + int onum; /* Flag: at least 1 outgoing number */ + int cps; /* current speed of this interface */ + int transcount; /* byte-counter for cps-calculation */ + int sqfull; /* Flag: netdev-queue overloaded */ + ulong sqfull_stamp; /* Start-Time of overload */ + ulong slavedelay; /* Dynamic bundling delaytime */ + struct device *srobin; /* Ptr to Master device for slaves */ + isdn_net_phone *phone[2]; /* List of remote-phonenumbers */ + /* phone[0] = Incoming Numbers */ + /* phone[1] = Outgoing Numbers */ + isdn_net_phone *dial; /* Pointer to dialed number */ + struct device *master; /* Ptr to Master device for slaves */ + struct device *slave; /* Ptr to Slave device for masters */ + struct isdn_net_local_s *next; /* Ptr to next link in bundle */ + struct isdn_net_local_s *last; /* Ptr to last link in bundle */ + struct isdn_net_dev_s *netdev; /* Ptr to netdev */ + struct sk_buff *first_skb; /* Ptr to skb that triggers dialing */ + struct sk_buff *sav_skb; /* Ptr to skb, rejected by LL-driver*/ + /* Ptr to orig. header_cache_bind */ + void (*org_hcb)(struct hh_cache **, struct device *, + unsigned short, __u32); + /* Ptr to orig. header_cache_update */ + void (*org_hcu)(struct hh_cache *, struct device *, + unsigned char *); + int pppbind; /* ippp device for bindings */ +} isdn_net_local; + +#ifdef CONFIG_ISDN_PPP +struct ippp_bundle { + int mp_mrru; /* unused */ + struct mpqueue *last; /* currently defined in isdn_net_dev */ + int min; /* currently calculated 'on the fly' */ + long next_num; /* we wanna see this seq.-number next */ + struct sqqueue *sq; + int modify:1; /* set to 1 while modifying sqqueue */ + int bundled:1; /* bundle active ? */ +}; +#endif + +/* the interface itself */ +typedef struct isdn_net_dev_s { + isdn_net_local local; + isdn_net_local *queue; + void *next; /* Pointer to next isdn-interface */ + struct device dev; /* interface to upper levels */ +#ifdef CONFIG_ISDN_PPP + struct mpqueue *mp_last; + struct ippp_bundle ib; +#endif +} isdn_net_dev; + +/*===================== End of ip-over-ISDN stuff ===========================*/ + +/*======================= Start of ISDN-tty stuff ===========================*/ + +#define ISDN_ASYNC_MAGIC 0x49344C01 /* for paranoia-checking */ +#define ISDN_ASYNC_INITIALIZED 0x80000000 /* port was initialized */ +#define ISDN_ASYNC_CALLOUT_ACTIVE 0x40000000 /* Call out device active */ +#define ISDN_ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device active */ +#define ISDN_ASYNC_CLOSING 0x08000000 /* Serial port is closing */ +#define ISDN_ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */ +#define ISDN_ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */ +#define ISDN_ASYNC_HUP_NOTIFY 0x0001 /* Notify tty on hangups/closes */ +#define ISDN_ASYNC_SESSION_LOCKOUT 0x0100 /* Lock cua opens on session */ +#define ISDN_ASYNC_PGRP_LOCKOUT 0x0200 /* Lock cua opens on pgrp */ +#define ISDN_ASYNC_CALLOUT_NOHUP 0x0400 /* No hangup for cui */ +#define ISDN_ASYNC_SPLIT_TERMIOS 0x0008 /* Sep. termios for dialin/out */ +#define ISDN_SERIAL_XMIT_SIZE 4000 /* Maximum bufsize for write */ +#define ISDN_SERIAL_TYPE_NORMAL 1 +#define ISDN_SERIAL_TYPE_CALLOUT 2 + +/* Private data of AT-command-interpreter */ +typedef struct atemu { + u_char profile[ISDN_MODEM_ANZREG]; /* Modem-Regs. Profile 0 */ + u_char mdmreg[ISDN_MODEM_ANZREG]; /* Modem-Registers */ + char pmsn[ISDN_MSNLEN]; /* EAZ/MSNs Profile 0 */ + char msn[ISDN_MSNLEN];/* EAZ/MSN */ + u_char vpar[10]; /* Voice-parameters */ + int mdmcmdl; /* Length of Modem-Commandbuffer */ + int pluscount; /* Counter for +++ sequence */ + int lastplus; /* Timestamp of last + */ + int lastDLE; /* Flag for voice-coding: DLE seen */ + char mdmcmd[255]; /* Modem-Commandbuffer */ +} atemu; + +/* Private data (similar to async_struct in <linux/serial.h>) */ +typedef struct modem_info { + int magic; + int flags; /* defined in tty.h */ + int x_char; /* xon/xoff character */ + int mcr; /* Modem control register */ + int msr; /* Modem status register */ + int lsr; /* Line status register */ + int line; + int count; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + long session; /* Session of opening process */ + long pgrp; /* pgrp of opening process */ + int online; /* B-Channel is up */ + int vonline; /* Voice-channel status */ + int dialing; /* Dial in progress */ + int rcvsched; /* Receive needs schedule */ + int isdn_driver; /* Index to isdn-driver */ + int isdn_channel; /* Index to isdn-channel */ + int drv_index; /* Index to dev->usage */ + int ncarrier; /* Flag: schedule NO CARRIER */ + struct timer_list nc_timer; /* Timer for delayed NO CARRIER */ + int send_outstanding;/* # of outstanding send-requests */ + int xmit_size; /* max. # of chars in xmit_buf */ + int xmit_count; /* # of chars in xmit_buf */ + unsigned char *xmit_buf; /* transmit buffer */ + struct sk_buff_head xmit_queue; /* transmit queue */ + struct sk_buff_head dtmf_queue; /* queue for dtmf results */ + struct tty_struct *tty; /* Pointer to corresponding tty */ + atemu emu; /* AT-emulator data */ + void *adpcms; /* state for adpcm decompression */ + void *adpcmr; /* state for adpcm compression */ + void *dtmf_state; /* state for dtmf decoder */ + struct termios normal_termios; /* For saving termios structs */ + struct termios callout_termios; + struct wait_queue *open_wait; + struct wait_queue *close_wait; +} modem_info; + +#define ISDN_MODEM_WINSIZE 8 + +/* Description of one ISDN-tty */ +typedef struct { + int refcount; /* Number of opens */ + struct tty_driver tty_modem; /* tty-device */ + struct tty_driver cua_modem; /* cua-device */ + struct tty_struct *modem_table[ISDN_MAX_CHANNELS]; /* ?? copied from Orig */ + struct termios *modem_termios[ISDN_MAX_CHANNELS]; + struct termios *modem_termios_locked[ISDN_MAX_CHANNELS]; + modem_info info[ISDN_MAX_CHANNELS]; /* Private data */ +} modem; + +/*======================= End of ISDN-tty stuff ============================*/ + +/*======================= Start of sync-ppp stuff ==========================*/ + + +#define NUM_RCV_BUFFS 64 +#define PPP_HARD_HDR_LEN 4 + +#define IPPP_OPEN 0x1 +#define IPPP_CONNECT 0x2 +#define IPPP_CLOSEWAIT 0x4 +#define IPPP_NOBLOCK 0x8 + +#ifdef CONFIG_ISDN_PPP + +struct sqqueue { + struct sqqueue *next; + int sqno_start; + int sqno_end; + struct sk_buff *skb; + long timer; +}; + +struct mpqueue { + struct mpqueue *next; + struct mpqueue *last; + int sqno; + struct sk_buff *skb; + int BEbyte; + unsigned long time; +}; + +struct ippp_buf_queue { + struct ippp_buf_queue *next; + struct ippp_buf_queue *last; + char *buf; /* NULL here indicates end of queue */ + int len; +}; + +struct ippp_struct { + struct ippp_struct *next_link; + int state; + struct ippp_buf_queue rq[NUM_RCV_BUFFS]; /* packet queue for isdn_ppp_read() */ + struct ippp_buf_queue *first; /* pointer to (current) first packet */ + struct ippp_buf_queue *last; /* pointer to (current) last used packet in queue */ + struct wait_queue *wq; + struct wait_queue *wq1; + struct task_struct *tk; + unsigned int mpppcfg; + unsigned int pppcfg; + unsigned int mru; + unsigned int mpmru; + unsigned int mpmtu; + unsigned int maxcid; + isdn_net_local *lp; + int unit; + int minor; + long last_link_seqno; + long mp_seqno; + long range; +#ifdef CONFIG_ISDN_PPP_VJ + unsigned char *cbuf; + struct slcompress *slcomp; +#endif + unsigned long debug; +}; + +#endif + +/*======================== End of sync-ppp stuff ===========================*/ + +/*======================= Start of general stuff ===========================*/ + +typedef struct { + char *next; + char *private; +} infostruct; + +/* Description of hardware-level-driver */ +typedef struct { + ulong flags; /* Flags */ + int channels; /* Number of channels */ + int reject_bus; /* Flag: Reject rejected call on bus*/ + struct wait_queue *st_waitq; /* Wait-Queue for status-read's */ + int maxbufsize; /* Maximum Buffersize supported */ + unsigned long pktcount; /* Until now: unused */ + int running; /* Flag: Protocolcode running */ + int loaded; /* Flag: Driver loaded */ + int stavail; /* Chars avail on Status-device */ + isdn_if *interface; /* Interface to driver */ + int *rcverr; /* Error-counters for B-Ch.-receive */ + int *rcvcount; /* Byte-counters for B-Ch.-receive */ + unsigned long DLEflag; /* Flags: Insert DLE at next read */ + struct sk_buff_head *rpqueue; /* Pointers to start of Rcv-Queue */ + struct wait_queue **rcv_waitq; /* Wait-Queues for B-Channel-Reads */ + struct wait_queue **snd_waitq; /* Wait-Queue for B-Channel-Send's */ + char msn2eaz[10][ISDN_MSNLEN]; /* Mapping-Table MSN->EAZ */ +} driver; + +/* Main driver-data */ +typedef struct isdn_devt { + unsigned short flags; /* Bitmapped Flags: */ + /* */ + int drivers; /* Current number of drivers */ + int channels; /* Current number of channels */ + int net_verbose; /* Verbose-Flag */ + int modempoll; /* Flag: tty-read active */ + int tflags; /* Timer-Flags: */ + /* see ISDN_TIMER_..defines */ + int global_flags; + infostruct *infochain; /* List of open info-devs. */ + struct wait_queue *info_waitq; /* Wait-Queue for isdninfo */ + struct timer_list timer; /* Misc.-function Timer */ + int chanmap[ISDN_MAX_CHANNELS];/* Map minor->device-channel */ + int drvmap[ISDN_MAX_CHANNELS]; /* Map minor->driver-index */ + int usage[ISDN_MAX_CHANNELS]; /* Used by tty/ip/voice */ + char num[ISDN_MAX_CHANNELS][20];/* Remote number of active ch.*/ + int m_idx[ISDN_MAX_CHANNELS]; /* Index for mdm.... */ + driver *drv[ISDN_MAX_DRIVERS]; /* Array of drivers */ + isdn_net_dev *netdev; /* Linked list of net-if's */ + char drvid[ISDN_MAX_DRIVERS][20];/* Driver-ID */ + struct task_struct *profd; /* For iprofd */ + modem mdm; /* tty-driver-data */ + isdn_net_dev *rx_netdev[ISDN_MAX_CHANNELS]; /* rx netdev-pointers */ + isdn_net_dev *st_netdev[ISDN_MAX_CHANNELS]; /* stat netdev-pointers */ + ulong ibytes[ISDN_MAX_CHANNELS]; /* Statistics incoming bytes */ + ulong obytes[ISDN_MAX_CHANNELS]; /* Statistics outgoing bytes */ +} isdn_dev; + +extern isdn_dev *dev; + +/* Utility-Macros */ +#define MIN(a,b) ((a<b)?a:b) +#define MAX(a,b) ((a>b)?a:b) + +#endif /* __KERNEL__ */ +#endif /* isdn_h */ diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h new file mode 100644 index 000000000..5ce86f868 --- /dev/null +++ b/include/linux/isdn_ppp.h @@ -0,0 +1,35 @@ +#ifndef _LINUX_ISDN_PPP_H +#define _LINUX_ISDN_PPP_H + +extern int isdn_ppp_dial_slave(char *); +extern int isdn_ppp_hangup_slave(char *); + +struct pppinfo +{ + int type; /* set by user */ + union { + char clid[32]; /* calling ID */ + int bundles; + int linknumber; + } info; +}; + + +#define PPPIOCLINKINFO _IOWR('t',128,struct pppinfo) +#define PPPIOCBUNDLE _IOW('t',129,int) +#define PPPIOCGMPFLAGS _IOR('t',130,int) +#define PPPIOCSMPFLAGS _IOW('t',131,int) +#define PPPIOCSMPMTU _IOW('t',132,int) +#define PPPIOCSMPMRU _IOW('t',133,int) + +#define PPP_MP 0x003d + +#define SC_MP_PROT 0x00000200 +#define SC_REJ_MP_PROT 0x00000400 +#define SC_OUT_SHORT_SEQ 0x00000800 +#define SC_IN_SHORT_SEQ 0x00004000 + +#define MP_END_FRAG 0x40 +#define MP_BEGIN_FRAG 0x80 + +#endif diff --git a/include/linux/isdnif.h b/include/linux/isdnif.h new file mode 100644 index 000000000..113099edf --- /dev/null +++ b/include/linux/isdnif.h @@ -0,0 +1,307 @@ +/* $Id: isdnif.h,v 1.9 1996/06/06 21:24:24 fritz Exp $ + * + * Linux ISDN subsystem + * + * Definition of the interface between the subsystem and its low-level drivers. + * + * Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: isdnif.h,v $ + * Revision 1.9 1996/06/06 21:24:24 fritz + * Started adding support for suspend/resume. + * + * Revision 1.8 1996/05/18 01:45:37 fritz + * More spelling corrections. + * + * Revision 1.7 1996/05/18 01:37:19 fritz + * Added spelling corrections and some minor changes + * to stay in sync with kernel. + * + * Revision 1.6 1996/05/17 03:59:28 fritz + * Marked rcvcallb and writebuf obsolete. + * + * Revision 1.5 1996/05/01 11:43:54 fritz + * Removed STANDALONE + * + * Revision 1.4 1996/05/01 11:38:40 fritz + * Added ISDN_FEATURE_L2_TRANS + * + * Revision 1.3 1996/04/29 22:57:54 fritz + * Added driverId and channel parameters to + * writecmd() and readstat(). + * Added constant for voice-support. + * + * Revision 1.2 1996/04/20 17:02:40 fritz + * Changes to support skbuffs for Lowlevel-Drivers. + * Misc. typos + * + * Revision 1.1 1996/01/09 05:50:51 fritz + * Initial revision + * + */ + +#ifndef isdnif_h +#define isdnif_h + +/* + * Values for general protocol-selection + */ +#define ISDN_PTYPE_UNKNOWN 0 /* Protocol undefined */ +#define ISDN_PTYPE_1TR6 1 /* german 1TR6-protocol */ +#define ISDN_PTYPE_EURO 2 /* EDSS1-protocol */ + +/* + * Values for Layer-2-protocol-selection + */ +#define ISDN_PROTO_L2_X75I 0 /* X75/LAPB with I-Frames */ +#define ISDN_PROTO_L2_X75UI 1 /* X75/LAPB with UI-Frames */ +#define ISDN_PROTO_L2_X75BUI 2 /* X75/LAPB with UI-Frames */ +#define ISDN_PROTO_L2_HDLC 3 /* HDLC */ +#define ISDN_PROTO_L2_TRANS 4 /* Transparent (Voice) */ + +/* + * Values for Layer-3-protocol-selection + */ +#define ISDN_PROTO_L3_TRANS 0 /* Transparent */ + +#ifdef __KERNEL__ + +#include <linux/skbuff.h> + +/* + * Commands from linklevel to lowlevel + * + */ +#define ISDN_CMD_IOCTL 0 /* Perform ioctl */ +#define ISDN_CMD_DIAL 1 /* Dial out */ +#define ISDN_CMD_ACCEPTD 2 /* Accept an incoming call on D-Chan. */ +#define ISDN_CMD_ACCEPTB 3 /* Request B-Channel connect. */ +#define ISDN_CMD_HANGUP 4 /* Hangup */ +#define ISDN_CMD_CLREAZ 5 /* Clear EAZ(s) of channel */ +#define ISDN_CMD_SETEAZ 6 /* Set EAZ(s) of channel */ +#define ISDN_CMD_GETEAZ 7 /* Get EAZ(s) of channel */ +#define ISDN_CMD_SETSIL 8 /* Set Service-Indicator-List of channel */ +#define ISDN_CMD_GETSIL 9 /* Get Service-Indicator-List of channel */ +#define ISDN_CMD_SETL2 10 /* Set B-Chan. Layer2-Parameter */ +#define ISDN_CMD_GETL2 11 /* Get B-Chan. Layer2-Parameter */ +#define ISDN_CMD_SETL3 12 /* Set B-Chan. Layer3-Parameter */ +#define ISDN_CMD_GETL3 13 /* Get B-Chan. Layer3-Parameter */ +#define ISDN_CMD_LOCK 14 /* Signal usage by upper levels */ +#define ISDN_CMD_UNLOCK 15 /* Release usage-lock */ +#define ISDN_CMD_SUSPEND 16 /* Suspend connection */ +#define ISDN_CMD_RESUME 17 /* Resume connection */ + +/* + * Status-Values delivered from lowlevel to linklevel via + * statcallb(). + * + */ +#define ISDN_STAT_STAVAIL 256 /* Raw status-data available */ +#define ISDN_STAT_ICALL 257 /* Incoming call detected */ +#define ISDN_STAT_RUN 258 /* Signal protocol-code is running */ +#define ISDN_STAT_STOP 259 /* Signal halt of protocol-code */ +#define ISDN_STAT_DCONN 260 /* Signal D-Channel connect */ +#define ISDN_STAT_BCONN 261 /* Signal B-Channel connect */ +#define ISDN_STAT_DHUP 262 /* Signal D-Channel disconnect */ +#define ISDN_STAT_BHUP 263 /* Signal B-Channel disconnect */ +#define ISDN_STAT_CINF 264 /* Charge-Info */ +#define ISDN_STAT_LOAD 265 /* Signal new lowlevel-driver is loaded */ +#define ISDN_STAT_UNLOAD 266 /* Signal unload of lowlevel-driver */ +#define ISDN_STAT_BSENT 267 /* Signal packet sent */ +#define ISDN_STAT_NODCH 268 /* Signal no D-Channel */ +#define ISDN_STAT_ADDCH 269 /* Add more Channels */ +#define ISDN_STAT_CAUSE 270 /* Cause-Message */ + +/* + * Values for feature-field of interface-struct. + */ +/* Layer 2 */ +#define ISDN_FEATURE_L2_X75I (0x0001 << ISDN_PROTO_L2_X75I) +#define ISDN_FEATURE_L2_X75UI (0x0001 << ISDN_PROTO_L2_X75UI) +#define ISDN_FEATURE_L2_X75BUI (0x0001 << ISDN_PROTO_L2_X75BUI) +#define ISDN_FEATURE_L2_HDLC (0x0001 << ISDN_PROTO_L2_HDLC) +#define ISDN_FEATURE_L2_TRANS (0x0001 << ISDN_PROTO_L2_TRANS) + +/* Layer 3 */ +#define ISDN_FEATURE_L3_TRANS (0x0100 << ISDN_PROTO_L3_TRANS) + +/* Signaling */ +#define ISDN_FEATURE_P_UNKNOWN (0x1000 << ISDN_PTYPE_UNKNOWN) +#define ISDN_FEATURE_P_1TR6 (0x1000 << ISDN_PTYPE_1TR6) +#define ISDN_FEATURE_P_EURO (0x1000 << ISDN_PTYPE_EURO) + +/* + * Structure for exchanging above infos + * + */ +typedef struct { + int driver; /* Lowlevel-Driver-ID */ + int command; /* Command or Status (see above) */ + ulong arg; /* Additional Data */ + char num[50]; /* Additional Data */ +} isdn_ctrl; + +/* + * The interface-struct itself (initialized at load-time of lowlevel-driver) + * + * See Documentation/isdn/INTERFACE for a description, how the communication + * between the ISDN subsystem and its drivers is done. + * + */ +typedef struct { + /* Number of channels supported by this driver + */ + int channels; + + /* + * Maximum Size of transmit/receive-buffer this driver supports. + */ + int maxbufsize; + + /* Feature-Flags for this driver. + * See defines ISDN_FEATURE_... for Values + */ + unsigned long features; + + /* + * Needed for calculating + * dev->hard_header_len = linklayer header + hl_hdrlen; + * Drivers, not supporting sk_buff's should set this to 0. + */ + unsigned short hl_hdrlen; + + /* Receive-Callback + * Parameters: + * int Driver-ID + * int local channel-number (0 ...) + * u_char pointer to received data (in Kernel-Space, volatile) + * int length of data + * + * NOTE: This callback is obsolete, and will be removed when all + * current LL-drivers support rcvcall_skb. Do NOT use for new + * drivers. + */ + void (*rcvcallb)(int, int, u_char*, int); + + /* + * Receive-Callback using sk_buff's + * Parameters: + * int Driver-ID + * int local channel-number (0 ...) + * struct sk_buff *skb received Data + */ + void (*rcvcallb_skb)(int, int, struct sk_buff *); + + /* Status-Callback + * Parameters: + * isdn_ctrl* + * driver = Driver ID. + * command = One of above ISDN_STAT_... constants. + * arg = depending on status-type. + * num = depending on status-type. + */ + int (*statcallb)(isdn_ctrl*); + /* Send command + * Parameters: + * isdn_ctrl* + * driver = Driver ID. + * command = One of above ISDN_CMD_... constants. + * arg = depending on command. + * num = depending on command. + */ + int (*command)(isdn_ctrl*); + /* Send Data + * Parameters: + * int driverId + * int local channel-number (0 ...) + * u_char pointer to data + * int length of data + * int Flag: 0 = Call form Kernel-Space (use memcpy, + * no schedule allowed) + * 1 = Data is in User-Space (use memcpy_fromfs, + * may schedule) + * + * NOTE: This call is obsolete, and will be removed when all + * current LL-drivers support writebuf_skb. Do NOT use for new + * drivers. + */ + int (*writebuf)(int, int, const u_char*, int, int); + + /* + * Send data using sk_buff's + * Parameters: + * int driverId + * int local channel-number (0...) + * struct sk_buff *skb Data to send + */ + int (*writebuf_skb) (int, int, struct sk_buff *); + + /* Send raw D-Channel-Commands + * Parameters: + * u_char pointer data + * int length of data + * int Flag: 0 = Call form Kernel-Space (use memcpy, + * no schedule allowed) + * 1 = Data is in User-Space (use memcpy_fromfs, + * may schedule) + * int driverId + * int local channel-number (0 ...) + */ + int (*writecmd)(const u_char*, int, int, int, int); + /* Read raw Status replies + * u_char pointer data (volatile) + * int length of buffer + * int Flag: 0 = Call form Kernel-Space (use memcpy, + * no schedule allowed) + * 1 = Data is in User-Space (use memcpy_fromfs, + * may schedule) + * int driverId + * int local channel-number (0 ...) + */ + int (*readstat)(u_char*, int, int, int, int); + char id[20]; +} isdn_if; + +/* + * Function which must be called by lowlevel-driver at loadtime with + * the following fields of above struct set: + * + * channels Number of channels that will be supported. + * hl_hdrlen Space to preserve in sk_buff's when sending. Drivers, not + * supporting sk_buff's should set this to 0. + * command Address of Command-Handler. + * features Bitwise coded Features of this driver. (use ISDN_FEATURE_...) + * writebuf Address of Send-Command-Handler. OBSOLETE do NOT use anymore. + * writebuf_skb Address of Skbuff-Send-Handler. (NULL if not supported) + * writecmd " " D-Channel " which accepts raw D-Ch-Commands. + * readstat " " D-Channel " which delivers raw Status-Data. + * + * The linklevel-driver fills the following fields: + * + * channels Driver-ID assigned to this driver. (Must be used on all + * subsequent callbacks. + * rcvcallb Address of handler for received data. OBSOLETE, do NOT use anymore. + * rcvcallb_skb Address of handler for received Skbuff's. (NULL if not supp.) + * statcallb " " " for status-changes. + * + */ +extern int register_isdn(isdn_if*); + +#endif /* __KERNEL__ */ +#endif /* isdnif_h */ + diff --git a/include/linux/iso_fs.h b/include/linux/iso_fs.h index 82a49a3c6..03239cfc3 100644 --- a/include/linux/iso_fs.h +++ b/include/linux/iso_fs.h @@ -122,21 +122,7 @@ struct iso_directory_record { #define ISOFS_BUFFER_SIZE(INODE) ((INODE)->i_sb->s_blocksize) #define ISOFS_BUFFER_BITS(INODE) ((INODE)->i_sb->s_blocksize_bits) - -#if 0 -#ifdef ISOFS_FIXED_BLOCKSIZE -/* We use these until the buffer cache supports 2048 */ -#define ISOFS_BUFFER_BITS 10 -#define ISOFS_BUFFER_SIZE 1024 - -#define ISOFS_BLOCK_NUMBER(X) (X<<1) -#else -#define ISOFS_BUFFER_BITS 11 -#define ISOFS_BUFFER_SIZE 2048 - -#define ISOFS_BLOCK_NUMBER(X) (X) -#endif -#endif +#define ISOFS_ZONE_BITS(INODE) ((INODE)->i_sb->u.isofs_sb.s_log_zone_size) #define ISOFS_SUPER_MAGIC 0x9660 #define ISOFS_FILE_UNKNOWN 0 @@ -167,7 +153,7 @@ extern int find_rock_ridge_relocation(struct iso_directory_record *, struct inod extern int isofs_open(struct inode * inode, struct file * filp); extern void isofs_release(struct inode * inode, struct file * filp); extern int isofs_lookup(struct inode * dir,const char * name, int len, - struct inode ** result); + struct inode ** result); extern unsigned long isofs_count_free_inodes(struct super_block *sb); extern int isofs_new_block(int dev); extern int isofs_free_block(int dev, int block); @@ -175,6 +161,7 @@ extern int isofs_bmap(struct inode *,int); extern void isofs_put_super(struct super_block *); extern struct super_block *isofs_read_super(struct super_block *,void *,int); +extern int init_iso9660_fs(void); extern void isofs_read_inode(struct inode *); extern void isofs_put_inode(struct inode *); extern void isofs_statfs(struct super_block *, struct statfs *, int); diff --git a/include/linux/iso_fs_sb.h b/include/linux/iso_fs_sb.h index 14f929921..25ebdb8ab 100644 --- a/include/linux/iso_fs_sb.h +++ b/include/linux/iso_fs_sb.h @@ -2,7 +2,7 @@ #define _ISOFS_FS_SB /* - * minix super-block data in memory + * iso9660 super-block data in memory */ struct isofs_sb_info { unsigned long s_ninodes; @@ -15,6 +15,7 @@ struct isofs_sb_info { unsigned char s_mapping; unsigned char s_conversion; unsigned char s_rock; + unsigned char s_name_check; /* r = relaxed, s = strict */ unsigned char s_cruft; /* Broken disks with high byte of length containing junk */ diff --git a/include/linux/isp16.h b/include/linux/isp16.h new file mode 100644 index 000000000..9945bb34c --- /dev/null +++ b/include/linux/isp16.h @@ -0,0 +1,75 @@ +/* -- isp16.h + * + * Header for detection and initialisation of cdrom interface (only) on + * ISP16 (MAD16, Mozart) sound card. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* These are the default values */ +#define ISP16_CDROM_TYPE "Sanyo" +#define ISP16_CDROM_IO_BASE 0x340 +#define ISP16_CDROM_IRQ 0 +#define ISP16_CDROM_DMA 0 + +/* Some (Media)Magic */ +/* define types of drive the interface on an ISP16 card may be looking at */ +#define ISP16_DRIVE_X 0x00 +#define ISP16_SONY 0x02 +#define ISP16_PANASONIC0 0x02 +#define ISP16_SANYO0 0x02 +#define ISP16_MITSUMI 0x04 +#define ISP16_PANASONIC1 0x06 +#define ISP16_SANYO1 0x06 +#define ISP16_DRIVE_NOT_USED 0x08 /* not used */ +#define ISP16_DRIVE_SET_MASK 0xF1 /* don't change 0-bit or 4-7-bits*/ +/* ...for port */ +#define ISP16_DRIVE_SET_PORT 0xF8D +/* set io parameters */ +#define ISP16_BASE_340 0x00 +#define ISP16_BASE_330 0x40 +#define ISP16_BASE_360 0x80 +#define ISP16_BASE_320 0xC0 +#define ISP16_IRQ_X 0x00 +#define ISP16_IRQ_5 0x04 /* shouldn't be used to avoid sound card conflicts */ +#define ISP16_IRQ_7 0x08 /* shouldn't be used to avoid sound card conflicts */ +#define ISP16_IRQ_3 0x0C +#define ISP16_IRQ_9 0x10 +#define ISP16_IRQ_10 0x14 +#define ISP16_IRQ_11 0x18 +#define ISP16_DMA_X 0x03 +#define ISP16_DMA_3 0x00 +#define ISP16_DMA_5 0x00 +#define ISP16_DMA_6 0x01 +#define ISP16_DMA_7 0x02 +#define ISP16_IO_SET_MASK 0x20 /* don't change 5-bit */ +/* ...for port */ +#define ISP16_IO_SET_PORT 0xF8E +/* enable the card */ +#define ISP16_C928__ENABLE_PORT 0xF90 /* ISP16 with OPTi 82C928 chip */ +#define ISP16_C929__ENABLE_PORT 0xF91 /* ISP16 with OPTi 82C929 chip */ +#define ISP16_ENABLE_CDROM 0x80 /* seven bit */ + +/* the magic stuff */ +#define ISP16_CTRL_PORT 0xF8F +#define ISP16_C928__CTRL 0xE2 /* ISP16 with OPTi 82C928 chip */ +#define ISP16_C929__CTRL 0xE3 /* ISP16 with OPTi 82C929 chip */ + +#define ISP16_IO_BASE 0xF8D +#define ISP16_IO_SIZE 5 /* ports used from 0xF8D up to 0xF91 */ + +void isp16_setup(char *str, int *ints); +int isp16_init(void); diff --git a/include/linux/istallion.h b/include/linux/istallion.h new file mode 100644 index 000000000..1cf916ad4 --- /dev/null +++ b/include/linux/istallion.h @@ -0,0 +1,132 @@ +/*****************************************************************************/ + +/* + * istallion.h -- stallion intelligent multiport serial driver. + * + * Copyright (C) 1994-1996 Greg Ungerer (gerg@stallion.oz.au). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*****************************************************************************/ +#ifndef _ISTALLION_H +#define _ISTALLION_H +/*****************************************************************************/ + +/* + * Define important driver constants here. + */ +#define STL_MAXBRDS 4 +#define STL_MAXPANELS 4 +#define STL_MAXPORTS 64 +#define STL_MAXCHANS (STL_MAXPORTS + 1) +#define STL_MAXDEVS (STL_MAXBRDS * STL_MAXPORTS) + + +/* + * Define a set of structures to hold all the board/panel/port info + * for our ports. These will be dynamically allocated as required at + * driver initialization time. + */ + +/* + * Port and board structures to hold status info about each object. + * The board structure contains pointers to structures for each port + * connected to it. Panels are not distinguished here, since + * communication with the slave board will always be on a per port + * basis. + */ +typedef struct { + unsigned long magic; + int portnr; + int panelnr; + int brdnr; + unsigned long state; + int devnr; + int flags; + int baud_base; + int custom_divisor; + int close_delay; + int closing_wait; + int refcount; + int openwaitcnt; + int rc; + int argsize; + void *argp; + long session; + long pgrp; + unsigned int rxmarkmsk; + struct tty_struct *tty; + struct wait_queue *open_wait; + struct wait_queue *close_wait; + struct wait_queue *raw_wait; + struct tq_struct tqhangup; + struct termios normaltermios; + struct termios callouttermios; + asysigs_t asig; + unsigned long addr; + unsigned long rxoffset; + unsigned long txoffset; + unsigned long sigs; + unsigned long pflag; + unsigned int rxsize; + unsigned int txsize; + unsigned char reqbit; + unsigned char portidx; + unsigned char portbit; +} stliport_t; + +/* + * Use a structure of function pointers to do board level operations. + * These include, enable/disable, paging shared memory, interrupting, etc. + */ +typedef struct stlibrd { + unsigned long magic; + int brdnr; + int brdtype; + int state; + int nrpanels; + int nrports; + int nrdevs; + unsigned int iobase; + unsigned long memaddr; + void *membase; + int memsize; + int pagesize; + int hostoffset; + int slaveoffset; + int bitsize; + int enabval; + int panels[STL_MAXPANELS]; + int panelids[STL_MAXPANELS]; + void (*init)(struct stlibrd *brdp); + void (*enable)(struct stlibrd *brdp); + void (*reenable)(struct stlibrd *brdp); + void (*disable)(struct stlibrd *brdp); + char *(*getmemptr)(struct stlibrd *brdp, unsigned long offset, int line); + void (*intr)(struct stlibrd *brdp); + void (*reset)(struct stlibrd *brdp); + stliport_t *ports[STL_MAXPORTS]; +} stlibrd_t; + + +/* + * Define MAGIC numbers used for above structures. + */ +#define STLI_PORTMAGIC 0xe671c7a1 +#define STLI_BOARDMAGIC 0x4bc6c825 + +/*****************************************************************************/ +#endif diff --git a/include/linux/kbdcntrlr.h b/include/linux/kbdcntrlr.h new file mode 100644 index 000000000..520e73892 --- /dev/null +++ b/include/linux/kbdcntrlr.h @@ -0,0 +1,67 @@ +/* + * Keyboard controller definitions. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef __LINUX_KBDCTRLR_H +#define __LINUX_KBDCTRLR_H + +/* + * keyboard controller registers + */ +#define KBD_STATUS_REG (unsigned int) 0x64 +#define KBD_CNTL_REG (unsigned int) 0x64 +#define KBD_DATA_REG (unsigned int) 0x60 +/* + * controller commands + */ +#define KBD_READ_MODE (unsigned int) 0x20 +#define KBD_WRITE_MODE (unsigned int) 0x60 +#define KBD_SELF_TEST (unsigned int) 0xAA +#define KBD_SELF_TEST2 (unsigned int) 0xAB +#define KBD_CNTL_ENABLE (unsigned int) 0xAE +/* + * keyboard commands + */ +#define KBD_ENABLE (unsigned int) 0xF4 +#define KBD_DISABLE (unsigned int) 0xF5 +#define KBD_RESET (unsigned int) 0xFF +/* + * keyboard replies + */ +#define KBD_ACK (unsigned int) 0xFA +#define KBD_POR (unsigned int) 0xAA +/* + * status register bits + */ +#define KBD_OBF (unsigned int) 0x01 +#define KBD_IBF (unsigned int) 0x02 +#define KBD_GTO (unsigned int) 0x40 +#define KBD_PERR (unsigned int) 0x80 +/* + * keyboard controller mode register bits + */ +#define KBD_EKI (unsigned int) 0x01 +#define KBD_SYS (unsigned int) 0x04 +#define KBD_DMS (unsigned int) 0x20 +#define KBD_KCC (unsigned int) 0x40 + +/* + * Had to increase this value - the speed ratio host cpu/keyboard + * processor on some MIPS machines make the controller initialization + * fail otherwise. -- Ralf + */ +#define TIMEOUT_CONST 1000000 + +/* + * These will be the new keyboard controller access macros. I don't use + * them yet since I want to talk about some details with Linus first. + */ +#define kbd_read_control() kbd_inb_p(0x64) +#define kbd_read_status() kbd_inb_p(0x64) +#define kbd_read_data() kbd_inb_p(0x60) +#define kbd_write_data() kbd_inb_p(0x60) + +#endif /* __LINUX_KBDCTRLR_H */ diff --git a/include/linux/kd.h b/include/linux/kd.h index 8ba56a1f9..0f669cbe6 100644 --- a/include/linux/kd.h +++ b/include/linux/kd.h @@ -7,6 +7,19 @@ #define GIO_FONT 0x4B60 /* gets font in expanded form */ #define PIO_FONT 0x4B61 /* use font in expanded form */ +#define GIO_FONTX 0x4B6B /* get font using struct consolefontdesc */ +#define PIO_FONTX 0x4B6C /* set font using struct consolefontdesc */ +struct consolefontdesc { + unsigned short charcount; /* characters in font (256 or 512) */ + unsigned short charheight; /* scan lines per character (1-32) */ + char *chardata; /* font data in expanded form */ +}; + +#define PIO_FONTRESET 0x4B6D /* reset to default font */ + +#define GIO_CMAP 0x4B70 /* gets colour palette on VGA+ */ +#define PIO_CMAP 0x4B71 /* sets colour palette on VGA+ */ + #define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */ #define KDMKTONE 0x4B30 /* generate tone */ @@ -40,24 +53,29 @@ typedef char scrnmap_t; #define E_TABSZ 256 #define GIO_SCRNMAP 0x4B40 /* get screen mapping from kernel */ #define PIO_SCRNMAP 0x4B41 /* put screen mapping table in kernel */ +#define GIO_UNISCRNMAP 0x4B69 /* get full Unicode screen mapping */ +#define PIO_UNISCRNMAP 0x4B6A /* set full Unicode screen mapping */ #define GIO_UNIMAP 0x4B66 /* get unicode-to-font mapping from kernel */ struct unipair { - u_short unicode; - u_short fontpos; + unsigned short unicode; + unsigned short fontpos; }; struct unimapdesc { - u_short entry_ct; + unsigned short entry_ct; struct unipair *entries; }; #define PIO_UNIMAP 0x4B67 /* put unicode-to-font mapping in kernel */ #define PIO_UNIMAPCLR 0x4B68 /* clear table, possibly advise hash algorithm */ struct unimapinit { - u_short advised_hashsize; /* 0 if no opinion */ - u_short advised_hashstep; /* 0 if no opinion */ - u_short advised_hashlevel; /* 0 if no opinion */ + unsigned short advised_hashsize; /* 0 if no opinion */ + unsigned short advised_hashstep; /* 0 if no opinion */ + unsigned short advised_hashlevel; /* 0 if no opinion */ }; +#define UNI_DIRECT_BASE 0xF000 /* start of Direct Font Region */ +#define UNI_DIRECT_MASK 0x01FF /* Direct Font Region bitmask */ + #define K_RAW 0x00 #define K_XLATE 0x01 #define K_MEDIUMRAW 0x02 @@ -77,9 +95,9 @@ struct unimapinit { #define KDSKBLED 0x4B65 /* set led flags (not lights) */ struct kbentry { - u_char kb_table; - u_char kb_index; - u_short kb_value; + unsigned char kb_table; + unsigned char kb_index; + unsigned short kb_value; }; #define K_NORMTAB 0x00 #define K_SHIFTTAB 0x01 @@ -90,14 +108,14 @@ struct kbentry { #define KDSKBENT 0x4B47 /* sets one entry in translation table */ struct kbsentry { - u_char kb_func; - u_char kb_string[512]; + unsigned char kb_func; + unsigned char kb_string[512]; }; #define KDGKBSENT 0x4B48 /* gets one function key string entry */ #define KDSKBSENT 0x4B49 /* sets one function key string entry */ struct kbdiacr { - u_char diacr, base, result; + unsigned char diacr, base, result; }; struct kbdiacrs { unsigned int kb_cnt; /* number of entries in following array */ @@ -116,6 +134,6 @@ struct kbkeycode { /* note: 0x4B00-0x4B4E all have had a value at some time; don't reuse for the time being */ -/* note: 0x4B60-0x4B68 used above */ +/* note: 0x4B60-0x4B6D, 0x4B70, 0x4B71 used above */ #endif /* _LINUX_KD_H */ diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h new file mode 100644 index 000000000..a06cdb9ed --- /dev/null +++ b/include/linux/kdev_t.h @@ -0,0 +1,114 @@ +#ifndef _LINUX_KDEV_T_H +#define _LINUX_KDEV_T_H +#ifdef __KERNEL__ +/* +As a preparation for the introduction of larger device numbers, +we introduce a type kdev_t to hold them. No information about +this type is known outside of this include file. + +Objects of type kdev_t designate a device. Outside of the kernel +the corresponding things are objects of type dev_t - usually an +integral type with the device major and minor in the high and low +bits, respectively. Conversion is done by + +extern kdev_t to_kdev_t(int); + +It is up to the various file systems to decide how objects of type +dev_t are stored on disk. +The only other point of contact between kernel and outside world +are the system calls stat and mknod, new versions of which will +eventually have to be used in libc. + +[Unfortunately, the floppy control ioctls fail to hide the internal +kernel structures, and the fd_device field of a struct floppy_drive_struct +is user-visible. So, it remains a dev_t for the moment, with some ugly +conversions in floppy.c.] + +Inside the kernel, we aim for a kdev_t type that is a pointer +to a structure with information about the device (like major, +minor, size, blocksize, sectorsize, name, read-only flag, +struct file_operations etc.). + +However, for the time being we let kdev_t be almost the same as dev_t: + +typedef struct { unsigned short major, minor; } kdev_t; + +Admissible operations on an object of type kdev_t: +- passing it along +- comparing it for equality with another such object +- storing it in ROOT_DEV, inode->i_dev, inode->i_rdev, sb->s_dev, + bh->b_dev, req->rq_dev, de->dc_dev, tty->device +- using its bit pattern as argument in a hash function +- finding its major and minor +- complaining about it + +An object of type kdev_t is created only by the function MKDEV(), +with the single exception of the constant 0 (no device). + +Right now the other information mentioned above is usually found +in static arrays indexed by major or major,minor. + +An obstacle to immediately using + typedef struct { ... (* lots of information *) } *kdev_t +is the case of mknod used to create a block device that the +kernel doesn't know about at present (but first learns about +when some module is inserted). + +aeb - 950811 +*/ + +/* Since MINOR(dev) is used as index in static arrays, + the kernel is not quite ready yet for larger minors. + However, everything runs fine with an arbitrary kdev_t type. */ + +#define MINORBITS 8 +#define MINORMASK ((1U << MINORBITS) - 1) + +typedef unsigned short kdev_t; + +#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) +#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) +#define HASHDEV(dev) ((unsigned int) (dev)) +#define NODEV 0 +#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi)) +#define B_FREE 0xffff /* yuk */ + +extern char * kdevname(kdev_t); /* note: returns pointer to static data! */ + +/* +As long as device numbers in the outside world have 16 bits only, +we use these conversions. +*/ + +static inline unsigned int kdev_t_to_nr(kdev_t dev) { + return (MAJOR(dev)<<8) | MINOR(dev); +} + +static inline kdev_t to_kdev_t(int dev) +{ + int major, minor; +#if 0 + major = (dev >> 16); + if (!major) { + major = (dev >> 8); + minor = (dev & 0xff); + } else + minor = (dev & 0xffff); +#else + major = (dev >> 8); + minor = (dev & 0xff); +#endif + return MKDEV(major, minor); +} + +#else /* __KERNEL__ */ + +/* +Some programs want their definitions of MAJOR and MINOR and MKDEV +from the kernel sources. These must be the externally visible ones. +*/ +#define MAJOR(dev) ((dev)>>8) +#define MINOR(dev) ((dev) & 0xff) +#define MKDEV(ma,mi) ((ma)<<8 | (mi)) +#endif /* __KERNEL__ */ +#endif diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 26dd68ef4..51b319891 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -10,6 +10,9 @@ #include <stdarg.h> #include <linux/linkage.h> +/* Optimization barrier */ +#define barrier() __asm__("": : :"memory") + #define INT_MAX ((int)(~0U>>1)) #define UINT_MAX (~0U) #define LONG_MAX ((long)(~0UL>>1)) @@ -26,15 +29,9 @@ #define KERN_INFO "<6>" /* informational */ #define KERN_DEBUG "<7>" /* debug-level messages */ -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -# define NORET_TYPE __volatile__ -# define ATTRIB_NORET /**/ -# define NORET_AND /**/ -#else # define NORET_TYPE /**/ # define ATTRIB_NORET __attribute__((noreturn)) # define NORET_AND noreturn, -#endif extern void math_error(void); NORET_TYPE void panic(const char * fmt, ...) @@ -54,17 +51,21 @@ extern int kill_sl(int sess, int sig, int priv); asmlinkage int printk(const char * fmt, ...) __attribute__ ((format (printf, 1, 2))); +#if DEBUG +#define pr_debug(fmt,arg...) \ + printk(KERN_DEBUG fmt,##arg) +#else +#define pr_debug(fmt,arg...) \ + do { } while (0) +#endif + +#define pr_info(fmt,arg...) \ + printk(KERN_INFO fmt,##arg) + /* - * This is defined as a macro, but at some point this might become a - * real subroutine that sets a flag if it returns true (to do - * BSD-style accounting where the process is flagged if it uses root - * privs). The implication of this is that you should do normal - * permissions checks first, and check suser() last. - * * "suser()" checks against the effective user id, while "fsuser()" * is used for file permission checking and checks against the fsuid.. */ -#define suser() (current->euid == 0) #define fsuser() (current->fsuid == 0) #endif /* __KERNEL__ */ diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 4d3f3e941..1966490a7 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -1,6 +1,8 @@ #ifndef _LINUX_KERNEL_STAT_H #define _LINUX_KERNEL_STAT_H +#include <asm/irq.h> + /* * 'kernel_stat.h' contains the definitions needed for doing * some kernel statistics (cpu usage, context switches ...), @@ -12,9 +14,13 @@ struct kernel_stat { unsigned int cpu_user, cpu_nice, cpu_system; unsigned int dk_drive[DK_NDRIVE]; + unsigned int dk_drive_rio[DK_NDRIVE]; + unsigned int dk_drive_wio[DK_NDRIVE]; + unsigned int dk_drive_rblk[DK_NDRIVE]; + unsigned int dk_drive_wblk[DK_NDRIVE]; unsigned int pgpgin, pgpgout; unsigned int pswpin, pswpout; - unsigned int interrupts[16]; + unsigned int interrupts[NR_IRQS]; unsigned int ipackets, opackets; unsigned int ierrors, oerrors; unsigned int collisions; diff --git a/include/linux/kerneld.h b/include/linux/kerneld.h new file mode 100644 index 000000000..5418b60d5 --- /dev/null +++ b/include/linux/kerneld.h @@ -0,0 +1,131 @@ +#ifndef _LINUX_KERNELD_H +#define _LINUX_KERNELD_H + +#define KERNELD_SYSTEM 1 +#define KERNELD_REQUEST_MODULE 2 /* "insmod" */ +#define KERNELD_RELEASE_MODULE 3 /* "rmmod" */ +#define KERNELD_DELAYED_RELEASE_MODULE 4 /* "rmmod" */ +#define KERNELD_CANCEL_RELEASE_MODULE 5 /* "rmmod" */ +#define KERNELD_REQUEST_ROUTE 6 /* from net/ipv4/route.c */ +#define KERNELD_BLANKER 7 /* from drivers/char/console.c */ +#define KERNELD_ARP 256 /* from net/ipv4/arp.c */ + +/* + * Uncomment the following line for the new kerneld protocol + * This includes the pid of the kernel level requester into the kerneld header + */ +/* +#define NEW_KERNELD_PROTOCOL + */ +#ifdef NEW_KERNELD_PROTOCOL +#define OLDIPC_KERNELD 00040000 /* use the kerneld message channel */ +#define IPC_KERNELD 00140000 /* use the kerneld message channel, new protocol */ +#define KDHDR (sizeof(long) + sizeof(short) + sizeof(short)) +#define NULL_KDHDR 0, 2, 0 +#else +#define IPC_KERNELD 00040000 /* use the kerneld message channel */ +#define KDHDR (sizeof(long)) +#define NULL_KDHDR 0 +#endif +#define KERNELD_MAXCMD 0x7ffeffff +#define KERNELD_MINSEQ 0x7fff0000 /* "commands" legal up to 0x7ffeffff */ +#define KERNELD_WAIT 0x80000000 +#define KERNELD_NOWAIT 0 + +struct kerneld_msg { + long mtype; + long id; +#ifdef NEW_KERNELD_PROTOCOL + short version; + short pid; +#endif +#ifdef __KERNEL__ + char *text; +#else + char text[1]; +#endif /* __KERNEL__ */ +}; + +#ifdef __KERNEL__ +extern int kerneld_send(int msgtype, int ret_size, int msgsz, + const char *text, const char *ret_val); + +/* + * Request that a module should be loaded. + * Wait for the exit status from insmod/modprobe. + * If it fails, it fails... at least we tried... + */ +static inline int request_module(const char *name) +{ + return kerneld_send(KERNELD_REQUEST_MODULE, + 0 | KERNELD_WAIT, + strlen(name), name, NULL); +} + +/* + * Request the removal of a module, maybe don't wait for it. + * It doesn't matter if the removal fails, now does it? + */ +static inline int release_module(const char *name, int waitflag) +{ + return kerneld_send(KERNELD_RELEASE_MODULE, + 0 | (waitflag?KERNELD_WAIT:KERNELD_NOWAIT), + strlen(name), name, NULL); +} + +/* + * Request a delayed removal of a module, but don't wait for it. + * The delay is done by kerneld (default: 60 seconds) + */ +static inline int delayed_release_module(const char *name) +{ + return kerneld_send(KERNELD_DELAYED_RELEASE_MODULE, + 0 | KERNELD_NOWAIT, + strlen(name), name, NULL); +} + +/* + * Attempt to cancel a previous request for removal of a module, + * but don't wait for it. + * This call can be made if the kernel wants to prevent a delayed + * unloading of a module. + */ +static inline int cancel_release_module(const char *name) +{ + return kerneld_send(KERNELD_CANCEL_RELEASE_MODULE, + 0 | KERNELD_NOWAIT, + strlen(name), name, NULL); +} + +/* + * Perform an "inverted" system call, maybe return the exit status + */ +static inline int ksystem(const char *cmd, int waitflag) +{ + return kerneld_send(KERNELD_SYSTEM, + 0 | (waitflag?KERNELD_WAIT:KERNELD_NOWAIT), + strlen(cmd), cmd, NULL); +} + +/* + * Try to create a route, possibly by opening a ppp-connection + */ +static inline int kerneld_route(const char *ip_route) +{ + return kerneld_send(KERNELD_REQUEST_ROUTE, + 0 | KERNELD_WAIT, + strlen(ip_route), ip_route, NULL); +} + +/* + * Handle an external screen blanker + */ +static inline int kerneld_blanker(int on_off) /* 0 => "off", else "on" */ +{ + return kerneld_send(KERNELD_BLANKER, + 0 | (on_off?KERNELD_NOWAIT:KERNELD_WAIT), + strlen(on_off?"on":"off"), on_off?"on":"off", NULL); +} + +#endif /* __KERNEL__ */ +#endif diff --git a/include/linux/keyboard.h b/include/linux/keyboard.h index d9f671f98..57a5323e1 100644 --- a/include/linux/keyboard.h +++ b/include/linux/keyboard.h @@ -38,6 +38,7 @@ extern unsigned short plain_map[NR_KEYS]; #define KT_META 8 #define KT_ASCII 9 #define KT_LOCK 10 +#define KT_SLOCK 12 #define K(t,v) (((t)<<8)|(v)) #define KTYP(x) ((x) >> 8) @@ -351,8 +352,9 @@ extern unsigned short plain_map[NR_KEYS]; #define K_DCIRCM K(KT_DEAD,2) #define K_DTILDE K(KT_DEAD,3) #define K_DDIERE K(KT_DEAD,4) +#define K_DCEDIL K(KT_DEAD,5) -#define NR_DEAD 5 +#define NR_DEAD 6 #define K_DOWN K(KT_CUR,0) #define K_LEFT K(KT_CUR,1) @@ -407,6 +409,15 @@ extern unsigned short plain_map[NR_KEYS]; #define K_CTRLLLOCK K(KT_LOCK,KG_CTRLL) #define K_CTRLRLOCK K(KT_LOCK,KG_CTRLR) +#define K_SHIFT_SLOCK K(KT_SLOCK,KG_SHIFT) +#define K_CTRL_SLOCK K(KT_SLOCK,KG_CTRL) +#define K_ALT_SLOCK K(KT_SLOCK,KG_ALT) +#define K_ALTGR_SLOCK K(KT_SLOCK,KG_ALTGR) +#define K_SHIFTL_SLOCK K(KT_SLOCK,KG_SHIFTL) +#define K_SHIFTR_SLOCK K(KT_SLOCK,KG_SHIFTR) +#define K_CTRLL_SLOCK K(KT_SLOCK,KG_CTRLL) +#define K_CTRLR_SLOCK K(KT_SLOCK,KG_CTRLR) + #define NR_LOCK 8 #define MAX_DIACR 256 diff --git a/include/linux/limits.h b/include/linux/limits.h index d0f300c4f..14428592c 100644 --- a/include/linux/limits.h +++ b/include/linux/limits.h @@ -11,7 +11,7 @@ #define MAX_CANON 255 /* size of the canonical input queue */ #define MAX_INPUT 255 /* size of the type-ahead buffer */ #define NAME_MAX 255 /* # chars in a file name */ -#define PATH_MAX 1024 /* # chars in a path name */ +#define PATH_MAX 4095 /* # chars in a path name */ #define PIPE_BUF 4096 /* # bytes in atomic write to a pipe */ #endif diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 8f5c4d5f2..c8a7a491a 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -7,4 +7,53 @@ #define asmlinkage #endif +#ifdef __ELF__ +#define SYMBOL_NAME_STR(X) #X +#define SYMBOL_NAME(X) X +#ifdef __STDC__ +#define SYMBOL_NAME_LABEL(X) X##: +#else +#define SYMBOL_NAME_LABEL(X) X/**/: +#endif +#else +#define SYMBOL_NAME_STR(X) "_"#X +#ifdef __STDC__ +#define SYMBOL_NAME(X) _##X +#define SYMBOL_NAME_LABEL(X) _##X##: +#else +#define SYMBOL_NAME(X) _/**/X +#define SYMBOL_NAME_LABEL(X) _/**/X/**/: +#endif +#endif + +#if !defined(__i486__) && !defined(__i586__) +#ifdef __ELF__ +#define __ALIGN .align 4,0x90 +#define __ALIGN_STR ".align 4,0x90" +#else /* __ELF__ */ +#define __ALIGN .align 2,0x90 +#define __ALIGN_STR ".align 2,0x90" +#endif /* __ELF__ */ +#else /* __i486__/__i586__ */ +#ifdef __ELF__ +#define __ALIGN .align 16,0x90 +#define __ALIGN_STR ".align 16,0x90" +#else /* __ELF__ */ +#define __ALIGN .align 4,0x90 +#define __ALIGN_STR ".align 4,0x90" +#endif /* __ELF__ */ +#endif /* __i486__/__i586__ */ + +#ifdef __ASSEMBLY__ + +#define ALIGN __ALIGN +#define ALIGN_STRING __ALIGN_STRING + +#define ENTRY(name) \ + .globl SYMBOL_NAME(name); \ + ALIGN; \ + SYMBOL_NAME_LABEL(name) + +#endif + #endif diff --git a/include/linux/lists.h b/include/linux/lists.h new file mode 100644 index 000000000..04f905aaf --- /dev/null +++ b/include/linux/lists.h @@ -0,0 +1,40 @@ +/* + * lists.h: Simple list macros for Linux + */ + +#define DLNODE(ptype) \ + struct { \ + ptype * dl_prev; \ + ptype * dl_next; \ + } + +#define DNODE_SINGLE(node) {(node),(node)} +#define DNODE_NULL {0,0} + +#define DLIST_INIT(listnam) \ + (listnam).dl_prev = &(listnam); \ + (listnam).dl_last = &(listnam); + +#define DLIST_NEXT(listnam) listnam.dl_next +#define DLIST_PREV(listnam) listnam.dl_prev + +#define DLIST_INSERT_AFTER(node, new, listnam) do { \ + (new)->listnam.dl_prev = (node); \ + (new)->listnam.dl_next = (node)->listnam.dl_next; \ + (node)->listnam.dl_next->listnam.dl_prev = (new); \ + (node)->listnam.dl_next = (new); \ + } while (0) + +#define DLIST_INSERT_BEFORE(node, new, listnam) do { \ + (new)->listnam.dl_next = (node); \ + (new)->listnam.dl_prev = (node)->listnam.dl_prev; \ + (node)->listnam.dl_prev->listnam.dl_next = (new); \ + (node)->listnam.dl_prev = (new); \ + } while (0) + +#define DLIST_DELETE(node, listnam) do { \ + node->listnam.dl_prev->listnam.dl_next = \ + node->listnam.dl_next; \ + node->listnam.dl_next->listnam.dl_prev = \ + node->listnam.dl_prev; \ + } while (0) diff --git a/include/linux/locks.h b/include/linux/locks.h index ac9b29076..9735bc630 100644 --- a/include/linux/locks.h +++ b/include/linux/locks.h @@ -1,6 +1,19 @@ #ifndef _LINUX_LOCKS_H #define _LINUX_LOCKS_H +#ifndef _LINUX_MM_H +#include <linux/mm.h> +#endif +#ifndef _LINUX_PAGEMAP_H +#include <linux/pagemap.h> +#endif + +/* + * Unlocked, temporary IO buffer_heads gets moved to the reuse_list + * once their page becomes unlocked. + */ +extern struct buffer_head *reuse_list; + /* * Buffer cache locking - note that interrupts may only unlock, not * lock buffers. @@ -9,22 +22,18 @@ extern void __wait_on_buffer(struct buffer_head *); extern inline void wait_on_buffer(struct buffer_head * bh) { - if (bh->b_lock) + if (test_bit(BH_Lock, &bh->b_state)) __wait_on_buffer(bh); } extern inline void lock_buffer(struct buffer_head * bh) { - if (bh->b_lock) + while (set_bit(BH_Lock, &bh->b_state)) __wait_on_buffer(bh); - bh->b_lock = 1; } -extern inline void unlock_buffer(struct buffer_head * bh) -{ - bh->b_lock = 0; - wake_up(&bh->b_wait); -} +void unlock_buffer(struct buffer_head *); + /* * super-block locking. Again, interrupts may only unlock diff --git a/include/linux/loop.h b/include/linux/loop.h new file mode 100644 index 000000000..be2c1753b --- /dev/null +++ b/include/linux/loop.h @@ -0,0 +1,86 @@ +#ifndef _LINUX_LOOP_H +#define _LINUX_LOOP_H + +/* + * include/linux/loop.h + * + * Written by Theodore Ts'o, 3/29/93. + * + * Copyright 1993 by Theodore Ts'o. Redistribution of this file is + * permitted under the GNU Public License. + */ + +#define LO_NAME_SIZE 64 +#define LO_KEY_SIZE 32 + +#ifdef __KERNEL__ + +struct loop_device { + int lo_number; + struct inode *lo_inode; + int lo_refcnt; + kdev_t lo_device; + int lo_offset; + int lo_encrypt_type; + int lo_encrypt_key_size; + int lo_flags; + int (*transfer)(struct loop_device *, int cmd, + char *raw_buf, char *loop_buf, int size); + char lo_name[LO_NAME_SIZE]; + char lo_encrypt_key[LO_KEY_SIZE]; +#ifdef DES_AVAILABLE + des_key_schedule lo_des_key; + unsigned long lo_des_init[2]; +#endif +#ifdef IDEA_AVAILABLE + idea_key lo_idea_en_key; + idea_key lo_idea_de_key; +#endif +}; + +typedef int (* transfer_proc_t)(struct loop_device *, int cmd, + char *raw_buf, char *loop_buf, int size); + +/* + * Loop flags + */ +#define LO_FLAGS_DO_BMAP 0x00000001 +#define LO_FLAGS_READ_ONLY 0x00000002 + +#endif /* __KERNEL__ */ + +struct loop_info { + int lo_number; /* ioctl r/o */ + dev_t lo_device; /* ioctl r/o */ + unsigned long lo_inode; /* ioctl r/o */ + dev_t lo_rdevice; /* ioctl r/o */ + int lo_offset; + int lo_encrypt_type; + int lo_encrypt_key_size; /* ioctl w/o */ + int lo_flags; /* ioctl r/o */ + char lo_name[LO_NAME_SIZE]; + unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ + unsigned long lo_init[2]; + char reserved[4]; +}; + +/* + * Loop encryption types --- LO_CRYPT_IDEA isn't supported yet + */ + +#define LO_CRYPT_NONE 0 +#define LO_CRYPT_XOR 1 +#define LO_CRYPT_DES 2 +#define LO_CRYPT_IDEA 3 +#define MAX_LO_CRYPT 4 + +/* + * IOCTL commands --- we will commandeer 0x4C ('L') + */ + +#define LOOP_SET_FD 0x4C00 +#define LOOP_CLR_FD 0x4C01 +#define LOOP_SET_STATUS 0x4C02 +#define LOOP_GET_STATUS 0x4C03 + +#endif diff --git a/include/linux/lp.h b/include/linux/lp.h index 1d3caa28f..6d488f64a 100644 --- a/include/linux/lp.h +++ b/include/linux/lp.h @@ -68,6 +68,8 @@ FALSE to ignore error. Default is ignore. */ #define LPGETSTATUS 0x060b /* return LP_S(minor) */ #define LPRESET 0x060c /* reset printer */ +#define LPGETSTATS 0x060d /* get statistics (struct lp_stats) */ +#define LPGETFLAGS 0x060e /* get status flags */ /* timeout for printk'ing a timeout, in jiffies (100ths of a second). This is also used for re-checking error conditions if LP_ABORT is @@ -85,9 +87,19 @@ #define LP_WAIT(minor) lp_table[(minor)].wait /* strobe wait */ #define LP_IRQ(minor) lp_table[(minor)].irq /* interrupt # */ /* 0 means polled */ +#define LP_STAT(minor) lp_table[(minor)].stats /* statistics area */ #define LP_BUFFER_SIZE 256 +struct lp_stats { + unsigned long chars; + unsigned long sleeps; + unsigned int maxrun; + unsigned int maxwait; + unsigned int meanwait; + unsigned int mdev; +}; + struct lp_struct { unsigned int base; unsigned int irq; @@ -97,6 +109,10 @@ struct lp_struct { unsigned int wait; struct wait_queue *lp_wait_q; char *lp_buffer; + unsigned int lastcall; + unsigned int runchars; + unsigned int waittime; + struct lp_stats stats; }; /* @@ -123,11 +139,11 @@ struct lp_struct { * base + 2 * accessed with LP_C(minor) */ -#define LP_PINTEN 0x10 +#define LP_PINTEN 0x10 /* high to read data in or-ed with data out */ #define LP_PSELECP 0x08 /* inverted output, active low */ #define LP_PINITP 0x04 /* unchanged output, active low */ #define LP_PAUTOLF 0x02 /* inverted output, active low */ -#define LP_PSTROBE 0x01 /* inverted output, active low */ +#define LP_PSTROBE 0x01 /* short high output on raising edge */ /* * the value written to ports to test existence. PC-style ports will @@ -137,15 +153,15 @@ struct lp_struct { #define LP_DUMMY 0x00 /* - * This is the port delay time. Your mileage may vary. - * It is used only in the lp_init() routine. + * This is the port delay time, in microseconds. + * It is used only in the lp_init() and lp_reset() routine. */ -#define LP_DELAY 150000 +#define LP_DELAY 50 /* * function prototypes */ -extern long lp_init(long); +extern int lp_init(void); #endif diff --git a/include/linux/lp_intern.h b/include/linux/lp_intern.h new file mode 100644 index 000000000..b6601c0b3 --- /dev/null +++ b/include/linux/lp_intern.h @@ -0,0 +1,22 @@ +#ifndef _LINUX_LP_INTERN_H_ +#define _LINUX_LP_INTERN_H_ + +/* + * split in two parts by Joerg Dorchain + * usr/include/linux/lp.h modified for Amiga by Michael Rausch + * modified for Atari by Andreas Schwab + * bug fixed by Jes Sorensen 18/8-94: + * It was not possible to compile the kernel only for Atari or Amiga. + * + * linux i386 version c.1991-1992 James Wiegand + * many modifications copyright (C) 1992 Michael K. Johnson + * Interrupt support added 1993 Nigel Gamble + */ + +#include <linux/types.h> +#include <linux/lp_m68k.h> + +int lp_internal_init(struct lp_struct *, int, int, int); + +#endif + diff --git a/include/linux/lp_m68k.h b/include/linux/lp_m68k.h new file mode 100644 index 000000000..26d078110 --- /dev/null +++ b/include/linux/lp_m68k.h @@ -0,0 +1,109 @@ +#ifndef _LINUX_LP_H +#define _LINUX_LP_H + +/* + * split in two parts by Joerg Dorchain + * usr/include/linux/lp.h modified for Amiga by Michael Rausch + * modified for Atari by Andreas Schwab + * bug fixed by Jes Sorensen 18/8-94: + * It was not possible to compile the kernel only for Atari or Amiga. + * + * linux i386 version c.1991-1992 James Wiegand + * many modifications copyright (C) 1992 Michael K. Johnson + * Interrupt support added 1993 Nigel Gamble + */ + +#include <linux/autoconf.h> +#include <asm/bootinfo.h> + +/* + * Per POSIX guidelines, this module reserves the LP and lp prefixes + * These are the lp_table[minor].flags flags... + */ +#define LP_EXIST 0x0001 +#define LP_BUSY 0x0004 +#define LP_ABORT 0x0040 +#define LP_CAREFUL 0x0080 +#define LP_ABORTOPEN 0x0100 + +/* timeout for each character. This is relative to bus cycles -- it + * is the count in a busy loop. THIS IS THE VALUE TO CHANGE if you + * have extremely slow printing, or if the machine seems to slow down + * a lot when you print. If you have slow printing, increase this + * number and recompile, and if your system gets bogged down, decrease + * this number. This can be changed with the tunelp(8) command as well. + */ + +#define LP_INIT_CHAR 1000 + +/* The parallel port specs apparently say that there needs to be + * a .5usec wait before and after the strobe. Since there are wildly + * different computers running linux, I can't come up with a perfect + * value, but since it worked well on most printers before without, + * I'll initialize it to 0. + */ + +#define LP_INIT_WAIT 0 + +/* This is the amount of time that the driver waits for the printer to + * catch up when the printer's buffer appears to be filled. If you + * want to tune this and have a fast printer (i.e. HPIIIP), decrease + * this number, and if you have a slow printer, increase this number. + * This is in hundredths of a second, the default 2 being .05 second. + * Or use the tunelp(8) command, which is especially nice if you want + * change back and forth between character and graphics printing, which + * are wildly different... + */ + +#define LP_INIT_TIME 40 + +/* IOCTL numbers */ +#define LPCHAR 0x0601 /* corresponds to LP_INIT_CHAR */ +#define LPTIME 0x0602 /* corresponds to LP_INIT_TIME */ +#define LPABORT 0x0604 /* call with TRUE arg to abort on error, + FALSE to retry. Default is retry. */ +#define LPSETIRQ 0x0605 /* call with new IRQ number, + or 0 for polling (no IRQ) */ +#define LPGETIRQ 0x0606 /* get the current IRQ number */ +#define LPWAIT 0x0608 /* corresponds to LP_INIT_WAIT */ +#define LPCAREFUL 0x0609 /* call with TRUE arg to require out-of-paper, off- + line, and error indicators good on all writes, + FALSE to ignore them. Default is ignore. */ +#define LPABORTOPEN 0x060a /* call with TRUE arg to abort open() on error, + FALSE to ignore error. Default is ignore. */ +#define LPGETSTATUS 0x060b /* return LP_S(minor) */ +#define LPRESET 0x060c /* reset printer */ + +/* timeout for printk'ing a timeout, in jiffies (100ths of a second). + This is also used for re-checking error conditions if LP_ABORT is + not set. This is the default behavior. */ + +#define LP_TIMEOUT_INTERRUPT (60 * HZ) +#define LP_TIMEOUT_POLLED (10 * HZ) + + +#define LP_BUFFER_SIZE 1024 /*256*/ + +struct lp_struct { + char *name; + unsigned int irq; + void (*lp_out)(int,int); /*output char function*/ + int (*lp_is_busy)(int); + int (*lp_has_pout)(int); + int (*lp_is_online)(int); + int (*lp_my_interrupt)(int); + int flags; /*for BUSY... */ + unsigned int chars; /*busy timeout */ + unsigned int time; /*wait time */ + unsigned int wait; + struct wait_queue *lp_wait_q; /*strobe wait */ + char lp_buffer[LP_BUFFER_SIZE]; + int do_print; + unsigned long copy_size,bytes_written; +}; + +extern struct lp_struct lp_table[]; + +extern int lp_init(void); + +#endif diff --git a/include/linux/major.h b/include/linux/major.h index 68edd3614..396b33a02 100644 --- a/include/linux/major.h +++ b/include/linux/major.h @@ -2,98 +2,84 @@ #define _LINUX_MAJOR_H /* - * This file has definitions for major device numbers + * This file has definitions for major device numbers. + * For the device number assignments, see Documentation/devices.txt. */ /* limits */ -#define MAX_CHRDEV 64 -#define MAX_BLKDEV 64 - -/* - * assignments - * - * devices are as follows (same as minix, so we can use the minix fs): - * - * character block comments - * -------------------- -------------------- -------------------- - * 0 - unnamed unnamed minor 0 = true nodev - * 1 - /dev/mem ramdisk - * 2 - floppy - * 3 - hd - * 4 - /dev/tty* - * 5 - /dev/tty; /dev/cua* - * 6 - lp - * 7 - /dev/vcs* - * 8 - scsi disk - * 9 - scsi tape - * 10 - mice - * 11 - scsi cdrom - * 12 - qic02 tape - * 13 - xt disk - * 14 - sound card - * 15 - cdu31a cdrom - * 16 - sockets - * 17 - af_unix - * 18 - af_inet - * 19 - cyclades /dev/ttyC* - * 20 - cyclades /dev/cub* - * 21 - scsi generic - * 22 - (at2disk) - * 23 - mitsumi cdrom - * 24 - sony535 cdrom - * 25 - matsushita cdrom minors 0..3 - * 26 - matsushita cdrom 2 minors 0..3 - * 27 - qic117 tape matsushita cdrom 3 minors 0..3 - * 28 - matsushita cdrom 4 minors 0..3 - * 29 - aztech/orchid/okano/wearnes cdrom - */ +#define MAX_CHRDEV 128 +#define MAX_BLKDEV 128 #define UNNAMED_MAJOR 0 #define MEM_MAJOR 1 +#define RAMDISK_MAJOR 1 #define FLOPPY_MAJOR 2 +#define PTY_MASTER_MAJOR 2 #define IDE0_MAJOR 3 +#define PTY_SLAVE_MAJOR 3 #define HD_MAJOR IDE0_MAJOR #define TTY_MAJOR 4 #define TTYAUX_MAJOR 5 #define LP_MAJOR 6 #define VCS_MAJOR 7 +#define LOOP_MAJOR 7 #define SCSI_DISK_MAJOR 8 #define SCSI_TAPE_MAJOR 9 -#define MOUSE_MAJOR 10 +#define MD_MAJOR 9 +#define MISC_MAJOR 10 #define SCSI_CDROM_MAJOR 11 #define QIC02_TAPE_MAJOR 12 #define XT_DISK_MAJOR 13 #define SOUND_MAJOR 14 #define CDU31A_CDROM_MAJOR 15 -#define SOCKET_MAJOR 16 -#define AF_UNIX_MAJOR 17 -#define AF_INET_MAJOR 18 +#define JOYSTICK_MAJOR 15 +#define GOLDSTAR_CDROM_MAJOR 16 +#define OPTICS_CDROM_MAJOR 17 +#define SANYO_CDROM_MAJOR 18 #define CYCLADES_MAJOR 19 #define CYCLADESAUX_MAJOR 20 +#define MITSUMI_X_CDROM_MAJOR 20 #define SCSI_GENERIC_MAJOR 21 +#define Z8530_MAJOR 34 +#define DIGI_MAJOR 23 #define IDE1_MAJOR 22 +#define DIGICU_MAJOR 22 #define MITSUMI_CDROM_MAJOR 23 #define CDU535_CDROM_MAJOR 24 +#define STL_SERIALMAJOR 24 #define MATSUSHITA_CDROM_MAJOR 25 +#define STL_CALLOUTMAJOR 25 #define MATSUSHITA_CDROM2_MAJOR 26 +#define QIC117_TAPE_MAJOR 27 #define MATSUSHITA_CDROM3_MAJOR 27 #define MATSUSHITA_CDROM4_MAJOR 28 -#define QIC117_TAPE_MAJOR 27 +#define STL_SIOMEMMAJOR 28 +#define ACSI_MAJOR 28 #define AZTECH_CDROM_MAJOR 29 +#define GRAPHDEV_MAJOR 29 /* SparcLinux & Linux/68k /dev/fb */ +#define CM206_CDROM_MAJOR 32 +#define IDE2_MAJOR 33 +#define IDE3_MAJOR 34 +#define NETLINK_MAJOR 36 +#define IDETAPE_MAJOR 37 +#define Z2RAM_MAJOR 37 +#define RISCOM8_NORMAL_MAJOR 48 +#define RISCOM8_CALLOUT_MAJOR 49 +#define MKISS_MAJOR 55 +#define APBLOCK_MAJOR 60 /* AP1000 Block device */ +#define DDV_MAJOR 61 /* AP1000 DDV block device */ /* * Tests for SCSI devices. */ -#define SCSI_MAJOR(M) \ +#define SCSI_BLK_MAJOR(M) \ ((M) == SCSI_DISK_MAJOR \ - || (M) == SCSI_TAPE_MAJOR \ - || (M) == SCSI_CDROM_MAJOR \ - || (M) == SCSI_GENERIC_MAJOR) + || (M) == SCSI_CDROM_MAJOR) -static inline int scsi_major(int m) { - return SCSI_MAJOR(m); +static __inline__ int scsi_blk_major(int m) { + return SCSI_BLK_MAJOR(m); } #endif diff --git a/include/linux/malloc.h b/include/linux/malloc.h index b0105150c..0ef085783 100644 --- a/include/linux/malloc.h +++ b/include/linux/malloc.h @@ -1,31 +1,11 @@ #ifndef _LINUX_MALLOC_H #define _LINUX_MALLOC_H -#include <linux/config.h> #include <linux/mm.h> -#ifdef CONFIG_DEBUG_MALLOC -#define kmalloc(a,b) deb_kmalloc(__FILE__,__LINE__,a,b) -#define kfree_s(a,b) deb_kfree_s(__FILE__,__LINE__,a,b) - -void *deb_kmalloc(const char *deb_file, unsigned short deb_line,unsigned int size, int priority); -void deb_kfree_s (const char *deb_file, unsigned short deb_line,void * obj, int size); -void deb_kcheck_s(const char *deb_file, unsigned short deb_line,void * obj, int size); - -#define kfree(a) deb_kfree_s(__FILE__,__LINE__, a,0) -#define kcheck(a) deb_kcheck_s(__FILE__,__LINE__, a,0) -#define kcheck_s(a,b) deb_kcheck_s(__FILE__,__LINE__, a,b) - -#else /* !debug */ - void * kmalloc(unsigned int size, int priority); -void kfree_s(void * obj, int size); - -#define kcheck_s(a,b) 0 - -#define kfree(x) kfree_s((x), 0) -#define kcheck(x) kcheck_s((x), 0) +void kfree(void * obj); -#endif +#define kfree_s(a,b) kfree(a) #endif /* _LINUX_MALLOC_H */ diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h index 5f22761fd..d942ccdc3 100644 --- a/include/linux/mc146818rtc.h +++ b/include/linux/mc146818rtc.h @@ -7,25 +7,10 @@ * in terms of the GNU Library General Public License, Version 2 or later, * at your option. */ - #ifndef _MC146818RTC_H #define _MC146818RTC_H -#include <asm/io.h> - -#ifndef RTC_PORT -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_ADDR(x) (0x80 | (x)) -#define RTC_ALWAYS_BCD 1 -#endif -#define CMOS_READ(addr) ({ \ -outb_p(RTC_ADDR(addr),RTC_PORT(0)); \ -inb_p(RTC_PORT(1)); \ -}) -#define CMOS_WRITE(val, addr) ({ \ -outb_p(RTC_ADDR(addr),RTC_PORT(0)); \ -outb_p(val,RTC_PORT(1)); \ -}) +#include <asm/mc146818rtc.h> /********************************************************************** * register summary @@ -107,4 +92,42 @@ outb_p(val,RTC_PORT(1)); \ #define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) #endif +/* + * The struct used to pass data via the following ioctl. Similar to the + * struct tm in <time.h>, but it needs to be here so that the kernel + * source is self contained, allowing cross-compiles, etc. etc. + */ + +struct rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +/* + * ioctl calls that are permitted to the /dev/rtc interface, if + * CONFIG_RTC was enabled. + */ + +#define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */ +#define RTC_AIE_OFF _IO('p', 0x02) /* ... off */ +#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */ +#define RTC_UIE_OFF _IO('p', 0x04) /* ... off */ +#define RTC_PIE_ON _IO('p', 0x05) /* Periodic int. enable on */ +#define RTC_PIE_OFF _IO('p', 0x06) /* ... off */ + +#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */ +#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */ +#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time) /* Read RTC time */ +#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time */ +#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */ +#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */ + + #endif /* _MC146818RTC_H */ diff --git a/include/linux/mcd.h b/include/linux/mcd.h index 975a3f840..b87d6bbe4 100644 --- a/include/linux/mcd.h +++ b/include/linux/mcd.h @@ -25,7 +25,11 @@ #define MCD_BASE_ADDR 0x300 /* *** change this to set the interrupt number */ -#define MCD_INTR_NR 10 +#define MCD_INTR_NR 11 + +/* *** make the following line uncommented, if you're sure, + * *** all configuration is done */ +/* #define I_WAS_HERE */ /* Increase this if you get lots of timeouts */ #define MCD_STATUS_DELAY 200 @@ -105,3 +109,8 @@ struct mcd_Toc { struct msf trackTime; struct msf diskTime; }; + +#ifndef I_WAS_HERE +#warning You have not edited mcd.h +#warning Perhaps irq and i/o settings are wrong. +#endif diff --git a/include/linux/mcdx.h b/include/linux/mcdx.h new file mode 100644 index 000000000..b1b431326 --- /dev/null +++ b/include/linux/mcdx.h @@ -0,0 +1,184 @@ +/* + * Definitions for the Mitsumi CDROM interface + * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de> + * VERSION: @VERSION@ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Thanks to + * The Linux Community at all and ... + * Martin Harris (he wrote the first Mitsumi Driver) + * Eberhard Moenkeberg (he gave me much support and the initial kick) + * Bernd Huebner, Ruediger Helsch (Unifix-Software Gmbh, they + * improved the original driver) + * Jon Tombs, Bjorn Ekwall (module support) + * Daniel v. Mosnenck (he sent me the Technical and Programming Reference) + * Gerd Knorr (he lent me his PhotoCD) + * Nils Faerber and Roger E. Wolff (extensively tested the LU portion) + * Andreas Kies (testing the mysterious hang up's) + * ... somebody forgotten? + * Marcin Dalecki + * + */ + +/* + * The following lines are for user configuration + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * {0|1} -- 1 if you want the driver detect your drive, may crash and + * needs a long time to seek. The higher the address the longer the + * seek. + * + * WARNING: AUTOPROBE doesn't work. + */ +#define MCDX_AUTOPROBE 0 + +/* + * Drive specific settings according to the jumpers on the controller + * board(s). + * o MCDX_NDRIVES : number of used entries of the following table + * o MCDX_DRIVEMAP : table of {i/o base, irq} per controller + * + * NOTE: I didn't get a drive at irq 9(2) working. Not even alone. + */ +#if MCDX_AUTOPROBE == 0 + #define MCDX_NDRIVES 1 + #define MCDX_DRIVEMAP { \ + {0x300, 11}, \ + {0x304, 05}, \ + {0x000, 00}, \ + {0x000, 00}, \ + {0x000, 00}, \ + } +#else + #error Autoprobing is not implemented yet. +#endif + +#ifndef MCDX_QUIET +#define MCDX_QUIET 1 +#endif + +#ifndef MCDX_DEBUG +#define MCDX_DEBUG 0 +#endif + +/* *** make the following line uncommented, if you're sure, + * *** all configuration is done */ +/* #define I_WAS_HERE */ +#define I_WAS_HERE /* delete this line, it's for heiko only */ + +/* The name of the device */ +#define MCDX "mcdx" + +/* Flags for DEBUGGING */ +#define INIT 0 +#define MALLOC 0 +#define IOCTL 0 +#define PLAYTRK 0 +#define SUBCHNL 0 +#define TOCHDR 0 +#define MS 0 +#define PLAYMSF 0 +#define READTOC 0 +#define OPENCLOSE 0 +#define HW 0 +#define TALK 0 +#define IRQ 0 +#define XFER 0 +#define REQUEST 0 +#define SLEEP 0 + +/* The following addresses are taken from the Mitsumi Reference + * and describe the possible i/o range for the controller. + */ +#define MCDX_IO_BEGIN ((char*) 0x300) /* first base of i/o addr */ +#define MCDX_IO_END ((char*) 0x3fc) /* last base of i/o addr */ + +/* Per controller 4 bytes i/o are needed. */ +#define MCDX_IO_SIZE 4 + +/* + * Bits + */ + +/* The status byte, returned from every command, set if + * the description is true */ +#define MCDX_RBIT_OPEN 0x80 /* door is open */ +#define MCDX_RBIT_DISKSET 0x40 /* disk set (recognised) */ +#define MCDX_RBIT_CHANGED 0x20 /* disk was changed */ +#define MCDX_RBIT_CHECK 0x10 /* disk rotates, servo is on */ +#define MCDX_RBIT_AUDIOTR 0x08 /* current track is audio */ +#define MCDX_RBIT_RDERR 0x04 /* read error, refer SENSE KEY */ +#define MCDX_RBIT_AUDIOBS 0x02 /* currently playing audio */ +#define MCDX_RBIT_CMDERR 0x01 /* command, param or format error */ + +/* The I/O Register holding the h/w status of the drive, + * can be read at i/o base + 1 */ +#define MCDX_RBIT_DOOR 0x10 /* door is open */ +#define MCDX_RBIT_STEN 0x04 /* if 0, i/o base contains drive status */ +#define MCDX_RBIT_DTEN 0x02 /* if 0, i/o base contains data */ + +/* + * The commands. + */ + +#define OPCODE 1 /* offset of opcode */ +#define MCDX_CMD_REQUEST_TOC 1, 0x10 +#define MCDX_CMD_REQUEST_STATUS 1, 0x40 +#define MCDX_CMD_RESET 1, 0x60 +#define MCDX_CMD_REQUEST_DRIVE_MODE 1, 0xc2 +#define MCDX_CMD_SET_INTERLEAVE 2, 0xc8, 0 +#define MCDX_CMD_DATAMODE_SET 2, 0xa0, 0 + #define MCDX_DATAMODE1 0x01 + #define MCDX_DATAMODE2 0x02 +#define MCDX_CMD_LOCK_DOOR 2, 0xfe, 0 + +#define READ_AHEAD 4 /* 8 Sectors (4K) */ + +/* Useful macros */ +#define e_door(x) ((x) & MCDX_RBIT_OPEN) +#define e_check(x) (~(x) & MCDX_RBIT_CHECK) +#define e_notset(x) (~(x) & MCDX_RBIT_DISKSET) +#define e_changed(x) ((x) & MCDX_RBIT_CHANGED) +#define e_audio(x) ((x) & MCDX_RBIT_AUDIOTR) +#define e_audiobusy(x) ((x) & MCDX_RBIT_AUDIOBS) +#define e_cmderr(x) ((x) & MCDX_RBIT_CMDERR) +#define e_readerr(x) ((x) & MCDX_RBIT_RDERR) + +/** no drive specific */ +#define MCDX_CDBLK 2048 /* 2048 cooked data each blk */ + +#define MCDX_DATA_TIMEOUT (HZ/10) /* 0.1 second */ + +/* + * Access to the msf array + */ +#define MSF_MIN 0 /* minute */ +#define MSF_SEC 1 /* second */ +#define MSF_FRM 2 /* frame */ + +/* + * Errors + */ +#define MCDX_E 1 /* unspec error */ +#define MCDX_ST_EOM 0x0100 /* end of media */ +#define MCDX_ST_DRV 0x00ff /* mask to query the drive status */ + +#ifndef I_WAS_HERE +#warning You have not edited mcdx.h +#warning Perhaps irq and i/o settings are wrong. +#endif + +/* ex:set ts=4 sw=4: */ diff --git a/include/linux/md.h b/include/linux/md.h new file mode 100644 index 000000000..2777a7191 --- /dev/null +++ b/include/linux/md.h @@ -0,0 +1,115 @@ + +/* + md.h : Multiple Devices driver for Linux + Copyright (C) 1994-96 Marc ZYNGIER + <zyngier@ufr-info-p7.ibp.fr> or + <maz@gloups.fdn.fr> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + You should have received a copy of the GNU General Public License + (for example /usr/src/linux/COPYING); if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _MD_H +#define _MD_H + +#include <linux/major.h> +#include <linux/mm.h> +#include <linux/ioctl.h> + +#define MD_VERSION "0.35" + +/* ioctls */ +#define REGISTER_DEV _IO (MD_MAJOR, 1) +#define START_MD _IO (MD_MAJOR, 2) +#define STOP_MD _IO (MD_MAJOR, 3) + +/* + personalities : + Byte 0 : Chunk size factor + Byte 1 : Fault tolerance count for each physical device + ( 0 means no fault tolerance, + 0xFF means always tolerate faults), not used by now. + Byte 2 : Personality + Byte 3 : Reserved. + */ + +#define FAULT_SHIFT 8 +#define PERSONALITY_SHIFT 16 + +#define FACTOR_MASK 0xFFUL +#define FAULT_MASK 0xFF00UL +#define PERSONALITY_MASK 0xFF0000UL + +#define MD_RESERVED 0 /* Not used by now */ +#define LINEAR (1UL << PERSONALITY_SHIFT) +#define STRIPED (2UL << PERSONALITY_SHIFT) +#define RAID0 STRIPED +#define RAID1 (3UL << PERSONALITY_SHIFT) +#define RAID5 (4UL << PERSONALITY_SHIFT) +#define MAX_PERSONALITY 5 + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/blkdev.h> + +#define MAX_REAL 8 /* Max number of physical dev per md dev */ +#define MAX_MD_DEV 4 /* Max number of md dev */ + +#define FACTOR(a) ((a)->repartition & FACTOR_MASK) +#define MAX_FAULT(a) (((a)->repartition & FAULT_MASK)>>8) +#define PERSONALITY(a) ((a)->repartition & PERSONALITY_MASK) + +#define FACTOR_SHIFT(a) (PAGE_SHIFT + (a) - 10) + +struct real_dev +{ + kdev_t dev; /* Device number */ + int size; /* Device size (in blocks) */ + int offset; /* Real device offset (in blocks) in md dev + (only used in linear mode) */ + struct inode *inode; /* Lock inode */ +}; + +struct md_dev; + +struct md_personality +{ + char *name; + int (*map)(struct md_dev *md_dev, kdev_t *rdev, + unsigned long *rsector, unsigned long size); + int (*run)(int minor, struct md_dev *md_dev); + int (*stop)(int minor, struct md_dev *md_dev); + int (*status)(char *page, int minor, struct md_dev *md_dev); + int (*ioctl)(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + int max_invalid_dev; +}; + +struct md_dev +{ + struct real_dev devices[MAX_REAL]; + struct md_personality *pers; + int repartition; + int busy; + int nb_dev; + void *private; +}; + +extern struct md_dev md_dev[MAX_MD_DEV]; +extern int md_size[MAX_MD_DEV]; + +extern char *partition_name (kdev_t dev); + +extern int register_md_personality (int p_num, struct md_personality *p); +extern int unregister_md_personality (int p_num); + +#endif __KERNEL__ +#endif _MD_H diff --git a/include/linux/minix_fs.h b/include/linux/minix_fs.h index 33fd9c1d9..3bc020fcd 100644 --- a/include/linux/minix_fs.h +++ b/include/linux/minix_fs.h @@ -8,8 +8,7 @@ /* * Thanks to Kees J Bot for sending me the definitions of the new * minix filesystem (aka V2) with bigger inodes and 32-bit block - * pointers. It's not actually implemented yet, but I'll look into - * it. + * pointers. */ #define MINIX_ROOT_INO 1 @@ -18,14 +17,21 @@ #define MINIX_LINK_MAX 250 #define MINIX_I_MAP_SLOTS 8 -#define MINIX_Z_MAP_SLOTS 8 +#define MINIX_Z_MAP_SLOTS 64 #define MINIX_SUPER_MAGIC 0x137F /* original minix fs */ #define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ -#define NEW_MINIX_SUPER_MAGIC 0x2468 /* minix V2 - not implemented */ +#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */ +#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */ #define MINIX_VALID_FS 0x0001 /* Clean fs. */ #define MINIX_ERROR_FS 0x0002 /* fs has errors. */ #define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode))) +#define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode))) + +#define MINIX_V1 0x0001 /* original minix fs */ +#define MINIX_V2 0x0002 /* minix V2 fs */ + +#define INODE_VERSION(inode) inode->i_sb->u.minix_sb.s_version /* * This is the original minix inode layout on disk. @@ -47,7 +53,7 @@ struct minix_inode { * instead of 7+1+1). Also, some previously 8-bit values are * now 16-bit. The inode is now 64 bytes instead of 32. */ -struct new_minix_inode { +struct minix2_inode { __u16 i_mode; __u16 i_nlinks; __u16 i_uid; @@ -72,6 +78,7 @@ struct minix_super_block { __u32 s_max_size; __u16 s_magic; __u16 s_state; + __u32 s_zones; }; struct minix_dir_entry { @@ -82,7 +89,7 @@ struct minix_dir_entry { #ifdef __KERNEL__ extern int minix_lookup(struct inode * dir,const char * name, int len, - struct inode ** result); + struct inode ** result); extern int minix_create(struct inode * dir,const char * name, int len, int mode, struct inode ** result); extern int minix_mkdir(struct inode * dir, const char * name, int len, int mode); @@ -93,7 +100,7 @@ extern int minix_symlink(struct inode * inode, const char * name, int len, extern int minix_link(struct inode * oldinode, struct inode * dir, const char * name, int len); extern int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rdev); extern int minix_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len); + struct inode * new_dir, const char * new_name, int new_len, int must_be_dir); extern struct inode * minix_new_inode(const struct inode * dir); extern void minix_free_inode(struct inode * inode); extern unsigned long minix_count_free_inodes(struct super_block *sb); @@ -109,6 +116,7 @@ extern struct buffer_head * minix_bread(struct inode *, int, int); extern void minix_truncate(struct inode *); extern void minix_put_super(struct super_block *); extern struct super_block *minix_read_super(struct super_block *,void *,int); +extern int init_minix_fs(void); extern void minix_write_super(struct super_block *); extern int minix_remount (struct super_block * sb, int * flags, char * data); extern void minix_read_inode(struct inode *); diff --git a/include/linux/minix_fs_i.h b/include/linux/minix_fs_i.h index c8677b4b9..c3711e522 100644 --- a/include/linux/minix_fs_i.h +++ b/include/linux/minix_fs_i.h @@ -5,7 +5,10 @@ * minix fs inode data in memory */ struct minix_inode_info { - __u16 i_data[16]; + union { + __u16 i1_data[16]; + __u32 i2_data[16]; + } u; }; #endif diff --git a/include/linux/minix_fs_sb.h b/include/linux/minix_fs_sb.h index a48347980..e77b4efc6 100644 --- a/include/linux/minix_fs_sb.h +++ b/include/linux/minix_fs_sb.h @@ -13,12 +13,13 @@ struct minix_sb_info { unsigned long s_log_zone_size; unsigned long s_max_size; struct buffer_head * s_imap[8]; - struct buffer_head * s_zmap[8]; + struct buffer_head * s_zmap[64]; unsigned long s_dirsize; unsigned long s_namelen; struct buffer_head * s_sbh; struct minix_super_block * s_ms; unsigned short s_mount_state; + unsigned short s_version; }; #endif diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h new file mode 100644 index 000000000..f8ea74922 --- /dev/null +++ b/include/linux/miscdevice.h @@ -0,0 +1,26 @@ +#ifndef _LINUX_MISCDEVICE_H +#define _LINUX_MISCDEVICE_H + +#define BUSMOUSE_MINOR 0 +#define PSMOUSE_MINOR 1 +#define MS_BUSMOUSE_MINOR 2 +#define ATIXL_BUSMOUSE_MINOR 3 +#define AMIGAMOUSE_MINOR 4 +#define ATARIMOUSE_MINOR 5 +#define SUN_MOUSE_MINOR 6 +#define MISC_DYNAMIC_MINOR 255 + +extern int misc_init(void); + +struct miscdevice +{ + int minor; + const char *name; + struct file_operations *fops; + struct miscdevice * next, * prev; +}; + +extern int misc_register(struct miscdevice * misc); +extern int misc_deregister(struct miscdevice * misc); + +#endif diff --git a/include/linux/mm.h b/include/linux/mm.h index c59651f38..149e6eaeb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -4,18 +4,16 @@ #include <linux/sched.h> #include <linux/errno.h> #include <linux/kernel.h> -#include <linux/string.h> - -extern unsigned long high_memory; - -#include <asm/page.h> #ifdef __KERNEL__ -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 +#include <linux/string.h> + +extern unsigned long max_mapnr; +extern void * high_memory; -extern int verify_area(int, const void *, unsigned long); +#include <asm/page.h> +#include <asm/atomic.h> /* * Linux kernel virtual memory manager primitives. @@ -33,7 +31,7 @@ extern int verify_area(int, const void *, unsigned long); * library, the executable area etc). */ struct vm_area_struct { - struct task_struct * vm_task; /* VM area parameters */ + struct mm_struct * vm_mm; /* VM area parameters */ unsigned long vm_start; unsigned long vm_end; pgprot_t vm_page_prot; @@ -71,10 +69,11 @@ struct vm_area_struct { #define VM_GROWSDOWN 0x0100 /* general info on the segment */ #define VM_GROWSUP 0x0200 -#define VM_SHM 0x0400 +#define VM_SHM 0x0400 /* shared memory area, don't swap out */ #define VM_DENYWRITE 0x0800 /* ETXTBSY on write attempts.. */ #define VM_EXECUTABLE 0x1000 +#define VM_LOCKED 0x2000 #define VM_STACK_FLAGS 0x0177 @@ -95,44 +94,136 @@ struct vm_operations_struct { void (*close)(struct vm_area_struct * area); void (*unmap)(struct vm_area_struct *area, unsigned long, size_t); void (*protect)(struct vm_area_struct *area, unsigned long, size_t, unsigned int newprot); - void (*sync)(struct vm_area_struct *area, unsigned long, size_t, unsigned int flags); + int (*sync)(struct vm_area_struct *area, unsigned long, size_t, unsigned int flags); void (*advise)(struct vm_area_struct *area, unsigned long, size_t, unsigned int advise); - unsigned long (*nopage)(struct vm_area_struct * area, unsigned long address, - unsigned long page, int write_access); + unsigned long (*nopage)(struct vm_area_struct * area, unsigned long address, int write_access); unsigned long (*wppage)(struct vm_area_struct * area, unsigned long address, unsigned long page); - void (*swapout)(struct vm_area_struct *, unsigned long, pte_t *); + int (*swapout)(struct vm_area_struct *, unsigned long, pte_t *); pte_t (*swapin)(struct vm_area_struct *, unsigned long, unsigned long); }; -extern mem_map_t * mem_map; - -/* planning stage.. */ -#define P_DIRTY 0x0001 -#define P_LOCKED 0x0002 -#define P_UPTODATE 0x0004 -#define P_RESERVED 0x8000 - -struct page_info { - unsigned short flags; - unsigned short count; - struct inode * inode; +/* + * Try to keep the most commonly accessed fields in single cache lines + * here (16 bytes or greater). This ordering should be particularly + * beneficial on 32-bit processors. + * + * The first line is data used in page cache lookup, the second line + * is used for linear searches (eg. clock algorithm scans). + */ +typedef struct page { + /* these must be first (free area handling) */ + struct page *next; + struct page *prev; + struct inode *inode; unsigned long offset; - struct page_info * next_same_inode; - struct page_info * prev_same_inode; - struct page_info * next_hash; - struct page_info * prev_hash; + struct page *next_hash; + atomic_t count; + unsigned flags; /* atomic flags, some possibly updated asynchronously */ + unsigned dirty:16, + age:8; struct wait_queue *wait; -}; -/* end of planning stage */ + struct page *prev_hash; + struct buffer_head * buffers; + unsigned long swap_unlock_entry; + unsigned long map_nr; /* page->map_nr == page - mem_map */ +} mem_map_t; + +/* Page flag bit values */ +#define PG_locked 0 +#define PG_error 1 +#define PG_referenced 2 +#define PG_uptodate 3 +#define PG_free_after 4 +#define PG_decr_after 5 +#define PG_swap_unlock_after 6 +#define PG_DMA 7 +#define PG_reserved 31 + +/* Make it prettier to test the above... */ +#define PageLocked(page) (test_bit(PG_locked, &(page)->flags)) +#define PageError(page) (test_bit(PG_error, &(page)->flags)) +#define PageReferenced(page) (test_bit(PG_referenced, &(page)->flags)) +#define PageDirty(page) (test_bit(PG_dirty, &(page)->flags)) +#define PageUptodate(page) (test_bit(PG_uptodate, &(page)->flags)) +#define PageFreeAfter(page) (test_bit(PG_free_after, &(page)->flags)) +#define PageDecrAfter(page) (test_bit(PG_decr_after, &(page)->flags)) +#define PageSwapUnlockAfter(page) (test_bit(PG_swap_unlock_after, &(page)->flags)) +#define PageDMA(page) (test_bit(PG_DMA, &(page)->flags)) +#define PageReserved(page) (test_bit(PG_reserved, &(page)->flags)) /* - * Free area management + * page->reserved denotes a page which must never be accessed (which + * may not even be present). + * + * page->dma is set for those pages which lie in the range of + * physical addresses capable of carrying DMA transfers. + * + * Multiple processes may "see" the same page. E.g. for untouched + * mappings of /dev/null, all processes see the same page full of + * zeroes, and text pages of executables and shared libraries have + * only one copy in memory, at most, normally. + * + * For the non-reserved pages, page->count denotes a reference count. + * page->count == 0 means the page is free. + * page->count == 1 means the page is used for exactly one purpose + * (e.g. a private data page of one process). + * + * A page may be used for kmalloc() or anyone else who does a + * get_free_page(). In this case the page->count is at least 1, and + * all other fields are unused but should be 0 or NULL. The + * management of this page is the responsibility of the one who uses + * it. + * + * The other pages (we may call them "process pages") are completely + * managed by the Linux memory manager: I/O, buffers, swapping etc. + * The following discussion applies only to them. + * + * A page may belong to an inode's memory mapping. In this case, + * page->inode is the inode, and page->offset is the file offset + * of the page (not necessarily a multiple of PAGE_SIZE). + * + * A page may have buffers allocated to it. In this case, + * page->buffers is a circular list of these buffer heads. Else, + * page->buffers == NULL. + * + * For pages belonging to inodes, the page->count is the number of + * attaches, plus 1 if buffers are allocated to the page. + * + * All pages belonging to an inode make up a doubly linked list + * inode->i_pages, using the fields page->next and page->prev. (These + * fields are also used for freelist management when page->count==0.) + * There is also a hash table mapping (inode,offset) to the page + * in memory if present. The lists for this hash table use the fields + * page->next_hash and page->prev_hash. + * + * All process pages can do I/O: + * - inode pages may need to be read from disk, + * - inode pages which have been modified and are MAP_SHARED may need + * to be written to disk, + * - private pages which have been modified may need to be swapped out + * to swap space and (later) to be read back into memory. + * During disk I/O, page->locked is true. This bit is set before I/O + * and reset when I/O completes. page->wait is a wait queue of all + * tasks waiting for the I/O on this page to complete. + * page->uptodate tells whether the page's contents is valid. + * When a read completes, the page becomes uptodate, unless a disk I/O + * error happened. + * When a write completes, and page->free_after is true, the page is + * freed without any further delay. + * + * For choosing which pages to swap out, inode pages carry a + * page->referenced bit, which is set any time the system accesses + * that page through the (inode,offset) hash table. + * There is also the page->age counter, which implements a linear + * decay (why not an exponential decay?), see swapctl.h. */ -extern int nr_swap_pages; -extern int nr_free_pages; -extern int min_free_pages; +extern mem_map_t * mem_map; + +/* + * Free area management + */ #define NR_MEM_LISTS 6 @@ -142,23 +233,24 @@ struct mem_list { }; extern struct mem_list free_area_list[NR_MEM_LISTS]; -extern unsigned char * free_area_map[NR_MEM_LISTS]; +extern unsigned int * free_area_map[NR_MEM_LISTS]; /* * This is timing-critical - most of the time in getting a new page * goes to clearing the page. If you want a page without the clearing * overhead, just use __get_free_page() directly.. */ -#define __get_free_page(priority) __get_free_pages((priority),0) -extern unsigned long __get_free_pages(int priority, unsigned long gfporder); -extern unsigned long __get_dma_pages(int priority, unsigned long gfporder); +#define __get_free_page(priority) __get_free_pages((priority),0,0) +#define __get_dma_pages(priority, order) __get_free_pages((priority),(order),1) +extern unsigned long __get_free_pages(int priority, unsigned long gfporder, int dma); + extern inline unsigned long get_free_page(int priority) { unsigned long page; page = __get_free_page(priority); if (page) - memset((void *) page, 0, PAGE_SIZE); + clear_page(page); return page; } @@ -166,22 +258,26 @@ extern inline unsigned long get_free_page(int priority) #define free_page(addr) free_pages((addr),0) extern void free_pages(unsigned long addr, unsigned long order); +extern void __free_page(struct page *); extern void show_free_areas(void); extern unsigned long put_dirty_page(struct task_struct * tsk,unsigned long page, unsigned long address); -extern void free_page_tables(struct task_struct * tsk); +extern void free_page_tables(struct mm_struct * mm); extern void clear_page_tables(struct task_struct * tsk); +extern int new_page_tables(struct task_struct * tsk); extern int copy_page_tables(struct task_struct * to); -extern int clone_page_tables(struct task_struct * to); -extern int unmap_page_range(unsigned long from, unsigned long size); + +extern int zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size); +extern int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma); extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot); extern int zeromap_page_range(unsigned long from, unsigned long size, pgprot_t prot); +extern void vmtruncate(struct inode * inode, unsigned long offset); extern void handle_mm_fault(struct vm_area_struct *vma, unsigned long address, int write_access); -extern void do_wp_page(struct vm_area_struct * vma, unsigned long address, int write_access); -extern void do_no_page(struct vm_area_struct * vma, unsigned long address, int write_access); +extern void do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long address, int write_access); +extern void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long address, int write_access); extern unsigned long paging_init(unsigned long start_mem, unsigned long end_mem); extern void mem_init(unsigned long start_mem, unsigned long end_mem); @@ -189,38 +285,21 @@ extern void show_mem(void); extern void oom(struct task_struct * tsk); extern void si_meminfo(struct sysinfo * val); -/* vmalloc.c */ - -extern void * vmalloc(unsigned long size); -extern void vfree(void * addr); -extern int vread(char *buf, char *addr, int count); - -/* swap.c */ - -extern void swap_free(unsigned long); -extern void swap_duplicate(unsigned long); -extern void swap_in(struct vm_area_struct *, pte_t *, unsigned long id, int write_access); - -extern void si_swapinfo(struct sysinfo * val); -extern void rw_swap_page(int rw, unsigned long nr, char * buf); - /* mmap.c */ extern unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long off); -extern struct vm_area_struct * find_vma (struct task_struct *, unsigned long); -extern struct vm_area_struct * find_vma_intersection (struct task_struct *, unsigned long, unsigned long); -extern void merge_segments(struct task_struct *, unsigned long, unsigned long); -extern void insert_vm_struct(struct task_struct *, struct vm_area_struct *); +extern void merge_segments(struct mm_struct *, unsigned long, unsigned long); +extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *); extern void remove_shared_vm_struct(struct vm_area_struct *); -extern void build_mmap_avl(struct task_struct *); -extern void exit_mmap(struct task_struct *); +extern void build_mmap_avl(struct mm_struct *); +extern void exit_mmap(struct mm_struct *); extern int do_munmap(unsigned long, size_t); extern unsigned long get_unmapped_area(unsigned long, unsigned long); -#define read_swap_page(nr,buf) \ - rw_swap_page(READ,(nr),(buf)) -#define write_swap_page(nr,buf) \ - rw_swap_page(WRITE,(nr),(buf)) +/* filemap.c */ +extern unsigned long page_unuse(unsigned long); +extern int shrink_mmap(int, int); +extern void truncate_inode_pages(struct inode *, unsigned long); #define GFP_BUFFER 0x00 #define GFP_ATOMIC 0x01 @@ -234,66 +313,64 @@ extern unsigned long get_unmapped_area(unsigned long, unsigned long); #define GFP_DMA 0x80 -/* - * vm_ops not present page codes for shared memory. - * - * Will go away eventually.. - */ -#define SHM_SWP_TYPE 0x41 -extern void shm_no_page (ulong *); - -/* - * swap cache stuff (in swap.c) - */ -#define SWAP_CACHE_INFO +#define GFP_LEVEL_MASK 0xf -extern unsigned long * swap_cache; - -#ifdef SWAP_CACHE_INFO -extern unsigned long swap_cache_add_total; -extern unsigned long swap_cache_add_success; -extern unsigned long swap_cache_del_total; -extern unsigned long swap_cache_del_success; -extern unsigned long swap_cache_find_total; -extern unsigned long swap_cache_find_success; -#endif - -extern inline unsigned long in_swap_cache(unsigned long addr) +/* vma is the first one with address < vma->vm_end, + * and even address < vma->vm_start. Have to extend vma. */ +static inline int expand_stack(struct vm_area_struct * vma, unsigned long address) { - return swap_cache[MAP_NR(addr)]; + unsigned long grow; + + address &= PAGE_MASK; + grow = vma->vm_start - address; + if (vma->vm_end - address + > (unsigned long) current->rlim[RLIMIT_STACK].rlim_cur || + (vma->vm_mm->total_vm << PAGE_SHIFT) + grow + > (unsigned long) current->rlim[RLIMIT_AS].rlim_cur) + return -ENOMEM; + vma->vm_start = address; + vma->vm_offset -= grow; + vma->vm_mm->total_vm += grow >> PAGE_SHIFT; + if (vma->vm_flags & VM_LOCKED) + vma->vm_mm->locked_vm += grow >> PAGE_SHIFT; + return 0; } -extern inline long find_in_swap_cache (unsigned long addr) -{ - unsigned long entry; +#define avl_empty (struct vm_area_struct *) NULL -#ifdef SWAP_CACHE_INFO - swap_cache_find_total++; -#endif - entry = (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL); -#ifdef SWAP_CACHE_INFO - if (entry) - swap_cache_find_success++; -#endif - return entry; +/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ +static inline struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr) +{ + struct vm_area_struct * result = NULL; + + if (mm) { + struct vm_area_struct ** next = &mm->mmap_avl; + for (;;) { + struct vm_area_struct *tree = *next; + if (tree == avl_empty) + break; + next = &tree->vm_avl_right; + if (tree->vm_end <= addr) + continue; + next = &tree->vm_avl_left; + result = tree; + if (tree->vm_start <= addr) + break; + } + } + return result; } -extern inline int delete_from_swap_cache(unsigned long addr) +/* Look up the first VMA which intersects the interval start_addr..end_addr-1, + NULL if none. Assume start_addr < end_addr. */ +static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr) { - unsigned long entry; - -#ifdef SWAP_CACHE_INFO - swap_cache_del_total++; -#endif - entry= (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL); - if (entry) { -#ifdef SWAP_CACHE_INFO - swap_cache_del_success++; -#endif - swap_free(entry); - return 1; - } - return 0; + struct vm_area_struct * vma; + + vma = find_vma(mm,start_addr); + if (vma && end_addr <= vma->vm_start) + vma = NULL; + return vma; } #endif /* __KERNEL__ */ diff --git a/include/linux/mman.h b/include/linux/mman.h index f9419b2f9..3bc0430bc 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h @@ -1,23 +1,8 @@ #ifndef _LINUX_MMAN_H #define _LINUX_MMAN_H -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_NONE 0x0 /* page can not be accessed */ +#include <asm/mman.h> -#define MAP_SHARED 1 /* Share changes */ -#define MAP_PRIVATE 2 /* Changes are private */ -#define MAP_TYPE 0xf /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ - -#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ -#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ -#define MAP_EXECUTABLE 0x1000 /* mark it as a executable */ - -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ +#define MREMAP_MAYMOVE 1 #endif /* _LINUX_MMAN_H */ diff --git a/include/linux/module.h b/include/linux/module.h index 699c13ccf..1bf540e93 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -7,21 +7,16 @@ #ifndef _LINUX_MODULE_H #define _LINUX_MODULE_H -#ifdef CONFIG_MODVERSIONS -# ifndef __GENKSYMS__ -# ifdef MODULE -# define _set_ver(sym,vers) sym ## _R ## vers -# include <linux/modversions.h> -# else /* MODULE */ -# ifdef EXPORT_SYMTAB -# define _set_ver(sym,vers) sym -# include <linux/modversions.h> -# endif /* EXPORT_SYMTAB */ -# endif /* MODULE */ -# else /* __GENKSYMS__ */ +#ifdef __GENKSYMS__ # define _set_ver(sym,vers) sym -# endif /* __GENKSYMS__ */ -#endif /* CONFIG_MODVERSIONS */ +# undef MODVERSIONS +# define MODVERSIONS +#else /* ! __GENKSYMS__ */ +# if defined(MODVERSIONS) && !defined(MODULE) && defined(EXPORT_SYMTAB) +# define _set_ver(sym,vers) sym +# include <linux/modversions.h> +# endif +#endif /* __GENKSYMS__ */ /* values of module.state */ #define MOD_UNINITIALIZED 0 @@ -31,6 +26,10 @@ /* maximum length of module name */ #define MOD_MAX_NAME 64 +/* magic marker for modules inserted from kerneld, to be auto-reaped */ +#define MOD_AUTOCLEAN 0x40000000 /* big enough, but no sign problems... */ +#define MOD_VISITED 0x20000000 /* Thanks Jacques! */ + /* maximum length of symbol name */ #define SYM_MAX_NAME 60 @@ -46,7 +45,7 @@ struct module_ref { struct internal_symbol { void *addr; - char *name; + const char *name; }; struct symbol_table { /* received from "insmod" */ @@ -59,44 +58,81 @@ struct symbol_table { /* received from "insmod" */ /* * Note: The string table follows immediately after the symbol table in memory! */ +struct _exceptinfo{ + struct exception_table_entry *start; + struct exception_table_entry *stop; +}; struct module { struct module *next; struct module_ref *ref; /* the list of modules that refer to me */ struct symbol_table *symtab; - char *name; + const char *name; int size; /* size of module in pages */ void* addr; /* address of module */ int state; void (*cleanup)(void); /* cleanup routine */ + struct _exceptinfo exceptinfo; }; +/* + prior to modules-2.1 there were no real way to identify + which insmod is talking to us Now a special signature must + be written here. + + The new module utilities knows about older kernel and write + the init in the signature and the cleanup in the init. + This is to make sure newer utilities work with older kernel + so it is simple for people to upgrade. +*/ +#define MODULE_2_1_7_SIG ((void*)0x00000217) + struct mod_routines { + void *signature; int (*init)(void); /* initialization routine */ void (*cleanup)(void); /* cleanup routine */ + struct _exceptinfo exceptinfo; }; -/* rename_module_symbol(old_name, new_name) WOW! */ -extern int rename_module_symbol(char *, char *); - -/* insert new symbol table */ -extern int register_symtab(struct symbol_table *); - /* * The first word of the module contains the use count. */ -#define GET_USE_COUNT(module) (* (int *) (module)->addr) +#define GET_USE_COUNT(module) (* (long *) (module)->addr) /* * define the count variable, and usage macros. */ -extern int mod_use_count_; -#if defined(CONFIG_MODVERSIONS) && defined(MODULE) && !defined(__GENKSYMS__) +#ifdef MODULE + +extern long mod_use_count_; +#define MOD_INC_USE_COUNT (mod_use_count_++, mod_use_count_ |= MOD_VISITED) +#define MOD_DEC_USE_COUNT (mod_use_count_--, mod_use_count_ |= MOD_VISITED) +#define MOD_IN_USE ((mod_use_count_ & ~(MOD_AUTOCLEAN | MOD_VISITED)) != 0) + +#ifndef __NO_VERSION__ +#include <linux/version.h> +char kernel_version[]=UTS_RELEASE; +#endif + +#if defined(MODVERSIONS) && !defined(__GENKSYMS__) int Using_Versions; /* gcc will handle this global (used as a flag) correctly */ #endif -#define MOD_INC_USE_COUNT mod_use_count_++ -#define MOD_DEC_USE_COUNT mod_use_count_-- -#define MOD_IN_USE (mod_use_count_ != 0) +#else + +#define MOD_INC_USE_COUNT do { } while (0) +#define MOD_DEC_USE_COUNT do { } while (0) +#define MOD_IN_USE 1 +extern struct module *module_list; + +#endif + +/* insert new symbol table */ +extern int register_symtab_from(struct symbol_table *, long *); +#ifdef MODULE +#define register_symtab(symtab) register_symtab_from(symtab, &mod_use_count_) +#else +#define register_symtab(symtab) register_symtab_from(symtab, 0) +#endif #endif diff --git a/include/linux/modules/ksyms.ver b/include/linux/modules/ksyms.ver deleted file mode 100644 index 76537cd4c..000000000 --- a/include/linux/modules/ksyms.ver +++ /dev/null @@ -1,194 +0,0 @@ -/**** This file is generated by genksyms DO NOT EDIT! ****/ -#if defined(CONFIG_MODVERSIONS) && !defined(__GENKSYMS__) -#ifndef _KSYMS_VER_ -#define _KSYMS_VER_ -#define rename_module_symbol _set_ver(rename_module_symbol, b81c73c1) -#define register_symtab _set_ver(register_symtab, e910ea66) -#define EISA_bus _set_ver(EISA_bus, 7e37737c) -#define wp_works_ok _set_ver(wp_works_ok, f37f99e9) -#define verify_area _set_ver(verify_area, 4cfda560) -#define do_mmap _set_ver(do_mmap, 677e7ee1) -#define do_munmap _set_ver(do_munmap, 6221f117) -#define zeromap_page_range _set_ver(zeromap_page_range, 7c395a26) -#define unmap_page_range _set_ver(unmap_page_range, 0110085f) -#define insert_vm_struct _set_ver(insert_vm_struct, 1f4e4882) -#define merge_segments _set_ver(merge_segments, 6854be5a) -#define __get_free_pages _set_ver(__get_free_pages, 5243d78b) -#define free_pages _set_ver(free_pages, 96448859) -#define kmalloc _set_ver(kmalloc, d31fb2cb) -#define kfree_s _set_ver(kfree_s, 1e72eb79) -#define vmalloc _set_ver(vmalloc, 667f3e25) -#define vfree _set_ver(vfree, 6df52add) -#define getname _set_ver(getname, 81487159) -#define putname _set_ver(putname, b19e8126) -#define __iget _set_ver(__iget, ee2b6320) -#define iput _set_ver(iput, 59241ced) -#define namei _set_ver(namei, 00478bcd) -#define lnamei _set_ver(lnamei, fcfddbb1) -#define open_namei _set_ver(open_namei, 414b2b0f) -#define close_fp _set_ver(close_fp, 1d4c15d8) -#define check_disk_change _set_ver(check_disk_change, b66ed457) -#define invalidate_buffers _set_ver(invalidate_buffers, c65255f1) -#define fsync_dev _set_ver(fsync_dev, a221190d) -#define permission _set_ver(permission, 0ebf7474) -#define inode_setattr _set_ver(inode_setattr, 0c80a3c1) -#define inode_change_ok _set_ver(inode_change_ok, 5d1cb326) -#define generic_mmap _set_ver(generic_mmap, d4ff59f3) -#define set_blocksize _set_ver(set_blocksize, f45fda38) -#define getblk _set_ver(getblk, d40228ac) -#define bread _set_ver(bread, c73bf0f0) -#define breada _set_ver(breada, eb8e858c) -#define brelse _set_ver(brelse, 4c27ac3d) -#define ll_rw_block _set_ver(ll_rw_block, f3aa4dd3) -#define __wait_on_buffer _set_ver(__wait_on_buffer, e8fcc968) -#define dcache_lookup _set_ver(dcache_lookup, 83336566) -#define dcache_add _set_ver(dcache_add, fe71f11e) -#define register_chrdev _set_ver(register_chrdev, da99513f) -#define unregister_chrdev _set_ver(unregister_chrdev, 61ea5ee8) -#define register_blkdev _set_ver(register_blkdev, 4699a621) -#define unregister_blkdev _set_ver(unregister_blkdev, d39bbca9) -#define tty_register_driver _set_ver(tty_register_driver, fcc8591c) -#define tty_unregister_driver _set_ver(tty_unregister_driver, c78132a8) -#define tty_std_termios _set_ver(tty_std_termios, cf350678) -#define block_read _set_ver(block_read, a7fe4f51) -#define block_write _set_ver(block_write, 902674c9) -#define block_fsync _set_ver(block_fsync, 182888d8) -#define wait_for_request _set_ver(wait_for_request, 9ca2932e) -#define blksize_size _set_ver(blksize_size, dea1eb55) -#define hardsect_size _set_ver(hardsect_size, ed1ee14f) -#define blk_size _set_ver(blk_size, f60b5398) -#define blk_dev _set_ver(blk_dev, dbf5fdd4) -#define is_read_only _set_ver(is_read_only, b0c5f83e) -#define set_device_ro _set_ver(set_device_ro, 8fb69e13) -#define bmap _set_ver(bmap, 73bb8bdd) -#define sync_dev _set_ver(sync_dev, 9bca536d) -#define get_blkfops _set_ver(get_blkfops, 83827791) -#define register_serial _set_ver(register_serial, 3425f38c) -#define unregister_serial _set_ver(unregister_serial, c013d717) -#define tty_hangup _set_ver(tty_hangup, e3487df0) -#define tty_wait_until_sent _set_ver(tty_wait_until_sent, da85d428) -#define tty_check_change _set_ver(tty_check_change, 705eaab0) -#define tty_hung_up_p _set_ver(tty_hung_up_p, f99ac1e4) -#define register_filesystem _set_ver(register_filesystem, 1c7110ef) -#define unregister_filesystem _set_ver(unregister_filesystem, 5e353af7) -#define register_binfmt _set_ver(register_binfmt, 66ece706) -#define unregister_binfmt _set_ver(unregister_binfmt, 41822618) -#define lookup_exec_domain _set_ver(lookup_exec_domain, 32f10d48) -#define register_exec_domain _set_ver(register_exec_domain, eda4711f) -#define unregister_exec_domain _set_ver(unregister_exec_domain, 78ea447c) -#define request_irq _set_ver(request_irq, 9e81629c) -#define free_irq _set_ver(free_irq, f487dc0c) -#define enable_irq _set_ver(enable_irq, 54e09f5f) -#define disable_irq _set_ver(disable_irq, b4449c1f) -#define bh_active _set_ver(bh_active, 98fb5ca1) -#define bh_mask _set_ver(bh_mask, 1abf3d3f) -#define add_timer _set_ver(add_timer, f13cb728) -#define del_timer _set_ver(del_timer, c7aff713) -#define tq_timer _set_ver(tq_timer, 46cf583e) -#define tq_immediate _set_ver(tq_immediate, 46cf583e) -#define tq_scheduler _set_ver(tq_scheduler, 46cf583e) -#define tq_last _set_ver(tq_last, 457cf547) -#define timer_active _set_ver(timer_active, 5a6747ee) -#define timer_table _set_ver(timer_table, 9e03b650) -#define request_dma _set_ver(request_dma, 2a687646) -#define free_dma _set_ver(free_dma, 5d4b914c) -#define disable_hlt _set_ver(disable_hlt, 794487ee) -#define enable_hlt _set_ver(enable_hlt, 9c7077bd) -#define check_region _set_ver(check_region, b91154fb) -#define request_region _set_ver(request_region, 138b0a1e) -#define release_region _set_ver(release_region, f41d6d31) -#define wake_up _set_ver(wake_up, e8d71419) -#define wake_up_interruptible _set_ver(wake_up_interruptible, 64c8cb92) -#define sleep_on _set_ver(sleep_on, 67a00cee) -#define interruptible_sleep_on _set_ver(interruptible_sleep_on, 6a5fc80d) -#define schedule _set_ver(schedule, 01000e51) -#define current _set_ver(current, fc1cb29b) -#define jiffies _set_ver(jiffies, 2f7c7437) -#define xtime _set_ver(xtime, e70c0be0) -#define loops_per_sec _set_ver(loops_per_sec, 40a14192) -#define need_resched _set_ver(need_resched, dfc016ea) -#define kill_proc _set_ver(kill_proc, 911f760a) -#define kill_pg _set_ver(kill_pg, 0a758a45) -#define kill_sl _set_ver(kill_sl, 49625e94) -#define panic _set_ver(panic, 400c0de3) -#define printk _set_ver(printk, ad1148ba) -#define sprintf _set_ver(sprintf, f9003107) -#define vsprintf _set_ver(vsprintf, e605cb6b) -#define simple_strtoul _set_ver(simple_strtoul, bdb8c1e3) -#define system_utsname _set_ver(system_utsname, 066845bc) -#define sys_call_table _set_ver(sys_call_table, 79fa4011) -#define do_signal _set_ver(do_signal, 86f9bc59) -#define send_sig _set_ver(send_sig, 5cddd8d9) -#define setup_arg_pages _set_ver(setup_arg_pages, fe68d94a) -#define copy_strings _set_ver(copy_strings, 232aee96) -#define create_tables _set_ver(create_tables, ba788fa2) -#define do_execve _set_ver(do_execve, 8c99dc0a) -#define flush_old_exec _set_ver(flush_old_exec, c737e178) -#define open_inode _set_ver(open_inode, 27302cb6) -#define read_exec _set_ver(read_exec, a80a2dd0) -#define si_meminfo _set_ver(si_meminfo, bb05fc9a) -#define sock_register _set_ver(sock_register, d68e1649) -#define sock_unregister _set_ver(sock_unregister, 72c332bd) -#define inet_add_protocol _set_ver(inet_add_protocol, 55292121) -#define inet_del_protocol _set_ver(inet_del_protocol, 73908a1b) -#define slhc_init _set_ver(slhc_init, e490a4b8) -#define slhc_free _set_ver(slhc_free, 39ab902b) -#define slhc_remember _set_ver(slhc_remember, db333be6) -#define slhc_compress _set_ver(slhc_compress, e753e2d2) -#define slhc_uncompress _set_ver(slhc_uncompress, 81cc1144) -#define register_netdevice_notifier _set_ver(register_netdevice_notifier, e7aace7c) -#define unregister_netdevice_notifier _set_ver(unregister_netdevice_notifier, be114416) -#define floppy_track_buffer _set_ver(floppy_track_buffer, c6e3f7c2) -#define register_netdev _set_ver(register_netdev, 0d8d1bb4) -#define unregister_netdev _set_ver(unregister_netdev, 25a99579) -#define ether_setup _set_ver(ether_setup, 4eafef91) -#define alloc_skb _set_ver(alloc_skb, b6b523ba) -#define kfree_skb _set_ver(kfree_skb, 0b938572) -#define dev_kfree_skb _set_ver(dev_kfree_skb, aa1fe7f4) -#define netif_rx _set_ver(netif_rx, d8051cb2) -#define dev_rint _set_ver(dev_rint, 040d3f4b) -#define dev_tint _set_ver(dev_tint, 860b350b) -#define irq2dev_map _set_ver(irq2dev_map, 10bdcd8a) -#define dev_add_pack _set_ver(dev_add_pack, 6d7d9be4) -#define dev_remove_pack _set_ver(dev_remove_pack, 784fa59f) -#define dev_get _set_ver(dev_get, 72ed90fd) -#define dev_ioctl _set_ver(dev_ioctl, 08760203) -#define dev_queue_xmit _set_ver(dev_queue_xmit, 4a478225) -#define dev_base _set_ver(dev_base, 0a8809f0) -#define dev_close _set_ver(dev_close, 9bdad56d) -#define arp_find _set_ver(arp_find, a141bd11) -#define n_tty_ioctl _set_ver(n_tty_ioctl, 538e5fa6) -#define tty_register_ldisc _set_ver(tty_register_ldisc, 8fdde939) -#define kill_fasync _set_ver(kill_fasync, 890501b6) -#define in_scan_scsis _set_ver(in_scan_scsis, 21874a88) -#define scsi_register_module _set_ver(scsi_register_module, 8eff1010) -#define scsi_unregister_module _set_ver(scsi_unregister_module, d913b8f0) -#define scsi_free _set_ver(scsi_free, 475dddfa) -#define scsi_malloc _set_ver(scsi_malloc, 1cce3f92) -#define scsi_register _set_ver(scsi_register, d6e77069) -#define scsi_unregister _set_ver(scsi_unregister, 3b0b616b) -#define scsicam_bios_param _set_ver(scsicam_bios_param, 3d965248) -#define scsi_init_malloc _set_ver(scsi_init_malloc, e5167cbc) -#define scsi_init_free _set_ver(scsi_init_free, 8b2721f8) -#define print_command _set_ver(print_command, 6f14cd75) -#define print_msg _set_ver(print_msg, 0465f877) -#define print_status _set_ver(print_status, 32f84646) -#define set_writetime _set_ver(set_writetime, 52131916) -#define sys_tz _set_ver(sys_tz, aa3c9782) -#define __wait_on_super _set_ver(__wait_on_super, 61a5c00a) -#define file_fsync _set_ver(file_fsync, d30a190f) -#define clear_inode _set_ver(clear_inode, da2b0e9f) -#define refile_buffer _set_ver(refile_buffer, 8c69e123) -#define ___strtok _set_ver(___strtok, 8b55d69c) -#define init_fifo _set_ver(init_fifo, 082629c7) -#define super_blocks _set_ver(super_blocks, e1f1ee99) -#define chrdev_inode_operations _set_ver(chrdev_inode_operations, 6ba1faa3) -#define blkdev_inode_operations _set_ver(blkdev_inode_operations, ed443696) -#define read_ahead _set_ver(read_ahead, bbcd3768) -#define get_hash_table _set_ver(get_hash_table, 3b5f3c55) -#define get_empty_inode _set_ver(get_empty_inode, 554bdc75) -#define insert_inode_hash _set_ver(insert_inode_hash, 59b8c371) -#define event _set_ver(event, a6aac9c1) -#define __down _set_ver(__down, 75aa9e96) -#endif /* _KSYMS_VER_ */ -#endif /* CONFIG_MODVERSIONS !__GENKSYMS__ */ diff --git a/include/linux/modversions.h b/include/linux/modversions.h deleted file mode 100644 index 25079e40b..000000000 --- a/include/linux/modversions.h +++ /dev/null @@ -1 +0,0 @@ -#include <linux/modules/ksyms.ver> diff --git a/include/linux/mount.h b/include/linux/mount.h new file mode 100644 index 000000000..c2e44397a --- /dev/null +++ b/include/linux/mount.h @@ -0,0 +1,30 @@ +/* + * + * Definitions for mount interface. This describes the in the kernel build + * linkedlist with mounted filesystems. + * + * Author: Marco van Wieringen <mvw@mcs.ow.nl> <mvw@tnix.net> <mvw@cistron.nl> + * + * Version: $Id: mount.h,v 1.3 1994/07/20 22:01:00 mvw Exp mvw $ + * + */ +#ifndef _LINUX_MOUNT_H +#define _LINUX_MOUNT_H + +struct vfsmount +{ + kdev_t mnt_dev; /* Device this applies to */ + char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ + char *mnt_dirname; /* Name of directory mounted on */ + unsigned int mnt_flags; /* Flags of this device */ + struct semaphore mnt_sem; /* lock device while I/O in progress */ + struct super_block *mnt_sb; /* pointer to superblock */ + struct file *mnt_quotas[MAXQUOTAS]; /* fp's to quotafiles */ + time_t mnt_iexp[MAXQUOTAS]; /* expiretime for inodes */ + time_t mnt_bexp[MAXQUOTAS]; /* expiretime for blocks */ + struct vfsmount *mnt_next; /* pointer to next in linkedlist */ +}; + +struct vfsmount *lookup_vfsmnt(kdev_t dev); + +#endif /* _LINUX_MOUNT_H */ diff --git a/include/linux/mouse.h b/include/linux/mouse.h deleted file mode 100644 index df4e42718..000000000 --- a/include/linux/mouse.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _LINUX_MOUSE_H -#define _LINUX_MOUSE_H - -#define BUSMOUSE_MINOR 0 -#define PSMOUSE_MINOR 1 -#define MS_BUSMOUSE_MINOR 2 -#define ATIXL_BUSMOUSE_MINOR 3 - -unsigned long mouse_init(unsigned long); - -#endif diff --git a/include/linux/mroute.h b/include/linux/mroute.h new file mode 100644 index 000000000..6772a60f8 --- /dev/null +++ b/include/linux/mroute.h @@ -0,0 +1,173 @@ +#ifndef __LINUX_MROUTE_H +#define __LINUX_MROUTE_H + +#include <linux/sockios.h> +#include <linux/in.h> + +/* + * Based on the MROUTING 3.5 defines primarily to keep + * source compatibility with BSD. + * + * See the mrouted code for the original history. + * + */ + +#define MRT_BASE 200 +#define MRT_INIT (MRT_BASE) /* Activate the kernel mroute code */ +#define MRT_DONE (MRT_BASE+1) /* Shutdown the kernel mroute */ +#define MRT_ADD_VIF (MRT_BASE+2) /* Add a virtual interface */ +#define MRT_DEL_VIF (MRT_BASE+3) /* Delete a virtual interface */ +#define MRT_ADD_MFC (MRT_BASE+4) /* Add a multicast forwarding entry */ +#define MRT_DEL_MFC (MRT_BASE+5) /* Delete a multicast forwarding entry */ +#define MRT_VERSION (MRT_BASE+6) /* Get the kernel multicast version */ +#define MRT_ASSERT (MRT_BASE+7) /* Activate PIM assert mode */ + +#define SIOCGETVIFCNT SIOCPROTOPRIVATE /* IP protocol privates */ +#define SIOCGETSGCNT (SIOCPROTOPRIVATE+1) + +#define MAXVIFS 32 +typedef unsigned long vifbitmap_t; /* User mode code depends on this lot */ +typedef unsigned short vifi_t; +#define ALL_VIFS ((vifi_t)(-1)) + +/* + * Same idea as select + */ + +#define VIFM_SET(n,m) ((m)|=(1<<(n))) +#define VIFM_CLR(n,m) ((m)&=~(1<<(n))) +#define VIFM_ISSET(n,m) ((m)&(1<<(n))) +#define VIFM_CLRALL(m) ((m)=0) +#define VIFM_COPY(mfrom,mto) ((mto)=(mfrom)) +#define VIFM_SAME(m1,m2) ((m1)==(m2)) + +/* + * Passed by mrouted for an MRT_ADD_VIF - again we use the + * mrouted 3.6 structures for compatibility + */ + +struct vifctl { + vifi_t vifc_vifi; /* Index of VIF */ + unsigned char vifc_flags; /* VIFF_ flags */ + unsigned char vifc_threshold; /* ttl limit */ + unsigned int vifc_rate_limit; /* Rate limiter values (NI) */ + struct in_addr vifc_lcl_addr; /* Our address */ + struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */ +}; + +#define VIFF_TUNNEL 0x1 /* IPIP tunnel */ +#define VIFF_SRCRT 0x02 /* NI */ + +/* + * Cache manipulation structures for mrouted + */ + +struct mfcctl +{ + struct in_addr mfcc_origin; /* Origin of mcast */ + struct in_addr mfcc_mcastgrp; /* Group in question */ + vifi_t mfcc_parent; /* Where it arrived */ + unsigned char mfcc_ttls[MAXVIFS]; /* Where it is going */ +}; + +/* + * Group count retrieval for mrouted + */ + +struct sioc_sg_req +{ + struct in_addr src; + struct in_addr grp; + unsigned long pktcnt; + unsigned long bytecnt; + unsigned long wrong_if; +}; + +/* + * To get vif packet counts + */ + +struct sioc_vif_req +{ + vifi_t vifi; /* Which iface */ + unsigned long icount; /* In packets */ + unsigned long ocount; /* Out packets */ + unsigned long ibytes; /* In bytes */ + unsigned long obytes; /* Out bytes */ +}; + +/* + * This is the format the mroute daemon expects to see IGMP control + * data. Magically happens to be like an IP packet as per the original + */ + +struct igmpmsg +{ + unsigned long unused1,unused2; + unsigned char im_msgtype; /* What is this */ + unsigned char im_mbz; /* Must be zero */ + unsigned char im_vif; /* Interface (this ought to be a vifi_t!) */ + unsigned char unused3; + struct in_addr im_src,im_dst; +}; + +/* + * That's all usermode folks + */ + +#ifdef __KERNEL__ +extern struct sock *mroute_socket; +extern int ip_mroute_setsockopt(struct sock *, int, char *, int); +extern int ip_mroute_getsockopt(struct sock *, int, char *, int *); +extern int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg); +extern void mroute_close(struct sock *sk); +extern void ipmr_forward(struct sk_buff *skb, int is_frag); + + +struct vif_device +{ + struct device *dev; /* Device we are using */ + struct route *rt_cache; /* Tunnel route cache */ + unsigned long bytes_in,bytes_out; + unsigned long pkt_in,pkt_out; /* Statistics */ + unsigned long rate_limit; /* Traffic shaping (NI) */ + unsigned char threshold; /* TTL threshold */ + unsigned short flags; /* Control flags */ + unsigned long local,remote; /* Addresses(remote for tunnels)*/ +}; + +struct mfc_cache +{ + struct mfc_cache *next; /* Next entry on cache line */ + __u32 mfc_mcastgrp; /* Group the entry belongs to */ + __u32 mfc_origin; /* Source of packet */ + vifi_t mfc_parent; /* Source interface */ + struct timer_list mfc_timer; /* Expiry timer */ + int mfc_flags; /* Flags on line */ + struct sk_buff_head mfc_unresolved; /* Unresolved buffers */ + int mfc_queuelen; /* Unresolved buffer counter */ + unsigned char mfc_ttls[MAXVIFS]; /* TTL thresholds */ +}; + +#define MFC_QUEUED 1 +#define MFC_RESOLVED 2 + + +#define MFC_LINES 64 + +#ifdef __BIG_ENDIAN +#define MFC_HASH(a,b) ((((a)>>24)^((b)>>26))&(MFC_LINES-1)) +#else +#define MFC_HASH(a,b) (((a)^((b)>>2))&(MFC_LINES-1)) +#endif + +#endif + +/* + * Pseudo messages used by mrouted + */ + +#define IGMPMSG_NOCACHE 1 /* Kernel cache fill request to mrouted */ +#define IGMPMSG_WRONGVIF 2 /* For PIM assert processing (unused) */ + +#endif diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index fa2dd9fa9..7aef08e01 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -21,6 +21,9 @@ #define FAT_CACHE 8 /* FAT cache size */ +#define MSDOS_MAX_EXTRA 3 /* tolerate up to that number of clusters which are + inaccessible because the FAT is too short */ + #define ATTR_RO 1 /* read-only */ #define ATTR_HIDDEN 2 /* hidden */ #define ATTR_SYS 4 /* system */ @@ -31,10 +34,26 @@ #define ATTR_NONE 0 /* no attribute bits */ #define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN) /* attribute bits that are copied "as is" */ +#define ATTR_EXT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME) + /* bits that are used by the Windows 95/Windows NT extended FAT */ + +#define ATTR_DIR_READ_BOTH 512 /* read both short and long names from the + * vfat filesystem. This is used by Samba + * to export the vfat filesystem with correct + * shortnames. */ +#define ATTR_DIR_READ_SHORT 1024 + +#define CASE_LOWER_BASE 8 /* base is lower case */ +#define CASE_LOWER_EXT 16 /* extension is lower case */ + +#define SCAN_ANY 0 /* either hidden or not */ +#define SCAN_HID 1 /* only hidden */ +#define SCAN_NOTHID 2 /* only not hidden */ +#define SCAN_NOTANY 3 /* test name, then use SCAN_HID or SCAN_NOTHID */ #define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */ -#define IS_FREE(n) (!*(n) || *(unsigned char *) (n) == DELETED_FLAG || \ - *(unsigned char *) (n) == FD_FILL_BYTE) +#define IS_FREE(n) (!*(n) || *(const unsigned char *) (n) == DELETED_FLAG || \ + *(const unsigned char *) (n) == FD_FILL_BYTE) #define MSDOS_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO) /* valid file mode bits */ @@ -43,16 +62,29 @@ #define MSDOS_I(i) (&((i)->u.msdos_i)) #define MSDOS_NAME 11 /* maximum name length */ +#define MSDOS_LONGNAME 256 /* maximum name length */ +#define MSDOS_SLOTS 21 /* max # of slots needed for short and long names */ #define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */ #define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ #define MSDOS_FAT12 4078 /* maximum number of clusters in a 12 bit FAT */ /* + * Inode flags + */ +#define FAT_BINARY_FL 0x00000001 /* File contains binary data */ + +/* + * ioctl commands + */ +#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, long) +#define VFAT_IOCTL_READDIR_SHORT _IOW('r', 2, long) + +/* * Conversion from and to little-endian byte order. (no-op on i386/i486) * - * Naming: Ca_b_c, where a: F = from, T = to, b: LE = little-endian, BE = big- - * endian, c: W = word (16 bits), L = longword (32 bits) + * Naming: Ca_b_c, where a: F = from, T = to, b: LE = little-endian, + * BE = big-endian, c: W = word (16 bits), L = longword (32 bits) */ #define CF_LE_W(v) (v) @@ -82,106 +114,164 @@ struct msdos_boot_sector { struct msdos_dir_entry { __s8 name[8],ext[3]; /* name and extension */ __u8 attr; /* attribute bits */ - __u8 unused[10]; + __u8 lcase; /* Case for base and extension */ + __u8 ctime_ms; /* Creation time, milliseconds */ + __u16 ctime; /* Creation time */ + __u16 cdate; /* Creation date */ + __u16 adate; /* Last access date */ + __u8 unused[2]; __u16 time,date,start;/* time, date and first cluster */ __u32 size; /* file size (in bytes) */ }; -struct fat_cache { - int device; /* device number. 0 means unused. */ - int ino; /* inode number. */ - int file_cluster; /* cluster number in the file. */ - int disk_cluster; /* cluster number on disk. */ - struct fat_cache *next; /* next cache entry */ +/* Up to 13 characters of the name */ +struct msdos_dir_slot { + __u8 id; /* sequence number for slot */ + __u8 name0_4[10]; /* first 5 characters in name */ + __u8 attr; /* attribute byte */ + __u8 reserved; /* always 0 */ + __u8 alias_checksum; /* checksum for 8.3 alias */ + __u8 name5_10[12]; /* 6 more characters in name */ + __u8 start[2]; /* starting cluster number */ + __u8 name11_12[4]; /* last 2 characters in name */ }; -/* Determine whether this FS has kB-aligned data. */ +struct slot_info { + int is_long; /* was the found entry long */ + int long_slots; /* number of long slots in filename */ + int total_slots; /* total slots (long and short) */ + loff_t longname_offset; /* dir offset for longname start */ + loff_t shortname_offset; /* dir offset for shortname start */ + int ino; /* ino for the file */ +}; +/* Determine whether this FS has kB-aligned data. */ #define MSDOS_CAN_BMAP(mib) (!(((mib)->cluster_size & 1) || \ ((mib)->data_start & 1))) /* Convert attribute bits and a mask to the UNIX mode. */ - #define MSDOS_MKMODE(a,m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO)) /* Convert the UNIX mode to MS-DOS attribute bits. */ - #define MSDOS_MKATTR(m) ((m & S_IWUGO) ? ATTR_NONE : ATTR_RO) + #ifdef __KERNEL__ -/* misc.c */ +typedef int (*fat_filldir_t)(filldir_t filldir, void *, const char *, + int, int, off_t, off_t, int, ino_t); + +struct fat_cache { + kdev_t device; /* device number. 0 means unused. */ + int ino; /* inode number. */ + int file_cluster; /* cluster number in the file. */ + int disk_cluster; /* cluster number on disk. */ + struct fat_cache *next; /* next cache entry */ +}; -extern void fs_panic(struct super_block *s,char *msg); +/* misc.c */ extern int is_binary(char conversion,char *extension); -extern void lock_creation(void); -extern void unlock_creation(void); extern void lock_fat(struct super_block *sb); extern void unlock_fat(struct super_block *sb); -extern int msdos_add_cluster(struct inode *inode); +extern int fat_add_cluster(struct inode *inode); extern int date_dos2unix(__u16 time, __u16 date); -extern void date_unix2dos(int unix_date,__u16 *time, __u16 *date); -extern int msdos_get_entry(struct inode *dir,loff_t *pos,struct buffer_head **bh, - struct msdos_dir_entry **de); -extern int msdos_scan(struct inode *dir,char *name,struct buffer_head **res_bh, - struct msdos_dir_entry **res_de,int *ino); -extern int msdos_parent_ino(struct inode *dir,int locked); -extern int msdos_subdirs(struct inode *dir); +extern void fat_fs_panic(struct super_block *s,const char *msg); +extern void fat_lock_creation(void); +extern void fat_unlock_creation(void); +extern void fat_date_unix2dos(int unix_date,__u16 *time, __u16 *date); +extern int fat_get_entry(struct inode *dir,loff_t *pos,struct buffer_head **bh, + struct msdos_dir_entry **de); +extern int fat_scan(struct inode *dir,const char *name,struct buffer_head **res_bh, + struct msdos_dir_entry **res_de,int *ino,char scantype); +extern int fat_parent_ino(struct inode *dir,int locked); +extern int fat_subdirs(struct inode *dir); /* fat.c */ - extern int fat_access(struct super_block *sb,int nr,int new_value); -extern int msdos_smap(struct inode *inode,int sector); +extern int fat_smap(struct inode *inode,int sector); extern int fat_free(struct inode *inode,int skip); +void fat_cache_inval_inode(struct inode *inode); +void fat_cache_inval_dev(kdev_t device); extern void cache_init(void); void cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu); void cache_add(struct inode *inode,int f_clu,int d_clu); -void cache_inval_inode(struct inode *inode); -void cache_inval_dev(int device); int get_cluster(struct inode *inode,int cluster); -/* namei.c */ - -extern int msdos_lookup(struct inode *dir,const char *name,int len, - struct inode **result); -extern int msdos_create(struct inode *dir,const char *name,int len,int mode, - struct inode **result); -extern int msdos_mkdir(struct inode *dir,const char *name,int len,int mode); -extern int msdos_rmdir(struct inode *dir,const char *name,int len); -extern int msdos_unlink(struct inode *dir,const char *name,int len); -extern int msdos_unlink_umsdos(struct inode *dir,const char *name,int len); -extern int msdos_rename(struct inode *old_dir,const char *old_name,int old_len, - struct inode *new_dir,const char *new_name,int new_len); - /* inode.c */ - -extern void msdos_put_inode(struct inode *inode); +extern int fat_bmap(struct inode *inode,int block); +extern int fat_notify_change(struct inode *,struct iattr *); +extern void fat_put_inode(struct inode *inode); +extern void fat_put_super(struct super_block *sb); +extern void fat_read_inode(struct inode *inode, struct inode_operations *dir_ops); +extern struct super_block *fat_read_super(struct super_block *s, void *data, int silent); extern void msdos_put_super(struct super_block *sb); -extern struct super_block *msdos_read_super(struct super_block *s, - void *data,int); -extern void msdos_statfs(struct super_block *sb,struct statfs *buf, int); -extern int msdos_bmap(struct inode *inode,int block); -extern void msdos_read_inode(struct inode *inode); -extern void msdos_write_inode(struct inode *inode); -extern int msdos_notify_change(struct inode *,struct iattr *); +extern void fat_statfs(struct super_block *sb,struct statfs *buf, int); +extern void fat_write_inode(struct inode *inode); /* dir.c */ +extern struct file_operations fat_dir_operations; +extern int fat_readdirx(struct inode *inode, struct file *filp, void *dirent, + fat_filldir_t fat_filldir, filldir_t filldir, + int shortnames, int longnames, int both); +extern int fat_readdir(struct inode *inode, struct file *filp, + void *dirent, filldir_t); +extern int fat_dir_ioctl(struct inode * inode, struct file * filp, + unsigned int cmd, unsigned long arg); -extern struct inode_operations msdos_dir_inode_operations; -extern int msdos_readdir (struct inode *inode, struct file *filp, - void *dirent, filldir_t); /* file.c */ +extern struct inode_operations fat_file_inode_operations; +extern struct inode_operations fat_file_inode_operations_1024; +extern long fat_file_read(struct inode *, struct file *, char *, unsigned long); +extern long fat_file_write(struct inode *, struct file *, const char *, unsigned long); +extern void fat_truncate(struct inode *inode); -extern struct inode_operations msdos_file_inode_operations; -extern struct inode_operations msdos_file_inode_operations_1024; -extern int msdos_file_read(struct inode *, struct file *, char *, int); -extern int msdos_file_write(struct inode *, struct file *, char *, int); -extern struct inode_operations msdos_file_inode_operations_no_bmap; +/* mmap.c */ +extern int fat_mmap(struct inode *, struct file *, struct vm_area_struct *); -extern void msdos_truncate(struct inode *inode); -/* mmap.c */ -extern int msdos_mmap(struct inode *, struct file *, struct vm_area_struct *); +/* vfat.c */ +extern int init_vfat_fs(void); + + +/* msdosfs_syms.c */ +extern int init_msdos_fs(void); +extern struct file_system_type msdos_fs_type; + +/* msdos.c */ +extern struct super_block *msdos_read_super(struct super_block *sb,void *data, int silent); + +/* msdos.c - these are for Umsdos */ +extern void msdos_read_inode(struct inode *inode); +extern int msdos_lookup(struct inode *dir,const char *name,int len, + struct inode **result); +extern int msdos_create(struct inode *dir,const char *name,int len,int mode, + struct inode **result); +extern int msdos_rmdir(struct inode *dir,const char *name,int len); +extern int msdos_mkdir(struct inode *dir,const char *name,int len,int mode); +extern int msdos_unlink(struct inode *dir,const char *name,int len); +extern int msdos_unlink_umsdos(struct inode *dir,const char *name,int len); +extern int msdos_rename(struct inode *old_dir,const char *old_name,int old_len, + struct inode *new_dir,const char *new_name,int new_len, + int must_be_dir); + +/* fatfs_syms.c */ +extern int init_fat_fs(void); + +/* vfat/namei.c - these are for dmsdos */ +extern int vfat_create(struct inode *dir,const char *name,int len,int mode, + struct inode **result); +extern int vfat_unlink(struct inode *dir,const char *name,int len); +extern int vfat_mkdir(struct inode *dir,const char *name,int len,int mode); +extern int vfat_rmdir(struct inode *dir,const char *name,int len); +extern int vfat_rename(struct inode *old_dir,const char *old_name,int old_len, + struct inode *new_dir,const char *new_name,int new_len, + int must_be_dir); +extern void vfat_put_super(struct super_block *sb); +extern struct super_block *vfat_read_super(struct super_block *sb,void *data, + int silent); +extern void vfat_read_inode(struct inode *inode); +extern int vfat_lookup(struct inode *dir,const char *name,int len, + struct inode **result); #endif /* __KERNEL__ */ diff --git a/include/linux/msdos_fs_i.h b/include/linux/msdos_fs_i.h index b11e22483..cc9d9ac85 100644 --- a/include/linux/msdos_fs_i.h +++ b/include/linux/msdos_fs_i.h @@ -33,6 +33,10 @@ struct msdos_inode_info { current inode */ struct inode *i_old; /* pointer to the old inode this inode depends on */ + struct inode *i_linked; /* pointer to inode linked to the current one, + happens when an open file is moved */ + struct inode *i_oldlink;/* pointer to open inode that references + the same file */ int i_binary; /* file contains non-text data */ }; diff --git a/include/linux/msdos_fs_sb.h b/include/linux/msdos_fs_sb.h index 8e5f3041b..bf5ea6345 100644 --- a/include/linux/msdos_fs_sb.h +++ b/include/linux/msdos_fs_sb.h @@ -5,6 +5,23 @@ * MS-DOS file system in-core superblock data */ +struct fat_mount_options { + uid_t fs_uid; + gid_t fs_gid; + unsigned short fs_umask; + unsigned char name_check; /* r = relaxed, n = normal, s = strict */ + unsigned char conversion; /* b = binary, t = text, a = auto */ + unsigned quiet:1, /* set = fake successful chmods and chowns */ + showexec:1, /* set = only set x bit for com/exe/bat */ + sys_immutable:1, /* set = system files are immutable */ + dotsOK:1, /* set = hidden and system files are named '.filename' */ + isvfat:1, /* 0=no vfat long filename support, 1=vfat support */ + unicode_xlate:1, /* create escape sequences for unhandled Unicode */ + posixfs:1, /* Allow names like makefile and Makefile to coexist */ + numtail:1; /* Does first alias have a numeric '~1' type tail? */ +}; + + struct msdos_sb_info { unsigned short cluster_size; /* sectors/cluster */ unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */ @@ -12,16 +29,11 @@ struct msdos_sb_info { unsigned short dir_start,dir_entries; /* root dir start & entries */ unsigned short data_start; /* first data sector */ unsigned long clusters; /* number of clusters */ - uid_t fs_uid; - gid_t fs_gid; - int quiet; /* fake successful chmods and chowns */ - unsigned short fs_umask; - unsigned char name_check; /* r = relaxed, n = normal, s = strict */ - unsigned char conversion; /* b = binary, t = text, a = auto */ struct wait_queue *fat_wait; int fat_lock; - int prev_free; /* previously returned free cluster number */ - int free_clusters; /* -1 if undefined */ + int prev_free; /* previously returned free cluster number */ + int free_clusters; /* -1 if undefined */ + struct fat_mount_options options; }; #endif diff --git a/include/linux/msg.h b/include/linux/msg.h index f31a08038..2be627198 100644 --- a/include/linux/msg.h +++ b/include/linux/msg.h @@ -1,44 +1,49 @@ #ifndef _LINUX_MSG_H #define _LINUX_MSG_H + #include <linux/ipc.h> +/* ipcs ctl commands */ +#define MSG_STAT 11 +#define MSG_INFO 12 + /* msgrcv options */ #define MSG_NOERROR 010000 /* no error if message is too big */ #define MSG_EXCEPT 020000 /* recv any msg except of specified type.*/ /* one msqid structure for each queue on the system */ struct msqid_ds { - struct ipc_perm msg_perm; - struct msg *msg_first; /* first message on queue */ - struct msg *msg_last; /* last message in queue */ - time_t msg_stime; /* last msgsnd time */ - time_t msg_rtime; /* last msgrcv time */ - time_t msg_ctime; /* last change time */ - struct wait_queue *wwait; - struct wait_queue *rwait; - ushort msg_cbytes; /* current number of bytes on queue */ - ushort msg_qnum; /* number of messages in queue */ - ushort msg_qbytes; /* max number of bytes on queue */ - ushort msg_lspid; /* pid of last msgsnd */ - ushort msg_lrpid; /* last receive pid */ + struct ipc_perm msg_perm; + struct msg *msg_first; /* first message on queue */ + struct msg *msg_last; /* last message in queue */ + __kernel_time_t msg_stime; /* last msgsnd time */ + __kernel_time_t msg_rtime; /* last msgrcv time */ + __kernel_time_t msg_ctime; /* last change time */ + struct wait_queue *wwait; + struct wait_queue *rwait; + unsigned short msg_cbytes; /* current number of bytes on queue */ + unsigned short msg_qnum; /* number of messages in queue */ + unsigned short msg_qbytes; /* max number of bytes on queue */ + __kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_ipc_pid_t msg_lrpid; /* last receive pid */ }; /* message buffer for msgsnd and msgrcv calls */ struct msgbuf { - long mtype; /* type of message */ - char mtext[1]; /* message text */ + long mtype; /* type of message */ + char mtext[1]; /* message text */ }; /* buffer for msgctl calls IPC_INFO, MSG_INFO */ struct msginfo { - int msgpool; - int msgmap; - int msgmax; - int msgmnb; - int msgmni; - int msgssz; - int msgtql; - ushort msgseg; + int msgpool; + int msgmap; + int msgmax; + int msgmnb; + int msgmni; + int msgssz; + int msgtql; + unsigned short msgseg; }; #define MSGMNI 128 /* <= 1K */ /* max # of msg queue identifiers */ @@ -57,15 +62,18 @@ struct msginfo { /* one msg structure for each message */ struct msg { - struct msg *msg_next; /* next message on queue */ - long msg_type; - char *msg_spot; /* message text address */ - short msg_ts; /* message text size */ + struct msg *msg_next; /* next message on queue */ + long msg_type; + char *msg_spot; /* message text address */ + time_t msg_stime; /* msgsnd time */ + short msg_ts; /* message text size */ }; -/* ipcs ctl commands */ -#define MSG_STAT 11 -#define MSG_INFO 12 +asmlinkage int sys_msgget (key_t key, int msgflg); +asmlinkage int sys_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); +asmlinkage int sys_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, + int msgflg); +asmlinkage int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf); #endif /* __KERNEL__ */ diff --git a/include/linux/mtio.h b/include/linux/mtio.h index f995bd2f9..22cec7aaa 100644 --- a/include/linux/mtio.h +++ b/include/linux/mtio.h @@ -1,5 +1,4 @@ -/* $Id: /usr/src/linux-1.1.64/include/linux/mtio.h at Tue Jan 10 21:02:51 1995 by root@kai.home$ - * +/* * linux/mtio.h header file for Linux. Written by H. Bergman */ @@ -43,7 +42,6 @@ struct mtop { #define MTRAS2 15 /* run self test 2 (destructive) */ #define MTRAS3 16 /* reserved for self test 3 */ - #define MTSETBLK 20 /* set block length (SCSI) */ #define MTSETDENSITY 21 /* set tape density (SCSI) */ #define MTSEEK 22 /* seek to block (Tandberg, etc.) */ @@ -54,6 +52,14 @@ struct mtop { #define MTBSS 26 /* space backward over setmarks */ #define MTWSM 27 /* write setmarks */ +#define MTLOCK 28 /* lock the drive door */ +#define MTUNLOCK 29 /* unlock the drive door */ +#define MTLOAD 30 /* execute the SCSI load command */ +#define MTUNLOAD 31 /* execute the SCSI unload command */ +#define MTCOMPRESSION 32/* control compression with SCSI mode page 15 */ +#define MTSETPART 33 /* Change the active tape partition */ +#define MTMKPART 34 /* Format the tape with one or two partitions */ + /* structure for MTIOCGET - mag tape get status command */ struct mtget { @@ -68,8 +74,8 @@ struct mtget { long mt_gstat; /* generic (device independent) status */ long mt_erreg; /* error register */ /* The next two fields are not always used */ - daddr_t mt_fileno; /* number of current file on tape */ - daddr_t mt_blkno; /* current block number */ + __kernel_daddr_t mt_fileno; /* number of current file on tape */ + __kernel_daddr_t mt_blkno; /* current block number */ }; @@ -97,23 +103,11 @@ struct mtget { #define MT_ISSCSI1 0x71 /* Generic ANSI SCSI-1 tape unit */ #define MT_ISSCSI2 0x72 /* Generic ANSI SCSI-2 tape unit */ -/* QIC-40/QIC-80 ftape supported drives. - * 20bit vendor ID + 0x800000 +/* QIC-40/80/3010/3020 ftape supported drives. + * 20bit vendor ID + 0x800000 (see vendors.h in ftape distribution) */ -#define MT_ISFTAPE_UNKNOWN 0x800000 -#define MT_ISCMSDJ10_DJ20 0x800047 -#define MT_ISCMSDJ10_DJ20_NEW 0x8011c4 -#define MT_ISARCHIVE_5580I 0x800005 -#define MT_ISARCHIVE_XL9250I 0x80014a -#define MT_ISARCHIVE_31250Q 0x800146 -#define MT_ISINSIGHT_80 0x810005 -#define MT_ISCONNER_C250MQT 0x80014c -#define MT_ISWANGTEK_2040F 0x8001c1 -#define MT_ISWANGTEK_2080F 0x8001c8 -#define MT_ISIOMEGA_250 0x808880 -#define MT_ISSUMMIT_SE150 0x800180 -#define MT_ISSUMMIT_SE250 0x800181 -#define MT_ISESCOM_IDTBU120E 0x800140 +#define MT_ISFTAPE_UNKNOWN 0x800000 /* obsolete */ +#define MT_ISFTAPE_FLAG 0x800000 struct mt_tape_info { long t_type; /* device type id (mt_type) */ @@ -137,20 +131,6 @@ struct mt_tape_info { {MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, \ {MT_ISSCSI1, "Generic SCSI-1 tape"}, \ {MT_ISSCSI2, "Generic SCSI-2 tape"}, \ - {MT_ISFTAPE_UNKNOWN, "Unknown floppy interface tape drive"},\ - {MT_ISCMSDJ10_DJ20, "Colorado DJ-10/DJ-20"},\ - {MT_ISCMSDJ10_DJ20_NEW, "Colorado DJ-10/DJ-20 (new)"},\ - {MT_ISARCHIVE_5580I, "Archive 5580i"},\ - {MT_ISARCHIVE_XL9250I, "Archive XL9250i [Conner/Escom]"},\ - {MT_ISARCHIVE_31250Q, "Escom/Archive 31250Q"},\ - {MT_ISINSIGHT_80, "Insight 80 Mb"},\ - {MT_ISCONNER_C250MQT, "Conner C250MQT"},\ - {MT_ISWANGTEK_2040F, "Wangtek 3040F"},\ - {MT_ISWANGTEK_2080F, "Wangtek 3080F"},\ - {MT_ISIOMEGA_250, "Iomega 250"},\ - {MT_ISSUMMIT_SE150, "Summit SE 150"},\ - {MT_ISSUMMIT_SE250, "Summit SE 250/Mountain FS8000"},\ - {MT_ISESCOM_IDTBU120E, "Identity IDTBU120E, Escom?"},\ {0, NULL} \ } @@ -162,6 +142,35 @@ struct mtpos { }; +/* structure for MTIOCGETCONFIG/MTIOCSETCONFIG primarily intended + * as an interim solution for QIC-02 until DDI is fully implemented. + */ +struct mtconfiginfo { + long mt_type; /* drive type */ + long ifc_type; /* interface card type */ + unsigned short irqnr; /* IRQ number to use */ + unsigned short dmanr; /* DMA channel to use */ + unsigned short port; /* IO port base address */ + + unsigned long debug; /* debugging flags */ + + unsigned have_dens:1; + unsigned have_bsf:1; + unsigned have_fsr:1; + unsigned have_bsr:1; + unsigned have_eod:1; + unsigned have_seek:1; + unsigned have_tell:1; + unsigned have_ras1:1; + unsigned have_ras2:1; + unsigned have_ras3:1; + unsigned have_qfa:1; + + unsigned pad1:5; + char reserved[10]; +}; + + /* mag tape io control commands */ #define MTIOCTOP _IOW('m', 1, struct mtop) /* do a mag tape op */ #define MTIOCGET _IOR('m', 2, struct mtget) /* get tape status */ @@ -173,7 +182,6 @@ struct mtpos { #define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo) /* get tape config */ #define MTIOCSETCONFIG _IOW('m', 5, struct mtconfiginfo) /* set tape config */ - /* Generic Mag Tape (device independent) status macros for examining * mt_gstat -- HP-UX compatible. * There is room for more generic status bits here, but I don't @@ -198,12 +206,9 @@ struct mtpos { #define GMT_IM_REP_EN(x) ((x) & 0x00010000) /* immediate report mode */ /* 16 generic status bits unused */ -/* DDS drives have 'setmarks', sort of like filemarks but used to group - * files, rather than blocks. Not used. Not supported. - * I think DDS drives are DAT drives. - */ /* SCSI-tape specific definitions */ +/* Bitfield shifts in the status */ #define MT_ST_BLKSIZE_SHIFT 0 #define MT_ST_BLKSIZE_MASK 0xffffff #define MT_ST_DENSITY_SHIFT 24 @@ -212,14 +217,32 @@ struct mtpos { #define MT_ST_SOFTERR_SHIFT 0 #define MT_ST_SOFTERR_MASK 0xffff +/* Bitfields for the MTSETDRVBUFFER ioctl */ #define MT_ST_OPTIONS 0xf0000000 #define MT_ST_BOOLEANS 0x10000000 +#define MT_ST_SETBOOLEANS 0x30000000 +#define MT_ST_CLEARBOOLEANS 0x40000000 #define MT_ST_WRITE_THRESHOLD 0x20000000 +#define MT_ST_DEF_BLKSIZE 0x50000000 +#define MT_ST_DEF_OPTIONS 0x60000000 + #define MT_ST_BUFFER_WRITES 0x1 #define MT_ST_ASYNC_WRITES 0x2 #define MT_ST_READ_AHEAD 0x4 #define MT_ST_DEBUGGING 0x8 #define MT_ST_TWO_FM 0x10 #define MT_ST_FAST_MTEOM 0x20 +#define MT_ST_AUTO_LOCK 0x40 +#define MT_ST_DEF_WRITES 0x80 +#define MT_ST_CAN_BSR 0x100 +#define MT_ST_NO_BLKLIMS 0x200 +#define MT_ST_CAN_PARTITIONS 0x400 +#define MT_ST_SCSI2LOGICAL 0x800 + +/* The mode parameters to be controlled. Parameter chosen with bits 20-28 */ +#define MT_ST_CLEAR_DEFAULT 0xfffff +#define MT_ST_DEF_DENSITY (MT_ST_DEF_OPTIONS | 0x100000) +#define MT_ST_DEF_COMPRESSION (MT_ST_DEF_OPTIONS | 0x200000) +#define MT_ST_DEF_DRVBUFFER (MT_ST_DEF_OPTIONS | 0x300000) #endif /* _LINUX_MTIO_H */ diff --git a/include/linux/ncp.h b/include/linux/ncp.h new file mode 100644 index 000000000..3d5286ec1 --- /dev/null +++ b/include/linux/ncp.h @@ -0,0 +1,304 @@ +/* + * ncp.h + * + * Copyright (C) 1995 by Volker Lendecke + * + */ + +#ifndef _LINUX_NCP_H +#define _LINUX_NCP_H + +#include <linux/types.h> +#include <linux/ipx.h> + +#define NCP_PTYPE (0x11) +#define NCP_PORT (0x0451) + +#define NCP_ALLOC_SLOT_REQUEST (0x1111) +#define NCP_REQUEST (0x2222) +#define NCP_DEALLOC_SLOT_REQUEST (0x5555) + +struct ncp_request_header { + __u16 type __attribute__ ((packed)); + __u8 sequence __attribute__ ((packed)); + __u8 conn_low __attribute__ ((packed)); + __u8 task __attribute__ ((packed)); + __u8 conn_high __attribute__ ((packed)); + __u8 function __attribute__ ((packed)); + __u8 data[0] __attribute__ ((packed)); +}; + +#define NCP_REPLY (0x3333) +#define NCP_POSITIVE_ACK (0x9999) + +struct ncp_reply_header { + __u16 type __attribute__ ((packed)); + __u8 sequence __attribute__ ((packed)); + __u8 conn_low __attribute__ ((packed)); + __u8 task __attribute__ ((packed)); + __u8 conn_high __attribute__ ((packed)); + __u8 completion_code __attribute__ ((packed)); + __u8 connection_state __attribute__ ((packed)); + __u8 data[0] __attribute__ ((packed)); +}; + + +#define NCP_BINDERY_USER (0x0001) +#define NCP_BINDERY_UGROUP (0x0002) +#define NCP_BINDERY_PQUEUE (0x0003) +#define NCP_BINDERY_FSERVER (0x0004) +#define NCP_BINDERY_NAME_LEN (48) +struct ncp_bindery_object { + __u32 object_id; + __u16 object_type; + __u8 object_name[NCP_BINDERY_NAME_LEN]; + __u8 object_flags; + __u8 object_security; + __u8 object_has_prop; +}; + +struct nw_property { + __u8 value[128]; + __u8 more_flag; + __u8 property_flag; +}; + +struct prop_net_address { + __u32 network __attribute__ ((packed)); + __u8 node[IPX_NODE_LEN] __attribute__ ((packed)); + __u16 port __attribute__ ((packed)); +}; + +#define NCP_VOLNAME_LEN (16) +#define NCP_NUMBER_OF_VOLUMES (64) +struct ncp_volume_info { + __u32 total_blocks; + __u32 free_blocks; + __u32 purgeable_blocks; + __u32 not_yet_purgeable_blocks; + __u32 total_dir_entries; + __u32 available_dir_entries; + __u8 sectors_per_block; + char volume_name[NCP_VOLNAME_LEN+1]; +}; + +struct ncp_filesearch_info { + __u8 volume_number; + __u16 directory_id; + __u16 sequence_no; + __u8 access_rights; +}; + +#define NCP_MAX_FILENAME 14 + +/* these define the attribute byte as seen by NCP */ +#define aRONLY (1L<<0) +#define aHIDDEN (1L<<1) +#define aSYSTEM (1L<<2) +#define aEXECUTE (1L<<3) +#define aDIR (1L<<4) +#define aARCH (1L<<5) + +#define AR_READ (0x01) +#define AR_WRITE (0x02) +#define AR_EXCLUSIVE (0x20) + +#define NCP_FILE_ID_LEN 6 +struct ncp_file_info { + __u8 file_id[NCP_FILE_ID_LEN]; + char file_name[NCP_MAX_FILENAME+1]; + __u8 file_attributes; + __u8 file_mode; + __u32 file_length; + __u16 creation_date; + __u16 access_date; + __u16 update_date; + __u16 update_time; +}; + +/* Defines for Name Spaces */ +#define NW_NS_DOS 0 +#define NW_NS_MAC 1 +#define NW_NS_NFS 2 +#define NW_NS_FTAM 3 +#define NW_NS_OS2 4 + +/* Defines for ReturnInformationMask */ +#define RIM_NAME (0x0001L) +#define RIM_SPACE_ALLOCATED (0x0002L) +#define RIM_ATTRIBUTES (0x0004L) +#define RIM_DATA_SIZE (0x0008L) +#define RIM_TOTAL_SIZE (0x0010L) +#define RIM_EXT_ATTR_INFO (0x0020L) +#define RIM_ARCHIVE (0x0040L) +#define RIM_MODIFY (0x0080L) +#define RIM_CREATION (0x0100L) +#define RIM_OWNING_NAMESPACE (0x0200L) +#define RIM_DIRECTORY (0x0400L) +#define RIM_RIGHTS (0x0800L) +#define RIM_ALL (0x0FFFL) +#define RIM_COMPRESSED_INFO (0x80000000L) + +/* open/create modes */ +#define OC_MODE_OPEN 0x01 +#define OC_MODE_TRUNCATE 0x02 +#define OC_MODE_REPLACE 0x02 +#define OC_MODE_CREATE 0x08 + +/* open/create results */ +#define OC_ACTION_NONE 0x00 +#define OC_ACTION_OPEN 0x01 +#define OC_ACTION_CREATE 0x02 +#define OC_ACTION_TRUNCATE 0x04 +#define OC_ACTION_REPLACE 0x04 + +/* access rights attributes */ +#ifndef AR_READ_ONLY +#define AR_READ_ONLY 0x0001 +#define AR_WRITE_ONLY 0x0002 +#define AR_DENY_READ 0x0004 +#define AR_DENY_WRITE 0x0008 +#define AR_COMPATIBILITY 0x0010 +#define AR_WRITE_THROUGH 0x0040 +#define AR_OPEN_COMPRESSED 0x0100 +#endif + +struct nw_info_struct +{ + __u32 spaceAlloc __attribute__ ((packed)); + __u32 attributes __attribute__ ((packed)); + __u16 flags __attribute__ ((packed)); + __u32 dataStreamSize __attribute__ ((packed)); + __u32 totalStreamSize __attribute__ ((packed)); + __u16 numberOfStreams __attribute__ ((packed)); + __u16 creationTime __attribute__ ((packed)); + __u16 creationDate __attribute__ ((packed)); + __u32 creatorID __attribute__ ((packed)); + __u16 modifyTime __attribute__ ((packed)); + __u16 modifyDate __attribute__ ((packed)); + __u32 modifierID __attribute__ ((packed)); + __u16 lastAccessDate __attribute__ ((packed)); + __u16 archiveTime __attribute__ ((packed)); + __u16 archiveDate __attribute__ ((packed)); + __u32 archiverID __attribute__ ((packed)); + __u16 inheritedRightsMask __attribute__ ((packed)); + __u32 dirEntNum __attribute__ ((packed)); + __u32 DosDirNum __attribute__ ((packed)); + __u32 volNumber __attribute__ ((packed)); + __u32 EADataSize __attribute__ ((packed)); + __u32 EAKeyCount __attribute__ ((packed)); + __u32 EAKeySize __attribute__ ((packed)); + __u32 NSCreator __attribute__ ((packed)); + __u8 nameLen __attribute__ ((packed)); + __u8 entryName[256] __attribute__ ((packed)); +}; + +/* modify mask - use with MODIFY_DOS_INFO structure */ +#define DM_ATTRIBUTES (0x0002L) +#define DM_CREATE_DATE (0x0004L) +#define DM_CREATE_TIME (0x0008L) +#define DM_CREATOR_ID (0x0010L) +#define DM_ARCHIVE_DATE (0x0020L) +#define DM_ARCHIVE_TIME (0x0040L) +#define DM_ARCHIVER_ID (0x0080L) +#define DM_MODIFY_DATE (0x0100L) +#define DM_MODIFY_TIME (0x0200L) +#define DM_MODIFIER_ID (0x0400L) +#define DM_LAST_ACCESS_DATE (0x0800L) +#define DM_INHERITED_RIGHTS_MASK (0x1000L) +#define DM_MAXIMUM_SPACE (0x2000L) + +struct nw_modify_dos_info +{ + __u32 attributes __attribute__ ((packed)); + __u16 creationDate __attribute__ ((packed)); + __u16 creationTime __attribute__ ((packed)); + __u32 creatorID __attribute__ ((packed)); + __u16 modifyDate __attribute__ ((packed)); + __u16 modifyTime __attribute__ ((packed)); + __u32 modifierID __attribute__ ((packed)); + __u16 archiveDate __attribute__ ((packed)); + __u16 archiveTime __attribute__ ((packed)); + __u32 archiverID __attribute__ ((packed)); + __u16 lastAccessDate __attribute__ ((packed)); + __u16 inheritanceGrantMask __attribute__ ((packed)); + __u16 inheritanceRevokeMask __attribute__ ((packed)); + __u32 maximumSpace __attribute__ ((packed)); +}; + +struct nw_file_info { + struct nw_info_struct i; + int opened; + int access; + __u32 server_file_handle __attribute__ ((packed)); + __u8 open_create_action __attribute__ ((packed)); + __u8 file_handle[6] __attribute__ ((packed)); +}; + +struct nw_search_sequence { + __u8 volNumber __attribute__ ((packed)); + __u32 dirBase __attribute__ ((packed)); + __u32 sequence __attribute__ ((packed)); +}; + +struct nw_queue_job_entry { + __u16 InUse __attribute__ ((packed)); + __u32 prev __attribute__ ((packed)); + __u32 next __attribute__ ((packed)); + __u32 ClientStation __attribute__ ((packed)); + __u32 ClientTask __attribute__ ((packed)); + __u32 ClientObjectID __attribute__ ((packed)); + __u32 TargetServerID __attribute__ ((packed)); + __u8 TargetExecTime[6] __attribute__ ((packed)); + __u8 JobEntryTime[6] __attribute__ ((packed)); + __u32 JobNumber __attribute__ ((packed)); + __u16 JobType __attribute__ ((packed)); + __u16 JobPosition __attribute__ ((packed)); + __u16 JobControlFlags __attribute__ ((packed)); + __u8 FileNameLen __attribute__ ((packed)); + char JobFileName[13] __attribute__ ((packed)); + __u32 JobFileHandle __attribute__ ((packed)); + __u32 ServerStation __attribute__ ((packed)); + __u32 ServerTaskNumber __attribute__ ((packed)); + __u32 ServerObjectID __attribute__ ((packed)); + char JobTextDescription[50] __attribute__ ((packed)); + char ClientRecordArea[152] __attribute__ ((packed)); +}; + +struct queue_job { + struct nw_queue_job_entry j; + __u8 file_handle[6]; +}; + +#define QJE_OPER_HOLD 0x80 +#define QJE_USER_HOLD 0x40 +#define QJE_ENTRYOPEN 0x20 +#define QJE_SERV_RESTART 0x10 +#define QJE_SERV_AUTO 0x08 + +/* ClientRecordArea for print jobs */ + +#define KEEP_ON 0x0400 +#define NO_FORM_FEED 0x0800 +#define NOTIFICATION 0x1000 +#define DELETE_FILE 0x2000 +#define EXPAND_TABS 0x4000 +#define PRINT_BANNER 0x8000 + +struct print_job_record { + __u8 Version __attribute__ ((packed)); + __u8 TabSize __attribute__ ((packed)); + __u16 Copies __attribute__ ((packed)); + __u16 CtrlFlags __attribute__ ((packed)); + __u16 Lines __attribute__ ((packed)); + __u16 Rows __attribute__ ((packed)); + char FormName[16] __attribute__ ((packed)); + __u8 Reserved[6] __attribute__ ((packed)); + char BannerName[13] __attribute__ ((packed)); + char FnameBanner[13] __attribute__ ((packed)); + char FnameHeader[14] __attribute__ ((packed)); + char Path[80] __attribute__ ((packed)); +}; + + +#endif /* _LINUX_NCP_H */ diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h new file mode 100644 index 000000000..1d6744420 --- /dev/null +++ b/include/linux/ncp_fs.h @@ -0,0 +1,165 @@ +/* + * ncp_fs.h + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * + */ + +#ifndef _LINUX_NCP_FS_H +#define _LINUX_NCP_FS_H + +#include <linux/fs.h> +#include <linux/in.h> +#include <linux/types.h> + +#include <linux/ncp_mount.h> +#include <linux/ncp_fs_sb.h> +#include <linux/ncp_fs_i.h> + +/* + * ioctl commands + */ + +struct ncp_ioctl_request { + unsigned int function; + unsigned int size; + char *data; +}; + +struct ncp_fs_info { + int version; + struct sockaddr_ipx addr; + uid_t mounted_uid; + int connection; /* Connection number the server assigned us */ + int buffer_size; /* The negotiated buffer size, to be + used for read/write requests! */ + + int volume_number; + __u32 directory_id; +}; + +#define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request) +#define NCP_IOC_GETMOUNTUID _IOW('n', 2, uid_t) +#define NCP_IOC_CONN_LOGGED_IN _IO('n', 3) + +#define NCP_GET_FS_INFO_VERSION (1) +#define NCP_IOC_GET_FS_INFO _IOWR('n', 4, struct ncp_fs_info) + +/* + * The packet size to allocate. One page should be enough. + */ +#define NCP_PACKET_SIZE 4070 + +#define NCP_MAXPATHLEN 255 +#define NCP_MAXNAMELEN 14 + +#define NCP_MSG_COMMAND "/sbin/nwmsg" + +#ifdef __KERNEL__ + +/* The readdir cache size controls how many directory entries are + * cached. + */ +#define NCP_READDIR_CACHE_SIZE 64 + + +#define NCP_MAX_RPC_TIMEOUT (6*HZ) + +/* Guess, what 0x564c is :-) */ +#define NCP_SUPER_MAGIC 0x564c + + +#define NCP_SBP(sb) ((struct ncp_server *)((sb)->u.generic_sbp)) +#define NCP_INOP(inode) ((struct ncp_inode_info *)((inode)->u.generic_ip)) + +#define NCP_SERVER(inode) NCP_SBP((inode)->i_sb) +#define NCP_FINFO(inode) (&(NCP_INOP(inode)->finfo)) +#define NCP_ISTRUCT(inode) (&(NCP_FINFO(inode)->i)) + +#ifdef DEBUG_NCP_MALLOC + +#include <linux/malloc.h> + +extern int ncp_malloced; +extern int ncp_current_malloced; + +static inline void * +ncp_kmalloc(unsigned int size, int priority) +{ + ncp_malloced += 1; + ncp_current_malloced += 1; + return kmalloc(size, priority); +} + +static inline void +ncp_kfree_s(void *obj, int size) +{ + ncp_current_malloced -= 1; + kfree_s(obj, size); +} + +#else /* DEBUG_NCP_MALLOC */ + +#define ncp_kmalloc(s,p) kmalloc(s,p) +#define ncp_kfree_s(o,s) kfree_s(o,s) + +#endif /* DEBUG_NCP_MALLOC */ + +#if DEBUG_NCP > 0 +#define DPRINTK(format, args...) printk(format , ## args) +#else +#define DPRINTK(format, args...) +#endif + +#if DEBUG_NCP > 1 +#define DDPRINTK(format, args...) printk(format , ## args) +#else +#define DDPRINTK(format, args...) +#endif + + +/* linux/fs/ncpfs/file.c */ +extern struct inode_operations ncp_file_inode_operations; +int ncp_make_open(struct inode *i, int right); + +/* linux/fs/ncpfs/dir.c */ +extern struct inode_operations ncp_dir_inode_operations; +void ncp_free_inode_info(struct ncp_inode_info *i); +void ncp_free_all_inodes(struct ncp_server *server); +void ncp_init_root(struct ncp_server *server); +int ncp_conn_logged_in(struct ncp_server *server); +void ncp_init_dir_cache(void); +void ncp_invalid_dir_cache(struct inode *ino); +struct ncp_inode_info *ncp_find_inode(struct inode *inode); +ino_t ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info); +void ncp_free_dir_cache(void); +int ncp_date_dos2unix(__u16 time, __u16 date); +void ncp_date_unix2dos(int unix_date, __u16 *time, __u16 *date); + + +/* linux/fs/ncpfs/ioctl.c */ +int ncp_ioctl (struct inode * inode, struct file * filp, + unsigned int cmd, unsigned long arg); + +/* linux/fs/ncpfs/inode.c */ +struct super_block *ncp_read_super(struct super_block *sb, + void *raw_data, int silent); +extern int init_ncp_fs(void); +void ncp_trigger_message(struct ncp_server *server); + +/* linux/fs/ncpfs/sock.c */ +int ncp_request(struct ncp_server *server, int function); +int ncp_connect(struct ncp_server *server); +int ncp_disconnect(struct ncp_server *server); +int ncp_catch_watchdog(struct ncp_server *server); +int ncp_dont_catch_watchdog(struct ncp_server *server); +int ncp_catch_message(struct ncp_server *server); +void ncp_lock_server(struct ncp_server *server); +void ncp_unlock_server(struct ncp_server *server); + +/* linux/fs/ncpfs/mmap.c */ +int ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma); + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_NCP_FS_H */ diff --git a/include/linux/ncp_fs_i.h b/include/linux/ncp_fs_i.h new file mode 100644 index 000000000..02ad1b452 --- /dev/null +++ b/include/linux/ncp_fs_i.h @@ -0,0 +1,36 @@ +/* + * ncp_fs_i.h + * + * Copyright (C) 1995 Volker Lendecke + * + */ + +#ifndef _LINUX_NCP_FS_I +#define _LINUX_NCP_FS_I + +#include <linux/ncp.h> + +#ifdef __KERNEL__ + +enum ncp_inode_state { + NCP_INODE_VALID = 19, /* Inode currently in use */ + NCP_INODE_LOOKED_UP, /* directly before iget */ + NCP_INODE_CACHED, /* in a path to an inode which is in use */ + NCP_INODE_INVALID +}; + +/* + * ncp fs inode data (in memory only) + */ +struct ncp_inode_info { + enum ncp_inode_state state; + int nused; /* for directories: + number of references in memory */ + struct ncp_inode_info *dir; + struct ncp_inode_info *next, *prev; + struct inode *inode; + struct nw_file_info finfo; +}; + +#endif +#endif diff --git a/include/linux/ncp_fs_sb.h b/include/linux/ncp_fs_sb.h new file mode 100644 index 000000000..6d1d7c510 --- /dev/null +++ b/include/linux/ncp_fs_sb.h @@ -0,0 +1,76 @@ +/* + * ncp_fs_sb.h + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * + */ + +#ifndef _NCP_FS_SB +#define _NCP_FS_SB + +#include <linux/ncp_mount.h> +#include <linux/types.h> + +#ifdef __KERNEL__ + +#define NCP_DEFAULT_BUFSIZE 1024 + +struct ncp_server { + + struct ncp_mount_data m; /* Nearly all of the mount data is of + interest for us later, so we store + it completely. */ + + __u8 name_space[NCP_NUMBER_OF_VOLUMES]; + + struct file *ncp_filp; /* File pointer to ncp socket */ + struct file *wdog_filp; /* File pointer to wdog socket */ + struct file *msg_filp; /* File pointer to message socket */ + void *data_ready; /* The wdog socket gets a new + data_ready callback. We store the + old one for checking purposes and + to reset it on unmounting. */ + + u8 sequence; + u8 task; + u16 connection; /* Remote connection number */ + + u8 completion; /* Status message from server */ + u8 conn_status; /* Bit 4 = 1 ==> Server going down, no + requests allowed anymore. + Bit 0 = 1 ==> Server is down. */ + + int buffer_size; /* Negotiated bufsize */ + + int reply_size; /* Size of last reply */ + + int packet_size; + unsigned char *packet; /* Here we prepare requests and + receive replies */ + + int lock; /* To prevent mismatch in protocols. */ + struct wait_queue *wait; + + int current_size; /* for packet preparation */ + int has_subfunction; + int ncp_reply_size; + + struct ncp_inode_info root; + char root_path; /* '\0' */ +}; + +static inline int +ncp_conn_valid(struct ncp_server *server) +{ + return ((server->conn_status & 0x11) == 0); +} + +static inline void +ncp_invalidate_conn(struct ncp_server *server) +{ + server->conn_status |= 0x01; +} + +#endif /* __KERNEL__ */ + +#endif diff --git a/include/linux/ncp_mount.h b/include/linux/ncp_mount.h new file mode 100644 index 000000000..3de288659 --- /dev/null +++ b/include/linux/ncp_mount.h @@ -0,0 +1,49 @@ +/* + * ncp_mount.h + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * + */ + +#ifndef _LINUX_NCP_MOUNT_H +#define _LINUX_NCP_MOUNT_H + +#include <linux/types.h> +#include <linux/ipx.h> +#include <linux/ncp.h> +#include <linux/ncp_fs_i.h> + +#define NCP_MOUNT_VERSION 2 + +#define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN) +#define NCP_PASSWORD_LEN 20 + +/* Values for flags */ +#define NCP_MOUNT_SOFT 0x0001 +#define NCP_MOUNT_INTR 0x0002 + +struct ncp_mount_data { + int version; + unsigned int ncp_fd; /* The socket to the ncp port */ + unsigned int wdog_fd; /* Watchdog packets come here */ + unsigned int message_fd; /* Message notifications come here */ + uid_t mounted_uid; /* Who may umount() this filesystem? */ + + struct sockaddr_ipx serv_addr; + unsigned char server_name[NCP_BINDERY_NAME_LEN]; + + unsigned char mount_point[PATH_MAX+1]; + unsigned char mounted_vol[NCP_VOLNAME_LEN+1]; + + unsigned int time_out; /* How long should I wait after + sending a NCP request? */ + unsigned int retry_count; /* And how often should I retry? */ + unsigned int flags; + + uid_t uid; + gid_t gid; + mode_t file_mode; + mode_t dir_mode; +}; + +#endif diff --git a/include/linux/net.h b/include/linux/net.h index bad60518f..a338a8efd 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -22,9 +22,6 @@ #include <linux/wait.h> #include <linux/socket.h> - -#define NSOCKETS 2000 /* Dynamic, this is MAX LIMIT */ -#define NSOCKETS_UNIX 128 /* unix domain static limit */ #define NPROTO 16 /* should be enough for now.. */ @@ -43,6 +40,8 @@ #define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ #define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ #define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ +#define SYS_SENDMSG 16 /* sys_sendmsg(2) */ +#define SYS_RECVMSG 17 /* sys_recvmsg(2) */ typedef enum { @@ -81,6 +80,7 @@ struct socket { struct wait_queue **wait; /* ptr to place to wait on */ struct inode *inode; struct fasync_struct *fasync_list; /* Asynchronous wake up list */ + struct file *file; /* File back pointer for gc */ }; #define SOCK_INODE(S) ((S)->inode) @@ -100,23 +100,11 @@ struct proto_ops { int flags); int (*getname) (struct socket *sock, struct sockaddr *uaddr, int *usockaddr_len, int peer); - int (*read) (struct socket *sock, char *ubuf, int size, - int nonblock); - int (*write) (struct socket *sock, char *ubuf, int size, - int nonblock); int (*select) (struct socket *sock, int sel_type, select_table *wait); int (*ioctl) (struct socket *sock, unsigned int cmd, unsigned long arg); int (*listen) (struct socket *sock, int len); - int (*send) (struct socket *sock, void *buff, int len, int nonblock, - unsigned flags); - int (*recv) (struct socket *sock, void *buff, int len, int nonblock, - unsigned flags); - int (*sendto) (struct socket *sock, void *buff, int len, int nonblock, - unsigned flags, struct sockaddr *, int addr_len); - int (*recvfrom) (struct socket *sock, void *buff, int len, int nonblock, - unsigned flags, struct sockaddr *, int *addr_len); int (*shutdown) (struct socket *sock, int flags); int (*setsockopt) (struct socket *sock, int level, int optname, char *optval, int optlen); @@ -124,14 +112,15 @@ struct proto_ops { char *optval, int *optlen); int (*fcntl) (struct socket *sock, unsigned int cmd, unsigned long arg); + int (*sendmsg) (struct socket *sock, struct msghdr *m, int total_len, int nonblock, int flags); + int (*recvmsg) (struct socket *sock, struct msghdr *m, int total_len, int nonblock, int flags, int *addr_len); }; struct net_proto { - char *name; /* Protocol name */ + const char *name; /* Protocol name */ void (*init_func)(struct net_proto *); /* Bootstrap */ }; -extern int sock_awaitconn(struct socket *mysock, struct socket *servsock, int flags); extern int sock_wake_async(struct socket *sock, int how); extern int sock_register(int family, struct proto_ops *ops); extern int sock_unregister(int family); diff --git a/include/linux/net_alias.h b/include/linux/net_alias.h new file mode 100644 index 000000000..67a9f9bea --- /dev/null +++ b/include/linux/net_alias.h @@ -0,0 +1,172 @@ +/* + * NET_ALIAS network device aliasing definitions. + * + * + * Version: @(#)net_alias.h 0.43 12/20/95 + * + * Author: Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar> + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#ifndef _NET_ALIAS_H +#define _NET_ALIAS_H + +#include <linux/types.h> +#include <linux/if.h> +#include <linux/netdevice.h> + +/* + * max. alias slot number allowed + */ + +#define NET_ALIAS_MAX_SLOT 256 + +struct net_alias; +struct net_alias_info; +struct net_alias_type; + + +/* + * main alias structure + * note that *defines* dev & devname + */ + +struct net_alias +{ + struct device dev; /* alias device defn*/ + char name[IFNAMSIZ]; /* device name defn */ + unsigned hash; /* my hash value: for quick rehash */ + unsigned slot; /* slot number */ + void *data; /* private data */ + struct device *main_dev; /* pointer to main device */ + struct net_alias_type *nat; /* alias type object bound */ + struct net_alias *next; /* next alias (hashed linked list) */ +}; + + +/* + * alias structure pointed by main device + * it holds main device's alias hash table + */ + +struct net_alias_info +{ + int n_aliases; /* num aliases */ + struct device *taildev; /* my last (alias) device */ + struct net_alias *hash_tab[16]; /* hashed alias table */ +}; + +/* + * net_alias_type class + * declares a generic (AF_ independent) structure that will + * manage generic to family-specific behavior. + */ + +struct net_alias_type +{ + int type; /* aliasing type: address family */ + int n_attach; /* number of aliases attached */ + char name[16]; /* af_name */ + __u32 (*get_addr32) /* get __u32 addr 'representation'*/ + (struct net_alias_type *this, struct sockaddr*); + int (*dev_addr_chk) /* address checking func: */ + (struct net_alias_type *this, struct device *, struct sockaddr *); + struct device * (*dev_select) /* closest alias selector*/ + (struct net_alias_type *this, struct device *, struct sockaddr *sa); + int (*alias_init_1) /* called after alias creation: */ + (struct net_alias_type *this,struct net_alias *alias, struct sockaddr *sa); + int (*alias_done_1) /* called before alias deletion */ + (struct net_alias_type *this, struct net_alias *alias); + int (*alias_print_1) + (struct net_alias_type *this, struct net_alias *alias, char *buf, int len); + struct net_alias_type *next; /* link */ +}; + + +/* + * is dev an alias? + */ + +static __inline__ int +net_alias_is(struct device *dev) +{ + return (dev->my_alias != NULL); +} + + +/* + * does dev have aliases? + */ + +static __inline__ int +net_alias_has(struct device *dev) +{ + return (dev->alias_info != NULL); +} + + +extern void net_alias_init(void); + +extern struct device * net_alias_dev_get(char *dev_name, int aliasing_ok, int *err, struct sockaddr *sa, void *data); +extern int net_alias_dev_rehash(struct device *dev, struct sockaddr *sa); + +extern int net_alias_getinfo(char *buf, char **, off_t , int , int ); +extern int net_alias_types_getinfo(char *buf, char **, off_t , int , int ); + +extern int register_net_alias_type(struct net_alias_type *nat, int type); +extern int unregister_net_alias_type(struct net_alias_type *nat); + +extern struct device * net_alias_dev_chk(struct device *main_dev, struct sockaddr *sa, int flags_on, int flags_off); +extern struct device * net_alias_dev_chk32(struct device *main_dev, int family, __u32 addr32, int flags_on, int flags_off); + +extern struct device * net_alias_dev_rcv_sel(struct device *main_dev, struct sockaddr *sa_src, struct sockaddr *sa_dst); +extern struct device * net_alias_dev_rcv_sel32(struct device *main_dev, int family, __u32 src, __u32 dst); + + +/* + * returns MY 'true' main device + * intended for alias devices + */ + +static __inline__ struct device *net_alias_main_dev(struct device *dev) +{ + return (net_alias_is(dev))? dev->my_alias->main_dev : dev; +} + + +/* + * returns NEXT 'true' device + * intended for true devices + */ + +static __inline__ struct device * +net_alias_nextdev(struct device *dev) +{ + return (dev->alias_info)? dev->alias_info->taildev->next : dev->next; +} + + +/* + * sets NEXT 'true' device + * intended for main devices (treat main device as block: dev+aliases). + */ + +static __inline__ struct device * +net_alias_nextdev_set(struct device *dev, struct device *nextdev) +{ + struct device *pdev = dev; + if (net_alias_has(dev)) + { + pdev = dev->alias_info->taildev; /* point to last dev alias */ + } + pdev->next = nextdev; + return nextdev; +} + +#endif /* _NET_ALIAS_H */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8800f647b..55c72a1c7 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -24,14 +24,30 @@ #ifndef _LINUX_NETDEVICE_H #define _LINUX_NETDEVICE_H +#include <linux/config.h> #include <linux/if.h> #include <linux/if_ether.h> -#include <linux/skbuff.h> /* for future expansion when we will have different priorities. */ #define DEV_NUMBUFFS 3 #define MAX_ADDR_LEN 7 -#define MAX_HEADER 38 + +#if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR) +#define LL_MAX_HEADER 32 +#else +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) +#define LL_MAX_HEADER 96 +#else +#define LL_MAX_HEADER 48 +#endif +#endif + +#if !defined(CONFIG_NET_IPIP) && \ + !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) +#define MAX_HEADER LL_MAX_HEADER +#else +#define MAX_HEADER (LL_MAX_HEADER + 48) +#endif #define IS_MYADDR 1 /* address is (one of) our own */ #define IS_LOOPBACK 2 /* address is for LOOPBACK */ @@ -39,8 +55,12 @@ #define IS_INVBCAST 4 /* Wrong netmask bcast not for us (unused)*/ #define IS_MULTICAST 5 /* Multicast IP address */ +#ifdef __KERNEL__ + +#include <linux/skbuff.h> + /* - * We tag these structures with multicasts. + * We tag multicasts with these structures. */ struct dev_mc_list @@ -51,6 +71,19 @@ struct dev_mc_list unsigned short dmi_users; }; +struct hh_cache +{ + struct hh_cache *hh_next; + void *hh_arp; /* Opaque pointer, used by + * any address resolution module, + * not only ARP. + */ + int hh_refcnt; /* number of users */ + unsigned short hh_type; /* protocol identifier, f.e ETH_P_IP */ + char hh_uptodate; /* hh_data is valid */ + char hh_data[16]; /* cached hardware header */ +}; + /* * The DEVICE structure. * Actually, this whole structure is a big mistake. It mixes I/O @@ -70,15 +103,15 @@ struct device /* I/O specific fields - FIXME: Merge these and struct ifmap into one */ unsigned long rmem_end; /* shmem "recv" end */ unsigned long rmem_start; /* shmem "recv" start */ - unsigned long mem_end; /* sahared mem end */ + unsigned long mem_end; /* shared mem end */ unsigned long mem_start; /* shared mem start */ unsigned long base_addr; /* device I/O address */ unsigned char irq; /* device IRQ number */ /* Low-level status flags. */ - volatile unsigned int tbusy; /* transmitter busy */ volatile unsigned char start, /* start an operation */ interrupt; /* interrupt arrived */ + unsigned long tbusy; /* transmitter busy must be long for bitops */ struct device *next; @@ -112,9 +145,16 @@ struct device /* Interface address info. */ unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ + unsigned char pad; /* make dev_addr aligned to 8 bytes */ unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */ unsigned char addr_len; /* hardware address length */ +#if 0 + __u32 pa_addr_arr[4]; + __u16 pa_prefix_len; +#define pa_addr pa_addr_arr[3]; +#else unsigned long pa_addr; /* protocol address */ +#endif unsigned long pa_brdaddr; /* protocol broadcast addr */ unsigned long pa_dstaddr; /* protocol P-P other side addr */ unsigned long pa_mask; /* protocol netmask */ @@ -124,13 +164,15 @@ struct device int mc_count; /* Number of installed mcasts */ struct ip_mc_list *ip_mc_list; /* IP multicast filter chain */ + __u32 tx_queue_len; /* Max frames per queue allowed */ /* For load balancing driver pair support */ unsigned long pkt_queue; /* Packets queued */ struct device *slave; /* Slave device */ + struct net_alias_info *alias_info; /* main dev alias info */ + struct net_alias *my_alias; /* alias devs */ - /* Pointer to the interface buffers. */ struct sk_buff_head buffs[DEV_NUMBUFFS]; @@ -139,25 +181,27 @@ struct device int (*stop)(struct device *dev); int (*hard_start_xmit) (struct sk_buff *skb, struct device *dev); - int (*hard_header) (unsigned char *buff, + int (*hard_header) (struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, void *saddr, - unsigned len, - struct sk_buff *skb); + unsigned len); int (*rebuild_header)(void *eth, struct device *dev, unsigned long raddr, struct sk_buff *skb); #define HAVE_MULTICAST - void (*set_multicast_list)(struct device *dev, - int num_addrs, void *addrs); + void (*set_multicast_list)(struct device *dev); #define HAVE_SET_MAC_ADDR int (*set_mac_address)(struct device *dev, void *addr); #define HAVE_PRIVATE_IOCTL int (*do_ioctl)(struct device *dev, struct ifreq *ifr, int cmd); #define HAVE_SET_CONFIG int (*set_config)(struct device *dev, struct ifmap *map); - int (*header_cache)(struct device *dev, struct sock *sk, unsigned long saddr, unsigned long daddr); +#define HAVE_HEADER_CACHE + void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev, unsigned short htype, __u32 daddr); + void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr); +#define HAVE_CHANGE_MTU + int (*change_mtu)(struct device *dev, int new_mtu); }; @@ -171,14 +215,13 @@ struct packet_type { }; -#ifdef __KERNEL__ - +#include <linux/interrupt.h> #include <linux/notifier.h> /* Used by dev_rint */ #define IN_SKBUFF 1 -extern volatile int in_bh; +extern volatile unsigned long in_bh; extern struct device loopback_dev; extern struct device *dev_base; @@ -187,34 +230,72 @@ extern struct packet_type *ptype_base[16]; extern int ip_addr_match(unsigned long addr1, unsigned long addr2); extern int ip_chk_addr(unsigned long addr); -extern struct device *ip_dev_check(unsigned long daddr); +extern struct device *ip_dev_bynet(unsigned long daddr, unsigned long mask); extern unsigned long ip_my_addr(void); extern unsigned long ip_get_mask(unsigned long addr); +extern struct device *ip_dev_find(unsigned long addr); +extern struct device *dev_getbytype(unsigned short type); extern void dev_add_pack(struct packet_type *pt); extern void dev_remove_pack(struct packet_type *pt); -extern struct device *dev_get(char *name); +extern struct device *dev_get(const char *name); extern int dev_open(struct device *dev); extern int dev_close(struct device *dev); extern void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri); + #define HAVE_NETIF_RX 1 extern void netif_rx(struct sk_buff *skb); -/* The old interface to netif_rx(). */ -extern int dev_rint(unsigned char *buff, long len, int flags, - struct device * dev); -extern void dev_transmit(void); -extern int in_net_bh(void); -extern void net_bh(void *tmp); +extern void net_bh(void); extern void dev_tint(struct device *dev); -extern int dev_get_info(char *buffer, char **start, off_t offset, int length); +extern int dev_get_info(char *buffer, char **start, off_t offset, int length, int dummy); extern int dev_ioctl(unsigned int cmd, void *); extern void dev_init(void); +/* Locking protection for page faults during outputs to devices unloaded during the fault */ + +extern int dev_lockct; + +/* + * These two don't currently need to be interrupt-safe + * but they may do soon. Do it properly anyway. + */ + +extern __inline__ void dev_lock_list(void) +{ + unsigned long flags; + save_flags(flags); + cli(); + dev_lockct++; + restore_flags(flags); +} + +extern __inline__ void dev_unlock_list(void) +{ + unsigned long flags; + save_flags(flags); + cli(); + dev_lockct--; + restore_flags(flags); +} + +/* + * This almost never occurs, isn't in performance critical paths + * and we can thus be relaxed about it + */ + +extern __inline__ void dev_lock_wait(void) +{ + while(dev_lockct) + schedule(); +} + + /* These functions live elsewhere (drivers/net/net_init.c, but related) */ extern void ether_setup(struct device *dev); +extern void fddi_setup(struct device *dev); extern void tr_setup(struct device *dev); extern int ether_config(struct device *dev, struct ifmap *map); /* Support for loadable net-drivers */ diff --git a/include/linux/netrom.h b/include/linux/netrom.h index 935deb2b8..a7557ccb3 100644 --- a/include/linux/netrom.h +++ b/include/linux/netrom.h @@ -1,40 +1,45 @@ +/* + * These are the public elements of the Linux kernel NET/ROM implementation. + * For kernel AX.25 see the file ax25.h. This file requires ax25.h for the + * definition of the ax25_address structure. + */ + +#ifndef NETROM_KERNEL_H +#define NETROM_KERNEL_H + #define PF_NETROM AF_NETROM #define NETROM_MTU 236 #define NETROM_T1 1 #define NETROM_T2 2 #define NETROM_N2 3 +#define NETROM_HDRINCL 4 +#define NETROM_PACLEN 5 +#define NETROM_T4 6 +#define NETROM_IDLE 7 + +#define NETROM_KILL 99 -#define SIOCNRADDNODE (SIOCPROTOPRIVATE) -#define SIOCNRDELNODE (SIOCPROTOPRIVATE+1) -#define SIOCNRADDNEIGH (SIOCPROTOPRIVATE+2) -#define SIOCNRDELNEIGH (SIOCPROTOPRIVATE+3) -#define SIOCNRGETPARMS (SIOCPROTOPRIVATE+4) -#define SIOCNRSETPARMS (SIOCPROTOPRIVATE+5) -#define SIOCNRDECOBS (SIOCPROTOPRIVATE+6) +#define SIOCNRDECOBS (SIOCPROTOPRIVATE+0) +#define SIOCNRCTLCON (SIOCPROTOPRIVATE+1) -struct nr_node_struct { +struct nr_route_struct { +#define NETROM_NEIGH 0 +#define NETROM_NODE 1 + int type; ax25_address callsign; - char mnemonic[7]; - ax25_address neighbour; char device[16]; unsigned int quality; + char mnemonic[7]; + ax25_address neighbour; unsigned int obs_count; }; -struct nr_neigh_struct { - ax25_address callsign; - char device[16]; - unsigned int quality; +struct nr_ctl_struct { + unsigned char index; + unsigned char id; + unsigned int cmd; + unsigned long arg; }; -struct nr_parms_struct { - unsigned int quality; - unsigned int obs_count; - unsigned int ttl; - unsigned int timeout; - unsigned int ack_delay; - unsigned int busy_delay; - unsigned int tries; - unsigned int window; -}; +#endif diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 66116a4e7..7924ecdec 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -17,7 +17,7 @@ /* * The readdir cache size controls how many directory entries are cached. * Its size is limited by the number of nfs_entry structures that can fit - * in one 4096-byte page, currently 256. + * in one page, currently, the limit is 256 when using 4KB pages. */ #define NFS_READDIR_CACHE_SIZE 64 @@ -26,11 +26,10 @@ #define NFS_DEF_FILE_IO_BUFFER_SIZE 1024 /* - * The upper limit on timeouts for the exponential backoff algorithm - * in tenths of a second. + * The upper limit on timeouts for the exponential backoff algorithm. */ -#define NFS_MAX_RPC_TIMEOUT 600 +#define NFS_MAX_RPC_TIMEOUT (6*HZ) /* * Size of the lookup cache in units of number of entries cached. @@ -44,6 +43,19 @@ #define NFS_SERVER(inode) (&(inode)->i_sb->u.nfs_sb.s_server) #define NFS_FH(inode) (&(inode)->u.nfs_i.fhandle) +#define NFS_RENAMED_DIR(inode) ((inode)->u.nfs_i.silly_rename_dir) +#define NFS_READTIME(inode) ((inode)->u.nfs_i.read_cache_jiffies) +#define NFS_OLDMTIME(inode) ((inode)->u.nfs_i.read_cache_mtime) +#define NFS_ATTRTIMEO(inode) ((inode)->u.nfs_i.attrtimeo) +#define NFS_MINATTRTIMEO(inode) (S_ISREG((inode)->i_mode)? \ + NFS_SERVER(inode)->acregmin : \ + NFS_SERVER(inode)->acdirmin) +#define NFS_CACHEINV(inode) \ +do { \ + NFS_READTIME(inode) = jiffies - 1000000; \ + NFS_OLDMTIME(inode) = 0; \ +} while (0) + #ifdef __KERNEL__ @@ -61,10 +73,9 @@ extern int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle, unsigned int maxlen); extern int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle, int offset, int count, char *data, - struct nfs_fattr *fattr, int fs); -extern int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle, - int offset, int count, char *data, - struct nfs_fattr *fattr); + struct nfs_fattr *fattr); +extern int nfs_proc_write(struct inode * inode, int offset, + int count, const char *data, struct nfs_fattr *fattr); extern int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir, const char *name, struct nfs_sattr *sattr, struct nfs_fh *fhandle, struct nfs_fattr *fattr); @@ -72,7 +83,8 @@ extern int nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir, const char *name); extern int nfs_proc_rename(struct nfs_server *server, struct nfs_fh *old_dir, const char *old_name, - struct nfs_fh *new_dir, const char *new_name); + struct nfs_fh *new_dir, const char *new_name, + int must_be_dir); extern int nfs_proc_link(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fh *dir, const char *name); extern int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir, @@ -86,15 +98,26 @@ extern int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle, int cookie, int count, struct nfs_entry *entry); extern int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *res); +extern int nfs_proc_read_request(struct rpc_ioreq *, struct nfs_server *, + struct nfs_fh *, unsigned long offset, + unsigned long count, __u32 *buf); +extern int nfs_proc_read_reply(struct rpc_ioreq *, struct nfs_fattr *); +extern int *rpc_header(int *p, int procedure, int program, int version, + int uid, int gid, int ngroup, gid_t *groups); +extern int *rpc_verify(int *p); /* linux/fs/nfs/sock.c */ -extern int nfs_rpc_call(struct nfs_server *server, int *start, int *end, int size); +extern int nfs_rpc_call(struct nfs_server *server, int *start, + int *end, int size); +extern int nfs_rpc_doio(struct nfs_server *server, struct rpc_ioreq *, + int async); /* linux/fs/nfs/inode.c */ extern struct super_block *nfs_read_super(struct super_block *sb, void *data,int); +extern int init_nfs_fs(void); extern struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle, struct nfs_fattr *fattr); extern void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr); @@ -106,6 +129,8 @@ extern struct inode_operations nfs_file_inode_operations; /* linux/fs/nfs/dir.c */ extern struct inode_operations nfs_dir_inode_operations; +extern void nfs_sillyrename_cleanup(struct inode *); +extern void nfs_kfree_cache(void); /* linux/fs/nfs/symlink.c */ @@ -115,6 +140,21 @@ extern struct inode_operations nfs_symlink_inode_operations; extern int nfs_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma); +/* linux/fs/nfs/bio.c */ + +extern int nfs_readpage(struct inode *, struct page *); + +/* NFS root */ + +#define NFS_ROOT "/tftpboot/%s" +#define NFS_ROOT_NAME_LEN 256 +#define NFS_ROOT_ADDRS_LEN 128 + +extern int nfs_root_mount(struct super_block *sb); +extern int nfs_root_init(char *nfsname, char *nfsaddrs); +extern char nfs_root_name[]; +extern char nfs_root_addrs[]; + #endif /* __KERNEL__ */ #endif diff --git a/include/linux/nfs_fs_i.h b/include/linux/nfs_fs_i.h index d4652865b..7715c3a4d 100644 --- a/include/linux/nfs_fs_i.h +++ b/include/linux/nfs_fs_i.h @@ -2,12 +2,36 @@ #define _NFS_FS_I #include <linux/nfs.h> +#include <linux/pipe_fs_i.h> /* * nfs fs inode data in memory */ struct nfs_inode_info { + struct pipe_inode_info pipeinfo; struct nfs_fh fhandle; + /* + * read_cache_jiffies is when we started read-caching this inode, + * and read_cache_mtime is the mtime of the inode at that time. + * + * We need to invalidate the cache for this inode if + * + * jiffies - read_cache_jiffies > 30*HZ + * AND + * mtime != read_cache_mtime + */ + unsigned long read_cache_jiffies; + unsigned long read_cache_mtime; + /* + * This is to support the clandestine rename on unlink. + * Instead of the directory inode, we might as well keep its + * NFS FH, but that requires a kmalloc. + */ + struct inode *silly_rename_dir; + /* + * attrtimeo defines for how long the cached attributes are valid + */ + unsigned long attrtimeo; }; #endif diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 25db9e83f..bfdba35b4 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -1,10 +1,13 @@ #ifndef _NFS_FS_SB #define _NFS_FS_SB +#include <linux/rpcsock.h> #include <linux/nfs.h> struct nfs_server { struct file *file; + struct rpc_sock *rsock; + struct sockaddr toaddr ; /* Added for change to NFS code to use sendto() 1995-06-02 JSP */ int lock; struct wait_queue *wait; int flags; diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h index beb5f1dd8..b122b43dc 100644 --- a/include/linux/nfs_mount.h +++ b/include/linux/nfs_mount.h @@ -17,7 +17,19 @@ * but here they are anyway. */ -#define NFS_MOUNT_VERSION 1 /* current version */ +#define NFS_NFS_PROGRAM 100003 /* nfsd program number */ +#define NFS_NFS_VERSION 2 /* nfsd version */ +#define NFS_NFS_PORT 2049 /* portnumber on server for nfsd */ + +#define NFS_MOUNT_PROGRAM 100005 /* mountd program number */ +#define NFS_MOUNT_VERSION 1 /* mountd version */ +#define NFS_MOUNT_PROC 1 /* mount process id */ +#define NFS_MOUNT_PORT 627 /* portnumber on server for mountd */ + +#define NFS_PMAP_PROGRAM 100000 /* portmap program number */ +#define NFS_PMAP_VERSION 2 /* portmap version */ +#define NFS_PMAP_PROC 3 /* portmap getport id */ +#define NFS_PMAP_PORT 111 /* portnumber on server for portmap */ struct nfs_mount_data { int version; /* 1 */ diff --git a/include/linux/nfsiod.h b/include/linux/nfsiod.h new file mode 100644 index 000000000..fdd07a2d0 --- /dev/null +++ b/include/linux/nfsiod.h @@ -0,0 +1,52 @@ +/* + * linux/include/linux/nfsiod.h + * + * Declarations for asynchronous NFS RPC calls. + * + */ + +#ifndef _LINUX_NFSIOD_H +#define _LINUX_NFSIOD_H + +#include <linux/rpcsock.h> +#include <linux/nfs_fs.h> + +#ifdef __KERNEL__ + +/* + * This is the callback handler for nfsiod requests. + * Note that the callback procedure must NOT sleep. + */ +struct nfsiod_req; +typedef int (*nfsiod_callback_t)(int result, struct nfsiod_req *); + +/* + * This is the nfsiod request struct. + */ +struct nfsiod_req { + struct nfsiod_req * rq_next; + struct nfsiod_req * rq_prev; + struct wait_queue * rq_wait; + struct rpc_ioreq rq_rpcreq; + nfsiod_callback_t rq_callback; + struct nfs_server * rq_server; + struct inode * rq_inode; + struct page * rq_page; + + /* user creds */ + uid_t rq_fsuid; + gid_t rq_fsgid; + int rq_groups[NGROUPS]; + + /* retry handling */ + int rq_retries; +}; + +struct nfsiod_req * nfsiod_reserve(struct nfs_server *); +void nfsiod_release(struct nfsiod_req *); +void nfsiod_enqueue(struct nfsiod_req *); +int nfsiod(void); + + +#endif /* __KERNEL__ */ +#endif /* _LINUX_NFSIOD_H */ diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 78a446496..b3c9ccf65 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -13,7 +13,7 @@ struct notifier_block { - int (*notifier_call)(unsigned long, void *); + int (*notifier_call)(struct notifier_block *this, unsigned long, void *); struct notifier_block *next; int priority; }; @@ -68,7 +68,7 @@ extern __inline__ int notifier_call_chain(struct notifier_block **n, unsigned lo struct notifier_block *nb = *n; while(nb) { - ret=nb->notifier_call(val,v); + ret=nb->notifier_call(nb,val,v); if(ret&NOTIFY_STOP_MASK) return ret; nb=nb->next; diff --git a/include/linux/optcd.h b/include/linux/optcd.h new file mode 100644 index 000000000..00dd3aed8 --- /dev/null +++ b/include/linux/optcd.h @@ -0,0 +1,52 @@ +/* linux/include/linux/optcd.h - Optics Storage 8000 AT CDROM driver + $Id: optcd.h,v 1.2 1996/01/15 18:43:44 root Exp root $ + + Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl) + + + Configuration file for linux/drivers/cdrom/optcd.c +*/ + +#ifndef _LINUX_OPTCD_H +#define _LINUX_OPTCD_H + + +/* I/O base of drive. Drive uses base to base+2. + This setting can be overridden with the kernel or insmod command + line option 'optcd=<portbase>'. Use address of 0 to disable driver. */ +#define OPTCD_PORTBASE 0x340 + + +/* enable / disable parts of driver by define / undef */ +#define MULTISESSION /* multisession support (ALPHA) */ + + +/* Change 0 to 1 to debug various parts of the driver */ +#define DEBUG_DRIVE_IF 0 /* Low level drive interface */ +#define DEBUG_CONV 0 /* Address conversions */ +#define DEBUG_BUFFERS 0 /* Buffering and block size conversion */ +#define DEBUG_REQUEST 0 /* Request mechanism */ +#define DEBUG_STATE 0 /* State machine */ +#define DEBUG_TOC 0 /* Q-channel and Table of Contents */ +#define DEBUG_MULTIS 0 /* Multisession code */ +#define DEBUG_VFS 0 /* VFS interface */ + + +/* Don't touch these unless you know what you're doing. */ + +/* Various timeout loop repetition counts. */ +#define BUSY_TIMEOUT 10000000 /* for busy wait */ +#define FAST_TIMEOUT 100000 /* ibid. for probing */ +#define SLEEP_TIMEOUT 6000 /* for timer wait */ +#define MULTI_SEEK_TIMEOUT 1000 /* for timer wait */ +#define READ_TIMEOUT 6000 /* for poll wait */ +#define STOP_TIMEOUT 2000 /* for poll wait */ +#define RESET_WAIT 5000 /* busy wait at drive reset */ + +/* # of buffers for block size conversion. 6 is optimal for my setup (P75), + giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal + setting */ +#define N_BUFS 6 + + +#endif _LINUX_OPTCD_H diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h new file mode 100644 index 000000000..868874192 --- /dev/null +++ b/include/linux/pagemap.h @@ -0,0 +1,145 @@ +#ifndef _LINUX_PAGEMAP_H +#define _LINUX_PAGEMAP_H + +#include <asm/system.h> + +/* + * Page-mapping primitive inline functions + * + * Copyright 1995 Linus Torvalds + */ + +#include <linux/mm.h> +#include <linux/fs.h> + +static inline unsigned long page_address(struct page * page) +{ + return PAGE_OFFSET + PAGE_SIZE * page->map_nr; +} + +#define PAGE_HASH_BITS 11 +#define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS) + +#define PAGE_AGE_VALUE 16 + +extern unsigned long page_cache_size; /* # of pages currently in the hash table */ +extern struct page * page_hash_table[PAGE_HASH_SIZE]; + +/* + * We use a power-of-two hash table to avoid a modulus, + * and get a reasonable hash by knowing roughly how the + * inode pointer and offsets are distributed (ie, we + * roughly know which bits are "significant") + */ +static inline unsigned long _page_hashfn(struct inode * inode, unsigned long offset) +{ +#define i (((unsigned long) inode)/(sizeof(struct inode) & ~ (sizeof(struct inode) - 1))) +#define o (offset >> PAGE_SHIFT) +#define s(x) ((x)+((x)>>PAGE_HASH_BITS)) + return s(i+o) & (PAGE_HASH_SIZE-1); +#undef i +#undef o +#undef s +} + +#define page_hash(inode,offset) (page_hash_table+_page_hashfn(inode,offset)) + +static inline struct page * __find_page(struct inode * inode, unsigned long offset, struct page *page) +{ + goto inside; + for (;;) { + page = page->next_hash; +inside: + if (!page) + goto not_found; + if (page->inode != inode) + continue; + if (page->offset == offset) + break; + } + /* Found the page. */ + atomic_inc(&page->count); + set_bit(PG_referenced, &page->flags); +not_found: + return page; +} + +static inline struct page *find_page(struct inode * inode, unsigned long offset) +{ + return __find_page(inode, offset, *page_hash(inode, offset)); +} + +static inline void remove_page_from_hash_queue(struct page * page) +{ + struct page **p; + struct page *next_hash, *prev_hash; + + next_hash = page->next_hash; + prev_hash = page->prev_hash; + page->next_hash = NULL; + page->prev_hash = NULL; + if (next_hash) + next_hash->prev_hash = prev_hash; + if (prev_hash) + prev_hash->next_hash = next_hash; + p = page_hash(page->inode,page->offset); + if (*p == page) + *p = next_hash; + page_cache_size--; +} + +static inline void __add_page_to_hash_queue(struct page * page, struct page **p) +{ + page_cache_size++; + set_bit(PG_referenced, &page->flags); + page->age = PAGE_AGE_VALUE; + page->prev_hash = NULL; + if ((page->next_hash = *p) != NULL) + page->next_hash->prev_hash = page; + *p = page; +} + +static inline void add_page_to_hash_queue(struct page * page, struct inode * inode, unsigned long offset) +{ + __add_page_to_hash_queue(page, page_hash(inode,offset)); +} + + +static inline void remove_page_from_inode_queue(struct page * page) +{ + struct inode * inode = page->inode; + + page->inode = NULL; + inode->i_nrpages--; + if (inode->i_pages == page) + inode->i_pages = page->next; + if (page->next) + page->next->prev = page->prev; + if (page->prev) + page->prev->next = page->next; + page->next = NULL; + page->prev = NULL; +} + +static inline void add_page_to_inode_queue(struct inode * inode, struct page * page) +{ + struct page **p = &inode->i_pages; + + inode->i_nrpages++; + page->inode = inode; + page->prev = NULL; + if ((page->next = *p) != NULL) + page->next->prev = page; + *p = page; +} + +extern void __wait_on_page(struct page *); +static inline void wait_on_page(struct page * page) +{ + if (PageLocked(page)) + __wait_on_page(page); +} + +extern void update_vm_cache(struct inode *, unsigned long, const char *, int); + +#endif diff --git a/include/linux/pci.h b/include/linux/pci.h index 0be42eadc..4118dfdc0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -22,16 +22,23 @@ /* PROCEDURE TO REPORT NEW PCI DEVICES - * We are trying to collect informations on new PCI devices, using - * the standart PCI identification procedure. If some warning is + * We are trying to collect information on new PCI devices, using + * the standard PCI identification procedure. If some warning is * displayed at boot time, please report * - /proc/pci * - your exact hardware description. Try to find out * which device is unknown. It may be you mainboard chipset. * PCI-CPU bridge or PCI-ISA bridge. - * - Send all that to frederic@cao-vlsi.ibp.fr, and I'll add - * your device to the list as soon as possible - * fred. + * - If you can't find the actual information in your hardware + * booklet, try to read the references of the chip on the board. + * - Send all that to linux-pcisupport@cao-vlsi.ibp.fr, + * and I'll add your device to the list as soon as possible + * + * BEFORE you send a mail, please check the latest linux releases + * to be sure it has not been recently added. + * + * Thanks + * Frederic Potter. */ @@ -47,7 +54,7 @@ #define PCI_DEVICE_ID 0x02 /* 16 bits */ #define PCI_COMMAND 0x04 /* 16 bits */ #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ -#define PCI_COMMAND_MEMORY 0x2 /* Enable response in I/O space */ +#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ #define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ #define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */ #define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ @@ -58,6 +65,9 @@ #define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ #define PCI_STATUS 0x06 /* 16 bits */ +#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */ +#define PCI_STATUS_UDF 0x40 /* Support User Definable Features */ + #define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */ #define PCI_STATUS_PARITY 0x100 /* Detected parity error */ #define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */ @@ -108,7 +118,9 @@ #define PCI_BASE_ADDRESS_IO_MASK (~0x03) /* bit 1 is reserved if address_space = 1 */ -/* 0x28-0x2f are reserved */ +#define PCI_CARDBUS_CIS 0x28 +#define PCI_SUBSYSTEM_ID 0x2c +#define PCI_SUBSYSTEM_VENDOR_ID 0x2e #define PCI_ROM_ADDRESS 0x30 /* 32 bits */ #define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM, bits 31..11 are address, @@ -127,12 +139,14 @@ #define PCI_CLASS_STORAGE_IDE 0x0101 #define PCI_CLASS_STORAGE_FLOPPY 0x0102 #define PCI_CLASS_STORAGE_IPI 0x0103 +#define PCI_CLASS_STORAGE_RAID 0x0104 #define PCI_CLASS_STORAGE_OTHER 0x0180 #define PCI_BASE_CLASS_NETWORK 0x02 #define PCI_CLASS_NETWORK_ETHERNET 0x0200 #define PCI_CLASS_NETWORK_TOKEN_RING 0x0201 #define PCI_CLASS_NETWORK_FDDI 0x0202 +#define PCI_CLASS_NETWORK_ATM 0x0203 #define PCI_CLASS_NETWORK_OTHER 0x0280 #define PCI_BASE_CLASS_DISPLAY 0x03 @@ -157,196 +171,429 @@ #define PCI_CLASS_BRIDGE_MC 0x0603 #define PCI_CLASS_BRIDGE_PCI 0x0604 #define PCI_CLASS_BRIDGE_PCMCIA 0x0605 +#define PCI_CLASS_BRIDGE_NUBUS 0x0606 +#define PCI_CLASS_BRIDGE_CARDBUS 0x0607 #define PCI_CLASS_BRIDGE_OTHER 0x0680 + +#define PCI_BASE_CLASS_COMMUNICATION 0x07 +#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700 +#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701 +#define PCI_CLASS_COMMUNICATION_OTHER 0x0780 + +#define PCI_BASE_CLASS_SYSTEM 0x08 +#define PCI_CLASS_SYSTEM_PIC 0x0800 +#define PCI_CLASS_SYSTEM_DMA 0x0801 +#define PCI_CLASS_SYSTEM_TIMER 0x0802 +#define PCI_CLASS_SYSTEM_RTC 0x0803 +#define PCI_CLASS_SYSTEM_OTHER 0x0880 + +#define PCI_BASE_CLASS_INPUT 0x09 +#define PCI_CLASS_INPUT_KEYBOARD 0x0900 +#define PCI_CLASS_INPUT_PEN 0x0901 +#define PCI_CLASS_INPUT_MOUSE 0x0902 +#define PCI_CLASS_INPUT_OTHER 0x0980 + +#define PCI_BASE_CLASS_DOCKING 0x0a +#define PCI_CLASS_DOCKING_GENERIC 0x0a00 +#define PCI_CLASS_DOCKING_OTHER 0x0a01 + +#define PCI_BASE_CLASS_PROCESSOR 0x0b +#define PCI_CLASS_PROCESSOR_386 0x0b00 +#define PCI_CLASS_PROCESSOR_486 0x0b01 +#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02 +#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10 +#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20 +#define PCI_CLASS_PROCESSOR_CO 0x0b40 + +#define PCI_BASE_CLASS_SERIAL 0x0c +#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00 +#define PCI_CLASS_SERIAL_ACCESS 0x0c01 +#define PCI_CLASS_SERIAL_SSA 0x0c02 +#define PCI_CLASS_SERIAL_USB 0x0c03 +#define PCI_CLASS_SERIAL_FIBER 0x0c04 + #define PCI_CLASS_OTHERS 0xff +/* + * Vendor and card ID's: sort these numerically according to vendor + * (and according to card ID within vendor) + */ +#define PCI_VENDOR_ID_COMPAQ 0x0e11 +#define PCI_DEVICE_ID_COMPAQ_1280 0x3033 +#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130 #define PCI_VENDOR_ID_NCR 0x1000 #define PCI_DEVICE_ID_NCR_53C810 0x0001 -#define PCI_DEVICE_ID_NCR_53C815 0x0004 #define PCI_DEVICE_ID_NCR_53C820 0x0002 #define PCI_DEVICE_ID_NCR_53C825 0x0003 +#define PCI_DEVICE_ID_NCR_53C815 0x0004 -#define PCI_VENDOR_ID_ADAPTEC 0x9004 -#define PCI_DEVICE_ID_ADAPTEC_2940 0x7178 -#define PCI_DEVICE_ID_ADAPTEC_294x 0x7078 +#define PCI_VENDOR_ID_ATI 0x1002 +#define PCI_DEVICE_ID_ATI_68800 0x4158 +#define PCI_DEVICE_ID_ATI_215CT222 0x4354 +#define PCI_DEVICE_ID_ATI_210888CX 0x4358 +#define PCI_DEVICE_ID_ATI_210888GX 0x4758 -#define PCI_VENDOR_ID_DPT 0x1044 -#define PCI_DEVICE_ID_DPT 0xa400 +#define PCI_VENDOR_ID_VLSI 0x1004 +#define PCI_DEVICE_ID_VLSI_82C592 0x0005 +#define PCI_DEVICE_ID_VLSI_82C593 0x0006 +#define PCI_DEVICE_ID_VLSI_82C594 0x0007 +#define PCI_DEVICE_ID_VLSI_82C597 0x0009 -#define PCI_VENDOR_ID_S3 0x5333 -#define PCI_DEVICE_ID_S3_864_1 0x88c0 -#define PCI_DEVICE_ID_S3_864_2 0x88c1 -#define PCI_DEVICE_ID_S3_868 0x8880 -#define PCI_DEVICE_ID_S3_928 0x88b0 -#define PCI_DEVICE_ID_S3_964_1 0x88d0 -#define PCI_DEVICE_ID_S3_964_2 0x88d1 -#define PCI_DEVICE_ID_S3_811 0x8811 -#define PCI_DEVICE_ID_S3_968 0x88f0 +#define PCI_VENDOR_ID_ADL 0x1005 +#define PCI_DEVICE_ID_ADL_2301 0x2301 -#define PCI_VENDOR_ID_OPTI 0x1045 -#define PCI_DEVICE_ID_OPTI_82C822 0xc822 -#define PCI_DEVICE_ID_OPTI_82C621 0xc621 -#define PCI_DEVICE_ID_OPTI_82C557 0xc557 -#define PCI_DEVICE_ID_OPTI_82C558 0xc558 +#define PCI_VENDOR_ID_NS 0x100b +#define PCI_DEVICE_ID_NS_87410 0xd001 -#define PCI_VENDOR_ID_UMC 0x1060 -#define PCI_DEVICE_ID_UMC_UM8881F 0x8881 -#define PCI_DEVICE_ID_UMC_UM8891A 0x0891 -#define PCI_DEVICE_ID_UMC_UM8886F 0x8886 -#define PCI_DEVICE_ID_UMC_UM8673F 0x0101 +#define PCI_VENDOR_ID_TSENG 0x100c +#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 +#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205 +#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206 +#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207 + +#define PCI_VENDOR_ID_WEITEK 0x100e +#define PCI_DEVICE_ID_WEITEK_P9000 0x9001 +#define PCI_DEVICE_ID_WEITEK_P9100 0x9100 #define PCI_VENDOR_ID_DEC 0x1011 +#define PCI_DEVICE_ID_DEC_BRD 0x0001 #define PCI_DEVICE_ID_DEC_TULIP 0x0002 +#define PCI_DEVICE_ID_DEC_TGA 0x0004 #define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009 #define PCI_DEVICE_ID_DEC_FDDI 0x000F -#define PCI_DEVICE_ID_DEC_BRD 0x0001 +#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 +#define PCI_DEVICE_ID_DEC_21052 0x0021 +#define PCI_DEVICE_ID_DEC_21152 0x0024 + +#define PCI_VENDOR_ID_CIRRUS 0x1013 +#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0 +#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4 +#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8 +#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac +#define PCI_DEVICE_ID_CIRRUS_6729 0x1100 +#define PCI_DEVICE_ID_CIRRUS_7542 0x1200 +#define PCI_DEVICE_ID_CIRRUS_7543 0x1202 + +#define PCI_VENDOR_ID_IBM 0x1014 +#define PCI_DEVICE_ID_IBM_82G2675 0x001d + +#define PCI_VENDOR_ID_WD 0x101c +#define PCI_DEVICE_ID_WD_7197 0x3296 + +#define PCI_VENDOR_ID_AMD 0x1022 +#define PCI_DEVICE_ID_AMD_LANCE 0x2000 +#define PCI_DEVICE_ID_AMD_SCSI 0x2020 + +#define PCI_VENDOR_ID_TRIDENT 0x1023 +#define PCI_DEVICE_ID_TRIDENT_9420 0x9420 +#define PCI_DEVICE_ID_TRIDENT_9440 0x9440 +#define PCI_DEVICE_ID_TRIDENT_9660 0x9660 + +#define PCI_VENDOR_ID_AI 0x1025 +#define PCI_DEVICE_ID_AI_M1435 0x1435 #define PCI_VENDOR_ID_MATROX 0x102B #define PCI_DEVICE_ID_MATROX_MGA_2 0x0518 +#define PCI_DEVICE_ID_MATROX_MIL 0x0519 #define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10 -#define PCI_VENDOR_ID_INTEL 0x8086 -#define PCI_DEVICE_ID_INTEL_82378 0x0484 -#define PCI_DEVICE_ID_INTEL_82424 0x0483 -#define PCI_DEVICE_ID_INTEL_82375 0x0482 -#define PCI_DEVICE_ID_INTEL_82434 0x04a3 -#define PCI_DEVICE_ID_INTEL_82430 0x0486 -#define PCI_DEVICE_ID_INTEL_82437 0x122d -#define PCI_DEVICE_ID_INTEL_82371 0x122e +#define PCI_VENDOR_ID_CT 0x102c +#define PCI_DEVICE_ID_CT_65545 0x00d8 +#define PCI_DEVICE_ID_CT_65548 0x00dc -#define PCI_VENDOR_ID_SMC 0x1042 -#define PCI_DEVICE_ID_SMC_37C665 0x1000 +#define PCI_VENDOR_ID_MIRO 0x1031 +#define PCI_DEVICE_ID_MIRO_36050 0x5601 -#define PCI_VENDOR_ID_ATI 0x1002 -#define PCI_DEVICE_ID_ATI_M32 0x4158 -#define PCI_DEVICE_ID_ATI_M64 0x4758 +#define PCI_VENDOR_ID_FD 0x1036 +#define PCI_DEVICE_ID_FD_36C70 0x0000 -#define PCI_VENDOR_ID_WEITEK 0x100e -#define PCI_DEVICE_ID_WEITEK_P9000 0x9001 -#define PCI_DEVICE_ID_WEITEK_P9100 0x9100 +#define PCI_VENDOR_ID_SI 0x1039 +#define PCI_DEVICE_ID_SI_6201 0x0001 +#define PCI_DEVICE_ID_SI_6202 0x0002 +#define PCI_DEVICE_ID_SI_6205 0x0205 +#define PCI_DEVICE_ID_SI_503 0x0008 +#define PCI_DEVICE_ID_SI_501 0x0406 +#define PCI_DEVICE_ID_SI_496 0x0496 +#define PCI_DEVICE_ID_SI_601 0x0601 +#define PCI_DEVICE_ID_SI_5511 0x5511 +#define PCI_DEVICE_ID_SI_5513 0x5513 -#define PCI_VENDOR_ID_CIRRUS 0x1013 -#define PCI_DEVICE_ID_CIRRUS_5430 0x00A0 -#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00A4 -#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00A8 -#define PCI_DEVICE_ID_CIRRUS_6729 0x1100 +#define PCI_VENDOR_ID_HP 0x103c +#define PCI_DEVICE_ID_HP_J2585A 0x1030 + +#define PCI_VENDOR_ID_PCTECH 0x1042 +#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 +#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001 -#define PCI_VENDOR_ID_BUSLOGIC 0x104B -#define PCI_DEVICE_ID_BUSLOGIC_946C 0x1040 -#define PCI_DEVICE_ID_BUSLOGIC_946C_2 0x0140 +#define PCI_VENDOR_ID_DPT 0x1044 +#define PCI_DEVICE_ID_DPT 0xa400 + +#define PCI_VENDOR_ID_OPTI 0x1045 +#define PCI_DEVICE_ID_OPTI_92C178 0xc178 +#define PCI_DEVICE_ID_OPTI_82C557 0xc557 +#define PCI_DEVICE_ID_OPTI_82C558 0xc558 +#define PCI_DEVICE_ID_OPTI_82C621 0xc621 +#define PCI_DEVICE_ID_OPTI_82C822 0xc822 -#define PCI_VENDOR_ID_N9 0x105D +#define PCI_VENDOR_ID_SGS 0x104a +#define PCI_DEVICE_ID_SGS_2000 0x0008 +#define PCI_DEVICE_ID_SGS_1764 0x0009 + +#define PCI_VENDOR_ID_BUSLOGIC 0x104B +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140 +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040 +#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130 + +#define PCI_VENDOR_ID_OAK 0x104e +#define PCI_DEVICE_ID_OAK_OTI107 0x0107 + +#define PCI_VENDOR_ID_PROMISE 0x105a +#define PCI_DEVICE_ID_PROMISE_5300 0x5300 + +#define PCI_VENDOR_ID_N9 0x105d #define PCI_DEVICE_ID_N9_I128 0x2309 +#define PCI_DEVICE_ID_N9_I128_2 0x2339 -#define PCI_VENDOR_ID_AI 0x1025 -#define PCI_DEVICE_ID_AI_M1435 0x1435 +#define PCI_VENDOR_ID_UMC 0x1060 +#define PCI_DEVICE_ID_UMC_UM8673F 0x0101 +#define PCI_DEVICE_ID_UMC_UM8891A 0x0891 +#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a +#define PCI_DEVICE_ID_UMC_UM8886A 0x886a +#define PCI_DEVICE_ID_UMC_UM8881F 0x8881 +#define PCI_DEVICE_ID_UMC_UM8886F 0x8886 +#define PCI_DEVICE_ID_UMC_UM9017F 0x9017 +#define PCI_DEVICE_ID_UMC_UM8886N 0xe886 +#define PCI_DEVICE_ID_UMC_UM8891N 0xe891 -#define PCI_VENDOR_ID_AL 0x10b9 -#define PCI_DEVICE_ID_AL_M1445 0x1445 -#define PCI_DEVICE_ID_AL_M1449 0x1449 -#define PCI_DEVICE_ID_AL_M1451 0x1451 -#define PCI_DEVICE_ID_AL_M4803 0x5215 +#define PCI_VENDOR_ID_X 0x1061 +#define PCI_DEVICE_ID_X_AGX016 0x0001 -#define PCI_VENDOR_ID_TSENG 0x100c -#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 -#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205 -#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206 -#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207 +#define PCI_VENDOR_ID_NEXGEN 0x1074 +#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78 + +#define PCI_VENDOR_ID_QLOGIC 0x1077 +#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 +#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022 + +#define PCI_VENDOR_ID_LEADTEK 0x107d +#define PCI_DEVICE_ID_LEADTEK_805 0x0000 + +#define PCI_VENDOR_ID_CONTAQ 0x1080 +#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600 + +#define PCI_VENDOR_ID_FOREX 0x1083 + +#define PCI_VENDOR_ID_OLICOM 0x108d #define PCI_VENDOR_ID_CMD 0x1095 #define PCI_DEVICE_ID_CMD_640 0x0640 +#define PCI_DEVICE_ID_CMD_646 0x0646 #define PCI_VENDOR_ID_VISION 0x1098 #define PCI_DEVICE_ID_VISION_QD8500 0x0001 #define PCI_DEVICE_ID_VISION_QD8580 0x0002 -#define PCI_VENDOR_ID_AMD 0x1022 -#define PCI_DEVICE_ID_AMD_LANCE 0x2000 -#define PCI_DEVICE_ID_AMD_SCSI 0x2020 +#define PCI_VENDOR_ID_SIERRA 0x10a8 +#define PCI_DEVICE_ID_SIERRA_STB 0x0000 -#define PCI_VENDOR_ID_VLSI 0x1004 -#define PCI_DEVICE_ID_VLSI_82C593 0x0006 -#define PCI_DEVICE_ID_VLSI_82C592 0x0005 +#define PCI_VENDOR_ID_ACC 0x10aa +#define PCI_DEVICE_ID_ACC_2056 0x0000 -#define PCI_VENDOR_ID_ADL 0x1005 -#define PCI_DEVICE_ID_ADL_2301 0x2301 +#define PCI_VENDOR_ID_WINBOND 0x10ad +#define PCI_DEVICE_ID_WINBOND_83769 0x0001 +#define PCI_DEVICE_ID_WINBOND_82C105 0x0105 -#define PCI_VENDOR_ID_SYMPHONY 0x1c1c -#define PCI_DEVICE_ID_SYMPHONY_101 0x0001 +#define PCI_VENDOR_ID_3COM 0x10b7 +#define PCI_DEVICE_ID_3COM_3C590 0x5900 +#define PCI_DEVICE_ID_3COM_3C595TX 0x5950 +#define PCI_DEVICE_ID_3COM_3C595T4 0x5951 +#define PCI_DEVICE_ID_3COM_3C595MII 0x5952 -#define PCI_VENDOR_ID_TRIDENT 0x1023 -#define PCI_DEVICE_ID_TRIDENT_9420 0x9420 -#define PCI_DEVICE_ID_TRIDENT_9440 0x9440 +#define PCI_VENDOR_ID_AL 0x10b9 +#define PCI_DEVICE_ID_AL_M1445 0x1445 +#define PCI_DEVICE_ID_AL_M1449 0x1449 +#define PCI_DEVICE_ID_AL_M1451 0x1451 +#define PCI_DEVICE_ID_AL_M1461 0x1461 +#define PCI_DEVICE_ID_AL_M1489 0x1489 +#define PCI_DEVICE_ID_AL_M1511 0x1511 +#define PCI_DEVICE_ID_AL_M1513 0x1513 +#define PCI_DEVICE_ID_AL_M4803 0x5215 -#define PCI_VENDOR_ID_CONTAQ 0x1080 -#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600 +#define PCI_VENDOR_ID_ASP 0x10cd +#define PCI_DEVICE_ID_ASP_ABP940 0x1200 -#define PCI_VENDOR_ID_NS 0x100b -#define PCI_DEVICE_ID_NS_87410 0xd001 +#define PCI_VENDOR_ID_CERN 0x10dc +#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001 +#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002 + +#define PCI_VENDOR_ID_IMS 0x10e0 +#define PCI_DEVICE_ID_IMS_8849 0x8849 + +#define PCI_VENDOR_ID_TEKRAM2 0x10e1 +#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c + +#define PCI_VENDOR_ID_AMCC 0x10e8 +#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043 + +#define PCI_VENDOR_ID_INTERG 0x10ea +#define PCI_DEVICE_ID_INTERG_1680 0x1680 + +#define PCI_VENDOR_ID_REALTEK 0x10ec +#define PCI_DEVICE_ID_REALTEK_8029 0x8029 + +#define PCI_VENDOR_ID_INIT 0x1101 +#define PCI_DEVICE_ID_INIT_320P 0x9100 #define PCI_VENDOR_ID_VIA 0x1106 #define PCI_DEVICE_ID_VIA_82C505 0x0505 -#define PCI_DEVICE_ID_VIA_82C576 0x0576 #define PCI_DEVICE_ID_VIA_82C561 0x0561 +#define PCI_DEVICE_ID_VIA_82C576 0x0576 +#define PCI_DEVICE_ID_VIA_82C416 0x1571 + +#define PCI_VENDOR_ID_VORTEX 0x1119 +#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000 +#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001 +#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002 +#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003 +#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004 +#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005 +#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006 +#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007 +#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008 +#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009 +#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a +#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b +#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c +#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d -#define PCI_VENDOR_ID_SI 0x1039 -#define PCI_DEVICE_ID_SI_496 0x0496 -#define PCI_DEVICE_ID_SI_501 0x0406 -#define PCI_DEVICE_ID_SI_503 0x0008 -#define PCI_DEVICE_ID_SI_601 0x0601 +#define PCI_VENDOR_ID_EF 0x111a +#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000 +#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002 -#define PCI_VENDOR_ID_LEADTEK 0x107d -#define PCI_DEVICE_ID_LEADTEK_805 0x0000 +#define PCI_VENDOR_ID_FORE 0x1127 +#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210 +#define PCI_DEVICE_ID_FORE_PCA200E 0x0300 -#define PCI_VENDOR_ID_IMS 0x10e0 -#define PCI_DEVICE_ID_IMS_8849 0x8849 +#define PCI_VENDOR_ID_IMAGINGTECH 0x112f +#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000 -#define PCI_VENDOR_ID_ZEINET 0x1193 -#define PCI_DEVICE_ID_ZEINET_1221 0x0001 +#define PCI_VENDOR_ID_PLX 0x113c +#define PCI_DEVICE_ID_PLX_9060 0x0001 -#define PCI_VENDOR_ID_EF 0x111a -#define PCI_DEVICE_ID_EF_ATM 0x0000 +#define PCI_VENDOR_ID_ALLIANCE 0x1142 +#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210 +#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422 -#define PCI_VENDOR_ID_HER 0xedd8 -#define PCI_DEVICE_ID_HER_STING 0xa091 +#define PCI_VENDOR_ID_VMIC 0x114a +#define PCI_DEVICE_ID_VMIC_VME 0x7587 -#define PCI_VENDOR_ID_ATRONICS 0x907f -#define PCI_DEVICE_ID_ATRONICS_2015 0x2015 +#define PCI_VENDOR_ID_DIGI 0x114f +#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003 -#define PCI_VENDOR_ID_CT 0x102c -#define PCI_DEVICE_ID_CT_65545 0x00d8 +#define PCI_VENDOR_ID_MUTECH 0x1159 +#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001 -#define PCI_VENDOR_ID_FD 0x1036 -#define PCI_DEVICE_ID_FD_36C70 0x0000 +#define PCI_VENDOR_ID_TOSHIBA 0x1179 -#define PCI_VENDOR_ID_WINBOND 0x10ad -#define PCI_DEVICE_ID_WINBOND_83769 0x0001 +#define PCI_VENDOR_ID_ZEITNET 0x1193 +#define PCI_DEVICE_ID_ZEITNET_1221 0x0001 +#define PCI_DEVICE_ID_ZEITNET_1225 0x0002 -#define PCI_VENDOR_ID_3COM 0x10b7 -#define PCI_DEVICE_ID_3COM_3C590 0x5900 -#define PCI_DEVICE_ID_3COM_3C595TX 0x5950 -#define PCI_DEVICE_ID_3COM_3C595T4 0x5951 -#define PCI_DEVICE_ID_3COM_3C595MII 0x5952 +#define PCI_VENDOR_ID_SPECIALIX 0x11cb +#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000 +#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000 -#define PCI_VENDOR_ID_PROMISE 0x105a -#define PCI_DEVICE_ID_PROMISE_5300 0x5300 +#define PCI_VENDOR_ID_RP 0x11fe +#define PCI_DEVICE_ID_RP8OCTA 0x0001 +#define PCI_DEVICE_ID_RP8INTF 0x0002 +#define PCI_DEVICE_ID_RP16INTF 0x0003 +#define PCI_DEVICE_ID_RP32INTF 0x0004 -#define PCI_VENDOR_ID_QLOGIC 0x1077 -#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 -#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022 +#define PCI_VENDOR_ID_CYCLADES 0x120e +#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100 +#define PCI_DEVICE_ID_CYCLOM_Y_Hi 0x0101 +#define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200 +#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201 -#define PCI_VENDOR_ID_X 0x1061 -#define PCI_DEVICE_ID_X_AGX016 0x0001 +#define PCI_VENDOR_ID_SYMPHONY 0x1c1c +#define PCI_DEVICE_ID_SYMPHONY_101 0x0001 + +#define PCI_VENDOR_ID_TEKRAM 0x1de1 +#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 + +#define PCI_VENDOR_ID_3DLABS 0x3D3D +#define PCI_DEVICE_ID_3DLABS_300SX 0x0001 + +#define PCI_VENDOR_ID_AVANCE 0x4005 +#define PCI_DEVICE_ID_AVANCE_2302 0x2302 + +#define PCI_VENDOR_ID_S3 0x5333 +#define PCI_DEVICE_ID_S3_ViRGE 0x5631 +#define PCI_DEVICE_ID_S3_TRIO 0x8811 +#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812 +#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814 +#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d +#define PCI_DEVICE_ID_S3_868 0x8880 +#define PCI_DEVICE_ID_S3_928 0x88b0 +#define PCI_DEVICE_ID_S3_864_1 0x88c0 +#define PCI_DEVICE_ID_S3_864_2 0x88c1 +#define PCI_DEVICE_ID_S3_964_1 0x88d0 +#define PCI_DEVICE_ID_S3_964_2 0x88d1 +#define PCI_DEVICE_ID_S3_968 0x88f0 + +#define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_DEVICE_ID_INTEL_82375 0x0482 +#define PCI_DEVICE_ID_INTEL_82424 0x0483 +#define PCI_DEVICE_ID_INTEL_82378 0x0484 +#define PCI_DEVICE_ID_INTEL_82430 0x0486 +#define PCI_DEVICE_ID_INTEL_82434 0x04a3 +#define PCI_DEVICE_ID_INTEL_7116 0x1223 +#define PCI_DEVICE_ID_INTEL_82596 0x1226 +#define PCI_DEVICE_ID_INTEL_82865 0x1227 +#define PCI_DEVICE_ID_INTEL_82557 0x1229 +#define PCI_DEVICE_ID_INTEL_82437 0x122d +#define PCI_DEVICE_ID_INTEL_82371_0 0x122e +#define PCI_DEVICE_ID_INTEL_82371_1 0x1230 +#define PCI_DEVICE_ID_INTEL_82441 0x1237 +#define PCI_DEVICE_ID_INTEL_82439 0x1250 +#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 +#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 +#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 +#define PCI_DEVICE_ID_INTEL_82437VX 0x7030 +#define PCI_DEVICE_ID_INTEL_P6 0x84c4 + +#define PCI_VENDOR_ID_ADAPTEC 0x9004 +#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078 +#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578 +#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078 +#define PCI_DEVICE_ID_ADAPTEC_7861 0x6178 +#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078 +#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178 +#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278 +#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378 +#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478 +#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078 +#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178 +#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278 +#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378 +#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478 + +#define PCI_VENDOR_ID_ATRONICS 0x907f +#define PCI_DEVICE_ID_ATRONICS_2015 0x2015 + +#define PCI_VENDOR_ID_HER 0xedd8 +#define PCI_DEVICE_ID_HER_STING 0xa091 +#define PCI_DEVICE_ID_HER_STINGARK 0xa099 /* * The PCI interface treats multi-function devices as independent * devices. The slot/function address of each device is encoded * in a single byte as follows: * - * 7:4 = slot - * 3:0 = function + * 7:3 = slot + * 2:0 = function */ #define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) @@ -418,7 +665,6 @@ extern unsigned long pci_init (unsigned long mem_start, unsigned long mem_end); extern struct pci_dev_info *pci_lookup_dev (unsigned int vendor, unsigned int dev); -extern char *pci_strbioserr (int error); extern const char *pci_strclass (unsigned int class); extern const char *pci_strvendor (unsigned int vendor); extern const char *pci_strdev (unsigned int vendor, unsigned int device); diff --git a/include/linux/pcwd.h b/include/linux/pcwd.h new file mode 100644 index 000000000..6b77fdefa --- /dev/null +++ b/include/linux/pcwd.h @@ -0,0 +1,12 @@ +/* + * Berkshire PC Watchdog Defines + * For version 0.41 of the driver + */ + +#define PCWD_IOCTL_BASE 'W' + +#define PCWD_GETSTAT _IOR(PCWD_IOCTL_BASE, 1, int) +#define PCWD_PING _IOR(PCWD_IOCTL_BASE, 2, int) + +#define PCWD_PREVRESET 0x01 /* System previously reset by card */ +#define PCWD_TEMPSENSE 0x02 /* Temperature overheat sense */ diff --git a/include/linux/personality.h b/include/linux/personality.h index 47aa02c35..91538d2bd 100644 --- a/include/linux/personality.h +++ b/include/linux/personality.h @@ -32,12 +32,12 @@ typedef asmlinkage void (*lcall7_func)(struct pt_regs *); * offset of the handler is hard coded in kernel/sys_call.S. */ struct exec_domain { - char *name; + const char *name; lcall7_func handler; unsigned char pers_low, pers_high; unsigned long * signal_map; unsigned long * signal_invmap; - int *use_count; + long *use_count; struct exec_domain *next; }; @@ -46,6 +46,6 @@ extern struct exec_domain default_exec_domain; extern struct exec_domain *lookup_exec_domain(unsigned long personality); extern int register_exec_domain(struct exec_domain *it); extern int unregister_exec_domain(struct exec_domain *it); -extern asmlinkage int sys_personality(unsigned long personality); +asmlinkage int sys_personality(unsigned long personality); #endif /* _PERSONALITY_H */ diff --git a/include/linux/posix_types.h b/include/linux/posix_types.h new file mode 100644 index 000000000..f0ccb3bb9 --- /dev/null +++ b/include/linux/posix_types.h @@ -0,0 +1,56 @@ +#ifndef _LINUX_POSIX_TYPES_H +#define _LINUX_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +#ifndef NULL +# define NULL ((void *) 0) +#endif + +/* + * This allows for 1024 file descriptors: if NR_OPEN is ever grown + * beyond that you'll have to change this too. But 1024 fd's seem to be + * enough even for such "real" unices like OSF/1, so hopefully this is + * one limit that doesn't have to be changed [again]. + * + * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in + * <sys/time.h> (and thus <linux/time.h>) - but this is a more logical + * place for them. Solved by having dummy defines in <sys/time.h>. + */ + +/* + * Those macros may have been defined in <gnu/types.h>. But we always + * use the ones here. + */ +#undef __NFDBITS +#define __NFDBITS (8 * sizeof(unsigned long)) + +#undef __FD_SETSIZE +#define __FD_SETSIZE 1024 + +#undef __FDSET_LONGS +#define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS) + +#undef __FDELT +#define __FDELT(d) ((d) / __NFDBITS) + +#undef __FDMASK +#define __FDMASK(d) (1UL << ((d) % __NFDBITS)) + +typedef struct fd_set { + unsigned long fds_bits [__FDSET_LONGS]; +} __kernel_fd_set; + +/* Type of a signal handler. */ +typedef void (*__kernel_sighandler_t)(int); + +/* Type of a SYSV IPC key. */ +typedef int __kernel_key_t; + +#include <asm/posix_types.h> + +#endif /* _LINUX_POSIX_TYPES_H */ diff --git a/include/linux/ppp-comp.h b/include/linux/ppp-comp.h new file mode 100644 index 000000000..8bc478d6e --- /dev/null +++ b/include/linux/ppp-comp.h @@ -0,0 +1,192 @@ +/* + * ppp-comp.h - Definitions for doing PPP packet compression. + * + * Copyright (c) 1994 The Australian National University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, provided that the above copyright + * notice appears in all copies. This software is provided without any + * warranty, express or implied. The Australian National University + * makes no representations about the suitability of this software for + * any purpose. + * + * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY + * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO + * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, + * OR MODIFICATIONS. + * + * $Id: ppp-comp.h,v 1.7 1995/05/01 01:43:37 paulus Exp $ + */ + +/* + * ==FILEVERSION 960302== + * + * NOTE TO MAINTAINERS: + * If you modify this file at all, please set the above date. + * ppp-comp.h is shipped with a PPP distribution as well as with the kernel; + * if everyone increases the FILEVERSION number above, then scripts + * can do the right thing when deciding whether to install a new ppp-comp.h + * file. Don't change the format of that line otherwise, so the + * installation script can recognize it. + */ + +#ifndef _NET_PPP_COMP_H +#define _NET_PPP_COMP_H + +/* + * The following symbols control whether we include code for + * various compression methods. + */ + +#ifndef DO_BSD_COMPRESS +#define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ +#endif + +#define DO_PREDICTOR_1 0 +#define DO_PREDICTOR_2 0 +#define DO_DEFLATE 0 + +/* + * Structure giving methods for compression/decompression. + */ + +#ifdef PACKETPTR +struct compressor { + int compress_proto; /* CCP compression protocol number */ + + /* Allocate space for a compressor (transmit side) */ + void *(*comp_alloc) (unsigned char *options, int opt_len); + + /* Free space used by a compressor */ + void (*comp_free) (void *state); + + /* Initialize a compressor */ + int (*comp_init) (void *state, unsigned char *options, + int opt_len, int unit, int opthdr, int debug); + + /* Reset a compressor */ + void (*comp_reset) (void *state); + + /* Compress a packet */ + int (*compress) (void *state, unsigned char *rptr, + unsigned char *obuf, int isize, int osize); + + /* Return compression statistics */ + void (*comp_stat) (void *state, struct compstat *stats); + + /* Allocate space for a decompressor (receive side) */ + void *(*decomp_alloc) (unsigned char *options, int opt_len); + + /* Free space used by a decompressor */ + void (*decomp_free) (void *state); + + /* Initialize a decompressor */ + int (*decomp_init) (void *state, unsigned char *options, + int opt_len, int unit, int opthdr, int mru, + int debug); + + /* Reset a decompressor */ + void (*decomp_reset) (void *state); + + /* Decompress a packet. */ + int (*decompress) (void *state, unsigned char *ibuf, int isize, + unsigned char *obuf, int osize); + + /* Update state for an incompressible packet received */ + void (*incomp) (void *state, unsigned char *ibuf, int icnt); + + /* Return decompression statistics */ + void (*decomp_stat) (void *state, struct compstat *stats); +}; +#endif /* PACKETPTR */ + +/* + * Return values for decompress routine. + * We need to make these distinctions so that we can disable certain + * useful functionality, namely sending a CCP reset-request as a result + * of an error detected after decompression. This is to avoid infringing + * a patent held by Motorola. + * Don't you just lurve software patents. + */ + +#define DECOMP_OK 0 /* everything went OK */ +#define DECOMP_ERROR 1 /* error detected before decomp. */ +#define DECOMP_FATALERROR 2 /* error detected after decomp. */ + +/* + * CCP codes. + */ + +#define CCP_CONFREQ 1 +#define CCP_CONFACK 2 +#define CCP_TERMREQ 5 +#define CCP_TERMACK 6 +#define CCP_RESETREQ 14 +#define CCP_RESETACK 15 + +/* + * Max # bytes for a CCP option + */ + +#define CCP_MAX_OPTION_LENGTH 32 + +/* + * Parts of a CCP packet. + */ + +#define CCP_CODE(dp) ((dp)[0]) +#define CCP_ID(dp) ((dp)[1]) +#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) +#define CCP_HDRLEN 4 + +#define CCP_OPT_CODE(dp) ((dp)[0]) +#define CCP_OPT_LENGTH(dp) ((dp)[1]) +#define CCP_OPT_MINLEN 2 + +/* + * Definitions for BSD-Compress. + */ + +#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ +#define CILEN_BSD_COMPRESS 3 /* length of config. option */ + +/* Macros for handling the 3rd byte of the BSD-Compress config option. */ +#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ +#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ +#define BSD_CURRENT_VERSION 1 /* current version number */ +#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) + +#define BSD_MIN_BITS 9 /* smallest code size supported */ +#define BSD_MAX_BITS 15 /* largest code size supported */ + +/* + * Definitions for other, as yet unsupported, compression methods. + */ + +#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ +#define CILEN_PREDICTOR_1 2 /* length of its config option */ +#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ +#define CILEN_PREDICTOR_2 2 /* length of its config option */ + +#define CI_DEFLATE 24 /* config option for Deflate */ +#define CILEN_DEFLATE 4 /* length of its config option */ + +#define DEFLATE_MIN_SIZE 8 +#define DEFLATE_MAX_SIZE 15 +#define DEFLATE_METHOD_VAL 8 +#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) +#define DEFLATE_METHOD(x) ((x) & 0x0F) +#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ + + DEFLATE_METHOD_VAL) +#define DEFLATE_CHK_SEQUENCE 0 + +#endif /* _NET_PPP_COMP_H */ diff --git a/include/linux/ppp_defs.h b/include/linux/ppp_defs.h new file mode 100644 index 000000000..1b20ab9e1 --- /dev/null +++ b/include/linux/ppp_defs.h @@ -0,0 +1,178 @@ +/* $Id: ppp_defs.h,v 1.2 1994/09/21 01:31:06 paulus Exp $ */ + +/* + * ppp_defs.h - PPP definitions. + * + * Copyright (c) 1994 The Australian National University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, provided that the above copyright + * notice appears in all copies. This software is provided without any + * warranty, express or implied. The Australian National University + * makes no representations about the suitability of this software for + * any purpose. + * + * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY + * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO + * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, + * OR MODIFICATIONS. + */ + +/* + * ==FILEVERSION 960302== + * + * NOTE TO MAINTAINERS: + * If you modify this file at all, please set the above date. + * ppp_defs.h is shipped with a PPP distribution as well as with the kernel; + * if everyone increases the FILEVERSION number above, then scripts + * can do the right thing when deciding whether to install a new ppp_defs.h + * file. Don't change the format of that line otherwise, so the + * installation script can recognize it. + */ + +#ifndef _PPP_DEFS_H_ +#define _PPP_DEFS_H_ + +/* + * The basic PPP frame. + */ +#define PPP_HDRLEN 4 /* octets for standard ppp header */ +#define PPP_FCSLEN 2 /* octets for FCS */ +#define PPP_MRU 1500 /* default MRU = max length of info field */ + +#define PPP_ADDRESS(p) (((__u8 *)(p))[0]) +#define PPP_CONTROL(p) (((__u8 *)(p))[1]) +#define PPP_PROTOCOL(p) ((((__u8 *)(p))[2] << 8) + ((__u8 *)(p))[3]) + +/* + * Significant octet values. + */ +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_FLAG 0x7e /* Flag Sequence */ +#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ +#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ + +/* + * Protocol field values. + */ +#define PPP_IP 0x21 /* Internet Protocol */ +#define PPP_IPX 0x2b /* IPX protocol */ +#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ +#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ +#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ +#define PPP_COMP 0xfd /* compressed packet */ +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#define PPP_IPXCP 0x802b /* IPX Control Protocol */ +#define PPP_CCP 0x80fd /* Compression Control Protocol */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#define PPP_LQR 0xc025 /* Link Quality Report protocol */ +#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ + +/* + * Values for FCS calculations. + */ + +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +/* + * Extended asyncmap - allows any character to be escaped. + */ + +typedef __u32 ext_accm[8]; + +/* + * What to do with network protocol (NP) packets. + */ +enum NPmode { + NPMODE_PASS, /* pass the packet through */ + NPMODE_DROP, /* silently drop the packet */ + NPMODE_ERROR, /* return an error */ + NPMODE_QUEUE /* save it up for later. */ +}; + +/* + * Statistics for LQRP and pppstats + */ +struct pppstat { + __u32 ppp_discards; /* # frames discarded */ + + __u32 ppp_ibytes; /* bytes received */ + __u32 ppp_ioctects; /* bytes received not in error */ + __u32 ppp_ipackets; /* packets received */ + __u32 ppp_ierrors; /* receive errors */ + __u32 ppp_ilqrs; /* # LQR frames received */ + + __u32 ppp_obytes; /* raw bytes sent */ + __u32 ppp_ooctects; /* frame bytes sent */ + __u32 ppp_opackets; /* packets sent */ + __u32 ppp_oerrors; /* transmit errors */ + __u32 ppp_olqrs; /* # LQR frames sent */ +}; + +struct vjstat { + __u32 vjs_packets; /* outbound packets */ + __u32 vjs_compressed; /* outbound compressed packets */ + __u32 vjs_searches; /* searches for connection state */ + __u32 vjs_misses; /* times couldn't find conn. state */ + __u32 vjs_uncompressedin; /* inbound uncompressed packets */ + __u32 vjs_compressedin; /* inbound compressed packets */ + __u32 vjs_errorin; /* inbound unknown type packets */ + __u32 vjs_tossed; /* inbound packets tossed because of error */ +}; + +struct compstat { + __u32 unc_bytes; /* total uncompressed bytes */ + __u32 unc_packets; /* total uncompressed packets */ + __u32 comp_bytes; /* compressed bytes */ + __u32 comp_packets; /* compressed packets */ + __u32 inc_bytes; /* incompressible bytes */ + __u32 inc_packets; /* incompressible packets */ + + /* the compression ratio is defined as in_count / bytes_out */ + __u32 in_count; /* Bytes received */ + __u32 bytes_out; /* Bytes transmitted */ + + double ratio; /* not computed in kernel. */ +}; + +struct ppp_stats { + struct pppstat p; /* basic PPP statistics */ + struct vjstat vj; /* VJ header compression statistics */ +}; + +struct ppp_comp_stats { + struct compstat c; /* packet compression statistics */ + struct compstat d; /* packet decompression statistics */ +}; + +/* + * The following structure records the time in seconds since + * the last NP packet was sent or received. + */ +struct ppp_idle { + time_t xmit_idle; /* time since last NP packet sent */ + time_t recv_idle; /* time since last NP packet received */ +}; + +#ifndef __P +#ifdef __STDC__ +#define __P(x) x +#else +#define __P(x) () +#endif +#endif + +#endif /* _PPP_DEFS_H_ */ diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index c70aa162a..42ad7cacb 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -1,12 +1,17 @@ #ifndef _LINUX_PROC_FS_H #define _LINUX_PROC_FS_H -#include <linux/config.h> +#include <linux/fs.h> +#include <linux/malloc.h> /* * The proc filesystem constants/structures */ +/* + * We always define these enumerators + */ + enum root_directory_inos { PROC_ROOT_INO = 1, PROC_LOADAVG, @@ -18,9 +23,8 @@ enum root_directory_inos { PROC_PCI, PROC_SELF, /* will change inode # */ PROC_NET, -#ifdef CONFIG_DEBUG_MALLOC + PROC_SCSI, PROC_MALLOC, -#endif PROC_KCORE, PROC_MODULES, PROC_STAT, @@ -30,11 +34,21 @@ enum root_directory_inos { PROC_KSYMS, PROC_DMA, PROC_IOPORTS, - PROC_PROFILE /* whether enabled or not */ +#ifdef __SMP_PROF__ + PROC_SMP_PROF, +#endif + PROC_PROFILE, /* whether enabled or not */ + PROC_CMDLINE, + PROC_SYS, + PROC_MTAB, + PROC_MD, + PROC_RTC, + PROC_LOCKS }; enum pid_directory_inos { PROC_PID_INO = 2, + PROC_PID_STATUS, PROC_PID_MEM, PROC_PID_CWD, PROC_PID_ROOT, @@ -53,7 +67,6 @@ enum pid_subdirectory_inos { enum net_directory_inos { PROC_NET_UNIX = 128, -#ifdef CONFIG_INET PROC_NET_ARP, PROC_NET_ROUTE, PROC_NET_DEV, @@ -61,69 +74,210 @@ enum net_directory_inos { PROC_NET_TCP, PROC_NET_UDP, PROC_NET_SNMP, -#ifdef CONFIG_INET_RARP PROC_NET_RARP, -#endif -#ifdef CONFIG_IP_MULTICAST PROC_NET_IGMP, -#endif -#ifdef CONFIG_IP_FIREWALL + PROC_NET_IPMR_VIF, + PROC_NET_IPMR_MFC, PROC_NET_IPFWFWD, - PROC_NET_IPFWBLK, -#endif -#ifdef CONFIG_IP_ACCT + PROC_NET_IPFWIN, + PROC_NET_IPFWOUT, PROC_NET_IPACCT, -#endif -#ifdef CONFIG_IP_MASQUERADE PROC_NET_IPMSQHST, -#endif -#if defined(CONFIG_WAVELAN) PROC_NET_WAVELAN, -#endif /* defined(CONFIG_WAVELAN) */ -#endif -#ifdef CONFIG_IPX PROC_NET_IPX_INTERFACE, PROC_NET_IPX_ROUTE, PROC_NET_IPX, -#endif -#ifdef CONFIG_ATALK PROC_NET_ATALK, PROC_NET_AT_ROUTE, PROC_NET_ATIF, -#endif -#ifdef CONFIG_AX25 PROC_NET_AX25_ROUTE, PROC_NET_AX25, -#ifdef CONFIG_NETROM + PROC_NET_AX25_CALLS, PROC_NET_NR_NODES, PROC_NET_NR_NEIGH, PROC_NET_NR, -#endif -#endif PROC_NET_SOCKSTAT, + PROC_NET_RTCACHE, + PROC_NET_AX25_BPQETHER, + PROC_NET_ALIAS_TYPES, + PROC_NET_ALIASES, + PROC_NET_IP_MASQ_APP, + PROC_NET_RT6, + PROC_NET_RT6_STATS, + PROC_NET_STRIP_STATUS, + PROC_NET_STRIP_TRACE, + PROC_NET_Z8530, + PROC_NET_RS_NODES, + PROC_NET_RS_NEIGH, + PROC_NET_RS_ROUTES, + PROC_NET_RS, PROC_NET_LAST }; +enum scsi_directory_inos { + PROC_SCSI_SCSI = 256, + PROC_SCSI_ADVANSYS, + PROC_SCSI_EATA, + PROC_SCSI_EATA_PIO, + PROC_SCSI_AHA152X, + PROC_SCSI_AHA1542, + PROC_SCSI_AHA1740, + PROC_SCSI_AIC7XXX, + PROC_SCSI_BUSLOGIC, + PROC_SCSI_U14_34F, + PROC_SCSI_FDOMAIN, + PROC_SCSI_GENERIC_NCR5380, + PROC_SCSI_IN2000, + PROC_SCSI_PAS16, + PROC_SCSI_QLOGICFAS, + PROC_SCSI_QLOGICISP, + PROC_SCSI_SEAGATE, + PROC_SCSI_T128, + PROC_SCSI_NCR53C7xx, + PROC_SCSI_NCR53C8XX, + PROC_SCSI_ULTRASTOR, + PROC_SCSI_7000FASST, + PROC_SCSI_EATA2X, + PROC_SCSI_AM53C974, + PROC_SCSI_SSC, + PROC_SCSI_NCR53C406A, + PROC_SCSI_PPA, + PROC_SCSI_ESP, + PROC_SCSI_A3000, + PROC_SCSI_A2091, + PROC_SCSI_GVP11, + PROC_SCSI_ATARI, + PROC_SCSI_SCSI_DEBUG, + PROC_SCSI_NOT_PRESENT, + PROC_SCSI_FILE, /* I'm assuming here that we */ + PROC_SCSI_LAST = (PROC_SCSI_FILE + 16) /* won't ever see more than */ +}; /* 16 HBAs in one machine */ + +/* Finally, the dynamically allocatable proc entries are reserved: */ + +#define PROC_DYNAMIC_FIRST 4096 +#define PROC_NDYNAMIC 4096 + #define PROC_SUPER_MAGIC 0x9fa0 +/* + * This is not completely implemented yet. The idea is to + * create an in-memory tree (like the actual /proc filesystem + * tree) of these proc_dir_entries, so that we can dynamically + * add new files to /proc. + * + * The "next" pointer creates a linked list of one /proc directory, + * while parent/subdir create the directory structure (every + * /proc file has a parent, but "subdir" is NULL for all + * non-directory entries). + * + * "get_info" is called at "read", while "fill_inode" is used to + * fill in file type/protection/owner information specific to the + * particular /proc file. + */ struct proc_dir_entry { unsigned short low_ino; unsigned short namelen; - char * name; + const char *name; + mode_t mode; + nlink_t nlink; + uid_t uid; + gid_t gid; + unsigned long size; + struct inode_operations * ops; + int (*get_info)(char *, char **, off_t, int, int); + void (*fill_inode)(struct inode *); + struct proc_dir_entry *next, *parent, *subdir; + void *data; }; +extern int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start, + off_t offset, int length, int inout); + +extern struct proc_dir_entry proc_root; +extern struct proc_dir_entry proc_net; +extern struct proc_dir_entry proc_scsi; +extern struct proc_dir_entry proc_sys; +extern struct proc_dir_entry proc_pid; +extern struct proc_dir_entry proc_pid_fd; + +extern struct inode_operations proc_scsi_inode_operations; + +extern void proc_root_init(void); +extern void proc_base_init(void); +extern void proc_net_init(void); + +extern int proc_register(struct proc_dir_entry *, struct proc_dir_entry *); +extern int proc_register_dynamic(struct proc_dir_entry *, + struct proc_dir_entry *); +extern int proc_unregister(struct proc_dir_entry *, int); + +static inline int proc_net_register(struct proc_dir_entry * x) +{ + return proc_register(&proc_net, x); +} + +static inline int proc_net_unregister(int x) +{ + return proc_unregister(&proc_net, x); +} + +static inline int proc_scsi_register(struct proc_dir_entry *driver, + struct proc_dir_entry *x) +{ + x->ops = &proc_scsi_inode_operations; + if(x->low_ino < PROC_SCSI_FILE){ + return(proc_register(&proc_scsi, x)); + }else{ + return(proc_register(driver, x)); + } +} + +static inline int proc_scsi_unregister(struct proc_dir_entry *driver, int x) +{ + extern void scsi_init_free(char *ptr, unsigned int size); + + if(x <= PROC_SCSI_FILE) + return(proc_unregister(&proc_scsi, x)); + else { + struct proc_dir_entry **p = &driver->subdir, *dp; + int ret; + + while ((dp = *p) != NULL) { + if (dp->low_ino == x) + break; + p = &dp->next; + } + ret = proc_unregister(driver, x); + scsi_init_free((char *) dp, sizeof(struct proc_dir_entry) + 4); + return(ret); + } +} + extern struct super_block *proc_read_super(struct super_block *,void *,int); -extern void proc_put_inode(struct inode *); -extern void proc_put_super(struct super_block *); +extern int init_proc_fs(void); +extern struct inode * proc_get_inode(struct super_block *, int, struct proc_dir_entry *); extern void proc_statfs(struct super_block *, struct statfs *, int); extern void proc_read_inode(struct inode *); extern void proc_write_inode(struct inode *); extern int proc_match(int, const char *, struct proc_dir_entry *); -extern struct inode_operations proc_root_inode_operations; -extern struct inode_operations proc_base_inode_operations; +/* + * These are generic /proc routines that use the internal + * "struct proc_dir_entry" tree to traverse the filesystem. + * + * The /proc root directory has extended versions to take care + * of the /proc/<pid> subdirectories. + */ +extern int proc_readdir(struct inode *, struct file *, void *, filldir_t); +extern int proc_lookup(struct inode *, const char *, int, struct inode **); + +extern struct inode_operations proc_dir_inode_operations; extern struct inode_operations proc_net_inode_operations; +extern struct inode_operations proc_netdir_inode_operations; +extern struct inode_operations proc_scsi_inode_operations; extern struct inode_operations proc_mem_inode_operations; +extern struct inode_operations proc_sys_inode_operations; extern struct inode_operations proc_array_inode_operations; extern struct inode_operations proc_arraylong_inode_operations; extern struct inode_operations proc_kcore_inode_operations; diff --git a/include/linux/quota.h b/include/linux/quota.h new file mode 100644 index 000000000..5eebb8a7b --- /dev/null +++ b/include/linux/quota.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Robert Elz at The University of Melbourne. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Version: $Id: quota.h,v 1.8 1995/03/11 11:43:07 mvw Exp mvw $ + */ + +#ifndef _LINUX_QUOTA_ +#define _LINUX_QUOTA_ + +#include <linux/errno.h> + +/* + * Convert diskblocks to blocks and the other way around. + * currently only to fool the BSD source. :-) + */ +#define dbtob(num) (num << 10) +#define btodb(num) (num >> 10) + +/* + * Convert count of filesystem blocks to diskquota blocks, meant + * for filesystems where i_blksize != BLOCK_SIZE + */ +#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / BLOCK_SIZE) + +/* + * Definitions for disk quotas imposed on the average user + * (big brother finally hits Linux). + * + * The following constants define the amount of time given a user + * before the soft limits are treated as hard limits (usually resulting + * in an allocation failure). The timer is started when the user crosses + * their soft limit, it is reset when they go below their soft limit. + */ +#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */ +#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */ + +#define MAXQUOTAS 2 +#define USRQUOTA 0 /* element used for user quotas */ +#define GRPQUOTA 1 /* element used for group quotas */ + +/* + * Definitions for the default names of the quotas files. + */ +#define INITQFNAMES { \ + "user", /* USRQUOTA */ \ + "group", /* GRPQUOTA */ \ + "undefined", \ +}; + +#define QUOTAFILENAME "quota" +#define QUOTAGROUP "staff" + +#define NR_DQHASH 43 /* Just an arbitrary number any suggestions ? */ +#define NR_DQUOTS 256 /* Number of quotas active at one time */ + +/* + * Command definitions for the 'quotactl' system call. + * The commands are broken into a main command defined below + * and a subcommand that is used to convey the type of + * quota that is being manipulated (see above). + */ +#define SUBCMDMASK 0x00ff +#define SUBCMDSHIFT 8 +#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK)) + +#define Q_QUOTAON 0x0100 /* enable quotas */ +#define Q_QUOTAOFF 0x0200 /* disable quotas */ +#define Q_GETQUOTA 0x0300 /* get limits and usage */ +#define Q_SETQUOTA 0x0400 /* set limits and usage */ +#define Q_SETUSE 0x0500 /* set usage */ +#define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */ +#define Q_SETQLIM 0x0700 /* set limits */ +#define Q_GETSTATS 0x0800 /* get collected stats */ + +/* + * The following structure defines the format of the disk quota file + * (as it appears on disk) - the file is an array of these structures + * indexed by user or group number. + */ +struct dqblk { + __u32 dqb_bhardlimit; /* absolute limit on disk blks alloc */ + __u32 dqb_bsoftlimit; /* preferred limit on disk blks */ + __u32 dqb_curblocks; /* current block count */ + __u32 dqb_ihardlimit; /* maximum # allocated inodes */ + __u32 dqb_isoftlimit; /* preferred inode limit */ + __u32 dqb_curinodes; /* current # allocated inodes */ + time_t dqb_btime; /* time limit for excessive disk use */ + time_t dqb_itime; /* time limit for excessive files */ +}; + +/* + * Shorthand notation. + */ +#define dq_bhardlimit dq_dqb.dqb_bhardlimit +#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit +#define dq_curblocks dq_dqb.dqb_curblocks +#define dq_ihardlimit dq_dqb.dqb_ihardlimit +#define dq_isoftlimit dq_dqb.dqb_isoftlimit +#define dq_curinodes dq_dqb.dqb_curinodes +#define dq_btime dq_dqb.dqb_btime +#define dq_itime dq_dqb.dqb_itime + +#define dqoff(UID) ((off_t)((UID) * sizeof (struct dqblk))) + +struct dqstats { + __u32 lookups; + __u32 drops; + __u32 reads; + __u32 writes; + __u32 cache_hits; + __u32 pages_allocated; + __u32 allocated_dquots; + __u32 free_dquots; + __u32 syncs; +}; + +#ifdef __KERNEL__ + +#include <linux/mount.h> + +/* + * Maximum length of a message generated in the quota system, + * that needs to be kicked onto the tty. + */ +#define MAX_QUOTA_MESSAGE 75 + +#define DQ_LOCKED 0x01 /* locked for update */ +#define DQ_WANT 0x02 /* wanted for update */ +#define DQ_MOD 0x04 /* dquot modified since read */ +#define DQ_BLKS 0x10 /* uid/gid has been warned about blk limit */ +#define DQ_INODES 0x20 /* uid/gid has been warned about inode limit */ +#define DQ_FAKE 0x40 /* no limits only usage */ + +struct dquot { + unsigned int dq_id; /* id this applies to (uid, gid) */ + short dq_type; /* type of quota */ + kdev_t dq_dev; /* Device this applies to */ + short dq_flags; /* see DQ_* */ + short dq_count; /* reference count */ + struct vfsmount *dq_mnt; /* vfsmountpoint this applies to */ + struct dqblk dq_dqb; /* diskquota usage */ + struct wait_queue *dq_wait; /* pointer to waitqueue */ + struct dquot *dq_prev; /* pointer to prev dquot */ + struct dquot *dq_next; /* pointer to next dquot */ + struct dquot *dq_hash_prev; /* pointer to prev dquot */ + struct dquot *dq_hash_next; /* pointer to next dquot */ +}; + +#define NODQUOT (struct dquot *)NULL + +/* + * Flags used for set_dqblk. + */ +#define QUOTA_SYSCALL 0x01 +#define SET_QUOTA 0x02 +#define SET_USE 0x04 +#define SET_QLIMIT 0x08 + +#define QUOTA_OK 0 +#define NO_QUOTA 1 + +/* + * declaration of quota_function calls in kernel. + */ + +extern void dquot_initialize(struct inode *inode, short type); +extern void dquot_drop(struct inode *inode); +extern int dquot_alloc_block(const struct inode *inode, unsigned long number); +extern int dquot_alloc_inode(const struct inode *inode, unsigned long number); +extern void dquot_free_block(const struct inode *inode, unsigned long number); +extern void dquot_free_inode(const struct inode *inode, unsigned long number); +extern int dquot_transfer(struct inode *inode, struct iattr *iattr, char direction); + +extern void invalidate_dquots(kdev_t dev, short type); +extern int quota_off(kdev_t dev, short type); +extern int sync_dquots(kdev_t dev, short type); + +#else + +# /* nodep */ include <sys/cdefs.h> + +__BEGIN_DECLS +int quotactl __P ((int, const char *, int, caddr_t)); +__END_DECLS + +#endif /* __KERNEL__ */ +#endif /* _QUOTA_ */ diff --git a/include/linux/raid0.h b/include/linux/raid0.h new file mode 100644 index 000000000..e1ae51c02 --- /dev/null +++ b/include/linux/raid0.h @@ -0,0 +1,27 @@ +#ifndef _RAID0_H +#define _RAID0_H + +struct strip_zone +{ + int zone_offset; /* Zone offset in md_dev */ + int dev_offset; /* Zone offset in real dev */ + int size; /* Zone size */ + int nb_dev; /* Number of devices attached to the zone */ + struct real_dev *dev[MAX_REAL]; /* Devices attached to the zone */ +}; + +struct raid0_hash +{ + struct strip_zone *zone0, *zone1; +}; + +struct raid0_data +{ + struct raid0_hash *hash_table; /* Dynamically allocated */ + struct strip_zone *strip_zone; /* This one too */ + int nr_strip_zones; + struct strip_zone *smallest; + int nr_zones; +}; + +#endif diff --git a/include/linux/random.h b/include/linux/random.h new file mode 100644 index 000000000..b2706ce03 --- /dev/null +++ b/include/linux/random.h @@ -0,0 +1,65 @@ +/* + * include/linux/random.h + * + * Include file for the random number generator. + */ + +#ifndef _LINUX_RANDOM_H +#define _LINUX_RANDOM_H + +#include <linux/ioctl.h> + +/* ioctl()'s for the random number generator */ + +/* Get the entropy count. */ +#define RNDGETENTCNT _IOR( 'R', 0x00, int ) + +/* Add to (or subtract from) the entropy count. (Superuser only.) */ +#define RNDADDTOENTCNT _IOW( 'R', 0x01, int ) + +/* Get the contents of the entropy pool. (Superuser only.) */ +#define RNDGETPOOL _IOR( 'R', 0x02, int [2] ) + +/* + * Write bytes into the entropy pool and add to the entropy count. + * (Superuser only.) + */ +#define RNDADDENTROPY _IOW( 'R', 0x03, int [2] ) + +/* Clear entropy count to 0. (Superuser only.) */ +#define RNDZAPENTCNT _IO( 'R', 0x04 ) + +/* Clear the entropy pool and associated counters. (Superuser only.) */ +#define RNDCLEARPOOL _IO( 'R', 0x06 ) + +struct rand_pool_info { + int entropy_count; + int buf_size; + __u32 buf[0]; +}; + +/* Exported functions */ + +#ifdef __KERNEL__ + +extern void rand_initialize(void); +extern void rand_initialize_irq(int irq); +extern void rand_initialize_blkdev(int irq, int mode); + +extern void add_keyboard_randomness(unsigned char scancode); +extern void add_mouse_randomness(__u32 mouse_data); +extern void add_interrupt_randomness(int irq); +extern void add_blkdev_randomness(int major); + +extern void get_random_bytes(void *buf, int nbytes); + +extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr, + __u16 sport, __u16 dport); + +#ifndef MODULE +extern struct file_operations random_fops, urandom_fops; +#endif + +#endif /* __KERNEL___ */ + +#endif /* _LINUX_RANDOM_H */ diff --git a/include/linux/resource.h b/include/linux/resource.h index ebbbcfa4e..f3bffbd7f 100644 --- a/include/linux/resource.h +++ b/include/linux/resource.h @@ -1,6 +1,8 @@ #ifndef _LINUX_RESOURCE_H #define _LINUX_RESOURCE_H +#include <linux/time.h> + /* * Resource control/accounting header file for linux */ @@ -42,8 +44,8 @@ struct rlimit { long rlim_max; }; -#define PRIO_MIN (-99) -#define PRIO_MAX 14 +#define PRIO_MIN (-20) +#define PRIO_MAX 20 #define PRIO_PROCESS 0 #define PRIO_PGRP 1 diff --git a/include/linux/rose.h b/include/linux/rose.h new file mode 100644 index 000000000..ca69e1e8b --- /dev/null +++ b/include/linux/rose.h @@ -0,0 +1,51 @@ +/* + * These are the public elements of the Linux kernel Rose implementation. + * For kernel AX.25 see the file ax25.h. This file requires ax25.h for the + * definition of the ax25_address structure. + */ + +#ifndef ROSE_KERNEL_H +#define ROSE_KERNEL_H + +#define PF_ROSE AF_ROSE +#define ROSE_MTU 128 + +#define ROSE_T0 1 +#define ROSE_T1 2 +#define ROSE_T2 3 +#define ROSE_T3 4 +#define ROSE_IDLE 5 +#define ROSE_HDRINCL 6 + +#define ROSE_KILL 99 + +#define SIOCRSCTLCON (SIOCPROTOPRIVATE+0) + +typedef struct { + char rose_addr[5]; +} rose_address; + +struct sockaddr_rose { + sa_family_t srose_family; + rose_address srose_addr; + ax25_address srose_call; + int srose_ndigis; + ax25_address srose_digi; +}; + +struct rose_route_struct { + rose_address address; + ax25_address neighbour; + char device[16]; + unsigned char ndigis; + ax25_address digipeaters[AX25_MAX_DIGIS]; +}; + +struct rose_ctl_struct { + unsigned int lci; + char dev[20]; + unsigned int cmd; + unsigned long arg; +}; + +#endif diff --git a/include/linux/route.h b/include/linux/route.h index 0f11ea2eb..bf677b2e0 100644 --- a/include/linux/route.h +++ b/include/linux/route.h @@ -8,6 +8,8 @@ * Version: @(#)route.h 1.0.3 05/27/93 * * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988 + * for the purposes of compatibility only. + * * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * * This program is free software; you can redistribute it and/or @@ -22,7 +24,8 @@ /* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ -struct rtentry { +struct rtentry +{ unsigned long rt_hash; /* hash key for lookups */ struct sockaddr rt_dst; /* target address */ struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ @@ -50,11 +53,33 @@ struct rtentry { #define RTF_IRTT 0x0100 /* Initial round trip time */ #define RTF_REJECT 0x0200 /* Reject route */ +#define RTF_ADDRCONF 0x0800 /* announced on link prefix */ +#define RTF_INVALID 0x1000 +#define RTF_DCACHE 0x2000 +#define RTF_DEFAULT 0x4000 /* Route is a default route */ +#define RTF_NEXTHOP 0x8000 /* Non gateway route with nexthop */ + /* - * REMOVE THESE BY 1.2.0 !!!!!!!!!!!!!!!!! + * This structure is passed from the kernel to user space by netlink + * routing/device announcements */ - -#define RTF_MTU RTF_MSS -#define rt_mtu rt_mss +struct netlink_rtinfo +{ + unsigned long rtmsg_type; + struct sockaddr rtmsg_dst; + struct sockaddr rtmsg_gateway; + struct sockaddr rtmsg_genmask; + short rtmsg_flags; + short rtmsg_metric; + char rtmsg_device[16]; +}; + +#define RTMSG_NEWROUTE 0x01 +#define RTMSG_DELROUTE 0x02 +#define RTMSG_NEWDEVICE 0x11 +#define RTMSG_DELDEVICE 0x12 + +#define RTMSG_AR_FAILED 0x21 /* Address Resolution failed */ #endif /* _LINUX_ROUTE_H */ + diff --git a/include/linux/rpcsock.h b/include/linux/rpcsock.h new file mode 100644 index 000000000..9a7f5eae9 --- /dev/null +++ b/include/linux/rpcsock.h @@ -0,0 +1,121 @@ +/* + * rpcsock.h Declarations for the RPC call interface. + * + * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> + */ + + +#ifndef _LINUX_RPCSOCK_H +#define _LINUX_RPCSOCK_H + +/* + * The rpcsock code maintains an estimate on the maximum number of out- + * standing RPC requests, using the congestion avoidance implemented in + * 44BSD. This is basically the Van Jacobson slow start algorithm: If a + * retransmit occurs, the congestion window is halved; otherwise, it is + * incremented by 1/cwnd when a reply is received and a full number of + * requests are outstanding. + * + * Upper procedures may check whether a request would block waiting for + * a free RPC slot by using the RPC_CONGESTED() macro. + * + * Note: on machines with low memory we should probably use a smaller + * MAXREQS value: At 32 outstanding reqs with 8 megs of RAM, fragment + * reassembly will frequently run out of memory. + */ +#define RPC_MAXREQS 32 +#define RPC_CWNDSCALE 256 +#define RPC_MAXCWND (RPC_MAXREQS * RPC_CWNDSCALE) +/* #define RPC_INITCWND (RPC_MAXCWND / 2) */ +#define RPC_INITCWND RPC_CWNDSCALE +#define RPC_CONGESTED(rsock) ((rsock)->cong >= (rsock)->cwnd) + +/* RPC reply header size: xid, direction, status, accept_status (verifier + * size computed separately) + */ +#define RPC_HDRSIZE (4 * 4) + +/* + * This describes a timeout strategy + */ +struct rpc_timeout { + unsigned long to_initval, + to_maxval, + to_increment; + int to_retries; + char to_exponential; +}; + +/* + * This describes a complete RPC request + */ +struct rpc_ioreq { + struct rpc_wait * rq_slot; + struct sockaddr * rq_addr; + int rq_alen; + struct iovec rq_svec[UIO_MAXIOV]; + unsigned int rq_snr; + unsigned long rq_slen; + struct iovec rq_rvec[UIO_MAXIOV]; + unsigned int rq_rnr; + unsigned long rq_rlen; +}; + +/* + * This is the callback handler for async RPC. + */ +struct rpc_wait; +typedef void (*rpc_callback_fn_t)(int, struct rpc_wait *, void *); + +/* + * Wait information. This struct defines all the state of an RPC + * request currently in flight. + */ +struct rpc_wait { + struct rpc_sock * w_sock; + struct rpc_wait * w_prev; + struct rpc_wait * w_next; + struct rpc_ioreq * w_req; + int w_result; + struct wait_queue * w_wait; + rpc_callback_fn_t w_handler; + void * w_cdata; + char w_queued; + char w_gotit; + __u32 w_xid; +}; + +struct rpc_sock { + struct file * file; + struct socket * sock; + struct sock * inet; + struct rpc_wait waiting[RPC_MAXREQS]; + unsigned long cong; + unsigned long cwnd; + struct rpc_wait * pending; + struct rpc_wait * free; + struct wait_queue * backlog; + struct wait_queue * shutwait; + int shutdown; +}; + +#ifdef __KERNEL__ + +/* rpc_call: Call synchronously */ +int rpc_call(struct rpc_sock *, struct rpc_ioreq *, + struct rpc_timeout *); +/* These implement asynch calls for nfsiod: Process calls rpc_reserve and + * rpc_transmits, then passes the request to nfsiod, which collects the + * results via rpc_doio + */ +int rpc_reserve(struct rpc_sock *, struct rpc_ioreq *, int); +void rpc_release(struct rpc_sock *, struct rpc_ioreq *); +int rpc_transmit(struct rpc_sock *, struct rpc_ioreq *); +int rpc_doio(struct rpc_sock *, struct rpc_ioreq *, + struct rpc_timeout *, int); +struct rpc_sock * rpc_makesock(struct file *); +int rpc_closesock(struct rpc_sock *); + +#endif /* __KERNEL__*/ + +#endif /* _LINUX_RPCSOCK_H */ diff --git a/include/linux/sbpcd.h b/include/linux/sbpcd.h index ee7ec8d4c..e9021316d 100644 --- a/include/linux/sbpcd.h +++ b/include/linux/sbpcd.h @@ -5,22 +5,28 @@ /* * Attention! This file contains user-serviceable parts! * I recommend to make use of it... + * If you feel helpless, look into linux/Documentation/cdrom/sbpcd + * (good idea anyway, at least before mailing me). * * The definitions for the first controller can get overridden by * the kernel command line ("lilo boot option"). * Examples: + * sbpcd=0x300,LaserMate + * or * sbpcd=0x230,SoundBlaster * or - * sbpcd=0x300,LaserMate + * sbpcd=0x338,SoundScape * or - * sbpcd=0x330,SPEA + * sbpcd=0x2C0,Teac16bit * * If sbpcd gets used as a module, you can load it with - * insmod /usr/src/linux/modules/sbpcd.o sbpcd=0x230,1 + * insmod sbpcd.o sbpcd=0x300,0 * or - * insmod /usr/src/linux/modules/sbpcd.o sbpcd=0x300,0 + * insmod sbpcd.o sbpcd=0x230,1 * or - * insmod /usr/src/linux/modules/sbpcd.o sbpcd=0x330,2 + * insmod sbpcd.o sbpcd=0x338,2 + * or + * insmod sbpcd.o sbpcd=0x2C0,3 * respective to override the configured address and type. */ @@ -28,35 +34,36 @@ * define your CDROM port base address as CDROM_PORT * and specify the type of your interface card as SBPRO. * - * Read linux/drivers/block/README.sbpcd if you are in doubt about the - * type of your interface card (you should do that anyway). - * * address: * ======== * SBPRO type addresses typically are 0x0230 (=0x220+0x10), 0x0250, ... * LASERMATE type (CI-101P, WDH-7001C) addresses typically are 0x0300, ... - * SPEA addresses are from the LASERMATE type and range. + * SOUNDSCAPE addresses are from the LASERMATE type and range. You have to + * specify the REAL address here, not the configuration port address. Look + * at the CDROM driver's invoking line within your DOS CONFIG.SYS, or let + * sbpcd auto-probe, if you are not firm with the address. * There are some soundcards on the market with 0x0630, 0x0650, ...; their * type is not obvious (both types are possible). * * example: if your SBPRO audio address is 0x220, specify 0x230 and SBPRO 1. * if your soundcard has its CDROM port above 0x300, specify * that address and try SBPRO 0 first. + * if your SoundScape configuration port is at 0x330, specify + * 0x338 and SBPRO 2. * * interface type: * =============== * set SBPRO to 1 for "true" SoundBlaster card * set SBPRO to 0 for "compatible" soundcards and * for "poor" (no sound) interface cards. - * set SBPRO to 2 for the SPEA Media FX card + * set SBPRO to 2 for Ensonic SoundScape or SPEA Media FX cards + * set SBPRO to 3 for Teac 16bit interface cards * * Almost all "compatible" sound boards need to set SBPRO to 0. * If SBPRO is set wrong, the drives will get found - but any * data access will give errors (audio access will work). - * The "OmniCD" no-sound interface card from CreativeLabs needs SBPRO 1. - * - * mail to emoenke@gwdg.de if you have a "compatible" sound card which - * in fact needs to set SBPRO to 1 (not any known at time). + * The "OmniCD" no-sound interface card from CreativeLabs and most Teac + * interface cards need SBPRO 1. * * sound base: * =========== @@ -80,7 +87,7 @@ #define SOUND_BASE 0x000 /* <-----------<< sound address of this card or 0 */ #endif #if !(SBPCD_ISSUE-3) /* ===================== third interface board: === */ -#define CDROM_PORT 0x634 /* <-----------<< port address */ +#define CDROM_PORT 0x630 /* <-----------<< port address */ #define SBPRO 1 /* <-----------<< interface type */ #define MAX_DRIVES 4 /* set to 1 if the card does not use "drive select" */ #define SOUND_BASE 0x240 /* <-----------<< sound address of this card or 0 */ @@ -96,38 +103,85 @@ * some more or less user dependent definitions - service them! */ -/* Set this to 0 after you have configured your interface definitions right. */ +/* Set this to 0 once you have configured your interface definitions right. */ #define DISTRIBUTION 1 -/* max. number of audio frames to read with one */ -/* request (allocates n* 2352 bytes kernel memory!) */ -/* may be freely adjusted, f.e. 75 (= 1 sec.), at */ -/* runtime by use of the CDROMAUDIOBUFSIZ ioctl. */ -#define READ_AUDIO 0 +/* + * Time to wait after giving a message. + * This gets important if you enable non-standard DBG_xxx flags. + * You will see what happens if you omit the pause or make it + * too short. Be warned! + */ +#define KLOGD_PAUSE 1 -/* tray control: eject tray if no disk is in (0 or 1) */ +/* tray control: eject tray if no disk is in */ +#if DISTRIBUTION +#define JUKEBOX 0 +#else #define JUKEBOX 1 +#endif DISTRIBUTION -/* tray control: eject tray after last use (0 or 1) */ +/* tray control: eject tray after last use */ +#if DISTRIBUTION +#define EJECT 0 +#else #define EJECT 1 +#endif DISTRIBUTION + +/* max. number of audio frames to read with one */ +/* request (allocates n* 2352 bytes kernel memory!) */ +/* may be freely adjusted, f.e. 75 (= 1 sec.), at */ +/* runtime by use of the CDROMAUDIOBUFSIZ ioctl. */ +#define READ_AUDIO 0 + +/* Optimizations for the Teac CD-55A drive read performance. + * SBP_TEAC_SPEED can be changed here, or one can set the + * variable "teac" when loading as a module. + * Valid settings are: + * 0 - very slow - the recommended "DISTRIBUTION 1" setup. + * 1 - 2x performance with little overhead. No busy waiting. + * 2 - 4x performance with 5ms overhead per read. Busy wait. + * + * Setting SBP_TEAC_SPEED or the variable 'teac' to anything + * other than 0 may cause problems. If you run into them, first + * change SBP_TEAC_SPEED back to 0 and see if your drive responds + * normally. If yes, you are "allowed" to report your case - to help + * me with the driver, not to solve your hassle. Don´t mail if you + * simply are stuck into your own "tuning" experiments, you know? + */ +#define SBP_TEAC_SPEED 1 /*==========================================================================*/ /*==========================================================================*/ /* - * nothing to change below here if you are not experimenting + * nothing to change below here if you are not fully aware what you're doing */ #ifndef _LINUX_SBPCD_H #define _LINUX_SBPCD_H /*==========================================================================*/ /*==========================================================================*/ +/* + * driver's own read_ahead, data mode + */ +#define SBP_BUFFER_FRAMES 8 + #define LONG_TIMING 0 /* test against timeouts with "gold" CDs on CR-521 */ #undef FUTURE +#undef SAFE_MIXED #define TEST_UPC 0 #define SPEA_TEST 0 #define TEST_STI 0 +#define OLD_BUSY 0 #undef PATH_CHECK +#ifndef SOUND_BASE +#define SOUND_BASE 0 +#endif +#if DISTRIBUTION +#undef SBP_TEAC_SPEED +#define SBP_TEAC_SPEED 0 +#endif /*==========================================================================*/ /* * DDI interface definitions @@ -139,8 +193,6 @@ /* * "private" IOCTL functions */ -#define CDROMRESET 0x5380 /* hard-rest the drive */ -#define CDROMVOLREAD 0x5381 /* let the drive tell its volume settings */ #define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */ /*==========================================================================*/ @@ -174,9 +226,9 @@ #define DBG_AUD 25 /* READ AUDIO debugging */ #define DBG_SEQ 26 /* Sequoia interface configuration trace */ #define DBG_LCS 27 /* Longshine LCS-7260 debugging trace */ -#define DBG_CD2 28 /* MKE CD200 debugging trace */ +#define DBG_CD2 28 /* MKE/Funai CD200 debugging trace */ #define DBG_TEA 29 /* TEAC CD-55A debugging trace */ -#define DBG_TE2 30 /* TEAC CD-55A 2nd debugging level */ +#define DBG_ECS 30 /* ECS-AT (Vertos 100) debugging trace */ #define DBG_000 31 /* unnecessary information */ /*==========================================================================*/ @@ -233,7 +285,7 @@ * LCS-7260 special status result bits: */ #define p_lcs_door_locked 0x02 -#define p_lcs_door_closed 0x01 +#define p_lcs_door_closed 0x01 /* probably disk_in */ /* * CR-52x special status result bits: @@ -263,6 +315,14 @@ #define pL_door_locked 0x02 #define pL_door_closed 0x01 +#define pV_door_closed 0x40 +#define pV_spinning 0x20 +#define pV_check 0x10 +#define pV_success 0x08 +#define pV_busy 0x04 +#define pV_door_locked 0x02 +#define pV_disk_ok 0x01 + #define p1_door_closed 0x80 #define p1_disk_in 0x40 #define p1_spinning 0x20 @@ -306,9 +366,9 @@ #define RESULT_READY ((inb(CDi_status)&s_not_result_ready)==0) /* - * drive types (firmware versions): + * drive families and types (firmware versions): */ -#define drv_fam0 0x08 /* CR-52x family */ +#define drv_fam0 0x0100 /* CR-52x family */ #define drv_199 (drv_fam0+0x01) /* <200 */ #define drv_200 (drv_fam0+0x02) /* <201 */ #define drv_201 (drv_fam0+0x03) /* <210 */ @@ -316,25 +376,35 @@ #define drv_211 (drv_fam0+0x05) /* <300 */ #define drv_300 (drv_fam0+0x06) /* >=300 */ -#define drv_famL 0x10 /* Longshine family */ +#define drv_fam1 0x0200 /* CR-56x family */ +#define drv_099 (drv_fam1+0x01) /* <100 */ +#define drv_100 (drv_fam1+0x02) /* >=100, only 1.02 and 5.00 known */ + +#define drv_fam2 0x0400 /* CD200 family */ + +#define drv_famT 0x0800 /* TEAC CD-55A */ + +#define drv_famL 0x1000 /* Longshine family */ #define drv_260 (drv_famL+0x01) /* LCS-7260 */ #define drv_e1 (drv_famL+0x01) /* LCS-7260, firmware "A E1" */ #define drv_f4 (drv_famL+0x02) /* LCS-7260, firmware "A4F4" */ -#define drv_fam1 0x20 /* CR-56x family */ -#define drv_099 (drv_fam1+0x01) /* <100 */ -#define drv_100 (drv_fam1+0x02) /* >=100, only 5.00 known here */ - -#define drv_famT 0x40 /* TEAC CD-55A */ -#define drv_fam2 0x80 /* CD200 family */ +#define drv_famV 0x2000 /* ECS-AT (vertos-100) family */ +#define drv_at (drv_famV+0x01) /* ECS-AT, firmware "1.00" */ #define fam0_drive (D_S[d].drv_type&drv_fam0) #define famL_drive (D_S[d].drv_type&drv_famL) +#define famV_drive (D_S[d].drv_type&drv_famV) #define fam1_drive (D_S[d].drv_type&drv_fam1) #define fam2_drive (D_S[d].drv_type&drv_fam2) #define famT_drive (D_S[d].drv_type&drv_famT) #define fam0L_drive (D_S[d].drv_type&(drv_fam0|drv_famL)) +#define fam0V_drive (D_S[d].drv_type&(drv_fam0|drv_famV)) +#define famLV_drive (D_S[d].drv_type&(drv_famL|drv_famV)) +#define fam0LV_drive (D_S[d].drv_type&(drv_fam0|drv_famL|drv_famV)) #define fam1L_drive (D_S[d].drv_type&(drv_fam1|drv_famL)) +#define fam1V_drive (D_S[d].drv_type&(drv_fam1|drv_famV)) +#define fam1LV_drive (D_S[d].drv_type&(drv_fam1|drv_famL|drv_famV)) #define fam01_drive (D_S[d].drv_type&(drv_fam0|drv_fam1)) #define fam12_drive (D_S[d].drv_type&(drv_fam1|drv_fam2)) #define fam2T_drive (D_S[d].drv_type&(drv_fam2|drv_famT)) @@ -378,7 +448,6 @@ #define audx13 0x0d /* Audio play operation successfully completed */ #define audx14 0x0e /* Audio play operation stopped due to error */ #define audx15 0x0f /* No current audio status to return */ - /* audio status (bcd) */ #define aud_11 0x11 /* Audio play operation in progress */ #define aud_12 0x12 /* Audio play operation paused */ @@ -386,7 +455,6 @@ #define aud_14 0x14 /* Audio play operation stopped due to error */ #define aud_15 0x15 /* No current audio status to return */ - /* * highest allowed drive number (MINOR+1) */ @@ -404,13 +472,15 @@ /*==========================================================================*/ +#define MIXER_addr SOUND_BASE+4 /* sound card's address register */ +#define MIXER_data SOUND_BASE+5 /* sound card's data register */ #define MIXER_CD_Volume 0x28 /* internal SB Pro register address */ /*==========================================================================*/ -/* - * Creative Labs Programmers did this: - */ -#define MAX_TRACKS 120 /* why more than 99? */ + +#define MAX_TRACKS 99 + +#define ERR_DISKCHANGE 615 /*==========================================================================*/ /* @@ -589,6 +659,7 @@ Read XA Parameter: * CD200: CMD2_ * LCS-7260: CMDL_ * TEAC CD-55A: CMDT_ + * ECS-AT: CMDV_ */ #define CMD1_RESET 0x0a #define CMD2_RESET 0x01 @@ -598,14 +669,17 @@ Read XA Parameter: #define CMD2_LOCK_CTL 0x1e #define CMDT_LOCK_CTL CMD2_LOCK_CTL #define CMDL_LOCK_CTL 0x0e +#define CMDV_LOCK_CTL CMDL_LOCK_CTL #define CMD1_TRAY_CTL 0x07 #define CMD2_TRAY_CTL 0x1b #define CMDT_TRAY_CTL CMD2_TRAY_CTL #define CMDL_TRAY_CTL 0x0d +#define CMDV_TRAY_CTL CMDL_TRAY_CTL #define CMD1_MULTISESS 0x8d #define CMDL_MULTISESS 0x8c +#define CMDV_MULTISESS CMDL_MULTISESS #define CMD1_SUBCHANINF 0x11 #define CMD2_SUBCHANINF 0x?? @@ -623,22 +697,27 @@ Read XA Parameter: #define CMD2_PATH_CHECK 0x??? #define CMDT_PATH_CHECK 0x??? #define CMDL_PATH_CHECK CMD0_PATH_CHECK +#define CMDV_PATH_CHECK CMD0_PATH_CHECK #define CMD0_SEEK 0x01 #define CMD1_SEEK CMD0_SEEK #define CMD2_SEEK 0x2b #define CMDT_SEEK CMD2_SEEK #define CMDL_SEEK CMD0_SEEK +#define CMDV_SEEK CMD0_SEEK #define CMD0_READ 0x02 #define CMD1_READ 0x10 #define CMD2_READ 0x28 #define CMDT_READ CMD2_READ #define CMDL_READ CMD0_READ +#define CMDV_READ CMD0_READ #define CMD0_READ_XA 0x03 #define CMD2_READ_XA 0xd4 +#define CMD2_READ_XA2 0xd5 #define CMDL_READ_XA CMD0_READ_XA /* really ?? */ +#define CMDV_READ_XA CMD0_READ_XA #define CMD0_READ_HEAD 0x04 @@ -646,11 +725,13 @@ Read XA Parameter: #define CMD1_SPINUP 0x02 #define CMD2_SPINUP CMD2_TRAY_CTL #define CMDL_SPINUP CMD0_SPINUP +#define CMDV_SPINUP CMD0_SPINUP #define CMD0_SPINDOWN 0x06 /* really??? */ #define CMD1_SPINDOWN 0x06 #define CMD2_SPINDOWN CMD2_TRAY_CTL #define CMDL_SPINDOWN 0x0d +#define CMDV_SPINDOWN CMD0_SPINDOWN #define CMD0_DIAG 0x07 @@ -658,6 +739,7 @@ Read XA Parameter: #define CMD1_READ_UPC 0x88 #define CMD2_READ_UPC 0x??? #define CMDL_READ_UPC CMD0_READ_UPC +#define CMDV_READ_UPC 0x8f #define CMD0_READ_ISRC 0x09 @@ -665,6 +747,7 @@ Read XA Parameter: #define CMD1_PLAY 0x??? #define CMD2_PLAY 0x??? #define CMDL_PLAY CMD0_PLAY +#define CMDV_PLAY CMD0_PLAY #define CMD0_PLAY_MSF 0x0b #define CMD1_PLAY_MSF 0x0e @@ -680,18 +763,22 @@ Read XA Parameter: #define CMD2_STATUS 0x00 #define CMDT_STATUS CMD2_STATUS #define CMDL_STATUS CMD0_STATUS +#define CMDV_STATUS CMD0_STATUS +#define CMD2_SEEK_LEADIN 0x00 #define CMD0_READ_ERR 0x82 #define CMD1_READ_ERR CMD0_READ_ERR #define CMD2_READ_ERR 0x03 #define CMDT_READ_ERR CMD2_READ_ERR /* get audio status */ #define CMDL_READ_ERR CMD0_READ_ERR +#define CMDV_READ_ERR CMD0_READ_ERR #define CMD0_READ_VER 0x83 #define CMD1_READ_VER CMD0_READ_VER #define CMD2_READ_VER 0x12 #define CMDT_READ_VER CMD2_READ_VER /* really ?? */ #define CMDL_READ_VER CMD0_READ_VER +#define CMDV_READ_VER CMD0_READ_VER #define CMD0_SETMODE 0x84 #define CMD1_SETMODE 0x09 @@ -719,6 +806,7 @@ Read XA Parameter: #define CMD2_READSUBQ 0x42 #define CMDT_READSUBQ CMD2_READSUBQ #define CMDL_READSUBQ CMD0_READSUBQ +#define CMDV_READSUBQ CMD0_READSUBQ #define CMD0_DISKCODE 0x8a @@ -727,22 +815,26 @@ Read XA Parameter: #define CMD2_DISKINFO 0x43 #define CMDT_DISKINFO CMD2_DISKINFO #define CMDL_DISKINFO CMD0_DISKINFO +#define CMDV_DISKINFO CMD0_DISKINFO #define CMD0_READTOC 0x8c #define CMD1_READTOC CMD0_READTOC #define CMD2_READTOC 0x??? #define CMDL_READTOC CMD0_READTOC +#define CMDV_READTOC CMD0_READTOC #define CMD0_PAU_RES 0x8d #define CMD1_PAU_RES 0x0d #define CMD2_PAU_RES 0x4b #define CMDT_PAUSE CMD2_PAU_RES #define CMDL_PAU_RES CMD0_PAU_RES +#define CMDV_PAUSE CMD0_PAU_RES #define CMD0_PACKET 0x8e #define CMD1_PACKET CMD0_PACKET #define CMD2_PACKET 0x??? #define CMDL_PACKET CMD0_PACKET +#define CMDV_PACKET 0x??? /*==========================================================================*/ /*==========================================================================*/ diff --git a/include/linux/scc.h b/include/linux/scc.h index 696eb4b12..330143da4 100644 --- a/include/linux/scc.h +++ b/include/linux/scc.h @@ -1,4 +1,4 @@ -/* $Id: scc.h,v 1.9 1995/01/12 18:24:40 JReuter Exp JReuter $ */ +/* $Id: scc.h,v 1.28 1996/10/30 20:01:15 jreuter Exp jreuter $ */ #ifndef _SCC_H #define _SCC_H @@ -12,40 +12,21 @@ #define DRSI 0x08 /* hardware type for DRSI PC*Packet card */ #define BAYCOM 0x10 /* hardware type for BayCom (U)SCC */ -/* Constants */ - -#define MAXSCC 4 /* number of max. supported chips */ -#define MAX_IBUFS 200 /* change this if you run out of memory */ -#define BUFSIZE 128 /* must not exceed 4096 */ -#define TPS 25 /* scc_timer(): Ticks Per Second */ - -#define SCC_TIMER 3 - -#define SCC_PARANOIA_CHECK /* tell the user if something is going wrong */ - -/* ioctl() commands */ - -/* !!! NEW VALUES !!! */ - -#define TIOCSCCINI 0x5470 /* init driver */ -#define TIOCCHANINI 0x5471 /* init channel */ - -#define TIOCGKISS 0x5472 /* get kiss parameter */ -#define TIOCSKISS 0x5473 /* set kiss parameter */ - -#define TIOCSCCSTAT 0x5474 /* get scc status */ +/* DEV ioctl() commands */ +#define SIOCSCCRESERVED (SIOCDEVPRIVATE+0) +#define SIOCSCCCFG (SIOCDEVPRIVATE+1) +#define SIOCSCCINI (SIOCDEVPRIVATE+2) +#define SIOCSCCCHANINI (SIOCDEVPRIVATE+3) +#define SIOCSCCSMEM (SIOCDEVPRIVATE+4) +#define SIOCSCCGKISS (SIOCDEVPRIVATE+5) +#define SIOCSCCSKISS (SIOCDEVPRIVATE+6) +#define SIOCSCCGSTAT (SIOCDEVPRIVATE+7) /* magic number */ #define SCC_MAGIC 0x8530 /* ;-) */ -/* KISS protocol flags */ -#define FEND 192 -#define FESC 219 -#define TFEND 220 -#define TFESC 221 - /* KISS state machine */ #define KISS_IDLE 0 @@ -73,12 +54,27 @@ #define PARAM_WAIT 16 #define PARAM_MAXDEFER 17 #define PARAM_TX 18 -#define PARAM_SLIP 19 +#define PARAM_HWEVENT 31 #define PARAM_RETURN 255 /* reset kiss mode */ +/* fulldup parameter */ + +#define KISS_DUPLEX_HALF 0 /* normal CSMA operation */ +#define KISS_DUPLEX_FULL 1 /* fullduplex, key down trx after transmission */ +#define KISS_DUPLEX_LINK 2 /* fullduplex, key down trx after 'idletime' sec */ +#define KISS_DUPLEX_OPTIMA 3 /* fullduplex, let the protocol layer control the hw */ + +/* misc. parameters */ + #define TIMER_OFF 65535U /* to switch off timers */ #define NO_SUCH_PARAM 65534U /* param not implemented */ +/* HWEVENT parameter */ + +#define HWEV_DCD_ON 0 +#define HWEV_DCD_OFF 1 +#define HWEV_ALL_SENT 2 + /* channel grouping */ #define RXGROUP 0x100 /* if set, only tx when all channels clear */ @@ -97,86 +93,11 @@ #define TXS_BUSY 1 /* waiting for permission to send / tailtime */ #define TXS_ACTIVE 2 /* Transmitter on, sending data */ #define TXS_NEWFRAME 3 /* reset CRC and send (next) frame */ +#define TXS_IDLE2 4 /* Transmitter on, no data pending */ +#define TXS_WAIT 5 /* Waiting for Mintime to expire */ +#define TXS_TIMEOUT 6 /* We had a transmission timeout */ -#define TX_ON 1 /* command for scc_key_trx() */ -#define TX_OFF 0 /* dto */ - -/* Buffer management */ - -#define BT_RECEIVE 1 /* buffer allocated by receive */ -#define BT_TRANSMIT 2 /* buffer allocated by transmit */ - -#define QUEUE_THRES MAX_IBUFS/20 /* maximum amount of packets being queued */ -#define QUEUE_HYST 3 /* leave QUEUE_HYST packets untouched */ - -#define NULLBUF (struct mbuf *)0 -#define NULLBUFP (struct mbuf **)0 - - -typedef unsigned short io_port; /* type definition for an 'io port address' */ -typedef unsigned short ioaddr; /* old def */ - -#ifdef SCC_DELAY -#define Inb(port) inb_p(port) -#define Outb(port, val) outb_p(val, port) -#else -#define Inb(port) inb(port) -#define Outb(port, val) outb(val, port) -#endif - -/* some nasty macros (esp. Expired) */ - -#define TIMER_STOPPED 65535U -#define Running(k) (scc->k != TIMER_STOPPED) -#define Expired(k) (scc->k != TIMER_STOPPED) && (!(scc->k) || (--(scc->k) == 0)) -#define Stop_Timer(k) scc->k = TIMER_STOPPED - - -/* Basic message buffer structure */ - -/* looks familiar? Hmm, yes... */ - -struct mbuf { - struct mbuf *next; /* Links mbufs belonging to single packets */ - struct mbuf *anext; /* Links packets on queues */ - - char type; /* who allocated this buffer? */ - int time_out; /* unimplemented yet */ - - int size; /* Size of associated data buffer */ - int refcnt; /* Reference count */ - struct mbuf *dup; /* Pointer to duplicated mbuf */ - char data[BUFSIZE]; /* Active working pointers */ - int cnt; - int in_use; -}; - - -struct sccbuf { - struct mbuf *bp; - int inuse; -}; - - -/* SCC channel control structure for KISS */ - -struct scc_kiss { - unsigned char txdelay; /* Transmit Delay 10 ms/cnt */ - unsigned char persist; /* Persistence (0-255) as a % */ - unsigned char slottime; /* Delay to wait on persistence hit */ - unsigned char tailtime; /* Delay after XMTR OFF */ - unsigned char fulldup; /* Full Duplex mode 0=CSMA 1=DUP 2=ALWAYS KEYED */ - unsigned char waittime; /* Waittime before any transmit attempt */ - unsigned int maxkeyup; /* Maximum time to transmit (seconds) */ - unsigned char mintime; /* Minimal offtime after MAXKEYUP timeout */ - unsigned int idletime; /* Maximum idle time in ALWAYS KEYED mode (seconds) */ - unsigned int maxdefer; /* Timer for CSMA channel busy limit */ - unsigned char tx_inhibit; /* Transmit is not allowed when set */ - unsigned char group; /* group ID for AX.25 TX interlocking */ - unsigned char not_slip; /* set to zero: use SLIP instead of KISS */ - unsigned char softdcd; /* use DPLL instead of DCD pin for carrier detect */ -}; - +typedef unsigned long io_port; /* type definition for an 'io port address' */ /* SCC statistical information */ @@ -187,7 +108,7 @@ struct scc_stat { long spints; /* Special receiver interrupts */ long txframes; /* Packets sent */ - long rxframes; /* Number of Frames Actally Received */ + long rxframes; /* Number of Frames Actually Received */ long rxerrs; /* CRC Errors */ long txerrs; /* KISS errors */ @@ -196,358 +117,129 @@ struct scc_stat { unsigned int tx_under; /* Transmitter Underruns */ unsigned int tx_state; /* Transmitter state */ - - char tx_kiss_state; /* state of the kiss interpreter */ - char rx_kiss_state; /* state of the kiss encoder */ - int tx_queued; /* tx frames enqueued */ - int rx_queued; /* rx frames enqueued */ - - unsigned int rx_alloc; /* allocated rx_buffers */ - unsigned int tx_alloc; /* allocated tx_buffers */ - unsigned int used_buf; /* used buffers (should be rx_alloc+tx_alloc) */ + + unsigned int maxqueue; /* allocated tx_buffers */ + unsigned int bufsize; /* used buffersize */ }; -struct scc_modem{ +struct scc_modem { long speed; /* Line speed, bps */ char clocksrc; /* 0 = DPLL, 1 = external, 2 = divider */ char nrz; /* NRZ instead of NRZI */ }; -struct ioctl_command { - int command; /* one of the KISS-Commands devined above */ +struct scc_kiss_cmd { + int command; /* one of the KISS-Commands defined above */ unsigned param; /* KISS-Param */ }; -/* SCC channel structure */ - -struct scc_channel { - int magic; /* magic word */ - - int init; /* channel exists? */ - struct tty_struct *tty; /* link to tty control structure */ - unsigned char tty_opened; - - io_port ctrl; /* I/O address of CONTROL register */ - io_port data; /* I/O address of DATA register */ - char enhanced; /* Enhanced SCC support */ - - unsigned char wreg[16]; /* Copy of last written value in WRx */ - unsigned char status; /* Copy of R0 at last external interrupt */ - - struct scc_kiss kiss; /* control structure for KISS params */ - struct scc_stat stat; /* statistical information */ - struct scc_modem modem; /* modem information */ - - struct mbuf *rbp; /* rx: Head of mbuf chain being filled */ - struct mbuf *rbp1; /* rx: Pointer to mbuf currently being written */ - struct mbuf *rcvq; /* Pointer to mbuf packets currently received */ - - struct mbuf *sndq; /* tx: Packets awaiting transmission */ - struct mbuf *tbp; /* tx: Transmit mbuf being sent */ +struct scc_hw_config { + io_port data_a; /* data port channel A */ + io_port ctrl_a; /* control port channel A */ + io_port data_b; /* data port channel B */ + io_port ctrl_b; /* control port channel B */ + io_port vector_latch; /* INTACK-Latch (#) */ + io_port special; /* special function port */ - struct mbuf *sndq1; /* Pointer to mbuf currently under construction */ - struct mbuf *sndq2; /* Pointer to mbuf currently under construction */ + int irq; /* irq */ + long clock; /* clock */ + char option; /* command for function port */ - - /* Timer */ - - unsigned int t_dwait; /* wait time (DWAIT) */ - unsigned int t_slot; /* channel sample frequency */ - unsigned int t_txdel; /* TX delay */ - unsigned int t_tail; /* tail time */ - unsigned int t_maxk; /* max. key up */ - unsigned int t_min; /* minimal key up */ - unsigned int t_idle; /* */ - unsigned int t_mbusy; /* time until defer if channel busy */ + char brand; /* hardware type */ + char escc; /* use ext. features of a 8580/85180/85280 */ }; +/* (#) only one INTACK latch allowed. */ -/* 8530 Serial Communications Controller Register definitions */ -#define FLAG 0x7e - -/* Write Register 0 */ -#define R0 0 /* Register selects */ -#define R1 1 -#define R2 2 -#define R3 3 -#define R4 4 -#define R5 5 -#define R6 6 -#define R7 7 -#define R8 8 -#define R9 9 -#define R10 10 -#define R11 11 -#define R12 12 -#define R13 13 -#define R14 14 -#define R15 15 - -#define NULLCODE 0 /* Null Code */ -#define POINT_HIGH 0x8 /* Select upper half of registers */ -#define RES_EXT_INT 0x10 /* Reset Ext. Status Interrupts */ -#define SEND_ABORT 0x18 /* HDLC Abort */ -#define RES_RxINT_FC 0x20 /* Reset RxINT on First Character */ -#define RES_Tx_P 0x28 /* Reset TxINT Pending */ -#define ERR_RES 0x30 /* Error Reset */ -#define RES_H_IUS 0x38 /* Reset highest IUS */ - -#define RES_Rx_CRC 0x40 /* Reset Rx CRC Checker */ -#define RES_Tx_CRC 0x80 /* Reset Tx CRC Checker */ -#define RES_EOM_L 0xC0 /* Reset EOM latch */ - -/* Write Register 1 */ - -#define EXT_INT_ENAB 0x1 /* Ext Int Enable */ -#define TxINT_ENAB 0x2 /* Tx Int Enable */ -#define PAR_SPEC 0x4 /* Parity is special condition */ - -#define RxINT_DISAB 0 /* Rx Int Disable */ -#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */ -#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */ -#define INT_ERR_Rx 0x18 /* Int on error only */ - -#define WT_RDY_RT 0x20 /* Wait/Ready on R/T */ -#define WT_FN_RDYFN 0x40 /* Wait/FN/Ready FN */ -#define WT_RDY_ENAB 0x80 /* Wait/Ready Enable */ - -/* Write Register 2 (Interrupt Vector) */ - -/* Write Register 3 */ - -#define RxENABLE 0x1 /* Rx Enable */ -#define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ -#define ADD_SM 0x4 /* Address Search Mode (SDLC) */ -#define RxCRC_ENAB 0x8 /* Rx CRC Enable */ -#define ENT_HM 0x10 /* Enter Hunt Mode */ -#define AUTO_ENAB 0x20 /* Auto Enables */ -#define Rx5 0x0 /* Rx 5 Bits/Character */ -#define Rx7 0x40 /* Rx 7 Bits/Character */ -#define Rx6 0x80 /* Rx 6 Bits/Character */ -#define Rx8 0xc0 /* Rx 8 Bits/Character */ - -/* Write Register 4 */ - -#define PAR_ENA 0x1 /* Parity Enable */ -#define PAR_EVEN 0x2 /* Parity Even/Odd* */ - -#define SYNC_ENAB 0 /* Sync Modes Enable */ -#define SB1 0x4 /* 1 stop bit/char */ -#define SB15 0x8 /* 1.5 stop bits/char */ -#define SB2 0xc /* 2 stop bits/char */ - -#define MONSYNC 0 /* 8 Bit Sync character */ -#define BISYNC 0x10 /* 16 bit sync character */ -#define SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */ -#define EXTSYNC 0x30 /* External Sync Mode */ - -#define X1CLK 0x0 /* x1 clock mode */ -#define X16CLK 0x40 /* x16 clock mode */ -#define X32CLK 0x80 /* x32 clock mode */ -#define X64CLK 0xC0 /* x64 clock mode */ - -/* Write Register 5 */ - -#define TxCRC_ENAB 0x1 /* Tx CRC Enable */ -#define RTS 0x2 /* RTS */ -#define SDLC_CRC 0x4 /* SDLC/CRC-16 */ -#define TxENAB 0x8 /* Tx Enable */ -#define SND_BRK 0x10 /* Send Break */ -#define Tx5 0x0 /* Tx 5 bits (or less)/character */ -#define Tx7 0x20 /* Tx 7 bits/character */ -#define Tx6 0x40 /* Tx 6 bits/character */ -#define Tx8 0x60 /* Tx 8 bits/character */ -#define DTR 0x80 /* DTR */ - -/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */ - -/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ - -/* Write Register 8 (transmit buffer) */ - -/* Write Register 9 (Master interrupt control) */ -#define VIS 1 /* Vector Includes Status */ -#define NV 2 /* No Vector */ -#define DLC 4 /* Disable Lower Chain */ -#define MIE 8 /* Master Interrupt Enable */ -#define STATHI 0x10 /* Status high */ -#define NORESET 0 /* No reset on write to R9 */ -#define CHRB 0x40 /* Reset channel B */ -#define CHRA 0x80 /* Reset channel A */ -#define FHWRES 0xc0 /* Force hardware reset */ - -/* Write Register 10 (misc control bits) */ -#define BIT6 1 /* 6 bit/8bit sync */ -#define LOOPMODE 2 /* SDLC Loop mode */ -#define ABUNDER 4 /* Abort/flag on SDLC xmit underrun */ -#define MARKIDLE 8 /* Mark/flag on idle */ -#define GAOP 0x10 /* Go active on poll */ -#define NRZ 0 /* NRZ mode */ -#define NRZI 0x20 /* NRZI mode */ -#define FM1 0x40 /* FM1 (transition = 1) */ -#define FM0 0x60 /* FM0 (transition = 0) */ -#define CRCPS 0x80 /* CRC Preset I/O */ - -/* Write Register 11 (Clock Mode control) */ -#define TRxCXT 0 /* TRxC = Xtal output */ -#define TRxCTC 1 /* TRxC = Transmit clock */ -#define TRxCBR 2 /* TRxC = BR Generator Output */ -#define TRxCDP 3 /* TRxC = DPLL output */ -#define TRxCOI 4 /* TRxC O/I */ -#define TCRTxCP 0 /* Transmit clock = RTxC pin */ -#define TCTRxCP 8 /* Transmit clock = TRxC pin */ -#define TCBR 0x10 /* Transmit clock = BR Generator output */ -#define TCDPLL 0x18 /* Transmit clock = DPLL output */ -#define RCRTxCP 0 /* Receive clock = RTxC pin */ -#define RCTRxCP 0x20 /* Receive clock = TRxC pin */ -#define RCBR 0x40 /* Receive clock = BR Generator output */ -#define RCDPLL 0x60 /* Receive clock = DPLL output */ -#define RTxCX 0x80 /* RTxC Xtal/No Xtal */ - -/* Write Register 12 (lower byte of baud rate generator time constant) */ - -/* Write Register 13 (upper byte of baud rate generator time constant) */ - -/* Write Register 14 (Misc control bits) */ -#define BRENABL 1 /* Baud rate generator enable */ -#define BRSRC 2 /* Baud rate generator source */ -#define DTRREQ 4 /* DTR/Request function */ -#define AUTOECHO 8 /* Auto Echo */ -#define LOOPBAK 0x10 /* Local loopback */ -#define SEARCH 0x20 /* Enter search mode */ -#define RMC 0x40 /* Reset missing clock */ -#define DISDPLL 0x60 /* Disable DPLL */ -#define SSBR 0x80 /* Set DPLL source = BR generator */ -#define SSRTxC 0xa0 /* Set DPLL source = RTxC */ -#define SFMM 0xc0 /* Set FM mode */ -#define SNRZI 0xe0 /* Set NRZI mode */ - -/* Write Register 15 (external/status interrupt control) */ -#define ZCIE 2 /* Zero count IE */ -#define DCDIE 8 /* DCD IE */ -#define SYNCIE 0x10 /* Sync/hunt IE */ -#define CTSIE 0x20 /* CTS IE */ -#define TxUIE 0x40 /* Tx Underrun/EOM IE */ -#define BRKIE 0x80 /* Break/Abort IE */ - - -/* Read Register 0 */ -#define Rx_CH_AV 0x1 /* Rx Character Available */ -#define ZCOUNT 0x2 /* Zero count */ -#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */ -#define DCD 0x8 /* DCD */ -#define SYNC_HUNT 0x10 /* Sync/hunt */ -#define CTS 0x20 /* CTS */ -#define TxEOM 0x40 /* Tx underrun */ -#define BRK_ABRT 0x80 /* Break/Abort */ - -/* Read Register 1 */ -#define ALL_SNT 0x1 /* All sent */ -/* Residue Data for 8 Rx bits/char programmed */ -#define RES3 0x8 /* 0/3 */ -#define RES4 0x4 /* 0/4 */ -#define RES5 0xc /* 0/5 */ -#define RES6 0x2 /* 0/6 */ -#define RES7 0xa /* 0/7 */ -#define RES8 0x6 /* 0/8 */ -#define RES18 0xe /* 1/8 */ -#define RES28 0x0 /* 2/8 */ -/* Special Rx Condition Interrupts */ -#define PAR_ERR 0x10 /* Parity error */ -#define Rx_OVR 0x20 /* Rx Overrun Error */ -#define CRC_ERR 0x40 /* CRC/Framing Error */ -#define END_FR 0x80 /* End of Frame (SDLC) */ - -/* Read Register 2 (channel B only) - Interrupt vector */ - -#define VECTOR_MASK 0x06 - -#define TXINT 0x00 -#define EXINT 0x02 -#define RXINT 0x04 -#define SPINT 0x06 - - -/* Read Register 3 (interrupt pending register) ch a only */ -#define CHBEXT 0x1 /* Channel B Ext/Stat IP */ -#define CHBTxIP 0x2 /* Channel B Tx IP */ -#define CHBRxIP 0x4 /* Channel B Rx IP */ -#define CHAEXT 0x8 /* Channel A Ext/Stat IP */ -#define CHATxIP 0x10 /* Channel A Tx IP */ -#define CHARxIP 0x20 /* Channel A Rx IP */ - -/* Read Register 8 (receive data register) */ +struct scc_mem_config { + unsigned int dummy; + unsigned int bufsize; +}; -/* Read Register 10 (misc status bits) */ -#define ONLOOP 2 /* On loop */ -#define LOOPSEND 0x10 /* Loop sending */ -#define CLK2MIS 0x40 /* Two clocks missing */ -#define CLK1MIS 0x80 /* One clock missing */ -/* Read Register 12 (lower byte of baud rate generator constant) */ +#ifdef __KERNEL__ -/* Read Register 13 (upper byte of baud rate generator constant) */ +#define TX_ON 1 /* command for scc_key_trx() */ +#define TX_OFF 0 /* dto */ -/* Read Register 15 (value of WR 15) */ +/* Vector masks in RR2B */ +#define VECTOR_MASK 0x06 +#define TXINT 0x00 +#define EXINT 0x02 +#define RXINT 0x04 +#define SPINT 0x06 -/* 8536 register definitions */ -#define CIO_MICR 0x00 /* Master interrupt control register */ -#define CIO_MCCR 0x01 /* Master configuration control register */ -#define CIO_CTMS1 0x1c /* Counter/timer mode specification #1 */ -#define CIO_CTMS2 0x1d /* Counter/timer mode specification #2 */ -#define CIO_CTMS3 0x1e /* Counter/timer mode specification #3 */ -#define CIO_IVR 0x04 /* Interrupt vector register */ +#ifdef SCC_DELAY +#define Inb(port) inb_p(port) +#define Outb(port, val) outb_p(val, port) +#else +#define Inb(port) inb(port) +#define Outb(port, val) outb(val, port) +#endif -#define CIO_CSR1 0x0a /* Command and status register CTC #1 */ -#define CIO_CSR2 0x0b /* Command and status register CTC #2 */ -#define CIO_CSR3 0x0c /* Command and status register CTC #3 */ +/* SCC channel control structure for KISS */ -#define CIO_CT1MSB 0x16 /* CTC #1 Timer constant - MSB */ -#define CIO_CT1LSB 0x17 /* CTC #1 Timer constant - LSB */ -#define CIO_CT2MSB 0x18 /* CTC #2 Timer constant - MSB */ -#define CIO_CT2LSB 0x19 /* CTC #2 Timer constant - LSB */ -#define CIO_CT3MSB 0x1a /* CTC #3 Timer constant - MSB */ -#define CIO_CT3LSB 0x1b /* CTC #3 Timer constant - LSB */ -#define CIO_PDCA 0x23 /* Port A data direction control */ -#define CIO_PDCB 0x2b /* Port B data direction control */ +struct scc_kiss { + unsigned char txdelay; /* Transmit Delay 10 ms/cnt */ + unsigned char persist; /* Persistence (0-255) as a % */ + unsigned char slottime; /* Delay to wait on persistence hit */ + unsigned char tailtime; /* Delay after last byte written */ + unsigned char fulldup; /* Full Duplex mode 0=CSMA 1=DUP 2=ALWAYS KEYED */ + unsigned char waittime; /* Waittime before any transmit attempt */ + unsigned int maxkeyup; /* Maximum time to transmit (seconds) */ + unsigned char mintime; /* Minimal offtime after MAXKEYUP timeout (seconds) */ + unsigned int idletime; /* Maximum idle time in ALWAYS KEYED mode (seconds) */ + unsigned int maxdefer; /* Timer for CSMA channel busy limit */ + unsigned char tx_inhibit; /* Transmit is not allowed when set */ + unsigned char group; /* Group ID for AX.25 TX interlocking */ + unsigned char mode; /* 'normal' or 'hwctrl' mode (unused) */ + unsigned char softdcd; /* Use DPLL instead of DCD pin for carrier detect */ +}; -#define CIO_GCB 0x04 /* CTC Gate command bit */ -#define CIO_TCB 0x02 /* CTC Trigger command bit */ -#define CIO_IE 0xc0 /* CTC Interrupt enable (set) */ -#define CIO_CIP 0x20 /* CTC Clear interrupt pending */ -#define CIO_IP 0x20 /* CTC Interrupt pending */ +/* SCC channel structure */ -/* 8580/85180/85280 Enhanced SCC register definitions */ +struct scc_channel { + int magic; /* magic word */ + + int init; /* channel exists? */ -/* Write Register 7' (SDLC/HDLC Programmable Enhancements) */ -#define AUTOTXF 0x01 /* Auto Tx Flag */ -#define AUTOEOM 0x02 /* Auto EOM Latch Reset */ -#define AUTORTS 0x04 /* Auto RTS */ -#define TXDNRZI 0x08 /* TxD Pulled High in SDLC NRZI mode */ -#define FASTDTR 0x10 /* Fast DTR/REQ Mode */ -#define CRCCBCR 0x20 /* CRC Check Bytes Completely Received */ -#define EXTRDEN 0x40 /* Extended Read Enabled */ + struct device *dev; /* link to device control structure */ + struct enet_statistics dev_stat;/* device statistics */ -/* Write Register 15 (external/status interrupt control) */ -#define SHDLCE 1 /* SDLC/HDLC Enhancements Enable */ -#define FIFOE 4 /* FIFO Enable */ + char brand; /* manufacturer of the board */ + long clock; /* used clock */ + + io_port ctrl; /* I/O address of CONTROL register */ + io_port data; /* I/O address of DATA register */ + io_port special; /* I/O address of special function port */ + int irq; /* Number of Interrupt */ + + char option; + char enhanced; /* Enhanced SCC support */ -/* Read Register 6 (frame status FIFO) */ -#define BCLSB 0xff /* LSB of 14 bits count */ + unsigned char wreg[16]; /* Copy of last written value in WRx */ + unsigned char status; /* Copy of R0 at last external interrupt */ -/* Read Register 7 (frame status FIFO) */ -#define BCMSB 0x3f /* MSB of 14 bits count */ -#define FDA 0x40 /* FIFO Data Available Status */ -#define FOY 0x80 /* FIFO Overflow Status */ + struct scc_kiss kiss; /* control structure for KISS params */ + struct scc_stat stat; /* statistical information */ + struct scc_modem modem; /* modem information */ + + struct sk_buff_head tx_queue; /* next tx buffer */ + struct sk_buff *rx_buff; /* pointer to frame currently received */ + struct sk_buff *tx_buff; /* pointer to frame currently transmitted */ -#endif /* _SCC_H */ + /* Timer */ -/* global functions */ + struct timer_list tx_t; /* tx timer for this channel */ + struct timer_list tx_wdog; /* tx watchdogs */ +}; -extern long scc_init(long kmem_start); +int scc_init(void); +#endif /* defined(__KERNEL__) */ +#endif /* defined(_SCC_H) */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 42bd0dcad..3cff32ca0 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -11,14 +11,30 @@ #include <asm/param.h> /* for HZ */ -extern unsigned long intr_count; extern unsigned long event; #include <linux/binfmts.h> #include <linux/personality.h> #include <linux/tasks.h> #include <linux/kernel.h> + #include <asm/system.h> +#include <asm/semaphore.h> +#include <asm/page.h> + +#include <linux/smp.h> +#include <linux/tty.h> +#include <linux/sem.h> + +/* + * cloning flags: + */ +#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ +#define CLONE_VM 0x00000100 /* set if VM shared between processes */ +#define CLONE_FS 0x00000200 /* set if fs info shared between processes */ +#define CLONE_FILES 0x00000400 /* set if open files shared between processes */ +#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */ +#define CLONE_PID 0x00001000 /* set if pid shared */ /* * These are the constant used to fake the fixed-point load-average @@ -48,6 +64,7 @@ extern unsigned long avenrun[]; /* Load averages */ #define CT_TO_USECS(x) (((x) % HZ) * 1000000/HZ) extern int nr_running, nr_tasks; +extern int last_pid; #define FIRST_TASK task[0] #define LAST_TASK task[NR_TASKS-1] @@ -58,9 +75,8 @@ extern int nr_running, nr_tasks; #include <linux/time.h> #include <linux/param.h> #include <linux/resource.h> -#include <linux/vm86.h> -#include <linux/math_emu.h> #include <linux/ptrace.h> +#include <linux/timer.h> #include <asm/processor.h> @@ -71,30 +87,40 @@ extern int nr_running, nr_tasks; #define TASK_STOPPED 4 #define TASK_SWAPPING 5 +/* + * Scheduling policies + */ +#define SCHED_OTHER 0 +#define SCHED_FIFO 1 +#define SCHED_RR 2 + +struct sched_param { + int sched_priority; +}; + #ifndef NULL #define NULL ((void *) 0) #endif #ifdef __KERNEL__ -#define barrier() __asm__("": : :"memory") - extern void sched_init(void); extern void show_state(void); extern void trap_init(void); asmlinkage void schedule(void); -#endif /* __KERNEL__ */ - +/* Open file table structure */ struct files_struct { int count; fd_set close_on_exec; + fd_set open_fds; struct file * fd[NR_OPEN]; }; #define INIT_FILES { \ - 0, \ + 1, \ + { { 0, } }, \ { { 0, } }, \ { NULL, } \ } @@ -106,37 +132,44 @@ struct fs_struct { }; #define INIT_FS { \ - 0, \ + 1, \ 0022, \ NULL, NULL \ } struct mm_struct { int count; - unsigned long start_code, end_code, end_data; + pgd_t * pgd; + unsigned long context; + unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack, start_mmap; unsigned long arg_start, arg_end, env_start, env_end; - unsigned long rss; - unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; - int swappable:1; - unsigned long swap_address; - unsigned long old_maj_flt; /* old value of maj_flt */ - unsigned long dec_flt; /* page fault count of the last time */ - unsigned long swap_cnt; /* number of pages to swap on next pass */ + unsigned long rss, total_vm, locked_vm; + unsigned long def_flags; struct vm_area_struct * mmap; struct vm_area_struct * mmap_avl; + struct semaphore mmap_sem; }; #define INIT_MM { \ + 1, \ + swapper_pg_dir, \ 0, \ - 0, 0, 0, \ 0, 0, 0, 0, \ 0, 0, 0, 0, \ + 0, 0, 0, 0, \ + 0, 0, 0, \ 0, \ -/* ?_flt */ 0, 0, 0, 0, \ - 0, \ -/* swap */ 0, 0, 0, 0, \ - &init_mmap, &init_mmap } + &init_mmap, &init_mmap, MUTEX } + +struct signal_struct { + int count; + struct sigaction action[32]; +}; + +#define INIT_SIGNALS { \ + 1, \ + { {0,}, } } struct task_struct { /* these are hardcoded - don't touch */ @@ -147,21 +180,28 @@ struct task_struct { unsigned long blocked; /* bitmap of masked signals */ unsigned long flags; /* per process flags, defined below */ int errno; - int debugreg[8]; /* Hardware debugging registers */ + long debugreg[8]; /* Hardware debugging registers */ struct exec_domain *exec_domain; /* various fields */ struct linux_binfmt *binfmt; struct task_struct *next_task, *prev_task; struct task_struct *next_run, *prev_run; - struct sigaction sigaction[32]; unsigned long saved_kernel_stack; unsigned long kernel_stack_page; int exit_code, exit_signal; + /* ??? */ unsigned long personality; int dumpable:1; int did_exec:1; - int pid,pgrp,tty_old_pgrp,session,leader; - int groups[NGROUPS]; + /* shouldn't this be pid_t? */ + int pid; + int pgrp; + int tty_old_pgrp; + int session; + /* boolean value for session group leader */ + int leader; + int ngroups; + gid_t groups[NGROUPS]; /* * pointers to (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with @@ -171,11 +211,20 @@ struct task_struct { struct wait_queue *wait_chldexit; /* for wait4() */ unsigned short uid,euid,suid,fsuid; unsigned short gid,egid,sgid,fsgid; - unsigned long timeout; + unsigned long timeout, policy, rt_priority; unsigned long it_real_value, it_prof_value, it_virt_value; unsigned long it_real_incr, it_prof_incr, it_virt_incr; + struct timer_list real_timer; long utime, stime, cutime, cstime, start_time; - struct rlimit rlim[RLIM_NLIMITS]; +/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ + unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; + int swappable:1; + unsigned long swap_address; + unsigned long old_maj_flt; /* old value of maj_flt */ + unsigned long dec_flt; /* page fault count of the last time */ + unsigned long swap_cnt; /* number of pages to swap on next pass */ +/* limits */ + struct rlimit rlim[RLIM_NLIMITS]; unsigned short used_math; char comm[16]; /* file system info */ @@ -189,11 +238,18 @@ struct task_struct { /* tss for this task */ struct thread_struct tss; /* filesystem information */ - struct fs_struct fs[1]; + struct fs_struct *fs; /* open file information */ - struct files_struct files[1]; + struct files_struct *files; /* memory management info */ - struct mm_struct mm[1]; + struct mm_struct *mm; +/* signal handlers */ + struct signal_struct *sig; +#ifdef __SMP__ + int processor; + int last_processor; + int lock_depth; /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */ +#endif }; /* @@ -203,61 +259,85 @@ struct task_struct { /* Not implemented yet, only for 486*/ #define PF_PTRACED 0x00000010 /* set if ptrace (0) has been called. */ #define PF_TRACESYS 0x00000020 /* tracing system calls */ +#define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ +#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ +#define PF_DUMPCORE 0x00000200 /* dumped core */ +#define PF_SIGNALED 0x00000400 /* killed by a signal */ -#define PF_STARTING 0x00000100 /* being created */ -#define PF_EXITING 0x00000200 /* getting shut down */ +#define PF_STARTING 0x00000002 /* being created */ +#define PF_EXITING 0x00000004 /* getting shut down */ + +#define PF_USEDFPU 0x00100000 /* Process used the FPU this quantum (SMP only) */ +#define PF_DTRACE 0x00200000 /* delayed trace (used on m68k) */ /* - * cloning flags: + * Limit the stack by to some sane default: root can always + * increase this limit if needed.. 8MB seems reasonable. */ -#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ -#define COPYVM 0x00000100 /* set if VM copy desired (like normal fork()) */ -#define COPYFD 0x00000200 /* set if fd's should be copied, not shared (NI) */ +#define _STK_LIM (8*1024*1024) + +#define DEF_PRIORITY (20*HZ/100) /* 200 ms time slices */ /* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) */ #define INIT_TASK \ -/* state etc */ { 0,15,15,0,0,0,0, \ +/* state etc */ { 0,DEF_PRIORITY,DEF_PRIORITY,0,0,0,0, \ /* debugregs */ { 0, }, \ /* exec domain */&default_exec_domain, \ /* binfmt */ NULL, \ /* schedlink */ &init_task,&init_task, &init_task, &init_task, \ -/* signals */ {{ 0, },}, \ /* stack */ 0,(unsigned long) &init_kernel_stack, \ /* ec,brk... */ 0,0,0,0,0, \ /* pid etc.. */ 0,0,0,0,0, \ -/* suppl grps*/ {NOGROUP,}, \ +/* suppl grps*/ 0, {0,}, \ /* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \ /* uid etc */ 0,0,0,0,0,0,0,0, \ -/* timeout */ 0,0,0,0,0,0,0,0,0,0,0,0, \ -/* rlimits */ { {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ - {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ - { 0, LONG_MAX}, {LONG_MAX, LONG_MAX}, \ - {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, {NR_OPEN, NR_OPEN}}, \ +/* timeout */ 0,SCHED_OTHER,0,0,0,0,0,0,0, \ +/* timer */ { NULL, NULL, 0, 0, it_real_fn }, \ +/* utime */ 0,0,0,0,0, \ +/* flt */ 0,0,0,0,0,0, \ +/* swp */ 0,0,0,0,0, \ +/* rlimits */ INIT_RLIMITS, \ /* math */ 0, \ /* comm */ "swapper", \ /* fs info */ 0,NULL, \ /* ipc */ NULL, NULL, \ /* ldt */ NULL, \ /* tss */ INIT_TSS, \ -/* fs */ { INIT_FS }, \ -/* files */ { INIT_FILES }, \ -/* mm */ { INIT_MM } \ +/* fs */ &init_fs, \ +/* files */ &init_files, \ +/* mm */ &init_mm, \ +/* signals */ &init_signals, \ } -#ifdef __KERNEL__ - +extern struct mm_struct init_mm; extern struct task_struct init_task; extern struct task_struct *task[NR_TASKS]; extern struct task_struct *last_task_used_math; -extern struct task_struct *current; +extern struct task_struct *current_set[NR_CPUS]; +/* + * On a single processor system this comes out as current_set[0] when cpp + * has finished with it, which gcc will optimise away. + * Ralf: It won't. On MIPS something like + * la reg,current_set + * lw reg,(reg) + * will be generated which is one cycle to much. FIXME somewhen laaater. + */ +#define current (current_set[smp_processor_id()]) /* Current on this processor */ extern unsigned long volatile jiffies; extern unsigned long itimer_ticks; extern unsigned long itimer_next; extern struct timeval xtime; extern int need_resched; +extern void do_timer(struct pt_regs *); + +extern unsigned int * prof_buffer; +extern unsigned long prof_len; +extern unsigned long prof_shift; + +extern int securelevel; /* system security level */ #define CURRENT_TIME (xtime.tv_sec) @@ -265,89 +345,110 @@ extern void sleep_on(struct wait_queue ** p); extern void interruptible_sleep_on(struct wait_queue ** p); extern void wake_up(struct wait_queue ** p); extern void wake_up_interruptible(struct wait_queue ** p); +extern void wake_up_process(struct task_struct * tsk); extern void notify_parent(struct task_struct * tsk); +extern void force_sig(unsigned long sig,struct task_struct * p); extern int send_sig(unsigned long sig,struct task_struct * p,int priv); extern int in_group_p(gid_t grp); -extern int request_irq(unsigned int irq,void (*handler)(int, struct pt_regs *), - unsigned long flags, const char *device); -extern void free_irq(unsigned int irq); +extern int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, + const char *device, + void *dev_id); +extern void free_irq(unsigned int irq, void *dev_id); + +/* + * This has now become a routine instead of a macro, it sets a flag if + * it returns true (to do BSD-style accounting where the process is flagged + * if it uses root privs). The implication of this is that you should do + * normal permissions checks first, and check suser() last. + */ +extern inline int suser(void) +{ + if (current->euid == 0) { + current->flags |= PF_SUPERPRIV; + return 1; + } + return 0; +} extern void copy_thread(int, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); extern void flush_thread(void); extern void exit_thread(void); +extern void exit_mm(struct task_struct *); +extern void exit_fs(struct task_struct *); +extern void exit_files(struct task_struct *); +extern void exit_sighand(struct task_struct *); +extern void release_thread(struct task_struct *); + extern int do_execve(char *, char **, char **, struct pt_regs *); extern int do_fork(unsigned long, unsigned long, struct pt_regs *); -asmlinkage int do_signal(unsigned long, struct pt_regs *); + +/* See if we have a valid user level fd. + * If it makes sense, return the file structure it references. + * Otherwise return NULL. + */ +extern inline struct file *file_from_fd(const unsigned int fd) +{ + + if (fd >= NR_OPEN) + return NULL; + /* either valid or null */ + return current->files->fd[fd]; +} + /* * The wait-queues are circular lists, and you have to be *very* sure * to keep them correct. Use only these two functions to add/remove * entries in the queues. */ +extern inline void __add_wait_queue(struct wait_queue ** p, struct wait_queue * wait) +{ + struct wait_queue *head = *p; + struct wait_queue *next = WAIT_QUEUE_HEAD(p); + + if (head) + next = head; + *p = wait; + wait->next = next; +} + extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait) { unsigned long flags; -#ifdef DEBUG - if (wait->next) { - unsigned long pc; - __asm__ __volatile__("call 1f\n" - "1:\tpopl %0":"=r" (pc)); - printk("add_wait_queue (%08x): wait->next = %08x\n",pc,(unsigned long) wait->next); - } -#endif save_flags(flags); cli(); - if (!*p) { - wait->next = wait; - *p = wait; - } else { - wait->next = (*p)->next; - (*p)->next = wait; - } + __add_wait_queue(p, wait); restore_flags(flags); } +extern inline void __remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait) +{ + struct wait_queue * next = wait->next; + struct wait_queue * head = next; + + for (;;) { + struct wait_queue * nextlist = head->next; + if (nextlist == wait) + break; + head = nextlist; + } + head->next = next; +} + extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait) { unsigned long flags; - struct wait_queue * tmp; -#ifdef DEBUG - unsigned long ok = 0; -#endif save_flags(flags); cli(); - if ((*p == wait) && -#ifdef DEBUG - (ok = 1) && -#endif - ((*p = wait->next) == wait)) { - *p = NULL; - } else { - tmp = wait; - while (tmp->next != wait) { - tmp = tmp->next; -#ifdef DEBUG - if (tmp == *p) - ok = 1; -#endif - } - tmp->next = wait->next; - } - wait->next = NULL; + __remove_wait_queue(p, wait); restore_flags(flags); -#ifdef DEBUG - if (!ok) { - printk("removed wait_queue not on list.\n"); - printk("list = %08x, queue = %08x\n",(unsigned long) p, (unsigned long) wait); - __asm__("call 1f\n1:\tpopl %0":"=r" (ok)); - printk("eip = %08x\n",ok); - } -#endif } extern inline void select_wait(struct wait_queue ** wait_address, select_table * p) @@ -366,24 +467,6 @@ extern inline void select_wait(struct wait_queue ** wait_address, select_table * p->nr++; } -extern void __down(struct semaphore * sem); - -/* - * These are not yet interrupt-safe - */ -extern inline void down(struct semaphore * sem) -{ - if (sem->count <= 0) - __down(sem); - sem->count--; -} - -extern inline void up(struct semaphore * sem) -{ - sem->count++; - wake_up(&sem->wait); -} - #define REMOVE_LINKS(p) do { unsigned long flags; \ save_flags(flags) ; cli(); \ (p)->next_task->prev_task = (p)->prev_task; \ diff --git a/include/linux/sdla.h b/include/linux/sdla.h new file mode 100644 index 000000000..44ae55b1c --- /dev/null +++ b/include/linux/sdla.h @@ -0,0 +1,339 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Global definitions for the Frame relay interface. + * + * Version: @(#)if_ifrad.h 0.20 13 Apr 96 + * + * Author: Mike McLagan <mike.mclagan@linux.org> + * + * Changes: + * 0.15 Mike McLagan Structure packing + * + * 0.20 Mike McLagan New flags for S508 buffer handling + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef SDLA_H +#define SDLA_H + +/* adapter type */ +#define SDLA_TYPES +#define SDLA_S502A 5020 +#define SDLA_S502E 5021 +#define SDLA_S503 5030 +#define SDLA_S507 5070 +#define SDLA_S508 5080 +#define SDLA_S509 5090 +#define SDLA_UNKNOWN -1 + +/* port selection flags for the S508 */ +#define SDLA_S508_PORT_V35 0x00 +#define SDLA_S508_PORT_RS232 0x02 + +/* Z80 CPU speeds */ +#define SDLA_CPU_3M 0x00 +#define SDLA_CPU_5M 0x01 +#define SDLA_CPU_7M 0x02 +#define SDLA_CPU_8M 0x03 +#define SDLA_CPU_10M 0x04 +#define SDLA_CPU_16M 0x05 +#define SDLA_CPU_12M 0x06 + +/* some private IOCTLs */ +#define SDLA_IDENTIFY (FRAD_LAST_IOCTL + 1) +#define SDLA_CPUSPEED (FRAD_LAST_IOCTL + 2) +#define SDLA_PROTOCOL (FRAD_LAST_IOCTL + 3) + +#define SDLA_CLEARMEM (FRAD_LAST_IOCTL + 4) +#define SDLA_WRITEMEM (FRAD_LAST_IOCTL + 5) +#define SDLA_READMEM (FRAD_LAST_IOCTL + 6) + +struct sdla_mem { + int addr; + int len; + void *data; +}; + +#define SDLA_START (FRAD_LAST_IOCTL + 7) +#define SDLA_STOP (FRAD_LAST_IOCTL + 8) + +/* some offsets in the Z80's memory space */ +#define SDLA_NMIADDR 0x0000 +#define SDLA_CONF_ADDR 0x0010 +#define SDLA_S502A_NMIADDR 0x0066 +#define SDLA_CODE_BASEADDR 0x0100 +#define SDLA_WINDOW_SIZE 0x2000 +#define SDLA_ADDR_MASK 0x1FFF + +/* largest handleable block of data */ +#define SDLA_MAX_DATA 4080 +#define SDLA_MAX_MTU 4072 /* MAX_DATA - sizeof(fradhdr) */ +#define SDLA_MAX_DLCI 24 + +/* this should be the same as frad_conf */ +struct sdla_conf { + short station; + short config; + short kbaud; + short clocking; + short max_frm; + short T391; + short T392; + short N391; + short N392; + short N393; + short CIR_fwd; + short Bc_fwd; + short Be_fwd; + short CIR_bwd; + short Bc_bwd; + short Be_bwd; +}; + +/* this should be the same as dlci_conf */ +struct sdla_dlci_conf { + short config; + short CIR_fwd; + short Bc_fwd; + short Be_fwd; + short CIR_bwd; + short Bc_bwd; + short Be_bwd; + short Tc_fwd; + short Tc_bwd; + short Tf_max; + short Tb_max; +}; + +#ifndef __KERNEL__ + +void sdla(void *cfg_info, char *dev, struct frad_conf *conf, int quiet); + +#else + +/* important Z80 window addresses */ +#define SDLA_CONTROL_WND 0xE000 + +#define SDLA_502_CMD_BUF 0xEF60 +#define SDLA_502_RCV_BUF 0xA900 +#define SDLA_502_TXN_AVAIL 0xFFF1 +#define SDLA_502_RCV_AVAIL 0xFFF2 +#define SDLA_502_EVENT_FLAGS 0xFFF3 +#define SDLA_502_MDM_STATUS 0xFFF4 +#define SDLA_502_IRQ_INTERFACE 0xFFFD +#define SDLA_502_IRQ_PERMISSION 0xFFFE +#define SDLA_502_DATA_OFS 0x0010 + +#define SDLA_508_CMD_BUF 0xE000 +#define SDLA_508_TXBUF_INFO 0xF100 +#define SDLA_508_RXBUF_INFO 0xF120 +#define SDLA_508_EVENT_FLAGS 0xF003 +#define SDLA_508_MDM_STATUS 0xF004 +#define SDLA_508_IRQ_INTERFACE 0xF010 +#define SDLA_508_IRQ_PERMISSION 0xF011 +#define SDLA_508_TSE_OFFSET 0xF012 + +/* Event flags */ +#define SDLA_EVENT_STATUS 0x01 +#define SDLA_EVENT_DLCI_STATUS 0x02 +#define SDLA_EVENT_BAD_DLCI 0x04 +#define SDLA_EVENT_LINK_DOWN 0x40 + +/* IRQ Trigger flags */ +#define SDLA_INTR_RX 0x01 +#define SDLA_INTR_TX 0x02 +#define SDLA_INTR_MODEM 0x04 +#define SDLA_INTR_COMPLETE 0x08 +#define SDLA_INTR_STATUS 0x10 +#define SDLA_INTR_TIMER 0x20 + +/* DLCI status bits */ +#define SDLA_DLCI_DELETED 0x01 +#define SDLA_DLCI_ACTIVE 0x02 +#define SDLA_DLCI_WAITING 0x04 +#define SDLA_DLCI_NEW 0x08 +#define SDLA_DLCI_INCLUDED 0x40 + +/* valid command codes */ +#define SDLA_INFORMATION_WRITE 0x01 +#define SDLA_INFORMATION_READ 0x02 +#define SDLA_ISSUE_IN_CHANNEL_SIGNAL 0x03 +#define SDLA_SET_DLCI_CONFIGURATION 0x10 +#define SDLA_READ_DLCI_CONFIGURATION 0x11 +#define SDLA_DISABLE_COMMUNICATIONS 0x12 +#define SDLA_ENABLE_COMMUNICATIONS 0x13 +#define SDLA_READ_DLC_STATUS 0x14 +#define SDLA_READ_DLC_STATISTICS 0x15 +#define SDLA_FLUSH_DLC_STATISTICS 0x16 +#define SDLA_LIST_ACTIVE_DLCI 0x17 +#define SDLA_FLUSH_INFORMATION_BUFFERS 0x18 +#define SDLA_ADD_DLCI 0x20 +#define SDLA_DELETE_DLCI 0x21 +#define SDLA_ACTIVATE_DLCI 0x22 +#define SDLA_DEACTIVATE_DLCI 0x23 +#define SDLA_READ_MODEM_STATUS 0x30 +#define SDLA_SET_MODEM_STATUS 0x31 +#define SDLA_READ_COMMS_ERR_STATS 0x32 +#define SDLA_FLUSH_COMMS_ERR_STATS 0x33 +#define SDLA_READ_CODE_VERSION 0x40 +#define SDLA_SET_IRQ_TRIGGER 0x50 +#define SDLA_GET_IRQ_TRIGGER 0x51 + +/* In channel signal types */ +#define SDLA_ICS_LINK_VERIFY 0x02 +#define SDLA_ICS_STATUS_ENQ 0x03 + +/* modem status flags */ +#define SDLA_MODEM_DTR_HIGH 0x01 +#define SDLA_MODEM_RTS_HIGH 0x02 +#define SDLA_MODEM_DCD_HIGH 0x08 +#define SDLA_MODEM_CTS_HIGH 0x20 + +/* used for RET_MODEM interpretation */ +#define SDLA_MODEM_DCD_LOW 0x01 +#define SDLA_MODEM_CTS_LOW 0x02 + +/* return codes */ +#define SDLA_RET_OK 0x00 +#define SDLA_RET_COMMUNICATIONS 0x01 +#define SDLA_RET_CHANNEL_INACTIVE 0x02 +#define SDLA_RET_DLCI_INACTIVE 0x03 +#define SDLA_RET_DLCI_CONFIG 0x04 +#define SDLA_RET_BUF_TOO_BIG 0x05 +#define SDLA_RET_NO_DATA 0x05 +#define SDLA_RET_BUF_OVERSIZE 0x06 +#define SDLA_RET_CIR_OVERFLOW 0x07 +#define SDLA_RET_NO_BUFS 0x08 +#define SDLA_RET_TIMEOUT 0x0A +#define SDLA_RET_MODEM 0x10 +#define SDLA_RET_CHANNEL_OFF 0x11 +#define SDLA_RET_CHANNEL_ON 0x12 +#define SDLA_RET_DLCI_STATUS 0x13 +#define SDLA_RET_DLCI_UNKNOWN 0x14 +#define SDLA_RET_COMMAND_INVALID 0x1F + +/* Configuration flags */ +#define SDLA_DIRECT_RECV 0x0080 +#define SDLA_TX_NO_EXCEPT 0x0020 +#define SDLA_NO_ICF_MSGS 0x1000 +#define SDLA_TX50_RX50 0x0000 +#define SDLA_TX70_RX30 0x2000 +#define SDLA_TX30_RX70 0x4000 + +/* IRQ selection flags */ +#define SDLA_IRQ_RECEIVE 0x01 +#define SDLA_IRQ_TRANSMIT 0x02 +#define SDLA_IRQ_MODEM_STAT 0x04 +#define SDLA_IRQ_COMMAND 0x08 +#define SDLA_IRQ_CHANNEL 0x10 +#define SDLA_IRQ_TIMER 0x20 + +/* definitions for PC memory mapping */ +#define SDLA_8K_WINDOW 0x01 +#define SDLA_S502_SEG_A 0x10 +#define SDLA_S502_SEG_C 0x20 +#define SDLA_S502_SEG_D 0x00 +#define SDLA_S502_SEG_E 0x30 +#define SDLA_S507_SEG_A 0x00 +#define SDLA_S507_SEG_B 0x40 +#define SDLA_S507_SEG_C 0x80 +#define SDLA_S507_SEG_E 0xC0 +#define SDLA_S508_SEG_A 0x00 +#define SDLA_S508_SEG_C 0x10 +#define SDLA_S508_SEG_D 0x08 +#define SDLA_S508_SEG_E 0x18 + +/* SDLA adapter port constants */ +#define SDLA_IO_EXTENTS 0x04 + +#define SDLA_REG_CONTROL 0x00 +#define SDLA_REG_PC_WINDOW 0x01 /* offset for PC window select latch */ +#define SDLA_REG_Z80_WINDOW 0x02 /* offset for Z80 window select latch */ +#define SDLA_REG_Z80_CONTROL 0x03 /* offset for Z80 control latch */ + +#define SDLA_S502_STS 0x00 /* status reg for 502, 502E, 507 */ +#define SDLA_S508_GNRL 0x00 /* general purp. reg for 508 */ +#define SDLA_S508_STS 0x01 /* status reg for 508 */ +#define SDLA_S508_IDR 0x02 /* ID reg for 508 */ + +/* control register flags */ +#define SDLA_S502A_START 0x00 /* start the CPU */ +#define SDLA_S502A_INTREQ 0x02 +#define SDLA_S502A_INTEN 0x04 +#define SDLA_S502A_HALT 0x08 /* halt the CPU */ +#define SDLA_S502A_NMI 0x10 /* issue an NMI to the CPU */ + +#define SDLA_S502E_CPUEN 0x01 +#define SDLA_S502E_ENABLE 0x02 +#define SDLA_S502E_INTACK 0x04 + +#define SDLA_S507_ENABLE 0x01 +#define SDLA_S507_IRQ3 0x00 +#define SDLA_S507_IRQ4 0x20 +#define SDLA_S507_IRQ5 0x40 +#define SDLA_S507_IRQ7 0x60 +#define SDLA_S507_IRQ10 0x80 +#define SDLA_S507_IRQ11 0xA0 +#define SDLA_S507_IRQ12 0xC0 +#define SDLA_S507_IRQ15 0xE0 + +#define SDLA_HALT 0x00 +#define SDLA_CPUEN 0x02 +#define SDLA_MEMEN 0x04 +#define SDLA_S507_EPROMWR 0x08 +#define SDLA_S507_EPROMCLK 0x10 +#define SDLA_S508_INTRQ 0x08 +#define SDLA_S508_INTEN 0x10 + +struct sdla_cmd { + char opp_flag __attribute__((packed)); + char cmd __attribute__((packed)); + short length __attribute__((packed)); + char retval __attribute__((packed)); + short dlci __attribute__((packed)); + char flags __attribute__((packed)); + short rxlost_int __attribute__((packed)); + long rxlost_app __attribute__((packed)); + char reserve[2] __attribute__((packed)); + char data[SDLA_MAX_DATA] __attribute__((packed)); /* transfer data buffer */ +}; + +struct intr_info { + char flags __attribute__((packed)); + short txlen __attribute__((packed)); + char irq __attribute__((packed)); + char flags2 __attribute__((packed)); + short timeout __attribute__((packed)); +}; + +/* found in the 508's control window at RXBUF_INFO */ +struct buf_info { + unsigned short rse_num __attribute__((packed)); + unsigned long rse_base __attribute__((packed)); + unsigned long rse_next __attribute__((packed)); + unsigned long buf_base __attribute__((packed)); + unsigned short reserved __attribute__((packed)); + unsigned long buf_top __attribute__((packed)); +}; + +/* structure pointed to by rse_base in RXBUF_INFO struct */ +struct buf_entry { + char opp_flag __attribute__((packed)); + short length __attribute__((packed)); + short dlci __attribute__((packed)); + char flags __attribute__((packed)); + short timestamp __attribute__((packed)); + short reserved[2] __attribute__((packed)); + long buf_addr __attribute__((packed)); +}; + +#endif + +#endif diff --git a/include/linux/sem.h b/include/linux/sem.h index 9484d233e..a5b3134bf 100644 --- a/include/linux/sem.h +++ b/include/linux/sem.h @@ -1,5 +1,6 @@ #ifndef _LINUX_SEM_H #define _LINUX_SEM_H + #include <linux/ipc.h> /* semop flags */ @@ -14,45 +15,49 @@ #define SETVAL 16 /* set semval */ #define SETALL 17 /* set all semval's */ +/* ipcs ctl cmds */ +#define SEM_STAT 18 +#define SEM_INFO 19 + /* One semid data structure for each set of semaphores in the system. */ struct semid_ds { - struct ipc_perm sem_perm; /* permissions .. see ipc.h */ - time_t sem_otime; /* last semop time */ - time_t sem_ctime; /* last change time */ - struct sem *sem_base; /* ptr to first semaphore in array */ - struct sem_queue *sem_pending; /* pending operations to be processed */ - struct sem_queue **sem_pending_last; /* last pending operation */ - struct sem_undo *undo; /* undo requests on this array */ - ushort sem_nsems; /* no. of semaphores in array */ + struct ipc_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + __kernel_time_t sem_ctime; /* last change time */ + struct sem *sem_base; /* ptr to first semaphore in array */ + struct sem_queue *sem_pending; /* pending operations to be processed */ + struct sem_queue **sem_pending_last; /* last pending operation */ + struct sem_undo *undo; /* undo requests on this array */ + unsigned short sem_nsems; /* no. of semaphores in array */ }; /* semop system calls takes an array of these. */ struct sembuf { - ushort sem_num; /* semaphore index in array */ - short sem_op; /* semaphore operation */ - short sem_flg; /* operation flags */ + unsigned short sem_num; /* semaphore index in array */ + short sem_op; /* semaphore operation */ + short sem_flg; /* operation flags */ }; /* arg for semctl system calls. */ union semun { - int val; /* value for SETVAL */ - struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ - ushort *array; /* array for GETALL & SETALL */ - struct seminfo *__buf; /* buffer for IPC_INFO */ - void *__pad; + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + unsigned short *array; /* array for GETALL & SETALL */ + struct seminfo *__buf; /* buffer for IPC_INFO */ + void *__pad; }; struct seminfo { - int semmap; - int semmni; - int semmns; - int semmnu; - int semmsl; - int semopm; - int semume; - int semusz; - int semvmx; - int semaem; + int semmap; + int semmni; + int semmns; + int semmnu; + int semmsl; + int semopm; + int semume; + int semusz; + int semvmx; + int semaem; }; #define SEMMNI 128 /* ? max # of semaphore identifiers */ @@ -72,37 +77,37 @@ struct seminfo { /* One semaphore structure for each semaphore in the system. */ struct sem { - short semval; /* current value */ - short sempid; /* pid of last operation */ + int semval; /* current value */ + int sempid; /* pid of last operation */ }; -/* ipcs ctl cmds */ -#define SEM_STAT 18 -#define SEM_INFO 19 - /* One queue for each semaphore set in the system. */ struct sem_queue { - struct sem_queue * next; /* next entry in the queue */ - struct sem_queue ** prev; /* previous entry in the queue, *(q->prev) == q */ - struct wait_queue * sleeper; /* sleeping process */ - struct sem_undo * undo; /* undo structure */ - int pid; /* process id of requesting process */ - int status; /* completion status of operation */ - struct semid_ds * sma; /* semaphore array for operations */ - struct sembuf * sops; /* array of pending operations */ - int nsops; /* number of operations */ + struct sem_queue * next; /* next entry in the queue */ + struct sem_queue ** prev; /* previous entry in the queue, *(q->prev) == q */ + struct wait_queue * sleeper; /* sleeping process */ + struct sem_undo * undo; /* undo structure */ + int pid; /* process id of requesting process */ + int status; /* completion status of operation */ + struct semid_ds * sma; /* semaphore array for operations */ + struct sembuf * sops; /* array of pending operations */ + int nsops; /* number of operations */ }; /* Each task has a list of undo requests. They are executed automatically * when the process exits. */ struct sem_undo { - struct sem_undo * proc_next; /* next entry on this process */ - struct sem_undo * id_next; /* next entry on this semaphore set */ - int semid; /* semaphore set identifier */ - short * semadj; /* array of adjustments, one per semaphore */ + struct sem_undo * proc_next; /* next entry on this process */ + struct sem_undo * id_next; /* next entry on this semaphore set */ + int semid; /* semaphore set identifier */ + short * semadj; /* array of adjustments, one per semaphore */ }; +asmlinkage int sys_semget (key_t key, int nsems, int semflg); +asmlinkage int sys_semop (int semid, struct sembuf *sops, unsigned nsops); +asmlinkage int sys_semctl (int semid, int semnum, int cmd, union semun arg); + #endif /* __KERNEL__ */ #endif /* _LINUX_SEM_H */ diff --git a/include/linux/serial.h b/include/linux/serial.h index 02af4746a..141c6706c 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h @@ -44,7 +44,19 @@ struct serial_struct { #define PORT_16550A 4 #define PORT_CIRRUS 5 #define PORT_16650 6 -#define PORT_MAX 6 +#define PORT_16650V2 7 +#define PORT_16750 8 +#define PORT_MAX 8 + +struct serial_uart_config { + char *name; + int dfl_xmit_fifo_size; + int flags; +}; + +#define UART_CLEAR_FIFO 0x01 +#define UART_USE_FIFO 0x02 +#define UART_STARTECH 0x04 /* * Definitions for async_struct (and serial_struct) flags field @@ -55,7 +67,7 @@ struct serial_struct { #define ASYNC_SAK 0x0004 /* Secure Attention Key (Orange book) */ #define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */ -#define ASYNC_SPD_MASK 0x0030 +#define ASYNC_SPD_MASK 0x1030 #define ASYNC_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */ #define ASYNC_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */ @@ -67,8 +79,13 @@ struct serial_struct { #define ASYNC_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */ #define ASYNC_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */ -#define ASYNC_FLAGS 0x0FFF /* Possible legal async flags */ -#define ASYNC_USR_MASK 0x0430 /* Legal flags that non-privileged +#define ASYNC_HARDPPS_CD 0x0800 /* Call hardpps when CD goes high */ + +#define ASYNC_SPD_SHI 0x1000 /* Use 230400 instead of 38400 bps */ +#define ASYNC_SPD_WARP 0x1010 /* Use 460800 instead of 38400 bps */ + +#define ASYNC_FLAGS 0x1FFF /* Possible legal async flags */ +#define ASYNC_USR_MASK 0x1430 /* Legal flags that non-privileged * users can set or reset */ /* Internal flags used only by kernel/chr_drv/serial.c */ @@ -79,6 +96,9 @@ struct serial_struct { #define ASYNC_CLOSING 0x08000000 /* Serial port is closing */ #define ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */ #define ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */ +#define ASYNC_SHARE_IRQ 0x01000000 /* for multifunction cards */ + +#define ASYNC_INTERNAL_FLAGS 0xFF000000 /* Internal flags */ /* * Multiport serial configuration structure --- external structure @@ -97,6 +117,16 @@ struct serial_multiport_struct { int reserved[32]; }; +/* + * Serial input interrupt line counters -- external structure + * Four lines can interrupt: CTS, DSR, RI, DCD + */ +struct serial_icounter_struct { + int cts, dsr, rng, dcd; + int reserved[16]; +}; + + #ifdef __KERNEL__ /* * This is our internal structure for each serial port's state. @@ -107,20 +137,47 @@ struct serial_multiport_struct { * For definitions of the flags field, see tty.h */ +#include <linux/termios.h> +#include <linux/tqueue.h> + +/* + * Counters of the input lines (CTS, DSR, RI, CD) interrupts + */ +struct async_icount { + __u32 cts, dsr, rng, dcd; +}; + +struct serial_state { + int magic; + int baud_base; + int port; + int irq; + int flags; + int hub6; + int type; + int line; + int xmit_fifo_size; + int custom_divisor; + int count; + unsigned short close_delay; + unsigned short closing_wait; /* time to wait before closing */ + struct async_icount icount; + struct termios normal_termios; + struct termios callout_termios; + struct async_struct *info; +}; + struct async_struct { int magic; - int baud_base; int port; - int irq; - int flags; /* defined in tty.h */ - int hub6; /* HUB6 plus one */ - int type; /* UART type */ + int hub6; + int flags; + int xmit_fifo_size; + struct serial_state *state; struct tty_struct *tty; int read_status_mask; int ignore_status_mask; int timeout; - int xmit_fifo_size; - int custom_divisor; int x_char; /* xon/xoff character */ int close_delay; unsigned short closing_wait; @@ -131,7 +188,6 @@ struct async_struct { unsigned long event; unsigned long last_active; int line; - int count; /* # of fd on device */ int blocked_open; /* # of blocked opens */ long session; /* Session of opening process */ long pgrp; /* pgrp of opening process */ @@ -141,15 +197,15 @@ struct async_struct { int xmit_cnt; struct tq_struct tqueue; struct tq_struct tqueue_hangup; - struct termios normal_termios; - struct termios callout_termios; struct wait_queue *open_wait; struct wait_queue *close_wait; + struct wait_queue *delta_msr_wait; struct async_struct *next_port; /* For the linked list */ struct async_struct *prev_port; }; #define SERIAL_MAGIC 0x5301 +#define SSTATE_MAGIC 0x5302 /* * The size of the serial xmit buffer is 1 page, or 4096 bytes diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 19d7c0ba7..c982ae28b 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h @@ -51,6 +51,8 @@ #define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */ #define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */ #define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */ +/* TI 16750 definitions */ +#define UART_FCR7_64BYTE 0x20 /* Go into 64 byte mode */ /* * These are the definitions for the Line Control Register @@ -98,6 +100,11 @@ #define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */ #define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */ #define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ +/* + * Sleep mode for ST16650 and TI16750. + * Note that for 16650, EFR-bit 4 must be selected as well. + */ +#define UART_IERX_SLEEP 0x10 /* Enable sleep mode */ /* * These are the definitions for the Modem Control Register @@ -128,7 +135,7 @@ #define UART_EFR_CTS 0x80 /* CTS flow control */ #define UART_EFR_RTS 0x40 /* RTS flow control */ #define UART_EFR_SCD 0x20 /* Special character detect */ -#define UART_EFR_ENI 0x10 /* Enhanced Interrupt */ +#define UART_EFR_ECB 0x10 /* Enhanced control bit */ /* * the low four bits control software flow control */ diff --git a/include/linux/shm.h b/include/linux/shm.h index 2faa4e63d..f890c7356 100644 --- a/include/linux/shm.h +++ b/include/linux/shm.h @@ -1,20 +1,23 @@ #ifndef _LINUX_SHM_H_ #define _LINUX_SHM_H_ + #include <linux/ipc.h> +#include <asm/shmparam.h> + struct shmid_ds { - struct ipc_perm shm_perm; /* operation perms */ - int shm_segsz; /* size of segment (bytes) */ - time_t shm_atime; /* last attach time */ - time_t shm_dtime; /* last detach time */ - time_t shm_ctime; /* last change time */ - unsigned short shm_cpid; /* pid of creator */ - unsigned short shm_lpid; /* pid of last operator */ - short shm_nattch; /* no. of current attaches */ + struct ipc_perm shm_perm; /* operation perms */ + int shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + __kernel_time_t shm_dtime; /* last detach time */ + __kernel_time_t shm_ctime; /* last change time */ + __kernel_ipc_pid_t shm_cpid; /* pid of creator */ + __kernel_ipc_pid_t shm_lpid; /* pid of last operator */ + unsigned short shm_nattch; /* no. of current attaches */ /* the following are private */ - unsigned short shm_npages; /* size of segment (pages) */ - unsigned long *shm_pages; /* array of ptrs to frames -> SHMMAX */ - struct vm_area_struct *attaches; /* descriptors for attaches */ + unsigned short shm_npages; /* size of segment (pages) */ + unsigned long *shm_pages; /* array of ptrs to frames -> SHMMAX */ + struct vm_area_struct *attaches; /* descriptors for attaches */ }; /* permission flag for shmget */ @@ -30,47 +33,26 @@ struct shmid_ds { #define SHM_LOCK 11 #define SHM_UNLOCK 12 +/* ipcs ctl commands */ +#define SHM_STAT 13 +#define SHM_INFO 14 + struct shminfo { - int shmmax; - int shmmin; - int shmmni; - int shmseg; - int shmall; + int shmmax; + int shmmin; + int shmmni; + int shmseg; + int shmall; }; -/* address range for shared memory attaches if no address passed to shmat() */ -#define SHM_RANGE_START 0x50000000 -#define SHM_RANGE_END 0x60000000 - -/* format of page table entries that correspond to shared memory pages - currently out in swap space (see also mm/swap.c): - bit 0 (PAGE_PRESENT) is = 0 - bits 7..1 (SWP_TYPE) are = SHM_SWP_TYPE - bits 31..8 are used like this: - bits 14..8 (SHM_ID) the id of the shared memory segment - bits 29..15 (SHM_IDX) the index of the page within the shared memory segment - (actually only bits 24..15 get used since SHMMAX is so low) -*/ - -#define SHM_ID_SHIFT 8 -/* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and - there is a static array of size SHMMNI. */ -#define _SHM_ID_BITS 7 -#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) - -#define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS) -#define _SHM_IDX_BITS 15 -#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) - -/* We must have SHM_ID_SHIFT + _SHM_ID_BITS + _SHM_IDX_BITS <= 32 - and SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). */ - -#define SHMMAX 0x3fa000 /* max shared seg size (bytes) */ -#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ -#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ -#define SHMALL (1<<(_SHM_IDX_BITS+_SHM_ID_BITS))/* max shm system wide (pages) */ -#define SHMLBA 0x1000 /* attach addr a multiple of this */ -#define SHMSEG SHMMNI /* max shared segs per process */ +struct shm_info { + int used_ids; + unsigned long shm_tot; /* total allocated shm */ + unsigned long shm_rss; /* total resident shm */ + unsigned long shm_swp; /* total swapped shm */ + unsigned long swap_attempts; + unsigned long swap_successes; +}; #ifdef __KERNEL__ @@ -78,19 +60,11 @@ struct shminfo { #define SHM_DEST 01000 /* segment will be destroyed on last detach */ #define SHM_LOCKED 02000 /* segment will not be swapped */ -/* ipcs ctl commands */ -#define SHM_STAT 13 -#define SHM_INFO 14 -struct shm_info { - int used_ids; - ulong shm_tot; /* total allocated shm */ - ulong shm_rss; /* total resident shm */ - ulong shm_swp; /* total swapped shm */ - ulong swap_attempts; - ulong swap_successes; -}; +asmlinkage int sys_shmget (key_t key, int size, int flag); +asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, unsigned long *addr); +asmlinkage int sys_shmdt (char *shmaddr); +asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf); #endif /* __KERNEL__ */ #endif /* _LINUX_SHM_H_ */ - diff --git a/include/linux/sjcd.h b/include/linux/sjcd.h new file mode 100644 index 000000000..0aa5e7146 --- /dev/null +++ b/include/linux/sjcd.h @@ -0,0 +1,181 @@ +/* + * Definitions for a Sanyo CD-ROM interface. + * + * Copyright (C) 1995 Vadim V. Model + * model@cecmow.enet.dec.com + * vadim@rbrf.msk.su + * vadim@ipsun.ras.ru + * Eric van der Maarel + * H.T.M.v.d.Maarel@marin.nl + * + * This information is based on mcd.c from M. Harriss and sjcd102.lst from + * E. Moenkeberg. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __SJCD_H__ +#define __SJCD_H__ + +/* + * Change this to set the I/O port address as default. More flexibility + * come with setup implementation. + */ +#define SJCD_BASE_ADDR 0x340 + +/* + * Change this to set the irq as default. Really SANYO do not use interrupts + * at all. + */ +#define SJCD_INTR_NR 0 + +/* + * Change this to set the dma as default value. really SANYO does not use + * direct memory access at all. + */ +#define SJCD_DMA_NR 0 + +/* + * Macros which allow us to find out the status of the drive. + */ +#define SJCD_STATUS_AVAILABLE( x ) (((x)&0x02)==0) +#define SJCD_DATA_AVAILABLE( x ) (((x)&0x01)==0) + +/* + * Port access macro. Three ports are available: S-data port (command port), + * status port (read only) and D-data port (read only). + */ +#define SJCDPORT( x ) ( sjcd_base + ( x ) ) +#define SJCD_STATUS_PORT SJCDPORT( 1 ) +#define SJCD_S_DATA_PORT SJCDPORT( 0 ) +#define SJCD_COMMAND_PORT SJCDPORT( 0 ) +#define SJCD_D_DATA_PORT SJCDPORT( 2 ) + +/* + * Drive info bits. Drive info available as first (mandatory) byte of + * command completion status. + */ +#define SST_NOT_READY 0x10 /* no disk in the drive (???) */ +#define SST_MEDIA_CHANGED 0x20 /* disk is changed */ +#define SST_DOOR_OPENED 0x40 /* door is open */ + +/* commands */ + +#define SCMD_EJECT_TRAY 0xD0 /* eject tray if not locked */ +#define SCMD_LOCK_TRAY 0xD2 /* lock tray when in */ +#define SCMD_UNLOCK_TRAY 0xD4 /* unlock tray when in */ +#define SCMD_CLOSE_TRAY 0xD6 /* load tray in */ + +#define SCMD_RESET 0xFA /* soft reset */ +#define SCMD_GET_STATUS 0x80 +#define SCMD_GET_VERSION 0xCC + +#define SCMD_DATA_READ 0xA0 /* are the same, depend on mode&args */ +#define SCMD_SEEK 0xA0 +#define SCMD_PLAY 0xA0 + +#define SCMD_GET_QINFO 0xA8 + +#define SCMD_SET_MODE 0xC4 +#define SCMD_MODE_PLAY 0xE0 +#define SCMD_MODE_COOKED (0xF8 & ~0x20) +#define SCMD_MODE_RAW 0xF9 +#define SCMD_MODE_x20_BIT 0x20 /* What is it for ? */ + +#define SCMD_SET_VOLUME 0xAE +#define SCMD_PAUSE 0xE0 +#define SCMD_STOP 0xE0 + +#define SCMD_GET_DISK_INFO 0xAA + +/* + * Some standard arguments for SCMD_GET_DISK_INFO. + */ +#define SCMD_GET_1_TRACK 0xA0 /* get the first track information */ +#define SCMD_GET_L_TRACK 0xA1 /* get the last track information */ +#define SCMD_GET_D_SIZE 0xA2 /* get the whole disk information */ + +/* + * Borrowed from hd.c. Allows to optimize multiple port read commands. + */ +#define S_READ_DATA( port, buf, nr ) insb( port, buf, nr ) + +/* + * We assume that there are no audio disks with TOC length more than this + * number (I personally have never seen disks with more than 20 fragments). + */ +#define SJCD_MAX_TRACKS 100 + +struct msf { + unsigned char min; + unsigned char sec; + unsigned char frame; +}; + +struct sjcd_hw_disk_info { + unsigned char track_control; + unsigned char track_no; + unsigned char x, y, z; + union { + unsigned char track_no; + struct msf track_msf; + } un; +}; + +struct sjcd_hw_qinfo { + unsigned char track_control; + unsigned char track_no; + unsigned char x; + struct msf rel; + struct msf abs; +}; + +struct sjcd_play_msf { + struct msf start; + struct msf end; +}; + +struct sjcd_disk_info { + unsigned char first; + unsigned char last; + struct msf disk_length; + struct msf first_track; +}; + +struct sjcd_toc { + unsigned char ctrl_addr; + unsigned char track; + unsigned char point_index; + struct msf track_time; + struct msf disk_time; +}; + +#if defined( SJCD_GATHER_STAT ) + +struct sjcd_stat { + int ticks; + int tticks[ 8 ]; + int idle_ticks; + int start_ticks; + int mode_ticks; + int read_ticks; + int data_ticks; + int stop_ticks; + int stopping_ticks; +}; + +#endif + +#endif diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index e831eb130..57302ca98 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -13,83 +13,131 @@ #ifndef _LINUX_SKBUFF_H #define _LINUX_SKBUFF_H -#include <linux/malloc.h> -#include <linux/wait.h> -#include <linux/time.h> + #include <linux/config.h> +#include <linux/time.h> + +#include <asm/atomic.h> +#include <asm/types.h> -#undef CONFIG_SKB_CHECK +#define CONFIG_SKB_CHECK 0 #define HAVE_ALLOC_SKB /* For the drivers to know */ +#define HAVE_ALIGNABLE_SKB /* Ditto 8) */ #define FREE_READ 1 #define FREE_WRITE 0 +#define CHECKSUM_NONE 0 +#define CHECKSUM_HW 1 +#define CHECKSUM_UNNECESSARY 2 -struct sk_buff_head { - struct sk_buff * volatile next; - struct sk_buff * volatile prev; +struct sk_buff_head +{ + struct sk_buff * next; + struct sk_buff * prev; + __u32 qlen; /* Must be same length as a pointer + for using debugging */ #if CONFIG_SKB_CHECK - int magic_debug_cookie; + int magic_debug_cookie; #endif }; -struct sk_buff { - struct sk_buff * volatile next; /* Next buffer in list */ - struct sk_buff * volatile prev; /* Previous buffer in list */ +struct sk_buff +{ + struct sk_buff * next; /* Next buffer in list */ + struct sk_buff * prev; /* Previous buffer in list */ + struct sk_buff_head * list; /* List we are on */ #if CONFIG_SKB_CHECK - int magic_debug_cookie; + int magic_debug_cookie; #endif - struct sk_buff * volatile link3; /* Link for IP protocol level buffer chains */ - struct sock *sk; /* Socket we are owned by */ - volatile unsigned long when; /* used to compute rtt's */ - struct timeval stamp; /* Time we arrived */ - struct device *dev; /* Device we arrived on/are leaving by */ - struct sk_buff *mem_addr; /* Self reference (obsolete) */ - union { - struct tcphdr *th; - struct ethhdr *eth; - struct iphdr *iph; - struct udphdr *uh; - unsigned char *raw; - unsigned long seq; - } h; - struct iphdr *ip_hdr; /* For IPPROTO_RAW */ - unsigned long mem_len; /* Length of allocated memory */ - unsigned long len; /* Length of actual data */ - unsigned long fraglen; /* Unused (yet) */ - struct sk_buff *fraglist; /* Fragment list */ - unsigned long truesize; /* True buffer size (obsolete) */ - unsigned long saddr; /* IP source address */ - unsigned long daddr; /* IP target address */ - unsigned long raddr; /* IP next hop address */ - volatile char acked, /* Are we acked ? */ - used, /* Are we in use ? */ - free, /* How to free this buffer */ - arp; /* Has IP/ARP resolution finished */ - unsigned char tries, /* Times tried */ - lock, /* Are we locked ? */ - localroute, /* Local routing asserted for this frame */ - pkt_type; /* Packet class */ -#define PACKET_HOST 0 /* To us */ -#define PACKET_BROADCAST 1 /* To all */ -#define PACKET_MULTICAST 2 /* To group */ -#define PACKET_OTHERHOST 3 /* To someone else */ - unsigned short users; /* User count - see datagram.c,tcp.c */ - unsigned short protocol; /* Packet protocol from driver. */ -#ifdef CONFIG_SLAVE_BALANCING - unsigned short in_dev_queue; -#endif - unsigned long padding[0]; /* Force long word alignment */ - unsigned char data[0]; /* Data follows */ + struct sk_buff *link3; /* Link for IP protocol level buffer chains */ + struct sock *sk; /* Socket we are owned by */ + unsigned long when; /* used to compute rtt's */ + struct timeval stamp; /* Time we arrived */ + struct device *dev; /* Device we arrived on/are leaving by */ + union + { + struct tcphdr *th; + struct ethhdr *eth; + struct iphdr *iph; + struct udphdr *uh; + unsigned char *raw; + /* for passing file handles in a unix domain socket */ + void *filp; + } h; + + union + { + /* As yet incomplete physical layer views */ + unsigned char *raw; + struct ethhdr *ethernet; + } mac; + + struct iphdr *ip_hdr; /* For IPPROTO_RAW */ +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + struct ipv6hdr *ipv6_hdr; + + /* + * It would be inefficient to store the nexthop address in every + * skb. Instead we store a pointer to the respective neighbour + * cache entry. This might make ndisc cache management harder. + */ + + struct neighbour *nexthop; +#endif + unsigned int len; /* Length of actual data */ + unsigned int csum; /* Checksum */ + __u32 saddr; /* IP source address */ + __u32 daddr; /* IP target address */ + __u32 raddr; /* IP next hop address */ + __u32 seq; /* TCP sequence number */ + __u32 end_seq; /* seq [+ fin] [+ syn] + datalen */ + __u32 ack_seq; /* TCP ack sequence number */ + unsigned char proto_priv[16]; /* Protocol private data */ + volatile char acked, /* Are we acked ? */ + used, /* Are we in use ? */ + free, /* How to free this buffer */ + arp; /* Has IP/ARP resolution finished */ + unsigned char tries, /* Times tried */ + lock, /* Are we locked ? */ + localroute, /* Local routing asserted for this frame */ + pkt_type, /* Packet class */ + pkt_bridged, /* Tracker for bridging */ + ip_summed; /* Driver fed us an IP checksum */ +#define PACKET_HOST 0 /* To us */ +#define PACKET_BROADCAST 1 /* To all */ +#define PACKET_MULTICAST 2 /* To group */ +#define PACKET_OTHERHOST 3 /* To someone else */ +#define PACKET_NDISC 17 /* Outgoing NDISC packet */ + unsigned short users; /* User count - see datagram.c,tcp.c */ + unsigned short protocol; /* Packet protocol from driver. */ + unsigned short truesize; /* Buffer size */ + + atomic_t count; /* reference count */ + struct sk_buff *data_skb; /* Link to the actual data skb */ + unsigned char *head; /* Head of buffer */ + unsigned char *data; /* Data head pointer */ + unsigned char *tail; /* Tail pointer */ + unsigned char *end; /* End pointer */ + void (*destructor)(struct sk_buff *); /* Destruct function */ + __u16 redirport; /* Redirect port */ + __u16 inclone; /* Inline clone */ +#define SKB_CLONE_ORIG 1 +#define SKB_CLONE_INLINE 2 }; +#ifdef CONFIG_SKB_LARGE +#define SK_WMEM_MAX 65535 +#define SK_RMEM_MAX 65535 +#else #define SK_WMEM_MAX 32767 #define SK_RMEM_MAX 32767 +#endif -#ifdef CONFIG_SKB_CHECK +#if CONFIG_SKB_CHECK #define SK_FREED_SKB 0x0DE2C0DE #define SK_GOOD_SKB 0xDEC0DED1 #define SK_HEAD_SKB 0x12231298 @@ -99,6 +147,7 @@ struct sk_buff { /* * Handling routines are only of interest to the kernel */ +#include <linux/malloc.h> #include <asm/system.h> @@ -113,24 +162,61 @@ extern struct sk_buff * skb_dequeue(struct sk_buff_head *list); extern void skb_insert(struct sk_buff *old,struct sk_buff *newsk); extern void skb_append(struct sk_buff *old,struct sk_buff *newsk); extern void skb_unlink(struct sk_buff *buf); +extern __u32 skb_queue_len(struct sk_buff_head *list); extern struct sk_buff * skb_peek_copy(struct sk_buff_head *list); extern struct sk_buff * alloc_skb(unsigned int size, int priority); -extern void kfree_skbmem(struct sk_buff *skb, unsigned size); +extern struct sk_buff * dev_alloc_skb(unsigned int size); +extern void kfree_skbmem(struct sk_buff *skb); extern struct sk_buff * skb_clone(struct sk_buff *skb, int priority); +extern struct sk_buff * skb_copy(struct sk_buff *skb, int priority); extern void skb_device_lock(struct sk_buff *skb); extern void skb_device_unlock(struct sk_buff *skb); extern void dev_kfree_skb(struct sk_buff *skb, int mode); extern int skb_device_locked(struct sk_buff *skb); +extern unsigned char * skb_put(struct sk_buff *skb, unsigned int len); +extern unsigned char * skb_push(struct sk_buff *skb, unsigned int len); +extern unsigned char * skb_pull(struct sk_buff *skb, unsigned int len); +extern int skb_headroom(struct sk_buff *skb); +extern int skb_tailroom(struct sk_buff *skb); +extern void skb_reserve(struct sk_buff *skb, unsigned int len); +extern void skb_trim(struct sk_buff *skb, unsigned int len); + +extern __inline__ int skb_queue_empty(struct sk_buff_head *list) +{ + return (list->next == (struct sk_buff *) list); +} + +extern __inline__ struct sk_buff *skb_unshare(struct sk_buff *skb, int pri, int dir) +{ + struct sk_buff *nskb; + if(skb->users==1) + return skb; + nskb=skb_copy(skb, pri); + kfree_skb(skb, dir); /* Free our shared copy */ + return nskb; +} + /* * Peek an sk_buff. Unlike most other operations you _MUST_ * be careful with this one. A peek leaves the buffer on the * list and someone else may run off with it. For an interrupt * type system cli() peek the buffer copy the data and sti(); */ -static __inline__ struct sk_buff *skb_peek(struct sk_buff_head *list_) +extern __inline__ struct sk_buff *skb_peek(struct sk_buff_head *list_) +{ + struct sk_buff *list = ((struct sk_buff *)list_)->next; + if (list == (struct sk_buff *)list_) + list = NULL; + return list; +} + +/* + * Return the length of an sk_buff queue + */ + +extern __inline__ __u32 skb_queue_len(struct sk_buff_head *list_) { - struct sk_buff *list = (struct sk_buff *)list_; - return (list->next != list)? list->next : NULL; + return(list_->qlen); } #if CONFIG_SKB_CHECK @@ -145,23 +231,37 @@ extern __inline__ void skb_queue_head_init(struct sk_buff_head *list) { list->prev = (struct sk_buff *)list; list->next = (struct sk_buff *)list; + list->qlen = 0; } /* * Insert an sk_buff at the start of a list. + * + * The "__skb_xxxx()" functions are the non-atomic ones that + * can only be called with interrupts disabled. */ -extern __inline__ void skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk) +extern __inline__ void __skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) +{ + struct sk_buff *prev, *next; + + newsk->list = list; + list->qlen++; + prev = (struct sk_buff *)list; + next = prev->next; + newsk->next = next; + newsk->prev = prev; + next->prev = newsk; + prev->next = newsk; +} + +extern __inline__ void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) { unsigned long flags; - struct sk_buff *list = (struct sk_buff *)list_; save_flags(flags); cli(); - newsk->next = list->next; - newsk->prev = list; - newsk->next->prev = newsk; - newsk->prev->next = newsk; + __skb_queue_head(list, newsk); restore_flags(flags); } @@ -169,74 +269,92 @@ extern __inline__ void skb_queue_head(struct sk_buff_head *list_,struct sk_buff * Insert an sk_buff at the end of a list. */ -extern __inline__ void skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk) +extern __inline__ void __skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) +{ + struct sk_buff *prev, *next; + + newsk->list = list; + list->qlen++; + next = (struct sk_buff *)list; + prev = next->prev; + newsk->next = next; + newsk->prev = prev; + next->prev = newsk; + prev->next = newsk; +} + +extern __inline__ void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) { unsigned long flags; - struct sk_buff *list = (struct sk_buff *)list_; save_flags(flags); cli(); - - newsk->next = list; - newsk->prev = list->prev; - - newsk->next->prev = newsk; - newsk->prev->next = newsk; - + __skb_queue_tail(list, newsk); restore_flags(flags); } /* - * Remove an sk_buff from a list. This routine is also interrupt safe - * so you can grab read and free buffers as another process adds them. - * - * Note we now do the ful list + * Remove an sk_buff from a list. */ -extern __inline__ struct sk_buff *skb_dequeue(struct sk_buff_head *list_) +extern __inline__ struct sk_buff *__skb_dequeue(struct sk_buff_head *list) +{ + struct sk_buff *next, *prev, *result; + + prev = (struct sk_buff *) list; + next = prev->next; + result = NULL; + if (next != prev) { + result = next; + next = next->next; + list->qlen--; + next->prev = prev; + prev->next = next; + result->next = NULL; + result->prev = NULL; + result->list = NULL; + } + return result; +} + +extern __inline__ struct sk_buff *skb_dequeue(struct sk_buff_head *list) { long flags; struct sk_buff *result; - struct sk_buff *list = (struct sk_buff *)list_; save_flags(flags); cli(); + result = __skb_dequeue(list); + restore_flags(flags); + return result; +} - result = list->next; - if (result == list) - { - restore_flags(flags); - return NULL; - } - else - { - result->next->prev = list; - list->next = result->next; - - result->next = NULL; - result->prev = NULL; - - restore_flags(flags); +/* + * Insert a packet on a list. + */ - return result; - } +extern __inline__ void __skb_insert(struct sk_buff *newsk, + struct sk_buff * prev, struct sk_buff *next, + struct sk_buff_head * list) +{ + newsk->next = next; + newsk->prev = prev; + next->prev = newsk; + prev->next = newsk; + newsk->list = list; + list->qlen++; } /* - * Insert a packet before another one in a list. + * Place a packet before a given packet in a list */ - extern __inline__ void skb_insert(struct sk_buff *old, struct sk_buff *newsk) { unsigned long flags; save_flags(flags); cli(); - newsk->next = old; - newsk->prev = old->prev; - old->prev = newsk; - newsk->prev->next = newsk; - + __skb_insert(newsk, old->prev, old, old->list); restore_flags(flags); } @@ -250,16 +368,29 @@ extern __inline__ void skb_append(struct sk_buff *old, struct sk_buff *newsk) save_flags(flags); cli(); - - newsk->prev = old; - newsk->next = old->next; - newsk->next->prev = newsk; - old->next = newsk; - + __skb_insert(newsk, old, old->next, old->list); restore_flags(flags); } /* + * remove sk_buff from list. _Must_ be called atomically, and with + * the list known.. + */ +extern __inline__ void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) +{ + struct sk_buff * next, * prev; + + list->qlen--; + next = skb->next; + prev = skb->prev; + skb->next = NULL; + skb->prev = NULL; + skb->list = NULL; + next->prev = prev; + prev->next = next; +} + +/* * Remove an sk_buff from its list. Works even without knowing the list it * is sitting on, which can be handy at times. It also means that THE LIST * MUST EXIST when you unlink. Thus a list must have its contents unlinked @@ -272,23 +403,84 @@ extern __inline__ void skb_unlink(struct sk_buff *skb) save_flags(flags); cli(); + if(skb->list) + __skb_unlink(skb, skb->list); + restore_flags(flags); +} + +/* + * Add data to an sk_buff + */ + +extern __inline__ unsigned char *skb_put(struct sk_buff *skb, unsigned int len) +{ + extern char *skb_put_errstr; + unsigned char *tmp=skb->tail; + skb->tail+=len; + skb->len+=len; + if(skb->tail>skb->end) + { + __label__ here; + panic(skb_put_errstr,&&here,len); +here: + } + return tmp; +} - if(skb->prev && skb->next) +extern __inline__ unsigned char *skb_push(struct sk_buff *skb, unsigned int len) +{ + extern char *skb_push_errstr; + skb->data-=len; + skb->len+=len; + if(skb->data<skb->head) { - skb->next->prev = skb->prev; - skb->prev->next = skb->next; - skb->next = NULL; - skb->prev = NULL; + __label__ here; + panic(skb_push_errstr, &&here,len); +here: + } + return skb->data; +} + +extern __inline__ unsigned char * skb_pull(struct sk_buff *skb, unsigned int len) +{ + if (len > skb->len) + return NULL; + skb->data+=len; + skb->len-=len; + return skb->data; +} + +extern __inline__ int skb_headroom(struct sk_buff *skb) +{ + return skb->data-skb->head; +} + +extern __inline__ int skb_tailroom(struct sk_buff *skb) +{ + return skb->end-skb->tail; +} + +extern __inline__ void skb_reserve(struct sk_buff *skb, unsigned int len) +{ + skb->data+=len; + skb->tail+=len; +} + +extern __inline__ void skb_trim(struct sk_buff *skb, unsigned int len) +{ + if (skb->len > len) { + skb->len = len; + skb->tail = skb->data+len; } - restore_flags(flags); } #endif extern struct sk_buff * skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err); extern int datagram_select(struct sock *sk, int sel_type, select_table *wait); -extern void skb_copy_datagram(struct sk_buff *from, int offset, char *to,int size); -extern void skb_free_datagram(struct sk_buff *skb); +extern int skb_copy_datagram(struct sk_buff *from, int offset, char *to,int size); +extern int skb_copy_datagram_iovec(struct sk_buff *from, int offset, struct iovec *to,int size); +extern void skb_free_datagram(struct sock * sk, struct sk_buff *skb); #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/include/linux/smb.h b/include/linux/smb.h new file mode 100644 index 000000000..1bba4859e --- /dev/null +++ b/include/linux/smb.h @@ -0,0 +1,142 @@ +/* + * smb.h + * + * Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke + * + */ + +#ifndef _LINUX_SMB_H +#define _LINUX_SMB_H + +#define SMB_PORT 139 +#define SMB_MAXNAMELEN 255 +#define SMB_MAXPATHLEN 1024 + +#define SMB_DEF_MAX_XMIT 32768 + +/* Allocate max. 1 page */ +#define TRANS2_MAX_TRANSFER (4096-17) + +#include <asm/types.h> +#ifdef __KERNEL__ +typedef u8 byte; +typedef u16 word; +typedef u32 dword; +#else +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; +#endif + +/* The following macros have been taken directly from Samba. Thanks, + Andrew! */ + +#undef CAREFUL_ALIGNMENT + +/* we know that the 386 can handle misalignment and has the "right" + byteorder */ +#if defined(__i386__) +#define CAREFUL_ALIGNMENT 0 +#endif + +#ifndef CAREFUL_ALIGNMENT +#define CAREFUL_ALIGNMENT 1 +#endif + +#define BVAL(buf,pos) (((u8 *)(buf))[pos]) +#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos)) +#define BSET(buf,pos,val) (BVAL(buf,pos) = (val)) + + +#if CAREFUL_ALIGNMENT +#define WVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) +#define DVAL(buf,pos) (WVAL(buf,pos)|WVAL(buf,(pos)+2)<<16) + +#define SSVALX(buf,pos,val) (BVAL(buf,pos)=(val)&0xFF,BVAL(buf,pos+1)=(val)>>8) +#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16)) +#define WSET(buf,pos,val) { word __val = (val); \ + SSVALX((buf),(pos),((word)(__val))); } +#define DSET(buf,pos,val) { dword __val = (val); \ + SIVALX((buf),(pos),((dword)(__val))); } +#else +/* this handles things for architectures like the 386 that can handle + alignment errors */ +/* + WARNING: This section is dependent on the length of word and dword + being correct +*/ +#define WVAL(buf,pos) (*(word *)((char *)(buf) + (pos))) +#define DVAL(buf,pos) (*(dword *)((char *)(buf) + (pos))) +#define WSET(buf,pos,val) WVAL(buf,pos)=((word)(val)) +#define DSET(buf,pos,val) DVAL(buf,pos)=((dword)(val)) +#endif + + +/* where to find the base of the SMB packet proper */ +#define smb_base(buf) ((byte *)(((byte *)(buf))+4)) + +#define LANMAN1 +#define LANMAN2 +#define NT1 + +enum smb_protocol { + PROTOCOL_NONE, + PROTOCOL_CORE, + PROTOCOL_COREPLUS, + PROTOCOL_LANMAN1, + PROTOCOL_LANMAN2, + PROTOCOL_NT1 +}; + +enum smb_case_hndl { + CASE_DEFAULT, + CASE_LOWER, + CASE_UPPER +}; + +#ifdef __KERNEL__ + +enum smb_conn_state { + CONN_VALID, /* everything's fine */ + CONN_INVALID, /* Something went wrong, but did not + try to reconnect yet. */ + CONN_RETRIED /* Tried a reconnection, but was refused */ +}; + +struct smb_dskattr { + word total; + word allocblocks; + word blocksize; + word free; +}; + +/* + * Contains all relevant data on a SMB networked file. + */ +struct smb_dirent { + + unsigned long f_ino; + umode_t f_mode; + nlink_t f_nlink; + uid_t f_uid; + gid_t f_gid; + kdev_t f_rdev; + off_t f_size; + time_t f_atime; + time_t f_mtime; + time_t f_ctime; + unsigned long f_blksize; + unsigned long f_blocks; + + int opened; /* is it open on the fileserver? */ + word fileid; /* What id to handle a file with? */ + word attr; /* Attribute fields, DOS value */ + + unsigned short access; /* Access bits. */ + unsigned long f_pos; /* File position. (For readdir.) */ + unsigned char name[SMB_MAXNAMELEN+1]; + int len; /* namelength */ +}; + +#endif /* __KERNEL__ */ +#endif /* _LINUX_SMB_H */ diff --git a/include/linux/smb_fs.h b/include/linux/smb_fs.h new file mode 100644 index 000000000..c129cb540 --- /dev/null +++ b/include/linux/smb_fs.h @@ -0,0 +1,219 @@ +/* + * smb_fs.h + * + * Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke + * + */ + +#ifndef _LINUX_SMB_FS_H +#define _LINUX_SMB_FS_H + +#include <linux/smb.h> +#include <linux/fs.h> +#include <linux/in.h> +#include <linux/types.h> +#include <linux/vmalloc.h> + +#include <linux/smb_mount.h> +#include <linux/smb_fs_sb.h> +#include <linux/smb_fs_i.h> + +/* + * ioctl commands + */ +#define SMB_IOC_GETMOUNTUID _IOR('u', 1, uid_t) + +#ifdef __KERNEL__ + +/* + * The readdir cache size controls how many directory entries are cached. + */ +#define SMB_READDIR_CACHE_SIZE 64 + +/* + * This defines the number of filenames cached in memory to avoid + * constructing filenames from \ + */ +#define SMB_CACHE_TABLE_SIZE 64 + +#define SMB_SUPER_MAGIC 0x517B + + + +#define SMB_SBP(sb) ((struct smb_sb_info *)(sb->u.generic_sbp)) +#define SMB_INOP(inode) ((struct smb_inode_info *)(inode->u.generic_ip)) + +#define SMB_SERVER(inode) (&(SMB_SBP(inode->i_sb)->s_server)) +#define SMB_SERVATTR(inode) (&(SMB_SBP(inode->i_sb)->s_attr)) + +#define SMB_FINFO(inode) (&(SMB_INOP(inode)->finfo)) + +#define SMB_HEADER_LEN 37 /* includes everything up to, but not + * including smb_bcc */ + +#ifdef DEBUG_SMB_MALLOC + +#include <linux/malloc.h> + +extern int smb_malloced; +extern int smb_current_kmalloced; +extern int smb_current_vmalloced; + +static inline void * +smb_kmalloc(unsigned int size, int priority) +{ + smb_malloced += 1; + smb_current_kmalloced += 1; + return kmalloc(size, priority); +} + +static inline void +smb_kfree_s(void *obj, int size) +{ + smb_current_kmalloced -= 1; + kfree_s(obj, size); +} + +static inline void * +smb_vmalloc(unsigned int size) +{ + smb_malloced += 1; + smb_current_vmalloced += 1; + return vmalloc(size); +} + +static inline void +smb_vfree(void *obj) +{ + smb_current_vmalloced -= 1; + vfree(obj); +} + +#else /* DEBUG_SMB_MALLOC */ + +#define smb_kmalloc(s,p) kmalloc(s,p) +#define smb_kfree_s(o,s) kfree_s(o,s) +#define smb_vmalloc(s) vmalloc(s) +#define smb_vfree(o) vfree(o) + +#endif /* DEBUG_SMB_MALLOC */ + +#if DEBUG_SMB > 0 +#define DPRINTK(format, args...) printk(format , ## args) +#else +#define DPRINTK(format, args...) +#endif + +#if DEBUG_SMB > 1 +#define DDPRINTK(format, args...) printk(format , ## args) +#else +#define DDPRINTK(format, args...) +#endif + + +static inline ino_t +smb_info_ino(struct smb_inode_info *info) +{ +#if 0 + return (ino_t) info; +#else + if (info != NULL) + { + return info->finfo.f_ino; + } + return 1; +#endif +} + +/* linux/fs/smbfs/file.c */ +extern struct inode_operations smb_file_inode_operations; +int smb_make_open(struct inode *i, int right); + +/* linux/fs/smbfs/dir.c */ +extern struct inode_operations smb_dir_inode_operations; +struct smb_inode_info *smb_find_inode(struct smb_server *server, ino_t ino); +void smb_free_inode_info(struct smb_inode_info *i); +void smb_free_all_inodes(struct smb_server *server); +void smb_init_root(struct smb_server *server); +int smb_stat_root(struct smb_server *server); +void smb_init_dir_cache(void); +void smb_invalid_dir_cache(unsigned long ino); +void smb_invalidate_all_inodes(struct smb_server *server); +void smb_free_dir_cache(void); + +/* linux/fs/smbfs/ioctl.c */ +int smb_ioctl (struct inode * inode, struct file * filp, + unsigned int cmd, unsigned long arg); + +/* linux/fs/smbfs/inode.c */ +struct super_block *smb_read_super(struct super_block *sb, + void *raw_data, int silent); +extern int init_smb_fs(void); +int smb_notify_change(struct inode *inode, struct iattr *attr); +void smb_invalidate_connection(struct smb_server *server); +int smb_conn_is_valid(struct smb_server *server); + +/* linux/fs/smbfs/proc.c */ +dword smb_len(unsigned char *packet); +byte *smb_encode_smb_length(byte *p, dword len); +__u8 *smb_setup_header(struct smb_server *server, byte command, + word wct, word bcc); +void smb_init_root_dirent(struct smb_server *server, struct smb_dirent *entry); +int smb_proc_open(struct smb_server *server, + struct smb_inode_info *dir, const char *name, int len, + struct smb_dirent *entry); +int smb_proc_close(struct smb_server *server, + __u16 fileid, __u32 mtime); +int smb_proc_read(struct smb_server *server, struct smb_dirent *finfo, + off_t offset, long count, char *data, int fs); +int smb_proc_read_raw(struct smb_server *server, struct smb_dirent *finfo, + off_t offset, long count, char *data); +int smb_proc_write(struct smb_server *server, struct smb_dirent *finfo, + off_t offset, int count, const char *data); +int smb_proc_write_raw(struct smb_server *server, struct smb_dirent *finfo, + off_t offset, long count, const char *data); +int smb_proc_create(struct inode *dir, const char *name, int len, + word attr, time_t ctime); +int smb_proc_mv(struct inode *odir, const char *oname, const int olen, + struct inode *ndir, const char *nname, const int nlen); +int smb_proc_mkdir(struct inode *dir, const char *name, const int len); +int smb_proc_rmdir(struct inode *dir, const char *name, const int len); +int smb_proc_unlink(struct inode *dir, const char *name, const int len); +int smb_proc_readdir(struct smb_server *server, struct inode *dir, + int fpos, int cache_size, + struct smb_dirent *entry); +int smb_proc_getattr(struct inode *dir, const char *name, int len, + struct smb_dirent *entry); +int smb_proc_setattr(struct smb_server *server, + struct inode *ino, + struct smb_dirent *new_finfo); +int smb_proc_chkpath(struct smb_server *server, char *path, int len, + int *result); +int smb_proc_dskattr(struct super_block *super, struct smb_dskattr *attr); +int smb_proc_reconnect(struct smb_server *server); +int smb_proc_connect(struct smb_server *server); +int smb_proc_disconnect(struct smb_server *server); +int smb_proc_trunc(struct smb_server *server, word fid, dword length); + +/* linux/fs/smbfs/sock.c */ +int smb_release(struct smb_server *server); +int smb_connect(struct smb_server *server); +int smb_request(struct smb_server *server); +int smb_request_read_raw(struct smb_server *server, + unsigned char *target, int max_len); +int smb_request_write_raw(struct smb_server *server, + unsigned const char *source, int length); +int smb_catch_keepalive(struct smb_server *server); +int smb_dont_catch_keepalive(struct smb_server *server); +int smb_trans2_request(struct smb_server *server, __u16 trans2_command, + int ldata, unsigned char *data, + int lparam, unsigned char *param, + int *lrdata, unsigned char **rdata, + int *lrparam, unsigned char **rparam); + +/* linux/fs/smbfs/mmap.c */ +int smb_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma); + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_SMB_FS_H */ diff --git a/include/linux/smb_fs_i.h b/include/linux/smb_fs_i.h new file mode 100644 index 000000000..b6e38fd18 --- /dev/null +++ b/include/linux/smb_fs_i.h @@ -0,0 +1,34 @@ +/* + * smb_fs_i.h + * + * Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke + * + */ + +#ifndef _LINUX_SMB_FS_I +#define _LINUX_SMB_FS_I + +#ifdef __KERNEL__ +#include <linux/smb.h> + +enum smb_inode_state { + SMB_INODE_VALID = 19, /* Inode currently in use */ + SMB_INODE_LOOKED_UP, /* directly before iget */ + SMB_INODE_CACHED, /* in a path to an inode which is in use */ + SMB_INODE_INVALID +}; + +/* + * smb fs inode data (in memory only) + */ +struct smb_inode_info { + enum smb_inode_state state; + int nused; /* for directories: + number of references in memory */ + struct smb_inode_info *dir; + struct smb_inode_info *next, *prev; + struct smb_dirent finfo; +}; + +#endif +#endif diff --git a/include/linux/smb_fs_sb.h b/include/linux/smb_fs_sb.h new file mode 100644 index 000000000..863062022 --- /dev/null +++ b/include/linux/smb_fs_sb.h @@ -0,0 +1,79 @@ +/* + * smb_fs_sb.h + * + * Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke + * + */ + +#ifndef _SMB_FS_SB +#define _SMB_FS_SB + +#include <linux/smb.h> +#include <linux/smb_fs_i.h> +#include <linux/smb_mount.h> +#include <linux/types.h> + +#ifdef __KERNEL__ + +struct smb_server { + enum smb_protocol protocol; /* The protocol this + connection accepts. */ + enum smb_case_hndl case_handling; + struct file * sock_file; /* The socket we transfer + data on. */ + int lock; /* To prevent mismatch in + protocols. */ + struct wait_queue *wait; + + __u32 max_xmit; + char hostname[256]; + word pid; + word server_uid; + word mid; + word tid; + + struct smb_mount_data m; /* We store the complete information here + * to be able to reconnect. + */ + + unsigned short rcls; /* The error codes we received */ + unsigned short err; + + __u32 packet_size; + unsigned char * packet; + + enum smb_conn_state state; + unsigned long reconnect_time; /* The time of the last attempt */ + + /* The following are LANMAN 1.0 options transferred to us in + SMBnegprot */ + word secmode; + word maxmux; + word maxvcs; + word blkmode; + dword sesskey; + + /* We use our on data_ready callback, but need the original one */ + void *data_ready; + + /* We do not have unique numbers for files in the smb protocol + like NFS-filehandles. (SMB was designed for DOS, not for + UNIX!) So we have to create our own inode numbers. We keep + a complete path of smb_inode_info's to each active + inode. The inode number is then created by the address of + this structure. */ + struct smb_inode_info root; +}; + +/* + * This is the part of the super-block (in memory) for the SMB file system. + */ + +struct smb_sb_info { + struct smb_server s_server; + struct smb_dskattr s_attr; +}; + +#endif /* __KERNEL__ */ + +#endif diff --git a/include/linux/smb_mount.h b/include/linux/smb_mount.h new file mode 100644 index 000000000..7f1748731 --- /dev/null +++ b/include/linux/smb_mount.h @@ -0,0 +1,39 @@ +/* + * smb_mount.h + * + * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke + * + */ + +#ifndef _LINUX_SMB_MOUNT_H +#define _LINUX_SMB_MOUNT_H + +#include <linux/types.h> +#include <linux/in.h> + +#define SMB_MOUNT_VERSION 5 + +struct smb_mount_data { + int version; + unsigned int fd; + uid_t mounted_uid; /* Who may umount() this filesystem? */ + struct sockaddr_in addr; + + char server_name[17]; + char client_name[17]; + char service[64]; + char root_path[64]; + + char username[64]; + char password[64]; + char domain[64]; + + unsigned short max_xmit; + + uid_t uid; + gid_t gid; + mode_t file_mode; + mode_t dir_mode; +}; + +#endif diff --git a/include/linux/smbno.h b/include/linux/smbno.h new file mode 100644 index 000000000..176e88c86 --- /dev/null +++ b/include/linux/smbno.h @@ -0,0 +1,269 @@ +#ifndef _SMBNO_H_ +#define _SMBNO_H_ + +/* these define the attribute byte as seen by DOS */ +#define aRONLY (1L<<0) +#define aHIDDEN (1L<<1) +#define aSYSTEM (1L<<2) +#define aVOLID (1L<<3) +#define aDIR (1L<<4) +#define aARCH (1L<<5) + +/* error classes */ +#define SUCCESS 0 /* The request was successful. */ +#define ERRDOS 0x01 /* Error is from the core DOS operating system set. */ +#define ERRSRV 0x02 /* Error is generated by the server network file manager.*/ +#define ERRHRD 0x03 /* Error is an hardware error. */ +#define ERRCMD 0xFF /* Command was not in the "SMB" format. */ + +/* SMB X/Open error codes for the ERRdos error class */ + +#define ERRbadfunc 1 /* Invalid function (or system call) */ +#define ERRbadfile 2 /* File not found (pathname error) */ +#define ERRbadpath 3 /* Directory not found */ +#define ERRnofids 4 /* Too many open files */ +#define ERRnoaccess 5 /* Access denied */ +#define ERRbadfid 6 /* Invalid fid */ +#define ERRbadmcb 7 /* Memory control blocks destroyed */ +#define ERRnomem 8 /* Out of memory */ +#define ERRbadmem 9 /* Invalid memory block address */ +#define ERRbadenv 10 /* Invalid environment */ +#define ERRbadformat 11 /* Invalid format */ +#define ERRbadaccess 12 /* Invalid open mode */ +#define ERRbaddata 13 /* Invalid data (only from ioctl call) */ +#define ERRres 14 /* reserved */ +#define ERRbaddrive 15 /* Invalid drive */ +#define ERRremcd 16 /* Attempt to delete current directory */ +#define ERRdiffdevice 17 /* rename/move across different filesystems */ +#define ERRnofiles 18 /* no more files found in file search */ +#define ERRbadshare 32 /* Share mode on file conflict with open mode */ +#define ERRlock 33 /* Lock request conflicts with existing lock */ +#define ERRfilexists 80 /* File in operation already exists */ +#define ERRbadpipe 230 /* Named pipe invalid */ +#define ERRpipebusy 231 /* All instances of pipe are busy */ +#define ERRpipeclosing 232 /* named pipe close in progress */ +#define ERRnotconnected 233 /* No process on other end of named pipe */ +#define ERRmoredata 234 /* More data to be returned */ +#define ERROR_EAS_DIDNT_FIT 275 /* Extended attributes didn't fit */ +#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */ + +/* Error codes for the ERRSRV class */ + +#define ERRerror 1 /* Non specific error code */ +#define ERRbadpw 2 /* Bad password */ +#define ERRbadtype 3 /* reserved */ +#define ERRaccess 4 /* No permissions to do the requested operation */ +#define ERRinvnid 5 /* tid invalid */ +#define ERRinvnetname 6 /* Invalid servername */ +#define ERRinvdevice 7 /* Invalid device */ +#define ERRqfull 49 /* Print queue full */ +#define ERRqtoobig 50 /* Queued item too big */ +#define ERRinvpfid 52 /* Invalid print file in smb_fid */ +#define ERRsmbcmd 64 /* Unrecognised command */ +#define ERRsrverror 65 /* smb server internal error */ +#define ERRfilespecs 67 /* fid and pathname invalid combination */ +#define ERRbadlink 68 /* reserved */ +#define ERRbadpermits 69 /* Access specified for a file is not valid */ +#define ERRbadpid 70 /* reserved */ +#define ERRsetattrmode 71 /* attribute mode invalid */ +#define ERRpaused 81 /* Message server paused */ +#define ERRmsgoff 82 /* Not receiving messages */ +#define ERRnoroom 83 /* No room for message */ +#define ERRrmuns 87 /* too many remote usernames */ +#define ERRtimeout 88 /* operation timed out */ +#define ERRnoresource 89 /* No resources currently available for request. */ +#define ERRtoomanyuids 90 /* too many userids */ +#define ERRbaduid 91 /* bad userid */ +#define ERRuseMPX 250 /* temporarily unable to use raw mode, use MPX mode */ +#define ERRuseSTD 251 /* temporarily unable to use raw mode, use std.mode */ +#define ERRcontMPX 252 /* resume MPX mode */ +#define ERRbadPW /* reserved */ +#define ERRnosupport 0xFFFF + +/* Error codes for the ERRHRD class */ + +#define ERRnowrite 19 /* read only media */ +#define ERRbadunit 20 /* Unknown device */ +#define ERRnotready 21 /* Drive not ready */ +#define ERRbadcmd 22 /* Unknown command */ +#define ERRdata 23 /* Data (CRC) error */ +#define ERRbadreq 24 /* Bad request structure length */ +#define ERRseek 25 +#define ERRbadmedia 26 +#define ERRbadsector 27 +#define ERRnopaper 28 +#define ERRwrite 29 /* write fault */ +#define ERRread 30 /* read fault */ +#define ERRgeneral 31 /* General hardware failure */ +#define ERRwrongdisk 34 +#define ERRFCBunavail 35 +#define ERRsharebufexc 36 /* share buffer exceeded */ +#define ERRdiskfull 39 + +/* offsets into message for common items */ +#define smb_com 8 +#define smb_rcls 9 +#define smb_reh 10 +#define smb_err 11 +#define smb_flg 13 +#define smb_flg2 14 +#define smb_reb 13 +#define smb_tid 28 +#define smb_pid 30 +#define smb_uid 32 +#define smb_mid 34 +#define smb_wct 36 +#define smb_vwv 37 +#define smb_vwv0 37 +#define smb_vwv1 39 +#define smb_vwv2 41 +#define smb_vwv3 43 +#define smb_vwv4 45 +#define smb_vwv5 47 +#define smb_vwv6 49 +#define smb_vwv7 51 +#define smb_vwv8 53 +#define smb_vwv9 55 +#define smb_vwv10 57 +#define smb_vwv11 59 +#define smb_vwv12 61 +#define smb_vwv13 63 +#define smb_vwv14 65 + +/* these are the trans2 sub fields for primary requests */ +#define smb_tpscnt smb_vwv0 +#define smb_tdscnt smb_vwv1 +#define smb_mprcnt smb_vwv2 +#define smb_mdrcnt smb_vwv3 +#define smb_msrcnt smb_vwv4 +#define smb_flags smb_vwv5 +#define smb_timeout smb_vwv6 +#define smb_pscnt smb_vwv9 +#define smb_psoff smb_vwv10 +#define smb_dscnt smb_vwv11 +#define smb_dsoff smb_vwv12 +#define smb_suwcnt smb_vwv13 +#define smb_setup smb_vwv14 +#define smb_setup0 smb_setup +#define smb_setup1 (smb_setup+2) +#define smb_setup2 (smb_setup+4) + +/* these are for the secondary requests */ +#define smb_spscnt smb_vwv2 +#define smb_spsoff smb_vwv3 +#define smb_spsdisp smb_vwv4 +#define smb_sdscnt smb_vwv5 +#define smb_sdsoff smb_vwv6 +#define smb_sdsdisp smb_vwv7 +#define smb_sfid smb_vwv8 + +/* and these for responses */ +#define smb_tprcnt smb_vwv0 +#define smb_tdrcnt smb_vwv1 +#define smb_prcnt smb_vwv3 +#define smb_proff smb_vwv4 +#define smb_prdisp smb_vwv5 +#define smb_drcnt smb_vwv6 +#define smb_droff smb_vwv7 +#define smb_drdisp smb_vwv8 + +/* the complete */ +#define SMBmkdir 0x00 /* create directory */ +#define SMBrmdir 0x01 /* delete directory */ +#define SMBopen 0x02 /* open file */ +#define SMBcreate 0x03 /* create file */ +#define SMBclose 0x04 /* close file */ +#define SMBflush 0x05 /* flush file */ +#define SMBunlink 0x06 /* delete file */ +#define SMBmv 0x07 /* rename file */ +#define SMBgetatr 0x08 /* get file attributes */ +#define SMBsetatr 0x09 /* set file attributes */ +#define SMBread 0x0A /* read from file */ +#define SMBwrite 0x0B /* write to file */ +#define SMBlock 0x0C /* lock byte range */ +#define SMBunlock 0x0D /* unlock byte range */ +#define SMBctemp 0x0E /* create temporary file */ +#define SMBmknew 0x0F /* make new file */ +#define SMBchkpth 0x10 /* check directory path */ +#define SMBexit 0x11 /* process exit */ +#define SMBlseek 0x12 /* seek */ +#define SMBtcon 0x70 /* tree connect */ +#define SMBtconX 0x75 /* tree connect and X*/ +#define SMBtdis 0x71 /* tree disconnect */ +#define SMBnegprot 0x72 /* negotiate protocol */ +#define SMBdskattr 0x80 /* get disk attributes */ +#define SMBsearch 0x81 /* search directory */ +#define SMBsplopen 0xC0 /* open print spool file */ +#define SMBsplwr 0xC1 /* write to print spool file */ +#define SMBsplclose 0xC2 /* close print spool file */ +#define SMBsplretq 0xC3 /* return print queue */ +#define SMBsends 0xD0 /* send single block message */ +#define SMBsendb 0xD1 /* send broadcast message */ +#define SMBfwdname 0xD2 /* forward user name */ +#define SMBcancelf 0xD3 /* cancel forward */ +#define SMBgetmac 0xD4 /* get machine name */ +#define SMBsendstrt 0xD5 /* send start of multi-block message */ +#define SMBsendend 0xD6 /* send end of multi-block message */ +#define SMBsendtxt 0xD7 /* send text of multi-block message */ + +/* Core+ protocol */ +#define SMBlockread 0x13 /* Lock a range and read */ +#define SMBwriteunlock 0x14 /* Unlock a range then write */ +#define SMBreadbraw 0x1a /* read a block of data with no smb header */ +#define SMBwritebraw 0x1d /* write a block of data with no smb header */ +#define SMBwritec 0x20 /* secondary write request */ +#define SMBwriteclose 0x2c /* write a file then close it */ + +/* dos extended protocol */ +#define SMBreadBraw 0x1A /* read block raw */ +#define SMBreadBmpx 0x1B /* read block multiplexed */ +#define SMBreadBs 0x1C /* read block (secondary response) */ +#define SMBwriteBraw 0x1D /* write block raw */ +#define SMBwriteBmpx 0x1E /* write block multiplexed */ +#define SMBwriteBs 0x1F /* write block (secondary request) */ +#define SMBwriteC 0x20 /* write complete response */ +#define SMBsetattrE 0x22 /* set file attributes expanded */ +#define SMBgetattrE 0x23 /* get file attributes expanded */ +#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */ +#define SMBtrans 0x25 /* transaction - name, bytes in/out */ +#define SMBtranss 0x26 /* transaction (secondary request/response) */ +#define SMBioctl 0x27 /* IOCTL */ +#define SMBioctls 0x28 /* IOCTL (secondary request/response) */ +#define SMBcopy 0x29 /* copy */ +#define SMBmove 0x2A /* move */ +#define SMBecho 0x2B /* echo */ +#define SMBopenX 0x2D /* open and X */ +#define SMBreadX 0x2E /* read and X */ +#define SMBwriteX 0x2F /* write and X */ +#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */ +#define SMBtconX 0x75 /* tree connect and X */ +#define SMBffirst 0x82 /* find first */ +#define SMBfunique 0x83 /* find unique */ +#define SMBfclose 0x84 /* find close */ +#define SMBinvalid 0xFE /* invalid command */ + + +/* Extended 2.0 protocol */ +#define SMBtrans2 0x32 /* TRANS2 protocol set */ +#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */ +#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */ +#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */ +#define SMBulogoffX 0x74 /* user logoff */ + +/* these are the TRANS2 sub commands */ +#define TRANSACT2_OPEN 0 +#define TRANSACT2_FINDFIRST 1 +#define TRANSACT2_FINDNEXT 2 +#define TRANSACT2_QFSINFO 3 +#define TRANSACT2_SETFSINFO 4 +#define TRANSACT2_QPATHINFO 5 +#define TRANSACT2_SETPATHINFO 6 +#define TRANSACT2_QFILEINFO 7 +#define TRANSACT2_SETFILEINFO 8 +#define TRANSACT2_FSCTL 9 +#define TRANSACT2_IOCTL 10 +#define TRANSACT2_FINDNOTIFYFIRST 11 +#define TRANSACT2_FINDNOTIFYNEXT 12 +#define TRANSACT2_MKDIR 13 + +#endif /* _SMBNO_H_ */ diff --git a/include/linux/smp.h b/include/linux/smp.h new file mode 100644 index 000000000..72984f154 --- /dev/null +++ b/include/linux/smp.h @@ -0,0 +1,54 @@ +#ifndef __LINUX_SMP_H +#define __LINUX_SMP_H + +/* + * Generic SMP support + * Alan Cox. <alan@cymru.net> + */ + +#ifdef __SMP__ +#include <asm/smp.h> + +extern void smp_message_pass(int target, int msg, unsigned long data, int wait); +extern void smp_boot_cpus(void); /* Boot processor call to load the other CPU's */ +extern void smp_callin(void); /* Processor call in. Must hold processors until .. */ +extern void smp_commence(void); /* Multiprocessors may now schedule */ +extern int smp_num_cpus; +extern int smp_threads_ready; /* True once the per process idle is forked */ +#ifdef __SMP_PROF__ +extern volatile unsigned long smp_spins[NR_CPUS]; /* count of interrupt spins */ +extern volatile unsigned long smp_spins_sys_idle[]; /* count of idle spins */ +extern volatile unsigned long smp_spins_syscall[]; /* count of syscall spins */ +extern volatile unsigned long smp_spins_syscall_cur[]; /* count of syscall spins for the current + call */ +extern volatile unsigned long smp_idle_count[1+NR_CPUS];/* count idle ticks */ +extern volatile unsigned long smp_idle_map; /* map with idle cpus */ +#else +extern volatile unsigned long smp_spins; +#endif + + +extern volatile unsigned long smp_msg_data; +extern volatile int smp_src_cpu; +extern volatile int smp_msg_id; + +#define MSG_ALL_BUT_SELF 0x8000 /* Assume <32768 CPU's */ +#define MSG_ALL 0x8001 + +#define MSG_INVALIDATE_TLB 0x0001 /* Remote processor TLB invalidate */ +#define MSG_STOP_CPU 0x0002 /* Sent to shut down slave CPU's when rebooting */ +#define MSG_RESCHEDULE 0x0003 /* Reschedule request from master CPU */ + +#else + +/* + * These macros fold the SMP functionality into a single CPU system + */ + +#define smp_num_cpus 1 +#define smp_processor_id() 0 +#define smp_message_pass(t,m,d,w) +#define smp_threads_ready 1 +#define kernel_lock() +#endif +#endif diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h new file mode 100644 index 000000000..14c9f5b47 --- /dev/null +++ b/include/linux/smp_lock.h @@ -0,0 +1,9 @@ +#ifndef __LINUX_SMPLOCK_H +#define __LINUX_SMPLOCK_H + +#ifdef __SMP__ +#include <asm/pgtable.h> +#include <asm/smp_lock.h> +#endif + +#endif diff --git a/include/linux/socket.h b/include/linux/socket.h index 44cff1fc4..21d7169bb 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -1,47 +1,109 @@ #ifndef _LINUX_SOCKET_H #define _LINUX_SOCKET_H +#include <asm/socket.h> /* arch-dependent defines */ #include <linux/sockios.h> /* the SIOCxxx I/O controls */ +#include <linux/uio.h> /* iovec support */ +typedef unsigned short sa_family_t; -struct sockaddr { - unsigned short sa_family; /* address family, AF_xxx */ - char sa_data[14]; /* 14 bytes of protocol address */ +/* + * 1003.1g requires sa_family_t and that sa_data is char. + */ + +struct sockaddr +{ + sa_family_t sa_family; /* address family, AF_xxx */ + char sa_data[14]; /* 14 bytes of protocol address */ }; struct linger { - int l_onoff; /* Linger active */ - int l_linger; /* How long to linger for */ + int l_onoff; /* Linger active */ + int l_linger; /* How long to linger for */ }; -/* Socket types. */ -#define SOCK_STREAM 1 /* stream (connection) socket */ -#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ -#define SOCK_RAW 3 /* raw socket */ -#define SOCK_RDM 4 /* reliably-delivered message */ -#define SOCK_SEQPACKET 5 /* sequential packet socket */ -#define SOCK_PACKET 10 /* linux specific way of */ - /* getting packets at the dev */ - /* level. For writing rarp and */ - /* other similar things on the */ - /* user level. */ +/* + * As we do 4.4BSD message passing we use a 4.4BSD message passing + * system, not 4.3. Thus msg_accrights(len) are now missing. They + * belong in an obscure libc emulation or the bin. + */ + +struct msghdr +{ + void * msg_name; /* Socket name */ + int msg_namelen; /* Length of name */ + struct iovec * msg_iov; /* Data blocks */ + size_t msg_iovlen; /* Number of blocks */ + void * msg_control; /* Per protocol magic (eg BSD file descriptor passing) */ + size_t msg_controllen; /* Length of rights list */ + int msg_flags; /* 4.4 BSD item we dont use */ +}; + +/* + * POSIX 1003.1g - ancillary data object information + * Ancillary data consits of a sequence of pairs of + * (cmsghdr, cmsg_data[]) + */ + +struct cmsghdr { + size_t cmsg_len; /* data byte count, including hdr */ + int cmsg_level; /* originating protocol */ + int cmsg_type; /* protocol-specific type */ + unsigned char cmsg_data[0]; +}; + +/* + * Ancilliary data object information MACROS + * Table 5-14 of POSIX 1003.1g + */ + +#define CMSG_DATA(cmsg) cmsg->cmsg_data +#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr(mhdr, cmsg) +#define CMSG_FIRST(mhdr) ((struct cmsghdr *) (mhdr)->msg_control) + +extern __inline__ struct cmsghdr * cmsg_nxthdr(struct msghdr *mhdr, + struct cmsghdr *cmsg) +{ + unsigned char * ptr; + + if (cmsg->cmsg_len < sizeof(struct cmsghdr)) + { + return NULL; + } + ptr = ((unsigned char *) cmsg) + cmsg->cmsg_len; + if (ptr >= (unsigned char *) mhdr->msg_control + mhdr->msg_controllen) + return NULL; + + return (struct cmsghdr *) ptr; +} + +/* Control Messages */ + +#define SCM_RIGHTS 1 + /* Supported address families. */ #define AF_UNSPEC 0 #define AF_UNIX 1 /* Unix domain sockets */ +#define AF_LOCAL 1 /* POSIX name for AF_UNIX */ #define AF_INET 2 /* Internet IP Protocol */ #define AF_AX25 3 /* Amateur Radio AX.25 */ #define AF_IPX 4 /* Novell IPX */ #define AF_APPLETALK 5 /* Appletalk DDP */ -#define AF_NETROM 6 /* Amateur radio NetROM */ +#define AF_NETROM 6 /* Amateur Radio NET/ROM */ #define AF_BRIDGE 7 /* Multiprotocol bridge */ #define AF_AAL5 8 /* Reserved for Werner's ATM */ #define AF_X25 9 /* Reserved for X.25 project */ -#define AF_MAX 12 /* For now.. */ +#define AF_INET6 10 /* IP version 6 */ +#define AF_ROSE 11 /* Amateur Radio X.25 PLP */ +#define AF_DECNET 12 /* Reserved for DECnet project */ +#define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/ +#define AF_MAX 32 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC #define PF_UNIX AF_UNIX +#define PF_LOCAL AF_LOCAL #define PF_INET AF_INET #define PF_AX25 AF_AX25 #define PF_IPX AF_IPX @@ -50,50 +112,56 @@ struct linger { #define PF_BRIDGE AF_BRIDGE #define PF_AAL5 AF_AAL5 #define PF_X25 AF_X25 +#define PF_INET6 AF_INET6 +#define PR_ROSE AF_ROSE +#define PF_DECNET AF_DECNET +#define PF_NETBEUI AF_NETBEUI #define PF_MAX AF_MAX -/* Flags we can use with send/ and recv. */ -#define MSG_OOB 1 -#define MSG_PEEK 2 -#define MSG_DONTROUTE 4 +/* Maximum queue length specifiable by listen. */ +#define SOMAXCONN 128 + +/* Flags we can use with send/ and recv. + Added those for 1003.1g not all are supported yet + */ + +enum +{ + MSG_OOB = 0x01, /* Process out-of-band data. */ + MSG_PEEK = 0x02, /* Peek at incoming messages. */ + MSG_DONTROUTE = 0x04, /* Don't use local routing. */ + MSG_CTRUNC = 0x08, /* We need to support this for BSD oddments */ + MSG_PROXY = 0x10, /* Supply or ask second address. */ + MSG_EOR = 0x20, /* End of record */ + MSG_TRUNC = 0x40, /* Data was discarded before delivery */ + MSG_WAITALL = 0x80, /* Wait for a full request */ +}; /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ -#define SOL_SOCKET 1 #define SOL_IP 0 +#define SOL_IPV6 41 +#define SOL_ICMPV6 58 +#define SOL_RAW 255 #define SOL_IPX 256 #define SOL_AX25 257 #define SOL_ATALK 258 -#define SOL_NETROM 259 +#define SOL_NETROM 259 +#define SOL_ROSE 260 +#define SOL_DECNET 261 +#define SOL_X25 262 #define SOL_TCP 6 #define SOL_UDP 17 -/* For setsockoptions(2) */ -#define SO_DEBUG 1 -#define SO_REUSEADDR 2 -#define SO_TYPE 3 -#define SO_ERROR 4 -#define SO_DONTROUTE 5 -#define SO_BROADCAST 6 -#define SO_SNDBUF 7 -#define SO_RCVBUF 8 -#define SO_KEEPALIVE 9 -#define SO_OOBINLINE 10 -#define SO_NO_CHECK 11 -#define SO_PRIORITY 12 -#define SO_LINGER 13 -/* To add :#define SO_REUSEPORT 14 */ - /* IP options */ #define IP_TOS 1 #define IPTOS_LOWDELAY 0x10 #define IPTOS_THROUGHPUT 0x08 #define IPTOS_RELIABILITY 0x04 +#define IPTOS_MINCOST 0x02 #define IP_TTL 2 -#ifdef V1_3_WILL_DO_THIS_FUNKY_STUFF -#define IP_HRDINCL 3 +#define IP_HDRINCL 3 #define IP_OPTIONS 4 -#endif #define IP_MULTICAST_IF 32 #define IP_MULTICAST_TTL 33 @@ -101,7 +169,6 @@ struct linger { #define IP_ADD_MEMBERSHIP 35 #define IP_DROP_MEMBERSHIP 36 - /* These need to appear somewhere around here */ #define IP_DEFAULT_MULTICAST_TTL 1 #define IP_DEFAULT_MULTICAST_LOOP 1 @@ -119,4 +186,18 @@ struct linger { #define SOPRI_NORMAL 1 #define SOPRI_BACKGROUND 2 +#ifdef __KERNEL__ +extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); +extern int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, + int offset, int len); +extern unsigned int csum_partial_copy_fromiovecend(unsigned char *kdata, + struct iovec *iov, + int offset, + int len, int csum); + +extern int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode); +extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); +extern int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen); +extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr); +#endif #endif /* _LINUX_SOCKET_H */ diff --git a/include/linux/sockios.h b/include/linux/sockios.h index 4259d9c94..3ec71128e 100644 --- a/include/linux/sockios.h +++ b/include/linux/sockios.h @@ -18,15 +18,7 @@ #ifndef _LINUX_SOCKIOS_H #define _LINUX_SOCKIOS_H -/* This section will go away soon! */ - -/* Socket-level I/O control calls. */ -#define FIOSETOWN 0x8901 -#define SIOCSPGRP 0x8902 -#define FIOGETOWN 0x8903 -#define SIOCGPGRP 0x8904 -#define SIOCATMARK 0x8905 -#define SIOCGSTAMP 0x8906 /* Get stamp */ +#include <asm/sockios.h> /* Routing table calls. */ #define SIOCADDRT 0x890B /* add routing table entry */ @@ -52,26 +44,26 @@ #define SIOCSIFMEM 0x8920 /* set memory address (BSD) */ #define SIOCGIFMTU 0x8921 /* get MTU size */ #define SIOCSIFMTU 0x8922 /* set MTU size */ -#define OLD_SIOCGIFHWADDR 0x8923 /* get hardware address */ #define SIOCSIFHWADDR 0x8924 /* set hardware address (NI) */ #define SIOCGIFENCAP 0x8925 /* get/set slip encapsulation */ #define SIOCSIFENCAP 0x8926 #define SIOCGIFHWADDR 0x8927 /* Get hardware address */ #define SIOCGIFSLAVE 0x8929 /* Driver slaving support */ #define SIOCSIFSLAVE 0x8930 -/* begin multicast support change */ -#define SIOCADDMULTI 0x8931 -#define SIOCDELMULTI 0x8932 -/* end multicast support change */ +#define SIOCADDMULTI 0x8931 /* Multicast address lists */ +#define SIOCDELMULTI 0x8932 +#define SIOGIFINDEX 0x8933 /* name -> if_index mapping */ -/* Routing table calls (oldrtent - don't use) */ -#define SIOCADDRTOLD 0x8940 /* add routing table entry */ -#define SIOCDELRTOLD 0x8941 /* delete routing table entry */ +#define SIOCGIFBR 0x8940 /* Bridging support */ +#define SIOCSIFBR 0x8941 /* Set bridging options */ /* ARP cache control calls. */ -#define SIOCDARP 0x8950 /* delete ARP table entry */ -#define SIOCGARP 0x8951 /* get ARP table entry */ -#define SIOCSARP 0x8952 /* set ARP table entry */ +#define OLD_SIOCDARP 0x8950 /* old delete ARP table entry */ +#define OLD_SIOCGARP 0x8951 /* old get ARP table entry */ +#define OLD_SIOCSARP 0x8952 /* old set ARP table entry */ +#define SIOCDARP 0x8953 /* delete ARP table entry */ +#define SIOCGARP 0x8954 /* get ARP table entry */ +#define SIOCSARP 0x8955 /* set ARP table entry */ /* RARP cache control calls. */ #define SIOCDRARP 0x8960 /* delete RARP table entry */ @@ -83,6 +75,11 @@ #define SIOCGIFMAP 0x8970 /* Get device parameters */ #define SIOCSIFMAP 0x8971 /* Set device parameters */ +/* DLCI configuration calls */ + +#define SIOCADDDLCI 0x8980 /* Create new DLCI device */ +#define SIOCDELDLCI 0x8981 /* Delete DLCI device */ + /* Device private ioctl calls */ /* diff --git a/include/linux/sonycd535.h b/include/linux/sonycd535.h index 387e6f814..5dea1ef16 100644 --- a/include/linux/sonycd535.h +++ b/include/linux/sonycd535.h @@ -107,9 +107,9 @@ #define LOG_START_OFFSET 150 /* Offset of first logical sector */ -#define SONY_JIFFIES_TIMEOUT 500 /* Maximum number of jiffies (10ms) - the drive will wait/try for an - operation */ +#define SONY_JIFFIES_TIMEOUT (5*HZ) /* Maximum time + the drive will wait/try for an + operation */ #define SONY_READY_RETRIES (50000) /* How many times to retry a spin waiting for a register to come ready */ diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h index f839f1d89..3b6af75fa 100644 --- a/include/linux/soundcard.h +++ b/include/linux/soundcard.h @@ -1,45 +1,42 @@ #ifndef SOUNDCARD_H #define SOUNDCARD_H /* - * Copyright by Hannu Savolainen 1993 + * Copyright by Hannu Savolainen 1993-1996 * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * */ - /* - * If you make modifications to this file, please contact me before - * distributing the modified version. There is already enough - * diversity in the world. - * - * Regards, - * Hannu Savolainen - * hannu@voxware.pp.fi - */ -#define SOUND_VERSION 300 -#define VOXWARE +/* + * OSS interface version. With versions earlier than 3.6 this value is + * an integer with value less than 361. In versions 3.6 and later + * it's a six digit hexadecimal value. For example value + * of 0x030600 represents OSS version 3.6.0. + * Use ioctl(fd, OSS_GETVERSION, &int) to get the version number of + * the currently active driver. + */ +#define SOUND_VERSION 0x030700 +#define OPEN_SOUND_SYSTEM +/* In Linux we need to be prepared for cross compiling */ #include <linux/ioctl.h> /* @@ -58,13 +55,39 @@ #define SNDCARD_MSS 10 #define SNDCARD_PSS 11 #define SNDCARD_SSCAPE 12 +#define SNDCARD_PSS_MPU 13 +#define SNDCARD_PSS_MSS 14 +#define SNDCARD_SSCAPE_MSS 15 +#define SNDCARD_TRXPRO 16 +#define SNDCARD_TRXPRO_SB 17 +#define SNDCARD_TRXPRO_MPU 18 +#define SNDCARD_MAD16 19 +#define SNDCARD_MAD16_MPU 20 +#define SNDCARD_CS4232 21 +#define SNDCARD_CS4232_MPU 22 +#define SNDCARD_MAUI 23 +#define SNDCARD_PSEUDO_MSS 24 +#define SNDCARD_GUSPNP 25 +#define SNDCARD_UART401 26 +/* Soundcard numbers 27 to N are reserved. Don't add more numbers here */ /*********************************** * IOCTL Commands for /dev/sequencer */ -#ifndef _IOWR -/* @(#)ioctlp.h */ +#ifndef _SIOWR +#if defined(_IOWR) && !defined(sun) +/* Use already defined ioctl defines if they exist (except with Sun) */ +#define SIOCPARM_MASK IOCPARM_MASK +#define SIOC_VOID IOC_VOID +#define SIOC_OUT IOC_OUT +#define SIOC_IN IOC_IN +#define SIOC_INOUT IOC_INOUT +#define _SIO _IO +#define _SIOR _IOR +#define _SIOW _IOW +#define _SIOWR _IOWR +#else /* Ioctl's have the command encoded in the lower word, * and the size of any in or out parameters in the upper @@ -72,69 +95,89 @@ * to encode the in/out status of the parameter; for now * we restrict parameters to at most 128 bytes. */ -/* #define IOCTYPE (0xff<<8) */ -#define IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */ -#define IOC_VOID 0x00000000 /* no parameters */ -#define IOC_OUT 0x20000000 /* copy out parameters */ -#define IOC_IN 0x40000000 /* copy in parameters */ -#define IOC_INOUT (IOC_IN|IOC_OUT) +/* #define SIOCTYPE (0xff<<8) */ +#define SIOCPARM_MASK 0x1fff /* parameters must be < 8192 bytes */ +#define SIOC_VOID 0x00000000 /* no parameters */ +#define SIOC_OUT 0x20000000 /* copy out parameters */ +#define SIOC_IN 0x40000000 /* copy in parameters */ +#define SIOC_INOUT (SIOC_IN|SIOC_OUT) /* the 0x20000000 is so we can distinguish new ioctl's from old */ -#define _IO(x,y) ((int)(IOC_VOID|(x<<8)|y)) -#define _IOR(x,y,t) ((int)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)) -#define _IOW(x,y,t) ((int)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)) -/* this should be _IORW, but stdio got there first */ -#define _IOWR(x,y,t) ((int)(IOC_INOUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)) -#endif /* !_IOWR */ - -#define SNDCTL_SEQ_RESET _IO ('Q', 0) -#define SNDCTL_SEQ_SYNC _IO ('Q', 1) -#define SNDCTL_SYNTH_INFO _IOWR('Q', 2, struct synth_info) -#define SNDCTL_SEQ_CTRLRATE _IOWR('Q', 3, int) /* Set/get timer resolution (HZ) */ -#define SNDCTL_SEQ_GETOUTCOUNT _IOR ('Q', 4, int) -#define SNDCTL_SEQ_GETINCOUNT _IOR ('Q', 5, int) -#define SNDCTL_SEQ_PERCMODE _IOW ('Q', 6, int) -#define SNDCTL_FM_LOAD_INSTR _IOW ('Q', 7, struct sbi_instrument) /* Valid for FM only */ -#define SNDCTL_SEQ_TESTMIDI _IOW ('Q', 8, int) -#define SNDCTL_SEQ_RESETSAMPLES _IOW ('Q', 9, int) -#define SNDCTL_SEQ_NRSYNTHS _IOR ('Q',10, int) -#define SNDCTL_SEQ_NRMIDIS _IOR ('Q',11, int) -#define SNDCTL_MIDI_INFO _IOWR('Q',12, struct midi_info) -#define SNDCTL_SEQ_TRESHOLD _IOW ('Q',13, int) -#define SNDCTL_SYNTH_MEMAVL _IOWR('Q',14, int) /* in=dev#, out=memsize */ -#define SNDCTL_FM_4OP_ENABLE _IOW ('Q',15, int) /* in=dev# */ -#define SNDCTL_PMGR_ACCESS _IOWR('Q',16, struct patmgr_info) -#define SNDCTL_SEQ_PANIC _IO ('Q',17) - -#define SNDCTL_TMR_TIMEBASE _IOWR('T', 1, int) -#define SNDCTL_TMR_START _IO ('T', 2) -#define SNDCTL_TMR_STOP _IO ('T', 3) -#define SNDCTL_TMR_CONTINUE _IO ('T', 4) -#define SNDCTL_TMR_TEMPO _IOWR('T', 5, int) -#define SNDCTL_TMR_SOURCE _IOWR('T', 6, int) +#define _SIO(x,y) ((int)(SIOC_VOID|(x<<8)|y)) +#define _SIOR(x,y,t) ((int)(SIOC_OUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) +#define _SIOW(x,y,t) ((int)(SIOC_IN|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) +/* this should be _SIORW, but stdio got there first */ +#define _SIOWR(x,y,t) ((int)(SIOC_INOUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) +# endif /* _IOWR */ +#endif /* !_SIOWR */ + +#define SNDCTL_SEQ_RESET _SIO ('Q', 0) +#define SNDCTL_SEQ_SYNC _SIO ('Q', 1) +#define SNDCTL_SYNTH_INFO _SIOWR('Q', 2, struct synth_info) +#define SNDCTL_SEQ_CTRLRATE _SIOWR('Q', 3, int) /* Set/get timer resolution (HZ) */ +#define SNDCTL_SEQ_GETOUTCOUNT _SIOR ('Q', 4, int) +#define SNDCTL_SEQ_GETINCOUNT _SIOR ('Q', 5, int) +#define SNDCTL_SEQ_PERCMODE _SIOW ('Q', 6, int) +#define SNDCTL_FM_LOAD_INSTR _SIOW ('Q', 7, struct sbi_instrument) /* Obsolete */ +#define SNDCTL_SEQ_TESTMIDI _SIOW ('Q', 8, int) +#define SNDCTL_SEQ_RESETSAMPLES _SIOW ('Q', 9, int) +#define SNDCTL_SEQ_NRSYNTHS _SIOR ('Q',10, int) +#define SNDCTL_SEQ_NRMIDIS _SIOR ('Q',11, int) +#define SNDCTL_MIDI_INFO _SIOWR('Q',12, struct midi_info) +#define SNDCTL_SEQ_THRESHOLD _SIOW ('Q',13, int) +#define SNDCTL_SYNTH_MEMAVL _SIOWR('Q',14, int) /* in=dev#, out=memsize */ +#define SNDCTL_FM_4OP_ENABLE _SIOW ('Q',15, int) /* in=dev# */ +#define SNDCTL_SEQ_PANIC _SIO ('Q',17) +#define SNDCTL_SEQ_OUTOFBAND _SIOW ('Q',18, struct seq_event_rec) +#define SNDCTL_SEQ_GETTIME _SIOR ('Q',19, int) + + struct seq_event_rec { + unsigned char arr[8]; + }; + +#define SNDCTL_TMR_TIMEBASE _SIOWR('T', 1, int) +#define SNDCTL_TMR_START _SIO ('T', 2) +#define SNDCTL_TMR_STOP _SIO ('T', 3) +#define SNDCTL_TMR_CONTINUE _SIO ('T', 4) +#define SNDCTL_TMR_TEMPO _SIOWR('T', 5, int) +#define SNDCTL_TMR_SOURCE _SIOWR('T', 6, int) # define TMR_INTERNAL 0x00000001 # define TMR_EXTERNAL 0x00000002 # define TMR_MODE_MIDI 0x00000010 # define TMR_MODE_FSK 0x00000020 # define TMR_MODE_CLS 0x00000040 # define TMR_MODE_SMPTE 0x00000080 -#define SNDCTL_TMR_METRONOME _IOW ('T', 7, int) -#define SNDCTL_TMR_SELECT _IOW ('T', 8, int) +#define SNDCTL_TMR_METRONOME _SIOW ('T', 7, int) +#define SNDCTL_TMR_SELECT _SIOW ('T', 8, int) + +/* + * Some big endian/little endian handling macros + */ + +#if defined(_AIX) || defined(AIX) || defined(sparc) || defined(HPPA) || defined(PPC) +/* Big endian machines */ +# define _PATCHKEY(id) (0xfd00|id) +# define AFMT_S16_NE AFMT_S16_BE +#else +# define _PATCHKEY(id) ((id<<8)|0xfd) +# define AFMT_S16_NE AFMT_S16_LE +#endif /* * Sample loading mechanism for internal synthesizers (/dev/sequencer) * The following patch_info structure has been designed to support * Gravis UltraSound. It tries to be universal format for uploading - * sample based patches but is probably too limited. + * sample based patches but is propably too limited. */ struct patch_info { - short key; /* Use GUS_PATCH here */ -#define GUS_PATCH 0x04fd -#define OBSOLETE_GUS_PATCH 0x02fd + unsigned short key; /* Use GUS_PATCH here */ +#define GUS_PATCH _PATCHKEY(0x04) +#define OBSOLETE_GUS_PATCH _PATCHKEY(0x02) + short device_no; /* Synthesizer number */ short instr_no; /* Midi pgm# */ - unsigned long mode; + unsigned int mode; /* * The least significant byte has the same format than the GUS .PAT * files @@ -151,10 +194,14 @@ struct patch_info { #define WAVE_VIBRATO 0x00010000 /* The vibrato info is valid */ #define WAVE_TREMOLO 0x00020000 /* The tremolo info is valid */ #define WAVE_SCALE 0x00040000 /* The scaling info is valid */ +#define WAVE_FRACTIONS 0x00080000 /* Fraction information is valid */ +/* Reserved bits */ +#define WAVE_ROM 0x40000000 /* For future use */ +#define WAVE_MULAW 0x20000000 /* For future use */ /* Other bits must be zeroed */ - long len; /* Size of the wave data in bytes */ - long loop_start, loop_end; /* Byte offsets from the beginning */ + int len; /* Size of the wave data in bytes */ + int loop_start, loop_end; /* Byte offsets from the beginning */ /* * The base_freq and base_note fields are used when computing the @@ -164,7 +211,7 @@ struct patch_info { * * The low_note and high_note fields define the minimum and maximum note * frequencies for which this sample is valid. It is possible to define - * more than one samples for a instrument number at the same time. The + * more than one samples for an instrument number at the same time. The * low_note and high_note fields are used to select the most suitable one. * * The fields base_note, high_note and low_note should contain @@ -173,9 +220,9 @@ struct patch_info { */ unsigned int base_freq; - unsigned long base_note; - unsigned long high_note; - unsigned long low_note; + unsigned int base_note; + unsigned int high_note; + unsigned int low_note; int panning; /* -128=left, 127=right */ int detuning; @@ -203,104 +250,22 @@ struct patch_info { unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */ int volume; - int spare[4]; + int fractions; + int reserved1; + int spare[2]; char data[1]; /* The waveform data starts here */ }; - struct sysex_info { short key; /* Use GUS_PATCH here */ -#define SYSEX_PATCH 0x05fd +#define SYSEX_PATCH _PATCHKEY(0x05) +#define MAUI_PATCH _PATCHKEY(0x06) short device_no; /* Synthesizer number */ - long len; /* Size of the sysex data in bytes */ + int len; /* Size of the sysex data in bytes */ unsigned char data[1]; /* Sysex data starts here */ }; /* - * Patch management interface (/dev/sequencer, /dev/patmgr#) - * Don't use these calls if you want to maintain compatibility with - * the future versions of the driver. - */ - -#define PS_NO_PATCHES 0 /* No patch support on device */ -#define PS_MGR_NOT_OK 1 /* Plain patch support (no mgr) */ -#define PS_MGR_OK 2 /* Patch manager supported */ -#define PS_MANAGED 3 /* Patch manager running */ - -#define SNDCTL_PMGR_IFACE _IOWR('P', 1, struct patmgr_info) - -/* - * The patmgr_info is a fixed size structure which is used for two - * different purposes. The intended use is for communication between - * the application using /dev/sequencer and the patch manager daemon - * associated with a synthesizer device (ioctl(SNDCTL_PMGR_ACCESS)). - * - * This structure is also used with ioctl(SNDCTL_PGMR_IFACE) which allows - * a patch manager daemon to read and write device parameters. This - * ioctl available through /dev/sequencer also. Avoid using it since it's - * extremely hardware dependent. In addition access trough /dev/sequencer - * may confuse the patch manager daemon. - */ - -struct patmgr_info { /* Note! size must be < 4k since kmalloc() is used */ - unsigned long key; /* Don't worry. Reserved for communication - between the patch manager and the driver. */ -#define PM_K_EVENT 1 /* Event from the /dev/sequencer driver */ -#define PM_K_COMMAND 2 /* Request from a application */ -#define PM_K_RESPONSE 3 /* From patmgr to application */ -#define PM_ERROR 4 /* Error returned by the patmgr */ - int device; - int command; - -/* - * Commands 0x000 to 0xfff reserved for patch manager programs - */ -#define PM_GET_DEVTYPE 1 /* Returns type of the patch mgr interface of dev */ -#define PMTYPE_FM2 1 /* 2 OP fm */ -#define PMTYPE_FM4 2 /* Mixed 4 or 2 op FM (OPL-3) */ -#define PMTYPE_WAVE 3 /* Wave table synthesizer (GUS) */ -#define PM_GET_NRPGM 2 /* Returns max # of midi programs in parm1 */ -#define PM_GET_PGMMAP 3 /* Returns map of loaded midi programs in data8 */ -#define PM_GET_PGM_PATCHES 4 /* Return list of patches of a program (parm1) */ -#define PM_GET_PATCH 5 /* Return patch header of patch parm1 */ -#define PM_SET_PATCH 6 /* Set patch header of patch parm1 */ -#define PM_READ_PATCH 7 /* Read patch (wave) data */ -#define PM_WRITE_PATCH 8 /* Write patch (wave) data */ - -/* - * Commands 0x1000 to 0xffff are for communication between the patch manager - * and the client - */ -#define _PM_LOAD_PATCH 0x100 - -/* - * Commands above 0xffff reserved for device specific use - */ - - long parm1; - long parm2; - long parm3; - - union { - unsigned char data8[4000]; - unsigned short data16[2000]; - unsigned long data32[1000]; - struct patch_info patch; - } data; - }; - -/* - * When a patch manager daemon is present, it will be informed by the - * driver when something important happens. For example when the - * /dev/sequencer is opened or closed. A record with key == PM_K_EVENT is - * returned. The command field contains the event type: - */ -#define PM_E_OPENED 1 /* /dev/sequencer opened */ -#define PM_E_CLOSED 2 /* /dev/sequencer closed */ -#define PM_E_PATCH_RESET 3 /* SNDCTL_RESETSAMPLES called */ -#define PM_E_PATCH_LOADED 4 /* A patch has been loaded by appl */ - -/* * /dev/sequencer input events. * * The data written to the /dev/sequencer is a stream of events. Events @@ -343,14 +308,8 @@ struct patmgr_info { /* Note! size must be < 4k since kmalloc() is used */ * controllers. * In the MIDI 1.0 these controllers are sent using * two messages. Controller numbers 0 to 31 are used - * to send the LSB and the controller numbers 32 to 63 - * are for the LSB. - * - * This driver uses just the numbers 0 to 31 to store both - * the LSB and MSB. The controller value is a unsigned short - * and its valid range is between 0 and 16383 (0x0000 to 0x3fff). - * The driver sends the controller value using two messages when - * necessary. + * to send the MSB and the controller numbers 32 to 63 + * are for the LSB. Note that just 7 bits are used in MIDI bytes. */ #define CTL_BANK_SELECT 0x00 @@ -467,9 +426,9 @@ struct patmgr_info { /* Note! size must be < 4k since kmalloc() is used */ typedef unsigned char sbi_instr_data[32]; struct sbi_instrument { - unsigned short key; /* Initialize to FM_PATCH or OPL3_PATCH */ -#define FM_PATCH 0x01fd -#define OPL3_PATCH 0x03fd + unsigned short key; /* FM_PATCH or OPL3_PATCH */ +#define FM_PATCH _PATCHKEY(0x01) +#define OPL3_PATCH _PATCHKEY(0x03) short device; /* Synth# (0-4) */ int channel; /* Program# to be initialized */ sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */ @@ -486,6 +445,7 @@ struct synth_info { /* Read only */ int synth_subtype; #define FM_TYPE_ADLIB 0x00 #define FM_TYPE_OPL3 0x01 +#define MIDI_TYPE_MPU401 0x401 #define SAMPLE_TYPE_GUS 0x10 @@ -493,7 +453,7 @@ struct synth_info { /* Read only */ int nr_voices; int nr_drums; /* Obsolete field */ int instr_bank_size; - unsigned long capabilities; + unsigned int capabilities; #define SYNTH_CAP_PERCMODE 0x00000001 /* No longer used */ #define SYNTH_CAP_OPL3 0x00000002 /* Set if OPL3 supported */ #define SYNTH_CAP_INPUT 0x00000004 /* Input (MIDI) device */ @@ -501,7 +461,7 @@ struct synth_info { /* Read only */ }; struct sound_timer_info { - char name[30]; + char name[32]; int caps; }; @@ -510,7 +470,7 @@ struct sound_timer_info { struct midi_info { char name[30]; int device; /* 0-N. INITIALIZE BEFORE CALLING */ - unsigned long capabilities; /* To be defined later */ + unsigned int capabilities; /* To be defined later */ int dev_type; int dummies[18]; /* Reserve space */ }; @@ -524,29 +484,30 @@ typedef struct { unsigned char data[30]; } mpu_command_rec; -#define SNDCTL_MIDI_PRETIME _IOWR('m', 0, int) -#define SNDCTL_MIDI_MPUMODE _IOWR('m', 1, int) -#define SNDCTL_MIDI_MPUCMD _IOWR('m', 2, mpu_command_rec) +#define SNDCTL_MIDI_PRETIME _SIOWR('m', 0, int) +#define SNDCTL_MIDI_MPUMODE _SIOWR('m', 1, int) +#define SNDCTL_MIDI_MPUCMD _SIOWR('m', 2, mpu_command_rec) /******************************************** * IOCTL commands for /dev/dsp and /dev/audio */ -#define SNDCTL_DSP_RESET _IO ('P', 0) -#define SNDCTL_DSP_SYNC _IO ('P', 1) -#define SNDCTL_DSP_SPEED _IOWR('P', 2, int) -#define SNDCTL_DSP_STEREO _IOWR('P', 3, int) -#define SNDCTL_DSP_GETBLKSIZE _IOWR('P', 4, int) +#define SNDCTL_DSP_RESET _SIO ('P', 0) +#define SNDCTL_DSP_SYNC _SIO ('P', 1) +#define SNDCTL_DSP_SPEED _SIOWR('P', 2, int) +#define SNDCTL_DSP_STEREO _SIOWR('P', 3, int) +#define SNDCTL_DSP_GETBLKSIZE _SIOWR('P', 4, int) #define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT -#define SOUND_PCM_WRITE_CHANNELS _IOWR('P', 6, int) -#define SOUND_PCM_WRITE_FILTER _IOWR('P', 7, int) -#define SNDCTL_DSP_POST _IO ('P', 8) -#define SNDCTL_DSP_SUBDIVIDE _IOWR('P', 9, int) -#define SNDCTL_DSP_SETFRAGMENT _IOWR('P',10, int) +#define SNDCTL_DSP_CHANNELS _SIOWR('P', 6, int) +#define SOUND_PCM_WRITE_CHANNELS SNDCTL_DSP_CHANNELS +#define SOUND_PCM_WRITE_FILTER _SIOWR('P', 7, int) +#define SNDCTL_DSP_POST _SIO ('P', 8) +#define SNDCTL_DSP_SUBDIVIDE _SIOWR('P', 9, int) +#define SNDCTL_DSP_SETFRAGMENT _SIOWR('P',10, int) /* Audio data formats (Note! U8=8 and S16_LE=16 for compatibility) */ -#define SNDCTL_DSP_GETFMTS _IOR ('P',11, int) /* Returns a mask */ -#define SNDCTL_DSP_SETFMT _IOWR('P',5, int) /* Selects ONE fmt*/ +#define SNDCTL_DSP_GETFMTS _SIOR ('P',11, int) /* Returns a mask */ +#define SNDCTL_DSP_SETFMT _SIOWR('P',5, int) /* Selects ONE fmt*/ # define AFMT_QUERY 0x00000000 /* Return current fmt */ # define AFMT_MU_LAW 0x00000001 # define AFMT_A_LAW 0x00000002 @@ -557,11 +518,64 @@ typedef struct { # define AFMT_S8 0x00000040 # define AFMT_U16_LE 0x00000080 /* Little endian U16 */ # define AFMT_U16_BE 0x00000100 /* Big endian U16 */ +# define AFMT_MPEG 0x00000200 /* MPEG (2) audio */ -#define SOUND_PCM_READ_RATE _IOR ('P', 2, int) -#define SOUND_PCM_READ_CHANNELS _IOR ('P', 6, int) -#define SOUND_PCM_READ_BITS _IOR ('P', 5, int) -#define SOUND_PCM_READ_FILTER _IOR ('P', 7, int) +/* + * Buffer status queries. + */ +typedef struct audio_buf_info { + int fragments; /* # of available fragments (partially usend ones not counted) */ + int fragstotal; /* Total # of fragments allocated */ + int fragsize; /* Size of a fragment in bytes */ + + int bytes; /* Available space in bytes (includes partially used fragments) */ + /* Note! 'bytes' could be more than fragments*fragsize */ + } audio_buf_info; + +#define SNDCTL_DSP_GETOSPACE _SIOR ('P',12, audio_buf_info) +#define SNDCTL_DSP_GETISPACE _SIOR ('P',13, audio_buf_info) +#define SNDCTL_DSP_NONBLOCK _SIO ('P',14) +#define SNDCTL_DSP_GETCAPS _SIOR ('P',15, int) +# define DSP_CAP_REVISION 0x000000ff /* Bits for revision level (0 to 255) */ +# define DSP_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */ +# define DSP_CAP_REALTIME 0x00000200 /* Real time capability */ +# define DSP_CAP_BATCH 0x00000400 /* Device has some kind of */ + /* internal buffers which may */ + /* cause some delays and */ + /* decrease precision of timing */ +# define DSP_CAP_COPROC 0x00000800 /* Has a coprocessor */ + /* Sometimes it's a DSP */ + /* but usually not */ +# define DSP_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */ +# define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */ + +#define SNDCTL_DSP_GETTRIGGER _SIOR ('P',16, int) +#define SNDCTL_DSP_SETTRIGGER _SIOW ('P',16, int) +# define PCM_ENABLE_INPUT 0x00000001 +# define PCM_ENABLE_OUTPUT 0x00000002 + +typedef struct count_info { + int bytes; /* Total # of bytes processed */ + int blocks; /* # of fragment transitions since last time */ + int ptr; /* Current DMA pointer value */ + } count_info; + +#define SNDCTL_DSP_GETIPTR _SIOR ('P',17, count_info) +#define SNDCTL_DSP_GETOPTR _SIOR ('P',18, count_info) + +typedef struct buffmem_desc { + unsigned *buffer; + int size; + } buffmem_desc; +#define SNDCTL_DSP_MAPINBUF _SIOR ('P', 19, buffmem_desc) +#define SNDCTL_DSP_MAPOUTBUF _SIOR ('P', 20, buffmem_desc) +#define SNDCTL_DSP_SETSYNCRO _SIO ('P', 21) +#define SNDCTL_DSP_SETDUPLEX _SIO ('P', 22) + +#define SOUND_PCM_READ_RATE _SIOR ('P', 2, int) +#define SOUND_PCM_READ_CHANNELS _SIOR ('P', 6, int) +#define SOUND_PCM_READ_BITS _SIOR ('P', 5, int) +#define SOUND_PCM_READ_FILTER _SIOR ('P', 7, int) /* Some alias names */ #define SOUND_PCM_WRITE_BITS SNDCTL_DSP_SETFMT @@ -573,21 +587,58 @@ typedef struct { #define SOUND_PCM_SETFRAGMENT SNDCTL_DSP_SETFRAGMENT #define SOUND_PCM_GETFMTS SNDCTL_DSP_GETFMTS #define SOUND_PCM_SETFMT SNDCTL_DSP_SETFMT +#define SOUND_PCM_GETOSPACE SNDCTL_DSP_GETOSPACE +#define SOUND_PCM_GETISPACE SNDCTL_DSP_GETISPACE +#define SOUND_PCM_NONBLOCK SNDCTL_DSP_NONBLOCK +#define SOUND_PCM_GETCAPS SNDCTL_DSP_GETCAPS +#define SOUND_PCM_GETTRIGGER SNDCTL_DSP_GETTRIGGER +#define SOUND_PCM_SETTRIGGER SNDCTL_DSP_SETTRIGGER +#define SOUND_PCM_SETSYNCRO SNDCTL_DSP_SETSYNCRO +#define SOUND_PCM_GETIPTR SNDCTL_DSP_GETIPTR +#define SOUND_PCM_GETOPTR SNDCTL_DSP_GETOPTR +#define SOUND_PCM_MAPINBUF SNDCTL_DSP_MAPINBUF +#define SOUND_PCM_MAPOUTBUF SNDCTL_DSP_MAPOUTBUF -/********************************************* - * IOCTL /dev/pss (experimental PSS API by marc.hoffman@analog.com. - * likely to change in near future. +/* + * ioctl calls to be used in communication with coprocessors and + * DSP chips. */ -#define SNDCTL_PSS_RESET _IO ('C', 0) -#define SNDCTL_PSS_SETUP_REGISTERS _IO ('C', 1) -#define SNDCTL_PSS_SPEAKER _IOW ('C', 2, struct pss_speaker) -struct pss_speaker { - int volume; - int bass; - int treb; - int mode; -}; +typedef struct copr_buffer { + int command; /* Set to 0 if not used */ + int flags; +#define CPF_NONE 0x0000 +#define CPF_FIRST 0x0001 /* First block */ +#define CPF_LAST 0x0002 /* Last block */ + int len; + int offs; /* If required by the device (0 if not used) */ + + unsigned char data[4000]; /* NOTE! 4000 is not 4k */ + } copr_buffer; + +typedef struct copr_debug_buf { + int command; /* Used internally. Set to 0 */ + int parm1; + int parm2; + int flags; + int len; /* Length of data in bytes */ + } copr_debug_buf; + +typedef struct copr_msg { + int len; + unsigned char data[4000]; + } copr_msg; + +#define SNDCTL_COPR_RESET _SIO ('C', 0) +#define SNDCTL_COPR_LOAD _SIOWR('C', 1, copr_buffer) +#define SNDCTL_COPR_RDATA _SIOWR('C', 2, copr_debug_buf) +#define SNDCTL_COPR_RCODE _SIOWR('C', 3, copr_debug_buf) +#define SNDCTL_COPR_WDATA _SIOW ('C', 4, copr_debug_buf) +#define SNDCTL_COPR_WCODE _SIOW ('C', 5, copr_debug_buf) +#define SNDCTL_COPR_RUN _SIOWR('C', 6, copr_debug_buf) +#define SNDCTL_COPR_HALT _SIOWR('C', 7, copr_debug_buf) +#define SNDCTL_COPR_SENDMSG _SIOWR('C', 8, copr_msg) +#define SNDCTL_COPR_RCVMSG _SIOR ('C', 9, copr_msg) /********************************************* * IOCTL commands for /dev/mixer @@ -602,7 +653,7 @@ struct pss_speaker { * the devices supported by the particular mixer. */ -#define SOUND_MIXER_NRDEVICES 12 +#define SOUND_MIXER_NRDEVICES 17 #define SOUND_MIXER_VOLUME 0 #define SOUND_MIXER_BASS 1 #define SOUND_MIXER_TREBLE 2 @@ -615,22 +666,42 @@ struct pss_speaker { #define SOUND_MIXER_IMIX 9 /* Recording monitor */ #define SOUND_MIXER_ALTPCM 10 #define SOUND_MIXER_RECLEV 11 /* Recording level */ +#define SOUND_MIXER_IGAIN 12 /* Input gain */ +#define SOUND_MIXER_OGAIN 13 /* Output gain */ +/* + * The AD1848 codec and compatibles have three line level inputs + * (line, aux1 and aux2). Since each card manufacturer have assigned + * different meanings to these inputs, it's inpractical to assign + * specific meanings (line, cd, synth etc.) to them. + */ +#define SOUND_MIXER_LINE1 14 /* Input source 1 (aux1) */ +#define SOUND_MIXER_LINE2 15 /* Input source 2 (aux2) */ +#define SOUND_MIXER_LINE3 16 /* Input source 3 (line) */ /* Some on/off settings (SOUND_SPECIAL_MIN - SOUND_SPECIAL_MAX) */ /* Not counted to SOUND_MIXER_NRDEVICES, but use the same number space */ #define SOUND_ONOFF_MIN 28 #define SOUND_ONOFF_MAX 30 -#define SOUND_MIXER_MUTE 28 /* 0 or 1 */ -#define SOUND_MIXER_ENHANCE 29 /* Enhanced stereo (0, 40, 60 or 80) */ -#define SOUND_MIXER_LOUD 30 /* 0 or 1 */ /* Note! Number 31 cannot be used since the sign bit is reserved */ +#define SOUND_MIXER_NONE 31 + +/* + * The following unsupported macros are no longer functional. + * Use SOUND_MIXER_PRIVATE# macros in future. + */ +#define SOUND_MIXER_ENHANCE SOUND_MIXER_NONE +#define SOUND_MIXER_MUTE SOUND_MIXER_NONE +#define SOUND_MIXER_LOUD SOUND_MIXER_NONE + #define SOUND_DEVICE_LABELS {"Vol ", "Bass ", "Trebl", "Synth", "Pcm ", "Spkr ", "Line ", \ - "Mic ", "CD ", "Mix ", "Pcm2 ", "rec"} + "Mic ", "CD ", "Mix ", "Pcm2 ", "Rec ", "IGain", "OGain", \ + "Line1", "Line2", "Line3"} #define SOUND_DEVICE_NAMES {"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \ - "mic", "cd", "mix", "pcm2", "rec"} + "mic", "cd", "mix", "pcm2", "rec", "igain", "ogain", \ + "line1", "line2", "line3"} /* Device bitmask identifiers */ @@ -638,7 +709,7 @@ struct pss_speaker { #define SOUND_MIXER_DEVMASK 0xfe /* Arg contains a bit for each supported device */ #define SOUND_MIXER_RECMASK 0xfd /* Arg contains a bit for each supported recording source */ #define SOUND_MIXER_CAPS 0xfc - #define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */ +# define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */ #define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */ /* Device mask bits */ @@ -655,12 +726,18 @@ struct pss_speaker { #define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX) #define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM) #define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV) +#define SOUND_MASK_IGAIN (1 << SOUND_MIXER_IGAIN) +#define SOUND_MASK_OGAIN (1 << SOUND_MIXER_OGAIN) +#define SOUND_MASK_LINE1 (1 << SOUND_MIXER_LINE1) +#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2) +#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3) +/* Obsolete macros */ #define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE) #define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE) #define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD) -#define MIXER_READ(dev) _IOR('M', dev, int) +#define MIXER_READ(dev) _SIOR('M', dev, int) #define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME) #define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS) #define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE) @@ -673,6 +750,13 @@ struct pss_speaker { #define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX) #define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM) #define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV) +#define SOUND_MIXER_READ_IGAIN MIXER_READ(SOUND_MIXER_IGAIN) +#define SOUND_MIXER_READ_OGAIN MIXER_READ(SOUND_MIXER_OGAIN) +#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1) +#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2) +#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3) + +/* Obsolete macros */ #define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE) #define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE) #define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD) @@ -683,7 +767,7 @@ struct pss_speaker { #define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS) #define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS) -#define MIXER_WRITE(dev) _IOWR('M', dev, int) +#define MIXER_WRITE(dev) _SIOWR('M', dev, int) #define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME) #define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS) #define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE) @@ -696,12 +780,81 @@ struct pss_speaker { #define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX) #define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM) #define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV) +#define SOUND_MIXER_WRITE_IGAIN MIXER_WRITE(SOUND_MIXER_IGAIN) +#define SOUND_MIXER_WRITE_OGAIN MIXER_WRITE(SOUND_MIXER_OGAIN) +#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1) +#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2) +#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3) + +/* Obsolete macros */ #define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE) #define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE) #define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD) #define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC) +typedef struct mixer_info +{ + char id[16]; + char name[32]; + int modify_counter; + int fillers[10]; +} mixer_info; + +typedef struct _old_mixer_info /* Obsolete */ +{ + char id[16]; + char name[32]; +} _old_mixer_info; + +#define SOUND_MIXER_INFO _SIOR ('M', 101, mixer_info) +#define SOUND_OLD_MIXER_INFO _SIOR ('M', 101, _old_mixer_info) + +/* + * A mechanism for accessing "proprietary" mixer features. This method + * permits passing 128 bytes of arbitrary data between a mixer application + * and the mixer driver. Interpretation of the record is defined by + * the particular mixer driver. + */ +typedef unsigned char mixer_record[128]; + +#define SOUND_MIXER_ACCESS _SIOWR('M', 102, mixer_record) + +/* + * The SOUND_MIXER_PRIVATE# commands can be redefined by low level drivers. + * These features can be used when accessing device specific features. + */ +#define SOUND_MIXER_PRIVATE1 _SIOWR('M', 111, int) +#define SOUND_MIXER_PRIVATE2 _SIOWR('M', 112, int) +#define SOUND_MIXER_PRIVATE3 _SIOWR('M', 113, int) +#define SOUND_MIXER_PRIVATE4 _SIOWR('M', 114, int) +#define SOUND_MIXER_PRIVATE5 _SIOWR('M', 115, int) + +/* + * SOUND_MIXER_GETLEVELS and SOUND_MIXER_SETLEVELS calls can be used + * for querying current mixer settings from the driver and for loading + * default volume settings _prior_ activating the mixer (loading + * doesn't affect current state of the mixer hardware). These calls + * are for internal use only. + */ + +typedef struct mixer_vol_table { + int num; /* Index to volume table */ + char name[32]; + int levels[32]; +} mixer_vol_table; + +#define SOUND_MIXER_GETLEVELS _SIOWR('M', 116, mixer_vol_table) +#define SOUND_MIXER_SETLEVELS _SIOWR('M', 117, mixer_vol_table) + +/* + * An ioctl for identifying the driver version. It will return value + * of the SOUND_VERSION macro used when compiling the driver. + * This call was introduced in OSS version 3.6 and it will not work + * with earlier versions (returns EINVAL). + */ +#define OSS_GETVERSION _SIOR ('M', 118, int) + /* * Level 2 event types for /dev/sequencer */ @@ -724,6 +877,7 @@ struct pss_speaker { #define EV_TIMING 0x81 #define EV_CHN_COMMON 0x92 #define EV_CHN_VOICE 0x93 +#define EV_SYSEX 0x94 /* * Event types 200 to 220 are reserved for application use. * These numbers will not be used by the driver. @@ -762,6 +916,11 @@ struct pss_speaker { #define TMR_SPP 10 /* Song position pointer */ #define TMR_TIMESIG 11 /* Time signature */ +/* + * Local event types + */ +#define LOCL_STARTAUDIO 1 + #if (!defined(__KERNEL__) && !defined(KERNEL) && !defined(INKERNEL) && !defined(_KERNEL)) || defined(USE_SEQ_MACROS) /* * Some convenience macros to simplify programming of the @@ -795,7 +954,6 @@ void seqbuf_dump(void); /* This function must be provided by programs */ #define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0 #define SEQ_USE_EXTBUF() extern unsigned char _seqbuf[]; extern int _seqbuflen;extern int _seqbufptr #define SEQ_DECLAREBUF() SEQ_USE_EXTBUF() -#define SEQ_PM_DEFINES struct patmgr_info _pm_info #define _SEQ_NEEDBUF(len) if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump() #define _SEQ_ADVBUF(len) _seqbufptr += len #define SEQ_DUMPBUF seqbuf_dump @@ -817,15 +975,6 @@ void seqbuf_dump(void); /* This function must be provided by programs */ #define _SEQ_NEEDBUF(len) /* empty */ #endif -#define PM_LOAD_PATCH(dev, bank, pgm) (SEQ_DUMPBUF(), _pm_info.command = _PM_LOAD_PATCH, \ - _pm_info.device=dev, _pm_info.data.data8[0]=pgm, \ - _pm_info.parm1 = bank, _pm_info.parm2 = 1, \ - ioctl(seqfd, SNDCTL_PMGR_ACCESS, &_pm_info)) -#define PM_LOAD_PATCHES(dev, bank, pgm) (SEQ_DUMPBUF(), _pm_info.command = _PM_LOAD_PATCH, \ - _pm_info.device=dev, memcpy(_pm_info.data.data8, pgm, 128), \ - _pm_info.parm1 = bank, _pm_info.parm2 = 128, \ - ioctl(seqfd, SNDCTL_PMGR_ACCESS, &_pm_info)) - #define SEQ_VOLUME_MODE(dev, mode) {_SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;\ @@ -876,6 +1025,28 @@ void seqbuf_dump(void); /* This function must be provided by programs */ _seqbuf[_seqbufptr+5] = (p2);\ *(short *)&_seqbuf[_seqbufptr+6] = (w14);\ _SEQ_ADVBUF(8);} +/* + * SEQ_SYSEX permits sending of sysex messages. (It may look that it permits + * sending any MIDI bytes but it's absolutely not possible. Trying to do + * so _will_ cause problems with MPU401 intelligent mode). + * + * Sysex messages are sent in blocks of 1 to 6 bytes. Longer messages must be + * sent by calling SEQ_SYSEX() several times (there must be no other events + * between them). First sysex fragment must have 0xf0 in the first byte + * and the last byte (buf[len-1] of the last fragment must be 0xf7. No byte + * between these sysex start and end markers cannot be larger than 0x7f. Also + * lengths of each fragments (except the last one) must be 6. + * + * Breaking the above rules may work with some MIDI ports but is likely to + * cause fatal problems with some other devices (such as MPU401). + */ +#define SEQ_SYSEX(dev, buf, len) \ + {int i, l=(len); if (l>6)l=6;\ + _SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = EV_SYSEX;\ + for(i=0;i<l;i++)_seqbuf[_seqbufptr+i+1] = (buf)[i];\ + for(i=l;i<6;i++)_seqbuf[_seqbufptr+i+1] = 0xff;\ + _SEQ_ADVBUF(8);} #define SEQ_CHN_PRESSURE(dev, chn, pressure) \ _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0) @@ -896,7 +1067,8 @@ void seqbuf_dump(void); /* This function must be provided by programs */ _seqbuf[_seqbufptr+2] = (dev);\ _seqbuf[_seqbufptr+3] = (voice);\ _seqbuf[_seqbufptr+4] = (controller);\ - *(short *)&_seqbuf[_seqbufptr+5] = (value);\ + _seqbuf[_seqbufptr+5] = ((value)&0xff);\ + _seqbuf[_seqbufptr+6] = ((value>>8)&0xff);\ _seqbuf[_seqbufptr+7] = 0;\ _SEQ_ADVBUF(8);} /* @@ -908,21 +1080,9 @@ void seqbuf_dump(void); /* This function must be provided by programs */ #define SEQ_EXPRESSION(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_EXPRESSION, value*128) #define SEQ_MAIN_VOLUME(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_MAIN_VOLUME, (value*16383)/100) #define SEQ_PANNING(dev, voice, pos) SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2) -#if 0 -#define SEQ_PANNING(dev, voice, pos) {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ - _seqbuf[_seqbufptr+1] = SEQ_BALANCE;\ - _seqbuf[_seqbufptr+2] = (dev);\ - _seqbuf[_seqbufptr+3] = (voice);\ - (char)_seqbuf[_seqbufptr+4] = (pos);\ - _seqbuf[_seqbufptr+5] = 0;\ - _seqbuf[_seqbufptr+6] = 0;\ - _seqbuf[_seqbufptr+7] = 1;\ - _SEQ_ADVBUF(8);} -#endif /* - * Timing and synchronization macros + * Timing and syncronization macros */ #define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ @@ -944,6 +1104,19 @@ void seqbuf_dump(void); /* This function must be provided by programs */ #define SEQ_TIME_SIGNATURE(sig) _TIMER_EVENT(TMR_TIMESIG, sig) /* + * Local control events + */ + +#define _LOCAL_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr+0] = EV_SEQ_LOCAL; \ + _seqbuf[_seqbufptr+1] = (ev); \ + _seqbuf[_seqbufptr+2] = 0;\ + _seqbuf[_seqbufptr+3] = 0;\ + *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ + _SEQ_ADVBUF(8);} + +#define SEQ_PLAYAUDIO(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO, devmask) +/* * Events for the level 1 interface only */ @@ -963,5 +1136,4 @@ void seqbuf_dump(void); /* This function must be provided by programs */ #define SEQ_WRPATCH2(patchx, len) (seqbuf_dump(), write(seqfd, (char*)(patchx), len)) #endif -long soundcard_init(long mem_start); #endif diff --git a/include/linux/soundmodem.h b/include/linux/soundmodem.h new file mode 100644 index 000000000..0bea35fce --- /dev/null +++ b/include/linux/soundmodem.h @@ -0,0 +1,107 @@ +/* + * The Linux soundcard driver for 1200 baud and 9600 baud packet radio + * (C) 1996 by Thomas Sailer, HB9JNX/AE4WA + */ + +#ifndef _SOUNDMODEM_H +#define _SOUNDMODEM_H + +#include <linux/sockios.h> +#include <linux/if_ether.h> + +/* -------------------------------------------------------------------- */ +/* + * structs for the IOCTL commands + */ + +struct sm_debug_data { + unsigned long debug1; + unsigned long debug2; + long debug3; +}; + +struct sm_diag_data { + unsigned int mode; + unsigned int flags; + unsigned int samplesperbit; + unsigned int datalen; + short *data; +}; + +struct sm_mixer_data { + unsigned int mixer_type; + unsigned int sample_rate; + unsigned int bit_rate; + unsigned int reg; + unsigned int data; +}; + +struct sm_config { + int hardware; + int mode; +}; + +struct sm_ioctl { + int cmd; + union { + struct sm_config cfg; + struct sm_diag_data diag; + struct sm_mixer_data mix; + struct sm_debug_data dbg; + } data; +}; + +/* -------------------------------------------------------------------- */ + +/* + * config: hardware + */ +#define SM_HARDWARE_INVALID -1 +#define SM_HARDWARE_SBC 0 +#define SM_HARDWARE_WSS 1 +#define SM_HARDWARE_WSSFDX 2 /* currently does not work! */ + +/* + * config: mode + */ +#define SM_MODE_INVALID -1 +#define SM_MODE_AFSK1200 0 +#define SM_MODE_FSK9600 1 + +/* + * diagnose modes + */ +#define SM_DIAGMODE_OFF 0 +#define SM_DIAGMODE_INPUT 1 +#define SM_DIAGMODE_DEMOD 2 + +/* + * diagnose flags + */ +#define SM_DIAGFLAG_DCDGATE (1<<0) +#define SM_DIAGFLAG_VALID (1<<1) + +/* + * mixer types + */ +#define SM_MIXER_INVALID 0 +#define SM_MIXER_AD1848 0x10 +#define SM_MIXER_CT1335 0x20 +#define SM_MIXER_CT1345 0x21 +#define SM_MIXER_CT1745 0x22 + +/* + * ioctl values + */ +#define SMCTL_GETMODEMTYPE 0x80 +#define SMCTL_SETMODEMTYPE 0x81 +#define SMCTL_DIAGNOSE 0x82 +#define SMCTL_GETMIXER 0x83 +#define SMCTL_SETMIXER 0x84 +#define SMCTL_GETDEBUG 0x85 + +/* -------------------------------------------------------------------- */ + +#endif /* _SOUNDMODEM_H */ + +/* --------------------------------------------------------------------- */ diff --git a/include/linux/stallion.h b/include/linux/stallion.h new file mode 100644 index 000000000..b1aa738bc --- /dev/null +++ b/include/linux/stallion.h @@ -0,0 +1,142 @@ +/*****************************************************************************/ + +/* + * stallion.h -- stallion multiport serial driver. + * + * Copyright (C) 1994-1996 Greg Ungerer (gerg@stallion.oz.au). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*****************************************************************************/ +#ifndef _STALLION_H +#define _STALLION_H +/*****************************************************************************/ + +/* + * Define important driver constants here. + */ +#define STL_MAXBRDS 4 +#define STL_MAXPANELS 4 +#define STL_PORTSPERPANEL 16 +#define STL_MAXPORTS 64 +#define STL_MAXDEVS (STL_MAXBRDS * STL_MAXPORTS) + + +/* + * Define a set of structures to hold all the board/panel/port info + * for our ports. These will be dynamically allocated as required. + */ + +/* + * Define a ring queue structure for each port. This will hold the + * TX data waiting to be output. Characters are fed into this buffer + * from the line discipline (or even direct from user space!) and + * then fed into the UARTs during interrupts. Will use a classic ring + * queue here for this. The good thing about this type of ring queue + * is that the head and tail pointers can be updated without interrupt + * protection - since "write" code only needs to change the head, and + * interrupt code only needs to change the tail. + */ +typedef struct { + char *buf; + char *head; + char *tail; +} stlrq_t; + +/* + * Port, panel and board structures to hold status info about each. + * The board structure contains pointers to structures for each panel + * connected to it, and in turn each panel structure contains pointers + * for each port structure for each port on that panel. Note that + * the port structure also contains the board and panel number that it + * is associated with, this makes it (fairly) easy to get back to the + * board/panel info for a port. + */ +typedef struct { + unsigned long magic; + int portnr; + int panelnr; + int brdnr; + int ioaddr; + int uartaddr; + int pagenr; + int istate; + int flags; + int baud_base; + int custom_divisor; + int close_delay; + int closing_wait; + int refcount; + int openwaitcnt; + int brklen; + long session; + long pgrp; + unsigned int sigs; + unsigned int rxignoremsk; + unsigned int rxmarkmsk; + unsigned long clk; + unsigned long hwid; + struct tty_struct *tty; + struct wait_queue *open_wait; + struct wait_queue *close_wait; + struct termios normaltermios; + struct termios callouttermios; + struct tq_struct tqueue; + comstats_t stats; + stlrq_t tx; +} stlport_t; + +typedef struct { + unsigned long magic; + int panelnr; + int brdnr; + int pagenr; + int nrports; + int iobase; + unsigned int hwid; + unsigned int ackmask; + stlport_t *ports[STL_PORTSPERPANEL]; +} stlpanel_t; + +typedef struct { + unsigned long magic; + int brdnr; + int brdtype; + int state; + int nrpanels; + int nrports; + int irq; + int irqtype; + unsigned int ioaddr1; + unsigned int ioaddr2; + unsigned int iostatus; + unsigned int ioctrl; + unsigned int ioctrlval; + unsigned int hwid; + unsigned long clk; + stlpanel_t *panels[STL_MAXPANELS]; +} stlbrd_t; + + +/* + * Define MAGIC numbers used for above structures. + */ +#define STL_PORTMAGIC 0x5a7182c9 +#define STL_PANELMAGIC 0x7ef621a1 +#define STL_BOARDMAGIC 0xa2267f52 + +/*****************************************************************************/ +#endif diff --git a/include/linux/stddef.h b/include/linux/stddef.h index c6221e712..39da8088d 100644 --- a/include/linux/stddef.h +++ b/include/linux/stddef.h @@ -1,11 +1,6 @@ #ifndef _LINUX_STDDEF_H #define _LINUX_STDDEF_H -#ifndef _SIZE_T -#define _SIZE_T -typedef unsigned int size_t; -#endif - #undef NULL #define NULL ((void *)0) diff --git a/include/linux/string.h b/include/linux/string.h index 3fddfdd65..214503c20 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -13,25 +13,25 @@ extern "C" { extern char * ___strtok; extern char * strcpy(char *,const char *); -extern char * strncpy(char *,const char *,size_t); +extern char * strncpy(char *,const char *, __kernel_size_t); extern char * strcat(char *, const char *); -extern char * strncat(char *, const char *, size_t); +extern char * strncat(char *, const char *, __kernel_size_t); extern char * strchr(const char *,int); +extern char * strrchr(const char *,int); extern char * strpbrk(const char *,const char *); -extern char * ___strtok; extern char * strtok(char *,const char *); extern char * strstr(const char *,const char *); -extern size_t strlen(const char *); -extern size_t strnlen(const char *,size_t); -extern size_t strspn(const char *,const char *); +extern __kernel_size_t strlen(const char *); +extern __kernel_size_t strnlen(const char *,__kernel_size_t); +extern __kernel_size_t strspn(const char *,const char *); extern int strcmp(const char *,const char *); -extern int strncmp(const char *,const char *,size_t); +extern int strncmp(const char *,const char *,__kernel_size_t); -extern void * memset(void *,int,size_t); -extern void * memcpy(void *,const void *,size_t); -extern void * memmove(void *,const void *,size_t); -extern void * memscan(void *,int,size_t); -extern int memcmp(const void *,const void *,size_t); +extern void * memset(void *,int,__kernel_size_t); +extern void * memcpy(void *,const void *,__kernel_size_t); +extern void * memmove(void *,const void *,__kernel_size_t); +extern void * memscan(void *,int,__kernel_size_t); +extern int memcmp(const void *,const void *,__kernel_size_t); /* * Include machine specific inline routines diff --git a/include/linux/swap.h b/include/linux/swap.h new file mode 100644 index 000000000..18fe74e8e --- /dev/null +++ b/include/linux/swap.h @@ -0,0 +1,144 @@ +#ifndef _LINUX_SWAP_H +#define _LINUX_SWAP_H + +#define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */ +#define SWAP_FLAG_PRIO_MASK 0x7fff +#define SWAP_FLAG_PRIO_SHIFT 0 + +#define MAX_SWAPFILES 8 + +#ifdef __KERNEL__ + +#include <asm/atomic.h> + +#define SWP_USED 1 +#define SWP_WRITEOK 3 + +#define SWAP_CLUSTER_MAX 32 + +struct swap_info_struct { + unsigned int flags; + kdev_t swap_device; + struct inode * swap_file; + unsigned char * swap_map; + unsigned char * swap_lockmap; + unsigned int lowest_bit; + unsigned int highest_bit; + unsigned int cluster_next; + unsigned int cluster_nr; + int prio; /* swap priority */ + int pages; + unsigned long max; + int next; /* next entry on swap list */ +}; + +extern int nr_swap_pages; +extern int nr_free_pages; +extern atomic_t nr_async_pages; +extern int min_free_pages; +extern int free_pages_low; +extern int free_pages_high; + +/* Incomplete types for prototype declarations: */ +struct task_struct; +struct vm_area_struct; +struct sysinfo; + +/* linux/ipc/shm.c */ +extern int shm_swap (int, int); + +/* linux/mm/vmscan.c */ +extern int try_to_free_page(int, int, int); + +/* linux/mm/page_io.c */ +extern void rw_swap_page(int, unsigned long, char *, int); +#define read_swap_page(nr,buf) \ + rw_swap_page(READ,(nr),(buf),1) +#define write_swap_page(nr,buf) \ + rw_swap_page(WRITE,(nr),(buf),1) +extern void swap_after_unlock_page (unsigned long entry); + +/* linux/mm/page_alloc.c */ +extern void swap_in(struct task_struct *, struct vm_area_struct *, + pte_t *, unsigned long, int); + + +/* linux/mm/swap_state.c */ +extern void show_swap_cache_info(void); +extern int add_to_swap_cache(unsigned long, unsigned long); +extern unsigned long init_swap_cache(unsigned long, unsigned long); +extern void swap_duplicate(unsigned long); + +/* linux/mm/swapfile.c */ +extern unsigned int nr_swapfiles; +extern struct swap_info_struct swap_info[]; +void si_swapinfo(struct sysinfo *); +unsigned long get_swap_page(void); +extern void swap_free(unsigned long); + +/* + * vm_ops not present page codes for shared memory. + * + * Will go away eventually.. + */ +#define SHM_SWP_TYPE 0x40 + +/* + * swap cache stuff (in linux/mm/swap_state.c) + */ + +#define SWAP_CACHE_INFO + +extern unsigned long * swap_cache; + +#ifdef SWAP_CACHE_INFO +extern unsigned long swap_cache_add_total; +extern unsigned long swap_cache_add_success; +extern unsigned long swap_cache_del_total; +extern unsigned long swap_cache_del_success; +extern unsigned long swap_cache_find_total; +extern unsigned long swap_cache_find_success; +#endif + +extern inline unsigned long in_swap_cache(unsigned long index) +{ + return swap_cache[index]; +} + +extern inline long find_in_swap_cache(unsigned long index) +{ + unsigned long entry; + +#ifdef SWAP_CACHE_INFO + swap_cache_find_total++; +#endif + entry = xchg(swap_cache + index, 0); +#ifdef SWAP_CACHE_INFO + if (entry) + swap_cache_find_success++; +#endif + return entry; +} + +extern inline int delete_from_swap_cache(unsigned long index) +{ + unsigned long entry; + +#ifdef SWAP_CACHE_INFO + swap_cache_del_total++; +#endif + entry = xchg(swap_cache + index, 0); + if (entry) { +#ifdef SWAP_CACHE_INFO + swap_cache_del_success++; +#endif + swap_free(entry); + return 1; + } + return 0; +} + + +#endif /* __KERNEL__*/ + +#endif /* _LINUX_SWAP_H */ diff --git a/include/linux/swapctl.h b/include/linux/swapctl.h new file mode 100644 index 000000000..c85aa6c24 --- /dev/null +++ b/include/linux/swapctl.h @@ -0,0 +1,132 @@ +#ifndef _LINUX_SWAPCTL_H +#define _LINUX_SWAPCTL_H + +#include <asm/page.h> +#include <linux/fs.h> + +/* Swap tuning control */ + +/* First, enumerate the different reclaim policies */ +enum RCL_POLICY {RCL_ROUND_ROBIN, RCL_BUFF_FIRST, RCL_PERSIST}; + +typedef struct swap_control_v5 +{ + unsigned int sc_max_page_age; + unsigned int sc_page_advance; + unsigned int sc_page_decline; + unsigned int sc_page_initial_age; + unsigned int sc_max_buff_age; + unsigned int sc_buff_advance; + unsigned int sc_buff_decline; + unsigned int sc_buff_initial_age; + unsigned int sc_age_cluster_fract; + unsigned int sc_age_cluster_min; + unsigned int sc_pageout_weight; + unsigned int sc_bufferout_weight; + unsigned int sc_buffer_grace; + unsigned int sc_nr_buffs_to_free; + unsigned int sc_nr_pages_to_free; + enum RCL_POLICY sc_policy; +} swap_control_v5; +typedef struct swap_control_v5 swap_control_t; +extern swap_control_t swap_control; + +typedef struct kswapd_control_v1 +{ + unsigned int maxpages; + unsigned int pages_buff; + unsigned int pages_shm; + unsigned int pages_mmap; + unsigned int pages_swap; +} kswapd_control_v1; +typedef kswapd_control_v1 kswapd_control_t; +extern kswapd_control_t kswapd_ctl; + +typedef struct swapstat_v1 +{ + unsigned int wakeups; + unsigned int pages_reclaimed; + unsigned int pages_shm; + unsigned int pages_mmap; + unsigned int pages_swap; +} swapstat_v1; +typedef swapstat_v1 swapstat_t; +extern swapstat_t swapstats; + +extern int min_free_pages, free_pages_low, free_pages_high; + +#define SC_VERSION 1 +#define SC_MAX_VERSION 1 + +#ifdef __KERNEL__ + +/* Define the maximum (least urgent) priority for the page reclaim code */ +#define RCL_MAXPRI 6 +/* We use an extra priority in the swap accounting code to represent + failure to free a resource at any priority */ +#define RCL_FAILURE (RCL_MAXPRI + 1) + +#define RCL_POLICY (swap_control.sc_policy) +#define AGE_CLUSTER_FRACT (swap_control.sc_age_cluster_fract) +#define AGE_CLUSTER_MIN (swap_control.sc_age_cluster_min) +#define PAGEOUT_WEIGHT (swap_control.sc_pageout_weight) +#define BUFFEROUT_WEIGHT (swap_control.sc_bufferout_weight) + +#define NR_BUFFS_TO_FREE (swap_control.sc_nr_buffs_to_free) +#define NR_PAGES_TO_FREE (swap_control.sc_nr_pages_to_free) + +#define BUFFERMEM_GRACE (swap_control.sc_buffer_grace) + +/* Page aging (see mm/swap.c) */ + +#define MAX_PAGE_AGE (swap_control.sc_max_page_age) +#define PAGE_ADVANCE (swap_control.sc_page_advance) +#define PAGE_DECLINE (swap_control.sc_page_decline) +#define PAGE_INITIAL_AGE (swap_control.sc_page_initial_age) + +#define MAX_BUFF_AGE (swap_control.sc_max_buff_age) +#define BUFF_ADVANCE (swap_control.sc_buff_advance) +#define BUFF_DECLINE (swap_control.sc_buff_decline) +#define BUFF_INITIAL_AGE (swap_control.sc_buff_initial_age) + +/* Given a resource of N units (pages or buffers etc), we only try to + * age and reclaim AGE_CLUSTER_FRACT per 1024 resources each time we + * scan the resource list. */ +static inline int AGE_CLUSTER_SIZE(int resources) +{ + unsigned int n = (resources * AGE_CLUSTER_FRACT) >> 10; + if (n < AGE_CLUSTER_MIN) + return AGE_CLUSTER_MIN; + else + return n; +} + +static inline void touch_page(struct page *page) +{ + if (page->age < (MAX_PAGE_AGE - PAGE_ADVANCE)) + page->age += PAGE_ADVANCE; + else + page->age = MAX_PAGE_AGE; +} + +static inline void age_page(struct page *page) +{ + if (page->age > PAGE_DECLINE) + page->age -= PAGE_DECLINE; + else + page->age = 0; +} + +static inline int age_of(unsigned long addr) +{ + return mem_map[MAP_NR(addr)].age; +} + +static inline void set_page_new(unsigned long addr) +{ + mem_map[MAP_NR(addr)].age = PAGE_INITIAL_AGE; +} + +#endif /* __KERNEL */ + +#endif /* _LINUX_SWAPCTL_H */ diff --git a/include/linux/symtab_begin.h b/include/linux/symtab_begin.h index c6f693687..65a87008c 100644 --- a/include/linux/symtab_begin.h +++ b/include/linux/symtab_begin.h @@ -1,16 +1,45 @@ -#ifdef CONFIG_MODVERSIONS /* CONFIG_MODVERSIONS */ -#undef _set_ver -#undef X -#ifndef __GENKSYMS__ -#ifdef MODULE -#define _set_ver(sym,ver) { (void *) & sym ## _R ## ver, "_" #sym "_R" #ver } -#else /* MODULE */ -#define _set_ver(sym,ver) { (void *) & sym, "_" #sym "_R" #ver } -#endif /* MODULE */ -#define X(a) a -#endif /* __GENKSYMS__ */ -#else /* CONFIG_MODVERSIONS */ -#define X(sym) { (void *) & sym, "_" #sym } -#endif /* CONFIG_MODVERSIONS */ +#include <linux/linkage.h> + +#ifdef MODVERSIONS +# undef _set_ver +# undef X +/* + * These two macros _will_ get enough arguments from the X* macros + * since "sym" expands to "symaddr, symstr" from the #define in *.ver + */ +# define _basic_version(symaddr,symstr) symaddr, symstr +# define _alias_version(really,symaddr,symstr) (void *) & really , symstr + +# ifndef __GENKSYMS__ +# ifdef MODULE +# define _set_ver(sym,ver) \ + (void *) & sym ## _R ## ver, SYMBOL_NAME_STR(sym) "_R" #ver +# else /* !MODULE */ +# define _set_ver(sym,ver) \ + (void *) & sym, SYMBOL_NAME_STR(sym) "_R" #ver +# endif /* !MODULE */ +# define X(sym) { _basic_version(sym) } +/* + * For _really_ stacked modules: + * + * Use "Xalias(local_symbol, symbol_from_other_module)" + * to make subsequent modules really use "local_symbol" + * when they think that they are using "symbol_from_other_module" + * + * The "aliasing" module can still use "symbol_from_other_module", + * but can now replace and/or modify the behaviour of that symbol. + */ +# define Xalias(really,sym) { _alias_version(really,sym) } +# endif /* !__GENKSYMS__ */ +#else /* !MODVERSIONS */ +# define X(sym) { (void *) & sym, SYMBOL_NAME_STR(sym)} +# define Xalias(really,sym) { (void *) & really, SYMBOL_NAME_STR(sym)} +#endif /* MODVERSIONS */ +/* + * Some symbols always need to be unversioned. This includes + * compiler generated calls to functions. + */ +#define XNOVERS(sym) { (void *) & sym, SYMBOL_NAME_STR(sym)} + #define EMPTY {0,0} 0, 0, 0, { diff --git a/include/linux/symtab_end.h b/include/linux/symtab_end.h index 4fbd50f99..91b92e298 100644 --- a/include/linux/symtab_end.h +++ b/include/linux/symtab_end.h @@ -1,11 +1,11 @@ -#ifdef CONFIG_MODVERSIONS /* CONFIG_MODVERSIONS */ +#ifdef MODVERSIONS #undef _set_ver #if defined(MODULE) && !defined(__GENKSYMS__) #define _set_ver(sym,vers) sym ## _R ## vers #else #define _set_ver(a,b) a #endif -#endif /* CONFIG_MODVERSIONS */ +#endif /* MODVERSIONS */ #undef X #undef EMPTY /* mark end of table, last entry above ended with a comma! */ diff --git a/include/linux/sys.h b/include/linux/sys.h index 40f9471d0..dcd325668 100644 --- a/include/linux/sys.h +++ b/include/linux/sys.h @@ -27,10 +27,4 @@ * These are system calls that haven't been implemented yet * but have an entry in the table for future expansion.. */ -#ifdef __mips__ -#define sys_quotactl sys_ni_syscall -#else -#define _sys_quotactl _sys_ni_syscall -#endif - #endif diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h new file mode 100644 index 000000000..b16ddb71f --- /dev/null +++ b/include/linux/sysctl.h @@ -0,0 +1,265 @@ +/* + * sysctl.h: General linux system control interface + * + * Begun 24 March 1995, Stephen Tweedie + */ + +#include <linux/lists.h> + +#ifndef _LINUX_SYSCTL_H +#define _LINUX_SYSCTL_H + +#define CTL_MAXNAME 10 + +struct __sysctl_args { + int *name; + int nlen; + void *oldval; + size_t *oldlenp; + void *newval; + size_t newlen; + unsigned long __unused[4]; +}; + +/* Define sysctl names first */ + +/* Top-level names: */ + +/* For internal pattern-matching use only: */ +#ifdef __KERNEL__ +#define CTL_ANY -1 /* Matches any name */ +#define CTL_NONE 0 +#endif + +#define CTL_KERN 1 /* General kernel info and control */ +#define CTL_VM 2 /* VM management */ +#define CTL_NET 3 /* Networking */ +#define CTL_PROC 4 /* Process info */ +#define CTL_FS 5 /* Filesystems */ +#define CTL_DEBUG 6 /* Debugging */ +#define CTL_DEV 7 /* Devices */ +#define CTL_MAXID 8 + +/* CTL_KERN names: */ +#define KERN_OSTYPE 1 /* string: system version */ +#define KERN_OSRELEASE 2 /* string: system release */ +#define KERN_OSREV 3 /* int: system revision */ +#define KERN_VERSION 4 /* string: compile time info */ +#define KERN_SECUREMASK 5 /* struct: maximum rights mask */ +#define KERN_PROF 6 /* table: profiling information */ +#define KERN_NODENAME 7 +#define KERN_DOMAINNAME 8 +#define KERN_NRINODE 9 +#define KERN_MAXINODE 10 +#define KERN_NRFILE 11 +#define KERN_MAXFILE 12 +#define KERN_MAXID 13 +#define KERN_SECURELVL 14 /* int: system security level */ +#define KERN_PANIC 15 /* int: panic timeout */ +#define KERN_REALROOTDEV 16 /* real root device to mount after initrd */ +#define KERN_NFSRNAME 17 /* NFS root name */ +#define KERN_NFSRADDRS 18 /* NFS root addresses */ +#define KERN_JAVA_INTERPRETER 19 /* path to Java(tm) interpreter */ +#define KERN_JAVA_APPLETVIEWER 20 /* path to Java(tm) appletviewer */ + +/* CTL_VM names: */ +#define VM_SWAPCTL 1 /* struct: Set vm swapping control */ +#define VM_KSWAPD 2 /* struct: control background pageout */ +#define VM_FREEPG 3 /* struct: Set free page thresholds */ +#define VM_BDFLUSH 4 /* struct: Control buffer cache flushing */ +#define VM_MAXID 5 + +/* CTL_NET names: */ +#define NET_CORE 1 +#define NET_ETHER 2 +#define NET_802 3 +#define NET_UNIX 4 +#define NET_IPV4 5 +#define NET_IPX 6 +#define NET_ATALK 7 +#define NET_NETROM 8 +#define NET_AX25 9 +#define NET_BRIDGE 10 +#define NET_IPV6 11 +#define NET_ROSE 12 +#define NET_X25 13 + +/* /proc/sys/net/core */ + +/* /proc/sys/net/ethernet */ + +/* /proc/sys/net/802 */ + +/* /proc/sys/net/unix */ + +/* /proc/sys/net/ipv4 */ +#define NET_IPV4_ARP_RES_TIME 1 +#define NET_IPV4_ARP_DEAD_RES_TIME 2 +#define NET_IPV4_ARP_MAX_TRIES 3 +#define NET_IPV4_ARP_TIMEOUT 4 +#define NET_IPV4_ARP_CHECK_INTERVAL 5 +#define NET_IPV4_ARP_CONFIRM_INTERVAL 6 +#define NET_IPV4_ARP_CONFIRM_TIMEOUT 7 +#define NET_IPV4_TCP_VEGAS_CONG_AVOID 8 + +/* /proc/sys/net/ipv6 */ +#define NET_IPV6_FORWARDING 1 +#define NET_IPV6_HOPLIMIT 2 +/* /proc/sys/net/ipx */ + +/* /proc/sys/net/appletalk */ + +/* /proc/sys/net/netrom */ +#define NET_NETROM_DEFAULT_PATH_QUALITY 1 +#define NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER 2 +#define NET_NETROM_NETWORK_TTL_INITIALISER 3 +#define NET_NETROM_TRANSPORT_TIMEOUT 4 +#define NET_NETROM_TRANSPORT_MAXIMUM_TRIES 5 +#define NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY 6 +#define NET_NETROM_TRANSPORT_BUSY_DELAY 7 +#define NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE 8 +#define NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT 9 +#define NET_NETROM_TRANSPORT_PACKET_LENGTH 10 +#define NET_NETROM_ROUTING_CONTROL 11 + +/* /proc/sys/net/ax25 */ +/* Values are generated dynamically */ + +/* /proc/sys/net/rose */ +#define NET_ROSE_RESTART_REQUEST_TIMEOUT 1 +#define NET_ROSE_CALL_REQUEST_TIMEOUT 2 +#define NET_ROSE_RESET_REQUEST_TIMEOUT 3 +#define NET_ROSE_CLEAR_REQUEST_TIMEOUT 4 +#define NET_ROSE_NO_ACTIVITY_TIMEOUT 5 +#define NET_ROSE_ROUTING_CONTROL 6 + +/* /proc/sys/net/x25 */ +#define NET_X25_RESTART_REQUEST_TIMEOUT 1 +#define NET_X25_CALL_REQUEST_TIMEOUT 2 +#define NET_X25_RESET_REQUEST_TIMEOUT 3 +#define NET_X25_CLEAR_REQUEST_TIMEOUT 4 +#define NET_X25_ACK_HOLDBACK_TIMEOUT 5 + +/* CTL_PROC names: */ + +/* CTL_FS names: */ + +/* CTL_DEBUG names: */ + +/* CTL_DEV names: */ + +#ifdef __KERNEL__ + +extern asmlinkage int sys_sysctl(struct __sysctl_args *); +extern void init_sysctl(void); + +typedef struct ctl_table ctl_table; + +typedef int ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, + void **context); + +typedef int proc_handler (ctl_table *ctl, int write, struct file * filp, + void *buffer, size_t *lenp); + +extern int proc_dostring(ctl_table *, int, struct file *, + void *, size_t *); +extern int proc_dointvec(ctl_table *, int, struct file *, + void *, size_t *); +extern int proc_dointvec_minmax(ctl_table *, int, struct file *, + void *, size_t *); + +extern int do_sysctl (int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen); + +extern int do_sysctl_strategy (ctl_table *table, + int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void ** context); + +extern ctl_handler sysctl_string; +extern ctl_handler sysctl_intvec; + +extern int do_string ( + void *oldval, size_t *oldlenp, void *newval, size_t newlen, + int rdwr, char *data, size_t max); +extern int do_int ( + void *oldval, size_t *oldlenp, void *newval, size_t newlen, + int rdwr, int *data); +extern int do_struct ( + void *oldval, size_t *oldlenp, void *newval, size_t newlen, + int rdwr, void *data, size_t len); + + +/* + * Register a set of sysctl names by calling register_sysctl_table + * with an initialised array of ctl_table's. An entry with zero + * ctl_name terminates the table. table->de will be set up by the + * registration and need not be initialised in advance. + * + * sysctl names can be mirrored automatically under /proc/sys. The + * procname supplied controls /proc naming. + * + * The table's mode will be honoured both for sys_sysctl(2) and + * proc-fs access. + * + * Leaf nodes in the sysctl tree will be represented by a single file + * under /proc; non-leaf nodes will be represented by directories. A + * null procname disables /proc mirroring at this node. + * + * sysctl(2) can automatically manage read and write requests through + * the sysctl table. The data and maxlen fields of the ctl_table + * struct enable minimal validation of the values being written to be + * performed, and the mode field allows minimal authentication. + * + * More sophisticated management can be enabled by the provision of a + * strategy routine with the table entry. This will be called before + * any automatic read or write of the data is performed. + * + * The strategy routine may return: + * <0: Error occurred (error is passed to user process) + * 0: OK - proceed with automatic read or write. + * >0: OK - read or write has been done by the strategy routine, so + * return immediately. + * + * There must be a proc_handler routine for any terminal nodes + * mirrored under /proc/sys (non-terminals are handled by a built-in + * directory handler). Several default handlers are available to + * cover common cases. + */ + +/* A sysctl table is an array of struct ctl_table: */ +struct ctl_table +{ + int ctl_name; /* Binary ID */ + const char *procname; /* Text ID for /proc/sys, or zero */ + void *data; + int maxlen; + mode_t mode; + ctl_table *child; + proc_handler *proc_handler; /* Callback for text formatting */ + ctl_handler *strategy; /* Callback function for all r/w */ + struct proc_dir_entry *de; /* /proc control block */ + void *extra1; + void *extra2; +}; + +/* struct ctl_table_header is used to maintain dynamic lists of + ctl_table trees. */ +struct ctl_table_header +{ + ctl_table *ctl_table; + DLNODE(struct ctl_table_header) ctl_entry; +}; + +struct ctl_table_header * register_sysctl_table(ctl_table * table, + int insert_at_head); +void unregister_sysctl_table(struct ctl_table_header * table); + +#else /* __KERNEL__ */ + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_SYSCTL_H */ diff --git a/include/linux/sysv_fs.h b/include/linux/sysv_fs.h index 984be6b1c..7b19dac3c 100644 --- a/include/linux/sysv_fs.h +++ b/include/linux/sysv_fs.h @@ -316,8 +316,6 @@ struct sysv_dir_entry { #define SYSV_DIRSIZE sizeof(struct sysv_dir_entry) /* size of every directory entry */ -#ifdef __KERNEL__ - /* Operations */ /* ========== */ @@ -335,23 +333,25 @@ struct sysv_dir_entry { #define SYSV2_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV2) #define COH_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_COH) +#ifdef __KERNEL__ + /* sv_get_hash_table(sb,dev,block) is equivalent to get_hash_table(dev,block,block_size) */ static inline struct buffer_head * -sv_get_hash_table (struct super_block *sb, int dev, unsigned int block) +sv_get_hash_table (struct super_block *sb, kdev_t dev, unsigned int block) { return get_hash_table (dev, block + sb->sv_block_base, sb->sv_block_size); } /* sv_getblk(sb,dev,block) is equivalent to getblk(dev,block,block_size) */ static inline struct buffer_head * -sv_getblk (struct super_block *sb, int dev, unsigned int block) +sv_getblk (struct super_block *sb, kdev_t dev, unsigned int block) { return getblk (dev, block + sb->sv_block_base, sb->sv_block_size); } /* sv_bread(sb,dev,block) is equivalent to bread(dev,block,block_size) */ static inline struct buffer_head * -sv_bread (struct super_block *sb, int dev, unsigned int block) +sv_bread (struct super_block *sb, kdev_t dev, unsigned int block) { return bread (dev, block + sb->sv_block_base, sb->sv_block_size); } @@ -362,7 +362,7 @@ sv_bread (struct super_block *sb, int dev, unsigned int block) */ extern int sysv_lookup(struct inode * dir,const char * name, int len, - struct inode ** result); + struct inode ** result); extern int sysv_create(struct inode * dir,const char * name, int len, int mode, struct inode ** result); extern int sysv_mkdir(struct inode * dir, const char * name, int len, int mode); @@ -373,7 +373,7 @@ extern int sysv_symlink(struct inode * inode, const char * name, int len, extern int sysv_link(struct inode * oldinode, struct inode * dir, const char * name, int len); extern int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rdev); extern int sysv_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len); + struct inode * new_dir, const char * new_name, int new_len, int must_be_dir); extern struct inode * sysv_new_inode(const struct inode * dir); extern void sysv_free_inode(struct inode * inode); extern unsigned long sysv_count_free_inodes(struct super_block *sb); @@ -385,11 +385,12 @@ extern int sysv_bmap(struct inode *,int); extern struct buffer_head * sysv_getblk(struct inode *, unsigned int, int); extern struct buffer_head * sysv_file_bread(struct inode *, int, int); -extern int sysv_file_read(struct inode *, struct file *, char *, int); +extern long sysv_file_read(struct inode *, struct file *, char *, unsigned long); extern void sysv_truncate(struct inode *); extern void sysv_put_super(struct super_block *); extern struct super_block *sysv_read_super(struct super_block *,void *,int); +extern int init_sysv_fs(void); extern void sysv_write_super(struct super_block *); extern void sysv_read_inode(struct inode *); extern int sysv_notify_change(struct inode *, struct iattr *); diff --git a/include/linux/tasks.h b/include/linux/tasks.h index 050bb3875..4540e34f0 100644 --- a/include/linux/tasks.h +++ b/include/linux/tasks.h @@ -4,6 +4,13 @@ /* * This is the maximum nr of tasks - change it if you need to */ + +#ifdef __SMP__ +#define NR_CPUS 32 /* Max processors that can be running in SMP */ +#else +#define NR_CPUS 1 +#endif + #define NR_TASKS 512 #define MAX_TASKS_PER_USER (NR_TASKS/2) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 7c95e5d02..89e42d849 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -17,16 +17,17 @@ #ifndef _LINUX_TCP_H #define _LINUX_TCP_H +#include <asm/byteorder.h> -#define HEADER_SIZE 128 /* maximum header size */ - +#include <linux/types.h> +#include <asm/byteorder.h> struct tcphdr { __u16 source; __u16 dest; __u32 seq; __u32 ack_seq; -#if defined(LITTLE_ENDIAN_BITFIELD) +#if defined(__LITTLE_ENDIAN_BITFIELD) __u16 res1:4, doff:4, fin:1, @@ -36,7 +37,7 @@ struct tcphdr { ack:1, urg:1, res2:2; -#elif defined(BIG_ENDIAN_BITFIELD) +#elif defined(__BIG_ENDIAN_BITFIELD) __u16 doff:4, res1:4, res2:2, diff --git a/include/linux/termios.h b/include/linux/termios.h index 5a01ae381..478662889 100644 --- a/include/linux/termios.h +++ b/include/linux/termios.h @@ -2,257 +2,6 @@ #define _LINUX_TERMIOS_H #include <linux/types.h> - -/* 0x54 is just a magic number to make these relatively unique ('T') */ - -#define TCGETS 0x5401 -#define TCSETS 0x5402 -#define TCSETSW 0x5403 -#define TCSETSF 0x5404 -#define TCGETA 0x5405 -#define TCSETA 0x5406 -#define TCSETAW 0x5407 -#define TCSETAF 0x5408 -#define TCSBRK 0x5409 -#define TCXONC 0x540A -#define TCFLSH 0x540B -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E -#define TIOCGPGRP 0x540F -#define TIOCSPGRP 0x5410 -#define TIOCOUTQ 0x5411 -#define TIOCSTI 0x5412 -#define TIOCGWINSZ 0x5413 -#define TIOCSWINSZ 0x5414 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define FIONREAD 0x541B -#define TIOCINQ FIONREAD -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 -#define FIONBIO 0x5421 -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ -#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ -#define FIOCLEX 0x5451 -#define FIOASYNC 0x5452 -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 8 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VTIME 5 -#define VMIN 6 -#define VSWTC 7 -#define VSTART 8 -#define VSTOP 9 -#define VSUSP 10 -#define VEOL 11 -#define VREPRINT 12 -#define VDISCARD 13 -#define VWERASE 14 -#define VLNEXT 15 -#define VEOL2 16 - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IUCLC 0001000 -#define IXON 0002000 -#define IXANY 0004000 -#define IXOFF 0010000 -#define IMAXBEL 0020000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define OLCUC 0000002 -#define ONLCR 0000004 -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 -#define OFILL 0000100 -#define OFDEL 0000200 -#define NLDLY 0000400 -#define NL0 0000000 -#define NL1 0000400 -#define CRDLY 0003000 -#define CR0 0000000 -#define CR1 0001000 -#define CR2 0002000 -#define CR3 0003000 -#define TABDLY 0014000 -#define TAB0 0000000 -#define TAB1 0004000 -#define TAB2 0010000 -#define TAB3 0014000 -#define XTABS 0014000 -#define BSDLY 0020000 -#define BS0 0000000 -#define BS1 0020000 -#define VTDLY 0040000 -#define VT0 0000000 -#define VT1 0040000 -#define FFDLY 0100000 -#define FF0 0000000 -#define FF1 0100000 - -/* c_cflag bit meaning */ -#define CBAUD 0010017 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CSIZE 0000060 -#define CS5 0000000 -#define CS6 0000020 -#define CS7 0000040 -#define CS8 0000060 -#define CSTOPB 0000100 -#define CREAD 0000200 -#define PARENB 0000400 -#define PARODD 0001000 -#define HUPCL 0002000 -#define CLOCAL 0004000 -#define CBAUDEX 0010000 -#define B57600 0010001 -#define B115200 0010002 -#define B230400 0010003 -#define CIBAUD 002003600000 /* input baud rate (not used) */ -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0000001 -#define ICANON 0000002 -#define XCASE 0000004 -#define ECHO 0000010 -#define ECHOE 0000020 -#define ECHOK 0000040 -#define ECHONL 0000100 -#define NOFLSH 0000200 -#define TOSTOP 0000400 -#define ECHOCTL 0001000 -#define ECHOPRT 0002000 -#define ECHOKE 0004000 -#define FLUSHO 0010000 -#define PENDIN 0040000 -#define IEXTEN 0100000 - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - - -/* tcflow() and TCXONC use these */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* tcflush() and TCFLSH use these */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* tcsetattr uses these */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -/* line disciplines */ -#define N_TTY 0 -#define N_SLIP 1 -#define N_MOUSE 2 -#define N_PPP 3 +#include <asm/termios.h> #endif diff --git a/include/linux/time.h b/include/linux/time.h index a6ce36c8c..47246a142 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -1,6 +1,14 @@ #ifndef _LINUX_TIME_H #define _LINUX_TIME_H +#ifndef _STRUCT_TIMESPEC +#define _STRUCT_TIMESPEC +struct timespec { + long tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif /* _STRUCT_TIMESPEC */ + struct timeval { int tv_sec; /* seconds */ int tv_usec; /* microseconds */ @@ -15,20 +23,16 @@ struct timezone { #ifdef __KERNEL__ void do_gettimeofday(struct timeval *tv); -#include <asm/bitops.h> -#include <linux/string.h> -#define FD_SETSIZE __FD_SETSIZE -#define FD_SET(fd,fdsetp) set_bit(fd,fdsetp) -#define FD_CLR(fd,fdsetp) clear_bit(fd,fdsetp) -#define FD_ISSET(fd,fdsetp) (0 != test_bit(fd,fdsetp)) -#define FD_ZERO(fdsetp) memset(fdsetp, 0, sizeof(struct fd_set)) -#else +void do_settimeofday(struct timeval *tv); +void get_fast_time(struct timeval *tv); +void (*do_get_fast_time)(struct timeval *); +#endif + #define FD_SETSIZE __FD_SETSIZE #define FD_SET(fd,fdsetp) __FD_SET(fd,fdsetp) #define FD_CLR(fd,fdsetp) __FD_CLR(fd,fdsetp) #define FD_ISSET(fd,fdsetp) __FD_ISSET(fd,fdsetp) #define FD_ZERO(fdsetp) __FD_ZERO(fdsetp) -#endif /* * Names of the interval timers, and structure @@ -38,6 +42,11 @@ void do_gettimeofday(struct timeval *tv); #define ITIMER_VIRTUAL 1 #define ITIMER_PROF 2 +struct itimerspec { + struct timespec it_interval; /* timer period */ + struct timespec it_value; /* timer expiration */ +}; + struct itimerval { struct timeval it_interval; /* timer interval */ struct timeval it_value; /* current value */ diff --git a/include/linux/timer.h b/include/linux/timer.h index acb9ca26e..b922d0dbb 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -14,6 +14,8 @@ * BEEP_TIMER console beep timer * * RS_TIMER timer for the RS-232 ports + * + * SWAP_TIMER timer for the background pageout daemon * * HD_TIMER harddisk timer * @@ -31,11 +33,14 @@ * * MCD_TIMER Mitsumi CD-ROM Timer * + * GSCD_TIMER Goldstar CD-ROM Timer + * */ #define BLANK_TIMER 0 #define BEEP_TIMER 1 #define RS_TIMER 2 +#define SWAP_TIMER 3 #define HD_TIMER 16 #define FLOPPY_TIMER 17 @@ -48,6 +53,9 @@ #define MCD_TIMER 23 #define HD_TIMER2 24 +#define GSCD_TIMER 25 + +#define DIGI_TIMER 29 struct timer_struct { unsigned long expires; @@ -81,6 +89,8 @@ struct timer_list { extern void add_timer(struct timer_list * timer); extern int del_timer(struct timer_list * timer); +extern void it_real_fn(unsigned long); + extern inline void init_timer(struct timer_list * timer) { timer->next = NULL; diff --git a/include/linux/timex.h b/include/linux/timex.h index ce82e020f..ff5420832 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -16,82 +16,161 @@ /* * Modification history timex.h - * + * + * 26 Sep 94 David L. Mills + * Added defines for hybrid phase/frequency-lock loop. + * + * 19 Mar 94 David L. Mills + * Moved defines from kernel routines to header file and added new + * defines for PPS phase-lock loop. + * + * 20 Feb 94 David L. Mills + * Revised status codes and structures for external clock and PPS + * signal discipline. + * + * 28 Nov 93 David L. Mills + * Adjusted parameters to improve stability and increase poll + * interval. + * * 17 Sep 93 David L. Mills * Created file $NTP/include/sys/timex.h * 07 Oct 93 Torsten Duwe * Derived linux/timex.h + * 1995-08-13 Torsten Duwe + * kernel PLL updated to 1994-12-13 specs (rfc-1589) */ #ifndef _LINUX_TIMEX_H #define _LINUX_TIMEX_H /* * The following defines establish the engineering parameters of the PLL - * model. The HZ variable establishes the timer interrupt frequency, 100 Hz + * model. The HZ variable establishes the timer interrupt frequency, 100 Hz * for the SunOS kernel, 256 Hz for the Ultrix kernel and 1024 Hz for the * OSF/1 kernel. The SHIFT_HZ define expresses the same value as the * nearest power of two in order to avoid hardware multiply operations. */ -#define SHIFT_HZ 7 /* log2(HZ) */ +#ifdef __alpha__ +# define SHIFT_HZ 10 /* log2(HZ) */ +#else +# define SHIFT_HZ 7 /* log2(HZ) */ +#endif /* - * The SHIFT_KG and SHIFT_KF defines establish the damping of the PLL - * and are chosen by analysis for a slightly underdamped convergence - * characteristic. The MAXTC define establishes the maximum time constant - * of the PLL. With the parameters given and the default time constant of - * zero, the PLL will converge in about 15 minutes. + * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen + * for a slightly underdamped convergence characteristic. SHIFT_KH + * establishes the damping of the FLL and is chosen by wisdom and black + * art. + * + * MAXTC establishes the maximum time constant of the PLL. With the + * SHIFT_KG and SHIFT_KF values given and a time constant range from + * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours, + * respectively. */ -#define SHIFT_KG 8 /* shift for phase increment */ -#define SHIFT_KF 20 /* shift for frequency increment */ +#define SHIFT_KG 6 /* phase factor (shift) */ +#define SHIFT_KF 16 /* PLL frequency factor (shift) */ +#define SHIFT_KH 2 /* FLL frequency factor (shift) */ #define MAXTC 6 /* maximum time constant (shift) */ /* * The SHIFT_SCALE define establishes the decimal point of the time_phase - * variable which serves as a an extension to the low-order bits of the + * variable which serves as an extension to the low-order bits of the * system clock variable. The SHIFT_UPDATE define establishes the decimal * point of the time_offset variable which represents the current offset * with respect to standard time. The FINEUSEC define represents 1 usec in * scaled units. + * + * SHIFT_USEC defines the scaling (shift) of the time_freq and + * time_tolerance variables, which represent the current frequency + * offset and maximum frequency tolerance. + * + * FINEUSEC is 1 us in SHIFT_UPDATE units of the time_phase variable. */ -#define SHIFT_SCALE 24 /* shift for phase scale factor */ -#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* shift for offset scale factor */ -#define FINEUSEC (1 << SHIFT_SCALE) /* 1 us in scaled units */ +#define SHIFT_SCALE 22 /* phase scale (shift) */ +#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* time offset scale (shift) */ +#define SHIFT_USEC 16 /* frequency offset scale (shift) */ +#define FINEUSEC (1L << SHIFT_SCALE) /* 1 us in phase units */ -#define MAXPHASE 128000 /* max phase error (us) */ -#define MAXFREQ 100 /* max frequency error (ppm) */ -#define MINSEC 16 /* min interval between updates (s) */ -#define MAXSEC 1200 /* max interval between updates (s) */ +#define MAXPHASE 512000L /* max phase error (us) */ +#define MAXFREQ (512L << SHIFT_USEC) /* max frequency error (ppm) */ +#define MAXTIME (200L << PPS_AVG) /* max PPS error (jitter) (200 us) */ +#define MINSEC 16L /* min interval between updates (s) */ +#define MAXSEC 1200L /* max interval between updates (s) */ +/* + * The following defines are used only if a pulse-per-second (PPS) + * signal is available and connected via a modem control lead, such as + * produced by the optional ppsclock feature incorporated in the Sun + * asynch driver. They establish the design parameters of the frequency- + * lock loop used to discipline the CPU clock oscillator to the PPS + * signal. + * + * PPS_AVG is the averaging factor for the frequency loop, as well as + * the time and frequency dispersion. + * + * PPS_SHIFT and PPS_SHIFTMAX specify the minimum and maximum + * calibration intervals, respectively, in seconds as a power of two. + * + * PPS_VALID is the maximum interval before the PPS signal is considered + * invalid and protocol updates used directly instead. + * + * MAXGLITCH is the maximum interval before a time offset of more than + * MAXTIME is believed. + */ +#define PPS_AVG 2 /* pps averaging constant (shift) */ +#define PPS_SHIFT 2 /* min interval duration (s) (shift) */ +#define PPS_SHIFTMAX 8 /* max interval duration (s) (shift) */ +#define PPS_VALID 120 /* pps signal watchdog max (s) */ +#define MAXGLITCH 30 /* pps signal glitch max (s) */ + +#ifndef __alpha__ +/* + * This definitively is wrong for the Alpha and none of the + * kernel code seems to reference this anymore. + */ #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ -#define FINETUNE (((((LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \ +#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \ (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \ << (SHIFT_SCALE-SHIFT_HZ)) / HZ) +#endif /* !__alpha__ */ /* * syscall interface - used (mainly by NTP daemon) * to discipline kernel clock oscillator */ struct timex { - int mode; /* mode selector */ + unsigned int modes; /* mode selector */ long offset; /* time offset (usec) */ - long frequency; /* frequency offset (scaled ppm) */ + long freq; /* frequency offset (scaled ppm) */ long maxerror; /* maximum error (usec) */ long esterror; /* estimated error (usec) */ int status; /* clock command/status */ - long time_constant; /* pll time constant */ + long constant; /* pll time constant */ long precision; /* clock precision (usec) (read only) */ long tolerance; /* clock frequency tolerance (ppm) * (read only) */ struct timeval time; /* (read only) */ long tick; /* (modified) usecs between clock ticks */ + + long ppsfreq; /* pps frequency (scaled ppm) (ro) */ + long jitter; /* pps jitter (us) (ro) */ + int shift; /* interval duration (s) (shift) (ro) */ + long stabil; /* pps stability (scaled ppm) (ro) */ + long jitcnt; /* jitter limit exceeded (ro) */ + long calcnt; /* calibration intervals (ro) */ + long errcnt; /* calibration errors (ro) */ + long stbcnt; /* stability limit exceeded (ro) */ + + int :32; int :32; int :32; int :32; + int :32; int :32; int :32; int :32; + int :32; int :32; int :32; int :32; }; /* - * Mode codes (timex.mode) + * Mode codes (timex.mode) */ #define ADJ_OFFSET 0x0001 /* time offset */ #define ADJ_FREQUENCY 0x0002 /* frequency offset */ @@ -102,18 +181,56 @@ struct timex { #define ADJ_TICK 0x4000 /* tick value */ #define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */ +/* xntp 3.4 compatibility names */ +#define MOD_OFFSET ADJ_OFFSET +#define MOD_FREQUENCY ADJ_FREQUENCY +#define MOD_MAXERROR ADJ_MAXERROR +#define MOD_ESTERROR ADJ_ESTERROR +#define MOD_STATUS ADJ_STATUS +#define MOD_TIMECONST ADJ_TIMECONST +#define MOD_CLKB ADJ_TICK +#define MOD_CLKA ADJ_OFFSET_SINGLESHOT /* 0x8000 in original */ + + +/* + * Status codes (timex.status) + */ +#define STA_PLL 0x0001 /* enable PLL updates (rw) */ +#define STA_PPSFREQ 0x0002 /* enable PPS freq discipline (rw) */ +#define STA_PPSTIME 0x0004 /* enable PPS time discipline (rw) */ +#define STA_FLL 0x0008 /* select frequency-lock mode (rw) */ + +#define STA_INS 0x0010 /* insert leap (rw) */ +#define STA_DEL 0x0020 /* delete leap (rw) */ +#define STA_UNSYNC 0x0040 /* clock unsynchronized (rw) */ +#define STA_FREQHOLD 0x0080 /* hold frequency (rw) */ + +#define STA_PPSSIGNAL 0x0100 /* PPS signal present (ro) */ +#define STA_PPSJITTER 0x0200 /* PPS signal jitter exceeded (ro) */ +#define STA_PPSWANDER 0x0400 /* PPS signal wander exceeded (ro) */ +#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */ + +#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */ + +#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \ + STA_PPSERROR | STA_CLOCKERR) /* read-only bits */ + /* - * Clock command/status codes (timex.status) + * Clock states (time_state) */ -#define TIME_OK 0 /* clock synchronized */ +#define TIME_OK 0 /* clock synchronized, no leap second */ #define TIME_INS 1 /* insert leap second */ #define TIME_DEL 2 /* delete leap second */ #define TIME_OOP 3 /* leap second in progress */ -#define TIME_BAD 4 /* clock not synchronized */ +#define TIME_WAIT 4 /* leap second has occurred */ +#define TIME_ERROR 5 /* clock not synchronized */ +#define TIME_BAD TIME_ERROR /* bw compat */ #ifdef __KERNEL__ /* * kernel variables + * Note: maximum error = NTP synch distance = dispersion + delay / 2; + * estimated error = NTP dispersion. */ extern long tick; /* timer interrupt period */ extern int tickadj; /* amount of adjustment per tick */ @@ -121,19 +238,36 @@ extern int tickadj; /* amount of adjustment per tick */ /* * phase-lock loop variables */ -extern int time_status; /* clock synchronization status */ +extern int time_state; /* clock status */ +extern int time_status; /* clock synchronization status bits */ extern long time_offset; /* time adjustment (us) */ extern long time_constant; /* pll time constant */ extern long time_tolerance; /* frequency tolerance (ppm) */ extern long time_precision; /* clock precision (us) */ extern long time_maxerror; /* maximum error */ extern long time_esterror; /* estimated error */ + extern long time_phase; /* phase offset (scaled us) */ extern long time_freq; /* frequency offset (scaled ppm) */ extern long time_adj; /* tick adjust (scaled 1 / HZ) */ extern long time_reftime; /* time at last adjustment (s) */ extern long time_adjust; /* The amount of adjtime left */ + +/* interface variables pps->timer interrupt */ +extern long pps_offset; /* pps time offset (us) */ +extern long pps_jitter; /* time dispersion (jitter) (us) */ +extern long pps_freq; /* frequency offset (scaled ppm) */ +extern long pps_stabil; /* frequency dispersion (scaled ppm) */ +extern long pps_valid; /* pps signal watchdog counter */ + +/* interface variables pps->adjtimex */ +extern int pps_shift; /* interval duration (s) (shift) */ +extern long pps_jitcnt; /* jitter limit exceeded */ +extern long pps_calcnt; /* calibration intervals */ +extern long pps_errcnt; /* calibration errors */ +extern long pps_stbcnt; /* stability limit exceeded */ + #endif /* KERNEL */ #endif /* LINUX_TIMEX_H */ diff --git a/include/linux/tpqic02.h b/include/linux/tpqic02.h index 8a824f7d0..d25fd465a 100644 --- a/include/linux/tpqic02.h +++ b/include/linux/tpqic02.h @@ -628,34 +628,6 @@ typedef char flag; #define BLOCKS_BEYOND_EW 2 /* nr of blocks after Early Warning hole */ #define BOGUS_IRQ 32009 -/* structure for MTIOCGETCONFIG/MTIOCSETCONFIG primarily intended - * as an interim solution for QIC-02 until DDI is fully implemented. - */ -struct mtconfiginfo { - long mt_type; /* drive type */ - long ifc_type; /* interface card type */ - unsigned short irqnr; /* IRQ number to use */ - unsigned short dmanr; /* DMA channel to use */ - unsigned short port; /* IO port base address */ - - unsigned long debug; /* debugging flags */ - - unsigned have_dens:1; - unsigned have_bsf:1; - unsigned have_fsr:1; - unsigned have_bsr:1; - unsigned have_eod:1; - unsigned have_seek:1; - unsigned have_tell:1; - unsigned have_ras1:1; - unsigned have_ras2:1; - unsigned have_ras3:1; - unsigned have_qfa:1; - - unsigned pad1:5; - char reserved[10]; -}; - /* This is internal data, filled in based on the ifc_type field given * by the user. Everex is mapped to Wangtek with a different @@ -685,7 +657,7 @@ struct qic02_ccb { }; -extern long qic02_tape_init(long); /* for mem.c */ +extern int qic02_tape_init(void); /* for mem.c */ #endif /* CONFIG_QIC02_TAPE */ diff --git a/include/linux/tqueue.h b/include/linux/tqueue.h index a5a15173a..8bd4e7f30 100644 --- a/include/linux/tqueue.h +++ b/include/linux/tqueue.h @@ -16,12 +16,6 @@ #include <asm/bitops.h> #include <asm/system.h> -#ifdef INCLUDE_INLINE_FUNCS -#define _INLINE_ extern -#else -#define _INLINE_ extern __inline__ -#endif - /* * New proposed "bottom half" handlers: * (C) 1994 Kai Petzke, wpp@marie.physik.tu-berlin.de @@ -54,22 +48,15 @@ struct tq_struct { typedef struct tq_struct * task_queue; -#define DECLARE_TASK_QUEUE(q) task_queue q = &tq_last - -extern struct tq_struct tq_last; -extern task_queue tq_timer, tq_immediate, tq_scheduler; +#define DECLARE_TASK_QUEUE(q) task_queue q = NULL -#ifdef INCLUDE_INLINE_FUNCS -struct tq_struct tq_last = { - &tq_last, 0, 0, 0 -}; -#endif +extern task_queue tq_timer, tq_immediate, tq_scheduler, tq_disk; /* * To implement your own list of active bottom halfs, use the following * two definitions: * - * struct tq_struct *my_bh = &tq_last; + * struct tq_struct *my_bh = NULL; * struct tq_struct run_my_bh = { * 0, 0, (void *)(void *) run_task_queue, &my_bh * }; @@ -92,7 +79,7 @@ struct tq_struct tq_last = { * "bh_list". You may call this function only from an interrupt * handler or a bottom half handler. */ -_INLINE_ void queue_task_irq(struct tq_struct *bh_pointer, +extern __inline__ void queue_task_irq(struct tq_struct *bh_pointer, task_queue *bh_list) { if (!set_bit(0,&bh_pointer->sync)) { @@ -105,7 +92,7 @@ _INLINE_ void queue_task_irq(struct tq_struct *bh_pointer, * queue_task_irq_off: put the bottom half handler "bh_pointer" on the list * "bh_list". You may call this function only when interrupts are off. */ -_INLINE_ void queue_task_irq_off(struct tq_struct *bh_pointer, +extern __inline__ void queue_task_irq_off(struct tq_struct *bh_pointer, task_queue *bh_list) { if (!(bh_pointer->sync & 1)) { @@ -119,7 +106,7 @@ _INLINE_ void queue_task_irq_off(struct tq_struct *bh_pointer, /* * queue_task: as queue_task_irq, but can be called from anywhere. */ -_INLINE_ void queue_task(struct tq_struct *bh_pointer, +extern __inline__ void queue_task(struct tq_struct *bh_pointer, task_queue *bh_list) { if (!set_bit(0,&bh_pointer->sync)) { @@ -135,29 +122,22 @@ _INLINE_ void queue_task(struct tq_struct *bh_pointer, /* * Call all "bottom halfs" on a given list. */ -_INLINE_ void run_task_queue(task_queue *list) +extern __inline__ void run_task_queue(task_queue *list) { - register struct tq_struct *save_p; - register struct tq_struct *p; - void *arg; - void (*f) (void *); - - while(1) { - p = xchg_ptr(list,&tq_last); - if(p == &tq_last) - break; - - do { - arg = p -> data; - f = p -> routine; - save_p = p -> next; - p -> sync = 0; - (*f)(arg); - p = save_p; - } while(p != &tq_last); + struct tq_struct *p; + + p = xchg(list,NULL); + while (p) { + void *arg; + void (*f) (void *); + struct tq_struct *save_p; + arg = p -> data; + f = p -> routine; + save_p = p; + p = p -> next; + save_p -> sync = 0; + (*f)(arg); } } -#undef _INLINE_ - #endif /* _LINUX_TQUEUE_H */ diff --git a/include/linux/trdevice.h b/include/linux/trdevice.h index f2e09fa98..96801763d 100644 --- a/include/linux/trdevice.h +++ b/include/linux/trdevice.h @@ -28,10 +28,9 @@ #include <linux/if_tr.h> #ifdef __KERNEL__ -extern int tr_header(unsigned char *buff, struct device *dev, +extern int tr_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, - void *saddr, unsigned len, - struct sk_buff *skb); + void *saddr, unsigned len); extern int tr_rebuild_header(void *buff, struct device *dev, unsigned long raddr, struct sk_buff *skb); extern unsigned short tr_type_trans(struct sk_buff *skb, struct device *dev); diff --git a/include/linux/tty.h b/include/linux/tty.h index d3761847c..c965cd287 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -5,6 +5,16 @@ * 'tty.h' defines some structures used by tty_io.c and some defines. */ +/* + * These constants are also useful for user-level apps (e.g., VC + * resizing). + */ +#define MIN_NR_CONSOLES 1 /* must be at least 1 */ +#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */ +#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */ + /* Note: the ioctl VT_GETSTATE does not work for + consoles 16 and higher (since it returns a short) */ + #ifdef __KERNEL__ #include <linux/fs.h> #include <linux/termios.h> @@ -21,12 +31,7 @@ * (Note: the *_driver.minor_start values 1, 64, 128, 192 are * hardcoded at present.) */ -#define MIN_NR_CONSOLES 1 /* must be at least 1 */ -#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */ -#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */ - /* Note: the ioctl VT_GETSTATE does not work for - consoles 16 and higher (since it returns a short) */ -#define NR_PTYS 64 +#define NR_PTYS 256 #define NR_LDISCS 16 /* @@ -40,30 +45,38 @@ struct screen_info { unsigned short orig_video_page; unsigned char orig_video_mode; unsigned char orig_video_cols; - unsigned short orig_video_ega_ax; + unsigned short unused2; unsigned short orig_video_ega_bx; - unsigned short orig_video_ega_cx; + unsigned short unused3; unsigned char orig_video_lines; + unsigned char orig_video_isVGA; + unsigned short orig_video_points; }; extern struct screen_info screen_info; #define ORIG_X (screen_info.orig_x) #define ORIG_Y (screen_info.orig_y) -#define ORIG_VIDEO_PAGE (screen_info.orig_video_page) #define ORIG_VIDEO_MODE (screen_info.orig_video_mode) #define ORIG_VIDEO_COLS (screen_info.orig_video_cols) -#define ORIG_VIDEO_EGA_AX (screen_info.orig_video_ega_ax) #define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx) -#define ORIG_VIDEO_EGA_CX (screen_info.orig_video_ega_cx) #define ORIG_VIDEO_LINES (screen_info.orig_video_lines) +#define ORIG_VIDEO_ISVGA (screen_info.orig_video_isVGA) +#define ORIG_VIDEO_POINTS (screen_info.orig_video_points) #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ #define VIDEO_TYPE_CGA 0x11 /* CGA Display */ #define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */ +#define VIDEO_TYPE_EGAC 0x21 /* EGA in Color Mode */ +#define VIDEO_TYPE_VGAC 0x22 /* VGA+ in Color Mode */ #define VIDEO_TYPE_EGAC 0x21 /* EGA/VGA in Color Mode */ #define VIDEO_TYPE_PICA_S3 0x30 /* ACER PICA-61 local S3 video */ -#define VIDEO_TYPE_MIPS_G364 0x31 /* MIPS Magnum 4000 G364 video */ +#define VIDEO_TYPE_MIPS_G364 0x31 /* MIPS Magnum 4000 G364 video */ +#define VIDEO_TYPE_SNI_RM 0x31 /* SNI RM200 PCI video */ + +#define VIDEO_TYPE_TGAC 0x40 /* DEC TGA */ + +#define VIDEO_TYPE_SUN 0x50 /* Sun frame buffer. */ /* * This character is the same as _POSIX_VDISABLE: it cannot be used as @@ -200,7 +213,7 @@ struct tty_struct { struct termios *termios, *termios_locked; int pgrp; int session; - dev_t device; + kdev_t device; unsigned long flags; int count; struct winsize winsize; @@ -252,12 +265,14 @@ struct tty_struct { */ #define TTY_THROTTLED 0 #define TTY_IO_ERROR 1 -#define TTY_SLAVE_CLOSED 2 +#define TTY_OTHER_CLOSED 2 #define TTY_EXCLUSIVE 3 #define TTY_DEBUG 4 #define TTY_DO_WRITE_WAKEUP 5 #define TTY_PUSH 6 #define TTY_CLOSING 7 +#define TTY_HW_COOK_OUT 14 +#define TTY_HW_COOK_IN 15 #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) @@ -266,28 +281,25 @@ extern void tty_write_flush(struct tty_struct *); extern struct termios tty_std_termios; extern struct tty_struct * redirect; extern struct tty_ldisc ldiscs[]; -extern int fg_console; +extern int fg_console, last_console, want_console; + +extern int kmsg_redirect; extern struct wait_queue * keypress_wait; -/* intr=^C quit=^| erase=del kill=^U - eof=^D vtime=\0 vmin=\1 sxtc=\0 - start=^Q stop=^S susp=^Z eol=\0 - reprint=^R discard=^U werase=^W lnext=^V - eol2=\0 -*/ -#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" - -extern long rs_init(long); -extern long lp_init(long); -extern long con_init(long); -extern long pty_init(long); -extern long tty_init(long); -extern long vcs_init(long); -#ifdef CONFIG_CYCLADES -extern long cy_init(long); -#endif +extern unsigned long con_init(unsigned long); + +extern int rs_init(void); +extern int lp_init(void); +extern int pty_init(void); +extern int tty_init(void); +extern int pcxe_init(void); +extern int vcs_init(void); +extern int cy_init(void); +extern int stl_init(void); +extern int stli_init(void); +extern int riscom8_init(void); -extern int tty_paranoia_check(struct tty_struct *tty, dev_t device, +extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device, const char *routine); extern char *_tty_name(struct tty_struct *tty, char *buf); extern char *tty_name(struct tty_struct *tty); @@ -300,6 +312,7 @@ extern int tty_register_driver(struct tty_driver *driver); extern int tty_unregister_driver(struct tty_driver *driver); extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen); +extern void tty_write_message(struct tty_struct *tty, char *msg); extern int is_orphaned_pgrp(int pgrp); extern int is_ignored(int sig); @@ -325,11 +338,13 @@ extern int rs_open(struct tty_struct * tty, struct file * filp); /* pty.c */ extern int pty_open(struct tty_struct * tty, struct file * filp); +extern int pcxe_open(struct tty_struct *tty, struct file *filp); /* console.c */ extern int con_open(struct tty_struct * tty, struct file * filp); extern void update_screen(int new_console); +extern void console_print(const char *); /* vt.c */ diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 6008f6343..244122047 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -18,7 +18,7 @@ * This routine is called when a particular tty device is closed. * * int (*write)(struct tty_struct * tty, int from_user, - * unsigned char *buf, int count); + * const unsigned char *buf, int count); * * This routine is called by the kernel to write a series of * characters to the tty device. The characters may come from @@ -91,14 +91,23 @@ * * This routine notifies the tty driver that it should hangup the * tty device. + * + * void (*wait_until_sent)(struct tty_struct *tty, int timeout); * + * This routine waits until the device has written out all of the + * characters in its transmitter FIFO. + * + * void (*send_xchar)(struct tty_struct *tty, char ch); + * + * This routine is used to send a high-priority XON/XOFF + * character to the device. */ #include <linux/fs.h> struct tty_driver { int magic; /* magic number for this structure */ - char *name; + const char *name; int name_base; /* offset of printed name */ short major; /* major device number */ short minor_start; /* start of minor device number*/ @@ -124,7 +133,7 @@ struct tty_driver { int (*open)(struct tty_struct * tty, struct file * filp); void (*close)(struct tty_struct * tty, struct file * filp); int (*write)(struct tty_struct * tty, int from_user, - unsigned char *buf, int count); + const unsigned char *buf, int count); void (*put_char)(struct tty_struct *tty, unsigned char ch); void (*flush_chars)(struct tty_struct *tty); int (*write_room)(struct tty_struct *tty); @@ -139,6 +148,8 @@ struct tty_driver { void (*hangup)(struct tty_struct *tty); void (*flush_buffer)(struct tty_struct *tty); void (*set_ldisc)(struct tty_struct *tty); + void (*wait_until_sent)(struct tty_struct *tty, int timeout); + void (*send_xchar)(struct tty_struct *tty, char ch); /* * linked list pointers diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 732f5a115..05a33261d 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -2,7 +2,100 @@ #define _LINUX_TTY_LDISC_H /* - * Definitions for the tty line discipline + * This structure defines the interface between the tty line discpline + * implementation and the tty routines. The following routines can be + * defined; unless noted otherwise, they are optional, and can be + * filled in with a null pointer. + * + * int (*open)(struct tty_struct *); + * + * This function is called when the line discpline is associated + * with the tty. The line discpline can use this as an + * opportunity to initialize any state needed by the ldisc routines. + * + * void (*close)(struct tty_struct *); + * + * This function is called when the line discpline is being + * shutdown, either because the tty is being closed or because + * the tty is being changed to use a new line discpline + * + * void (*flush_buffer)(struct tty_struct *tty); + * + * This function instructs the line discipline to clear its + * buffers of any input characters it may have queued to be + * delivered to the user mode process. + * + * int (*chars_in_buffer)(struct tty_struct *tty); + * + * This function returns the number of input characters the line + * iscpline may have queued up to be delivered to the user mode + * process. + * + * int (*read)(struct tty_struct * tty, struct file * file, + * unsigned char * buf, unsigned int nr); + * + * This function is called when the user requests to read from + * the tty. The line discpline will return whatever characters + * it has buffered up for the user. If this function is not + * defined, the user will receive an EIO error. + * + * int (*write)(struct tty_struct * tty, struct file * file, + * const unsigned char * buf, unsigned int nr); + * + * This function is called when the user requests to write to the + * tty. The line discpline will deliver the characters to the + * low-level tty device for transmission, optionally performing + * some processing on the characters first. If this function is + * not defined, the user will receive an EIO error. + * + * int (*ioctl)(struct tty_struct * tty, struct file * file, + * unsigned int cmd, unsigned long arg); + * + * This function is called when the user requests an ioctl which + * is not handled by the tty layer or the low-level tty driver. + * It is intended for ioctls which affect line discpline + * operation. Not that the search order for ioctls is (1) tty + * layer, (2) tty low-level driver, (3) line discpline. So a + * low-level driver can "grab" an ioctl request before the line + * discpline has a chance to see it. + * + * void (*set_termios)(struct tty_struct *tty, struct termios * old); + * + * This function notifies the line discpline that a change has + * been made to the termios stucture. + * + * int (*select)(struct tty_struct * tty, struct inode * inode, + * struct file * file, int sel_type, + * struct select_table_struct *wait); + * + * This function is called when a user attempts to select on a + * tty device. It is solely the responsibility of the line + * discipline to handle select requests. + * + * void (*receive_buf)(struct tty_struct *, const unsigned char *cp, + * char *fp, int count); + * + * This function is called by the low-level tty driver to send + * characters received by the hardware to the line discpline for + * processing. <cp> is a pointer to the buffer of input + * character received by the device. <fp> is a pointer to a + * pointer of flag bytes which indicate whether a character was + * received with a parity error, etc. + * + * int (*receive_room)(struct tty_struct *); + * + * This function is called by the low-level tty driver to + * determine how many characters the line discpline can accept. + * The low-level driver must not send more characters than was + * indicated by receive_room, or the line discpline may drop + * those characters. + * + * void (*write_wakeup)(struct tty_struct *); + * + * This function is called by the low-level tty driver to signal + * that line discpline should try to send more characters to the + * low-level driver for transmission. If the line discpline does + * not have any more data to send, it can just return. */ #include <linux/fs.h> @@ -22,7 +115,7 @@ struct tty_ldisc { int (*read)(struct tty_struct * tty, struct file * file, unsigned char * buf, unsigned int nr); int (*write)(struct tty_struct * tty, struct file * file, - unsigned char * buf, unsigned int nr); + const unsigned char * buf, unsigned int nr); int (*ioctl)(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg); void (*set_termios)(struct tty_struct *tty, struct termios * old); @@ -33,7 +126,7 @@ struct tty_ldisc { /* * The following routines are called from below. */ - void (*receive_buf)(struct tty_struct *, unsigned char *cp, + void (*receive_buf)(struct tty_struct *, const unsigned char *cp, char *fp, int count); int (*receive_room)(struct tty_struct *); void (*write_wakeup)(struct tty_struct *); diff --git a/include/linux/types.h b/include/linux/types.h index a06f4020d..7f98711a4 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -1,73 +1,85 @@ #ifndef _LINUX_TYPES_H #define _LINUX_TYPES_H +#include <linux/posix_types.h> #include <asm/types.h> -#ifndef NULL -#define NULL ((void *) 0) -#endif +#ifndef __KERNEL_STRICT_NAMES + +typedef __kernel_fd_set fd_set; +typedef __kernel_dev_t dev_t; +typedef __kernel_ino_t ino_t; +typedef __kernel_mode_t mode_t; +typedef __kernel_nlink_t nlink_t; +typedef __kernel_off_t off_t; +typedef __kernel_pid_t pid_t; +typedef __kernel_uid_t uid_t; +typedef __kernel_gid_t gid_t; +typedef __kernel_daddr_t daddr_t; +typedef __kernel_key_t key_t; #if defined(__GNUC__) && !defined(__STRICT_ANSI__) -#define _LOFF_T -typedef long long loff_t; +typedef __kernel_loff_t loff_t; #endif -/* bsd */ -typedef unsigned char u_char; -typedef unsigned short u_short; -typedef unsigned int u_int; -typedef unsigned long u_long; +/* + * The following typedefs are also protected by individual ifdefs for + * historical reasons: + */ +#ifndef _SIZE_T +#define _SIZE_T +typedef __kernel_size_t size_t; +#endif -/* sysv */ -typedef unsigned char unchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __kernel_ssize_t ssize_t; +#endif -typedef char *caddr_t; +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef __kernel_ptrdiff_t ptrdiff_t; +#endif -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; +#ifndef _TIME_T +#define _TIME_T +typedef __kernel_time_t time_t; +#endif -/* - * This allows for 256 file descriptors: if NR_OPEN is ever grown beyond that - * you'll have to change this too. But 256 fd's seem to be enough even for such - * "real" unices like SunOS, so hopefully this is one limit that doesn't have - * to be changed. - * - * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in <sys/time.h> - * (and thus <linux/time.h>) - but this is a more logical place for them. Solved - * by having dummy defines in <sys/time.h>. - */ +#ifndef _CLOCK_T +#define _CLOCK_T +typedef __kernel_clock_t clock_t; +#endif -/* - * Those macros may have been defined in <gnu/types.h>. But we always - * use the ones here. - */ -#undef __FDSET_LONGS -#define __FDSET_LONGS 8 +#ifndef _CADDR_T +#define _CADDR_T +typedef __kernel_caddr_t caddr_t; +#endif -typedef struct fd_set { - unsigned long fds_bits [__FDSET_LONGS]; -} fd_set; +/* bsd */ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; -#undef __NFDBITS -#define __NFDBITS (8 * sizeof(unsigned long)) +/* sysv */ +typedef unsigned char unchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; -#undef __FD_SETSIZE -#define __FD_SETSIZE (__FDSET_LONGS*__NFDBITS) +#endif /* __KERNEL_STRICT_NAMES */ /* - * Include machine dependent assembler stuff + * Below are truly Linux-specific types that should never collide with + * any application/library that wants linux/types.h. */ -#include <asm/types.h> struct ustat { - daddr_t f_tfree; - ino_t f_tinode; - char f_fname[6]; - char f_fpack[6]; + __kernel_daddr_t f_tfree; + __kernel_ino_t f_tinode; + char f_fname[6]; + char f_fpack[6]; }; -#endif +#endif /* _LINUX_TYPES_H */ diff --git a/include/linux/ucdrom.h b/include/linux/ucdrom.h new file mode 100644 index 000000000..6cf5c05b3 --- /dev/null +++ b/include/linux/ucdrom.h @@ -0,0 +1,114 @@ +/* ucdrom.h. Uniform cdrom data structures for cdrom.c. -*- linux-c -*- + Copyright (c) 1996 David van Leeuwen. + */ + +#ifndef LINUX_UCDROM_H +#define LINUX_UCDROM_H + +#ifdef __KERNEL__ +struct cdrom_device_info { + struct cdrom_device_ops *ops; /* link to device_ops */ + struct cdrom_device_info *next; /* next device_info for this major */ + void *handle; /* driver-dependent data */ +/* specifications */ + kdev_t dev; /* device number */ + int mask; /* mask of capability: disables them */ + int speed; /* maximum speed for reading data */ + int capacity; /* number of discs in jukebox */ +/* device-related storage */ + int options : 30; /* options flags */ + unsigned mc_flags : 2; /* media change buffer flags */ + int use_count; /* number of times device opened */ +}; + +struct cdrom_device_ops { +/* routines */ + int (*open) (struct cdrom_device_info *, int); + void (*release) (struct cdrom_device_info *); + int (*drive_status) (struct cdrom_device_info *, int); + int (*disc_status) (struct cdrom_device_info *); + int (*media_changed) (struct cdrom_device_info *, int); + int (*tray_move) (struct cdrom_device_info *, int); + int (*lock_door) (struct cdrom_device_info *, int); + int (*select_speed) (struct cdrom_device_info *, int); + int (*select_disc) (struct cdrom_device_info *, int); + int (*get_last_session) (struct cdrom_device_info *, + struct cdrom_multisession *); + int (*get_mcn) (struct cdrom_device_info *, + struct cdrom_mcn *); + /* hard reset device */ + int (*reset) (struct cdrom_device_info *); + /* play stuff */ + int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *); + /* dev-specific */ + int (*dev_ioctl) (struct cdrom_device_info *, + unsigned int, unsigned long); +/* driver specifications */ + const int capability; /* capability flags */ + int n_minors; /* number of active minor devices */ +}; +#endif + +/* capability flags */ +#define CDC_CLOSE_TRAY 0x1 /* caddy systems _can't_ close */ +#define CDC_OPEN_TRAY 0x2 /* but _can_ eject. */ +#define CDC_LOCK 0x4 /* disable manual eject */ +#define CDC_SELECT_SPEED 0x8 /* programmable speed */ +#define CDC_SELECT_DISC 0x10 /* select disc from juke-box */ +#define CDC_MULTI_SESSION 0x20 /* read sessions>1 */ +#define CDC_MCN 0x40 /* Medium Catalog Number */ +#define CDC_MEDIA_CHANGED 0x80 /* media changed */ +#define CDC_PLAY_AUDIO 0x100 /* audio functions */ + +/* drive status possibilities */ +#define CDS_NO_INFO 0 /* if not implemented */ +#define CDS_NO_DISC 1 +#define CDS_TRAY_OPEN 2 +#define CDS_DRIVE_NOT_READY 3 +#define CDS_DISC_OK 4 + +/* disc status possibilities, other than CDS_NO_DISC */ +#define CDS_AUDIO 100 +#define CDS_DATA_1 101 +#define CDS_DATA_2 102 +#define CDS_XA_2_1 103 +#define CDS_XA_2_2 104 + +/* User-configurable behavior options */ +#define CDO_AUTO_CLOSE 0x1 /* close tray on first open() */ +#define CDO_AUTO_EJECT 0x2 /* open tray on last release() */ +#define CDO_USE_FFLAGS 0x4 /* use O_NONBLOCK information on open */ +#define CDO_LOCK 0x8 /* lock tray on open files */ +#define CDO_CHECK_TYPE 0x10 /* check type on open for data */ + +/* Special codes for specifying changer slots. */ +#define CDSL_NONE ((int) (~0U>>1)-1) +#define CDSL_CURRENT ((int) (~0U>>1)) + +/* Some more ioctls to control these options */ +#define CDROM_SET_OPTIONS 0x5320 +#define CDROM_CLEAR_OPTIONS 0x5321 +#define CDROM_SELECT_SPEED 0x5322 /* head-speed */ +#define CDROM_SELECT_DISC 0x5323 /* for juke-boxes */ +#define CDROM_MEDIA_CHANGED 0x5325 +#define CDROM_DRIVE_STATUS 0x5326 /* tray position, etc. */ +#define CDROM_DISC_STATUS 0x5327 /* disc type etc. */ +#define CDROM_CHANGER_NSLOTS 0x5328 + +/* Rename an old ioctl */ +#define CDROM_GET_MCN CDROM_GET_UPC /* medium catalog number */ + +#ifdef __KERNEL__ +/* the general file operations structure: */ +extern struct file_operations cdrom_fops; + +extern int register_cdrom(struct cdrom_device_info *cdi, char *name); +extern int unregister_cdrom(struct cdrom_device_info *cdi); +#endif + +#endif /* LINUX_UCDROM_H */ +/* + * Local variables: + * comment-column: 40 + * End: + */ diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h new file mode 100644 index 000000000..af856645d --- /dev/null +++ b/include/linux/ufs_fs.h @@ -0,0 +1,270 @@ +/* + * linux/include/linux/ufs_fs.h + * + * Copyright (C) 1996 + * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu) + * Laboratory for Computer Science Research Computing Facility + * Rutgers, The State University of New Jersey + * + * $Id: ufs_fs.h,v 1.7 1996/08/13 19:27:59 ecd Exp $ + * + */ + +#ifndef __LINUX_UFS_FS_H +#define __LINUX_UFS_FS_H + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/time.h> +#include <linux/stat.h> + +#define UFS_BBLOCK 0 +#define UFS_BBSIZE 8192 +#define UFS_SBLOCK 8192 +#define UFS_SBSIZE 8192 + +#define UFS_MAGIC 0x00011954 + +#define UFS_FSIZE 1024 +#define UFS_BSIZE 8192 + +#define UFS_NDADDR 12 +#define UFS_NINDIR 3 + +#define UFS_IND_BLOCK (UFS_NDADDR + 0) +#define UFS_DIND_BLOCK (UFS_NDADDR + 1) +#define UFS_TIND_BLOCK (UFS_NDADDR + 2) + +#define UFS_ROOTINO 2 + +#define UFS_USEEFT ((__u16)65535) + +#define UFS_FSOK 0x7c269d38 +#define UFS_FSACTIVE ((char)0x00) +#define UFS_FSCLEAN ((char)0x01) +#define UFS_FSSTABLE ((char)0x02) +#define UFS_FSBAD ((char)0xff) + +/* Flags for ufs_sb_info */ +#define UFS_DEBUG 0x00000001 +#define UFS_DEBUG_INODE 0x00000002 +#define UFS_DEBUG_NAMEI 0x00000004 +#define UFS_DEBUG_LINKS 0x00000008 + +#define UFS_ADDR_PER_BLOCK(sb) ((sb)->u.ufs_sb.s_bsize >> 2) +#define UFS_ADDR_PER_BLOCK_BITS(sb) ((sb)->u.ufs_sb.s_bshift - 2) + +/* Test if the inode number is valid. */ +#define ufs_ino_ok(inode) ((inode->i_ino < 2) && \ + (inode->i_ino > (inode->i_sb->u.ufs_sb.s_ncg * inode->i_sb->u.ufs_sb.s_ipg - 1))) + +/* Convert (sb,cg) to the first physical block number for that cg. */ +#define ufs_cgstart(sb, cg) \ + (((sb)->u.ufs_sb.s_fpg * (cg)) + (sb)->u.ufs_sb.s_cgoffset * ((cg) & ~((sb)->u.ufs_sb.s_cgmask))) + +/* Convert (sb,cg) to the first phys. block number for inodes in that cg. */ +#define ufs_cgimin(sb, cg) (ufs_cgstart((sb), (cg)) + (sb)->u.ufs_sb.s_iblkno) +#define ufs_cgdmin(sb, cg) (ufs_cgstart((sb), (cg)) + (sb)->u.ufs_sb.s_dblkno) + +/* Convert an inode number to a cg number. */ +/* XXX - this can be optimized if s_ipg is a power of 2. */ +#define ufs_ino2cg(inode) ((inode)->i_ino/(inode)->i_sb->u.ufs_sb.s_ipg) + +#define UFS_MAXNAMLEN 255 + +#define ufs_lbn(sb, block) ((block) >> (sb)->u.ufs_sb.s_lshift) +#define ufs_boff(sb, block) ((block) & ~((sb)->u.ufs_sb.s_lmask)) +#define ufs_dbn(sb, block, boff) ((block) + ufs_boff((sb), (boff))) + +struct ufs_direct { + __u32 d_ino; /* inode number of this entry */ + __u16 d_reclen; /* length of this entry */ + __u16 d_namlen; /* actual length of d_name */ + char d_name[UFS_MAXNAMLEN + 1]; /* file name */ +}; + +#define MAXMNTLEN 512 +#define MAXCSBUFS 32 + +struct ufs_csum { + __u32 cs_ndir; /* number of directories */ + __u32 cs_nbfree; /* number of free blocks */ + __u32 cs_nifree; /* number of free inodes */ + __u32 cs_nffree; /* number of free frags */ +}; + +typedef struct _ufsquad { + __u32 val[2]; +} ufsquad; + +/* + * This is the actual superblock, as it is laid out on the disk. + */ +struct ufs_superblock { + __u32 fs_link; /* UNUSED */ + __u32 fs_rlink; /* UNUSED */ + __u32 fs_sblkno; /* addr of super-block in filesys */ + __u32 fs_cblkno; /* offset of cyl-block in filesys */ + __u32 fs_iblkno; /* offset of inode-blocks in filesys */ + __u32 fs_dblkno; /* offset of first data after cg */ + __u32 fs_cgoffset; /* cylinder group offset in cylinder */ + __u32 fs_cgmask; /* used to calc mod fs_ntrak */ + time_t fs_time; /* last time written */ + __u32 fs_size; /* number of blocks in fs */ + __u32 fs_dsize; /* number of data blocks in fs */ + __u32 fs_ncg; /* number of cylinder groups */ + __u32 fs_bsize; /* size of basic blocks in fs */ + __u32 fs_fsize; /* size of frag blocks in fs */ + __u32 fs_frag; /* number of frags in a block in fs */ +/* these are configuration parameters */ + __u32 fs_minfree; /* minimum percentage of free blocks */ + __u32 fs_rotdelay; /* num of ms for optimal next block */ + __u32 fs_rps; /* disk revolutions per second */ +/* these fields can be computed from the others */ + __u32 fs_bmask; /* ``blkoff'' calc of blk offsets */ + __u32 fs_fmask; /* ``fragoff'' calc of frag offsets */ + __u32 fs_bshift; /* ``lblkno'' calc of logical blkno */ + __u32 fs_fshift; /* ``numfrags'' calc number of frags */ +/* these are configuration parameters */ + __u32 fs_maxcontig; /* max number of contiguous blks */ + __u32 fs_maxbpg; /* max number of blks per cyl group */ +/* these fields can be computed from the others */ + __u32 fs_fragshift; /* block to frag shift */ + __u32 fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ + __u32 fs_sbsize; /* actual size of super block */ + __u32 fs_csmask; /* csum block offset */ + __u32 fs_csshift; /* csum block number */ + __u32 fs_nindir; /* value of NINDIR */ + __u32 fs_inopb; /* value of INOPB */ + __u32 fs_nspf; /* value of NSPF */ +/* yet another configuration parameter */ + __u32 fs_optim; /* optimization preference, see below */ +/* these fields are derived from the hardware */ + __u32 fs_npsect; /* # sectors/track including spares */ + __u32 fs_interleave; /* hardware sector interleave */ + __u32 fs_trackskew; /* sector 0 skew, per track */ +/* a unique id for this filesystem (currently unused and unmaintained) */ +/* In 4.3 Tahoe this space is used by fs_headswitch and fs_trkseek */ +/* Neither of those fields is used in the Tahoe code right now but */ +/* there could be problems if they are. */ + __u32 fs_id[2]; /* file system id */ +/* sizes determined by number of cylinder groups and their sizes */ + __u32 fs_csaddr; /* blk addr of cyl grp summary area */ + __u32 fs_cssize; /* size of cyl grp summary area */ + __u32 fs_cgsize; /* cylinder group size */ +/* these fields are derived from the hardware */ + __u32 fs_ntrak; /* tracks per cylinder */ + __u32 fs_nsect; /* sectors per track */ + __u32 fs_spc; /* sectors per cylinder */ +/* this comes from the disk driver partitioning */ + __u32 fs_ncyl; /* cylinders in file system */ +/* these fields can be computed from the others */ + __u32 fs_cpg; /* cylinders per group */ + __u32 fs_ipg; /* inodes per group */ + __u32 fs_fpg; /* blocks per group * fs_frag */ +/* this data must be re-computed after crashes */ + struct ufs_csum fs_cstotal; /* cylinder summary information */ +/* these fields are cleared at mount time */ + __u8 fs_fmod; /* super block modified flag */ + __u8 fs_clean; /* file system is clean flag */ + __u8 fs_ronly; /* mounted read-only flag */ + __u8 fs_flags; /* currently unused flag */ + __u8 fs_fsmnt[MAXMNTLEN]; /* name mounted on */ +/* these fields retain the current block allocation info */ + __u32 fs_cgrotor; /* last cg searched */ + struct ufs_csum * fs_csp[MAXCSBUFS]; /* list of fs_cs info buffers */ + __u32 fs_cpc; /* cyl per cycle in postbl */ + __u16 fs_opostbl[16][8]; /* old rotation block list head */ + __s32 fs_sparecon[55]; /* reserved for future constants */ + __s32 fs_state; /* file system state time stamp */ + ufsquad fs_qbmask; /* ~usb_bmask - for use with __s64 size */ + ufsquad fs_qfmask; /* ~usb_fmask - for use with __s64 size */ + __s32 fs_postblformat; /* format of positional layout tables */ + __s32 fs_nrpos; /* number of rotational positions */ + __s32 fs_postbloff; /* (__s16) rotation block list head */ + __s32 fs_rotbloff; /* (__u8) blocks for each rotation */ + __s32 fs_magic; /* magic number */ + __u8 fs_space[1]; /* list of blocks for each rotation */ + +}; + +/* + * structure of an on-disk inode + */ +struct ufs_inode { + __u16 ui_mode; /* 0x0 */ + __u16 ui_nlink; /* 0x2 */ + __u16 ui_suid; /* 0x4 */ + __u16 ui_sgid; /* 0x6 */ + ufsquad ui_size; /* 0x8 */ /* XXX - should be __u64 */ + struct timeval ui_atime; /* 0x10 */ + struct timeval ui_mtime; /* 0x18 */ + struct timeval ui_ctime; /* 0x20 */ + __u32 ui_db[UFS_NDADDR]; /* 0x28 data blocks */ + __u32 ui_ib[UFS_NINDIR]; /* 0x58 indirect blocks */ + __u32 ui_flags; /* 0x64 unused */ + __u32 ui_blocks; /* 0x68 blocks in use */ + __u32 ui_gen; /* 0x6c generation number XXX - what is this? */ + __u32 ui_shadow; /* 0x70 shadow inode XXX - what is this?*/ + __u32 ui_uid; /* 0x74 long EFT version of uid */ + __u32 ui_gid; /* 0x78 long EFT version of gid */ + __u32 ui_oeftflag; /* 0x7c reserved */ +}; + + +#ifdef __KERNEL__ +/* + * Function prototypes + */ + +/* ufs_inode.c */ +extern int ufs_bmap (struct inode *, int); +extern void ufs_read_inode(struct inode * inode); +extern void ufs_put_inode(struct inode * inode); + +extern void ufs_print_inode (struct inode *); + +/* ufs_namei.c */ +extern int ufs_lookup (struct inode *, const char *, int, struct inode **); + +/* ufs_super.c */ +extern void ufs_warning (struct super_block *, const char *, const char *, ...) + __attribute__ ((format (printf, 3, 4))); +extern int init_ufs_fs(void); + +/* + * Inodes and files operations + */ + +/* ufs_dir.c */ +extern struct inode_operations ufs_dir_inode_operations; +extern struct file_operations ufs_dir_operations; + +/* ufs_file.c */ +extern struct inode_operations ufs_file_inode_operations; +extern struct file_operations ufs_file_operations; + +/* ufs_symlink.c */ +extern struct inode_operations ufs_symlink_inode_operations; +extern struct file_operations ufs_symlink_operations; + +/* Byte swapping 32/16-bit quantities into little endian format. */ +extern int ufs_need_swab; + +extern __inline__ __u32 ufs_swab32(__u32 value) +{ + return (ufs_need_swab ? ((value >> 24) | + ((value >> 8) & 0xff00) | + ((value << 8) & 0xff0000) | + (value << 24)) : value); +} + +extern __inline__ __u16 ufs_swab16(__u16 value) +{ + return (ufs_need_swab ? ((value >> 8) | + (value << 8)) : value); +} + +#endif /* __KERNEL__ */ + +#endif /* __LINUX_UFS_FS_H */ diff --git a/include/linux/ufs_fs_i.h b/include/linux/ufs_fs_i.h new file mode 100644 index 000000000..f10b36d91 --- /dev/null +++ b/include/linux/ufs_fs_i.h @@ -0,0 +1,27 @@ +/* + * linux/include/linux/ufs_fs_i.h + * + * Copyright (C) 1996 + * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu) + * Laboratory for Computer Science Research Computing Facility + * Rutgers, The State University of New Jersey + * + * $Id: ufs_fs_i.h,v 1.2 1996/05/03 04:02:25 davem Exp $ + * + */ + +#ifndef _LINUX_UFS_FS_I_H +#define _LINUX_UFS_FS_I_H + +struct ufs_inode_info { + __u32 i_data[15]; + __u64 i_size; + __u32 i_flags; + __u32 i_gen; + __u32 i_shadow; + __u32 i_uid; + __u32 i_gid; + __u32 i_oeftflag; +}; + +#endif /* _LINUX_UFS_FS_I_H */ diff --git a/include/linux/ufs_fs_sb.h b/include/linux/ufs_fs_sb.h new file mode 100644 index 000000000..da56276a2 --- /dev/null +++ b/include/linux/ufs_fs_sb.h @@ -0,0 +1,40 @@ +/* + * linux/include/linux/ufs_fs_sb.h + * + * Copyright (C) 1996 + * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu) + * Laboratory for Computer Science Research Computing Facility + * Rutgers, The State University of New Jersey + * + * $Id: ufs_fs_sb.h,v 1.6 1996/06/01 15:31:08 ecd Exp $ + * + */ + +#ifndef __LINUX_UFS_FS_SB_H +#define __LINUX_UFS_FS_SB_H + +#include <linux/ufs_fs.h> + +struct ufs_sb_info { + struct ufs_superblock * s_raw_sb; + __u32 s_flags; /* internal flags for UFS code */ + __u32 s_ncg; /* used in ufs_read_inode */ + __u32 s_ipg; /* used in ufs_read_inode */ + __u32 s_fpg; + __u32 s_fsize; + __u32 s_fshift; + __u32 s_fmask; + __u32 s_bsize; + __u32 s_bmask; + __u32 s_bshift; + __u32 s_iblkno; + __u32 s_dblkno; + __u32 s_cgoffset; + __u32 s_cgmask; + __u32 s_inopb; + __u32 s_lshift; + __u32 s_lmask; + __u32 s_fsfrag; +}; + +#endif /* __LINUX_UFS_FS_SB_H */ diff --git a/include/linux/uio.h b/include/linux/uio.h new file mode 100644 index 000000000..5fbc2f7f1 --- /dev/null +++ b/include/linux/uio.h @@ -0,0 +1,30 @@ +#ifndef __LINUX_UIO_H +#define __LINUX_UIO_H + +/* + * Berkeley style UIO structures - Alan Cox 1994. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + + +/* A word of warning: Our uio structure will clash with the C library one (which is now obsolete). Remove the C + library one from sys/uio.h if you have a very old library set */ + +struct iovec +{ + void *iov_base; /* BSD uses caddr_t (1003.1g requires void *) */ + size_t iov_len; /* Must be size_t (1003.1g) */ +}; + +/* + * UIO_MAXIOV shall be at least 16 1003.1g (5.4.1.1) + */ + +#define UIO_MAXIOV 16 /* Maximum iovec's in one operation + 16 matches BSD */ + +#endif diff --git a/include/linux/ultrasound.h b/include/linux/ultrasound.h index 5571ca08d..9021ae919 100644 --- a/include/linux/ultrasound.h +++ b/include/linux/ultrasound.h @@ -1,36 +1,18 @@ #ifndef _ULTRASOUND_H_ #define _ULTRASOUND_H_ /* - * Copyright by Hannu Savolainen 1993 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/* * ultrasound.h - Macros for programming the Gravis Ultrasound * These macros are extremely device dependent * and not portable. */ +/* + * Copyright (C) by Hannu Savolainen 1993-1996 + * + * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) + * Version 2 (June 1991). See the "COPYING" file distributed with this software + * for more info. + */ + /* * Private events for Gravis Ultrasound (GUS) @@ -52,7 +34,7 @@ * _GUS_VOICEOFF - Stops voice (no parameters) * _GUS_VOICEFADE - Stops the voice smoothly. * _GUS_VOICEMODE - Alters the voice mode, don't start or stop voice (P1=voice mode) - * _GUS_VOICEBALA - Sets voice balance (P1, 0=left, 7=middle and 15=right, default 7) + * _GUS_VOICEBALA - Sets voice balence (P1, 0=left, 7=middle and 15=right, default 7) * _GUS_VOICEFREQ - Sets voice (sample) playback frequency (P1=Hz) * _GUS_VOICEVOL - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off) * _GUS_VOICEVOL2 - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off) diff --git a/include/linux/umsdos_fs.h b/include/linux/umsdos_fs.h index 170761a5e..b25f0c31e 100644 --- a/include/linux/umsdos_fs.h +++ b/include/linux/umsdos_fs.h @@ -16,6 +16,9 @@ #ifndef _LINUX_DIRENT_H #include <linux/dirent.h> #endif +#ifndef _LINUX_IOCTL_H +#include <linux/ioctl.h> +#endif struct umsdos_fake_info { char fname[13]; @@ -70,19 +73,19 @@ struct umsdos_info{ /* The next ioctl commands operate only on the DOS directory */ /* The file umsdos_progs/umsdosio.c contain a string table */ /* based on the order of those definition. Keep it in sync */ -#define UMSDOS_READDIR_DOS 1234 /* Do a readdir of the DOS directory */ -#define UMSDOS_UNLINK_DOS 1235 /* Erase in the DOS directory only */ -#define UMSDOS_RMDIR_DOS 1236 /* rmdir in the DOS directory only */ -#define UMSDOS_STAT_DOS 1237 /* Get info about a file */ +#define UMSDOS_READDIR_DOS _IO(0x04,210) /* Do a readdir of the DOS directory */ +#define UMSDOS_UNLINK_DOS _IO(0x04,211) /* Erase in the DOS directory only */ +#define UMSDOS_RMDIR_DOS _IO(0x04,212) /* rmdir in the DOS directory only */ +#define UMSDOS_STAT_DOS _IO(0x04,213) /* Get info about a file */ /* The next ioctl commands operate only on the EMD file */ -#define UMSDOS_CREAT_EMD 1238 /* Create a file */ -#define UMSDOS_UNLINK_EMD 1239 /* unlink (rmdir) a file */ -#define UMSDOS_READDIR_EMD 1240 /* read the EMD file only. */ -#define UMSDOS_GETVERSION 1241 /* Get the release number of UMSDOS */ -#define UMSDOS_INIT_EMD 1242 /* Create the EMD file if not there */ -#define UMSDOS_DOS_SETUP 1243 /* Set the defaults of the MsDOS driver */ - -#define UMSDOS_RENAME_DOS 1244 /* rename a file/directory in the DOS */ +#define UMSDOS_CREAT_EMD _IO(0x04,214) /* Create a file */ +#define UMSDOS_UNLINK_EMD _IO(0x04,215) /* unlink (rmdir) a file */ +#define UMSDOS_READDIR_EMD _IO(0x04,216) /* read the EMD file only. */ +#define UMSDOS_GETVERSION _IO(0x04,217) /* Get the release number of UMSDOS */ +#define UMSDOS_INIT_EMD _IO(0x04,218) /* Create the EMD file if not there */ +#define UMSDOS_DOS_SETUP _IO(0x04,219) /* Set the defaults of the MsDOS driver */ + +#define UMSDOS_RENAME_DOS _IO(0x04,220) /* rename a file/directory in the DOS */ /* directory only */ struct umsdos_ioctl{ struct dirent dos_dirent; @@ -133,6 +136,7 @@ extern struct file_operations umsdos_file_operations; extern struct inode_operations umsdos_file_inode_operations; extern struct inode_operations umsdos_file_inode_operations_no_bmap; extern struct inode_operations umsdos_symlink_inode_operations; +extern int init_umsdos_fs(void); #include <linux/umsdos_fs.p> diff --git a/include/linux/umsdos_fs.p b/include/linux/umsdos_fs.p index a89ae6e22..333f9940f 100644 --- a/include/linux/umsdos_fs.p +++ b/include/linux/umsdos_fs.p @@ -1,10 +1,10 @@ -/* check.c 30/01/95 22.05.32 */ +/* check.c 23/01/95 03.38.30 */ void check_page_tables (void); -/* dir.c 18/03/95 00.30.50 */ -int UMSDOS_dir_read (struct inode *inode, +/* dir.c 22/06/95 00.22.12 */ +long UMSDOS_dir_read (struct inode *inode, struct file *filp, char *buf, - int count); + unsigned long count); void umsdos_lookup_patch (struct inode *dir, struct inode *inode, struct umsdos_dirent *entry, @@ -19,27 +19,23 @@ int UMSDOS_lookup (struct inode *dir, int len, struct inode **result); int umsdos_hlink2inode (struct inode *hlink, struct inode **result); -/* emd.c 30/01/95 22.05.32 */ -int umsdos_readdir_kmem (struct inode *inode, - struct file *filp, - struct dirent *dirent, - int count); -int umsdos_file_read_kmem (struct inode *inode, +/* emd.c 22/06/95 00.22.04 */ +long umsdos_file_read_kmem (struct inode *inode, struct file *filp, char *buf, - int count); -int umsdos_file_write_kmem (struct inode *inode, + unsigned long count); +long umsdos_file_write_kmem (struct inode *inode, struct file *filp, - char *buf, - int count); -int umsdos_emd_dir_write (struct inode *emd_dir, + const char *buf, + unsigned long count); +long umsdos_emd_dir_write (struct inode *emd_dir, struct file *filp, char *buf, - int count); -int umsdos_emd_dir_read (struct inode *emd_dir, + unsigned long count); +long umsdos_emd_dir_read (struct inode *emd_dir, struct file *filp, char *buf, - int count); + unsigned long count); struct inode *umsdos_emd_dir_lookup (struct inode *dir, int creat); int umsdos_emd_dir_readentry (struct inode *emd_dir, struct file *filp, @@ -57,11 +53,13 @@ int umsdos_isempty (struct inode *dir); int umsdos_findentry (struct inode *dir, struct umsdos_info *info, int expect); -/* file.c 30/01/95 22.05.56 */ -/* inode.c 25/02/95 09.21.46 */ +/* file.c 25/01/95 02.25.38 */ +/* inode.c 12/06/95 09.49.40 */ void UMSDOS_put_inode (struct inode *inode); void UMSDOS_put_super (struct super_block *sb); -void UMSDOS_statfs (struct super_block *sb, struct statfs *buf, int); +void UMSDOS_statfs (struct super_block *sb, + struct statfs *buf, + int bufsiz); int umsdos_real_lookup (struct inode *dir, const char *name, int len, @@ -81,16 +79,16 @@ int UMSDOS_notify_change (struct inode *inode, struct iattr *attr); struct super_block *UMSDOS_read_super (struct super_block *s, void *data, int silent); -/* ioctl.c 21/02/95 20.58.22 */ +/* ioctl.c 22/06/95 00.22.08 */ int UMSDOS_ioctl_dir (struct inode *dir, struct file *filp, unsigned int cmd, unsigned long data); -/* mangle.c 30/01/95 22.05.56 */ +/* mangle.c 25/01/95 02.25.38 */ void umsdos_manglename (struct umsdos_info *info); int umsdos_evalrecsize (int len); int umsdos_parse (const char *fname, int len, struct umsdos_info *info); -/* namei.c 30/01/95 22.05.56 */ +/* namei.c 25/01/95 02.25.38 */ void umsdos_lockcreate (struct inode *dir); void umsdos_startlookup (struct inode *dir); void umsdos_unlockcreate (struct inode *dir); @@ -124,8 +122,9 @@ int UMSDOS_rename (struct inode *old_dir, int old_len, struct inode *new_dir, const char *new_name, - int new_len); -/* rdir.c 18/03/95 00.30.18 */ + int new_len, + int must_be_dir); +/* rdir.c 22/03/95 03.31.42 */ int umsdos_rlookup_x (struct inode *dir, const char *name, int len, @@ -135,4 +134,4 @@ int UMSDOS_rlookup (struct inode *dir, const char *name, int len, struct inode **result); -/* symlink.c 30/01/95 22.05.32 */ +/* symlink.c 23/01/95 03.38.30 */ diff --git a/include/linux/un.h b/include/linux/un.h index e11ad75fe..45561c564 100644 --- a/include/linux/un.h +++ b/include/linux/un.h @@ -4,7 +4,7 @@ #define UNIX_PATH_MAX 108 struct sockaddr_un { - unsigned short sun_family; /* AF_UNIX */ + sa_family_t sun_family; /* AF_UNIX */ char sun_path[UNIX_PATH_MAX]; /* pathname */ }; diff --git a/include/linux/unistd.h b/include/linux/unistd.h index 0ec2184f6..10ed9834b 100644 --- a/include/linux/unistd.h +++ b/include/linux/unistd.h @@ -1,158 +1,6 @@ #ifndef _LINUX_UNISTD_H_ #define _LINUX_UNISTD_H_ -/* - * This file contains the system call numbers. - */ - -#define __NR_setup 0 /* used only by init, to get system going */ -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_chown 16 -#define __NR_break 17 -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -#define __NR_stty 31 -#define __NR_gtty 32 -#define __NR_access 33 -#define __NR_nice 34 -#define __NR_ftime 35 -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_prof 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_phys 52 -#define __NR_lock 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_mpx 56 -#define __NR_setpgid 57 -#define __NR_ulimit 58 -#define __NR_oldolduname 59 -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_profil 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_ioperm 101 -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -#define __NR_olduname 109 -#define __NR_iopl 110 -#define __NR_vhangup 111 -#define __NR_idle 112 -#define __NR_vm86 113 -#define __NR_wait4 114 -#define __NR_swapoff 115 -#define __NR_sysinfo 116 -#define __NR_ipc 117 -#define __NR_fsync 118 -#define __NR_sigreturn 119 -#define __NR_clone 120 -#define __NR_setdomainname 121 -#define __NR_uname 122 -#define __NR_modify_ldt 123 -#define __NR_adjtimex 124 -#define __NR_mprotect 125 -#define __NR_sigprocmask 126 -#define __NR_create_module 127 -#define __NR_init_module 128 -#define __NR_delete_module 129 -#define __NR_get_kernel_syms 130 -#define __NR_quotactl 131 -#define __NR_getpgid 132 -#define __NR_fchdir 133 -#define __NR_bdflush 134 -#define __NR_sysfs 135 -#define __NR_personality 136 -#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#define __NR__llseek 140 -#define __NR_getdents 141 -#define __NR__newselect 142 -#define __NR_flock 143 -/* This one hasn't been assigned officially! Code that relies - on it deserves to die ... */ -#define __NR__cacheflush 144 - extern int errno; /* diff --git a/include/linux/user.h b/include/linux/user.h index 3fbee19e4..68daf840f 100644 --- a/include/linux/user.h +++ b/include/linux/user.h @@ -1,77 +1 @@ -#ifndef _LINUX_USER_H -#define _LINUX_USER_H - -#include <linux/ptrace.h> -/* Core file format: The core file is written in such a way that gdb - can understand it and provide useful information to the user (under - linux we use the 'trad-core' bfd). There are quite a number of - obstacles to being able to view the contents of the floating point - registers, and until these are solved you will not be able to view the - contents of them. Actually, you can read in the core file and look at - the contents of the user struct to find out what the floating point - registers contain. - The actual file contents are as follows: - UPAGE: 1 page consisting of a user struct that tells gdb what is present - in the file. Directly after this is a copy of the task_struct, which - is currently not used by gdb, but it may come in useful at some point. - All of the registers are stored as part of the upage. The upage should - always be only one page. - DATA: The data area is stored. We use current->end_text to - current->brk to pick up all of the user variables, plus any memory - that may have been malloced. No attempt is made to determine if a page - is demand-zero or if a page is totally unused, we just cover the entire - range. All of the addresses are rounded in such a way that an integral - number of pages is written. - STACK: We need the stack information in order to get a meaningful - backtrace. We need to write the data from (esp) to - current->start_stack, so we round each of these off in order to be able - to write an integer number of pages. - The minimum core file size is 3 pages, or 12288 bytes. -*/ - -struct user_i387_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ -}; - -/* When the kernel dumps core, it starts by dumping the user struct - - this will be used by gdb to figure out where the data and stack segments - are within the file, and what virtual addresses to use. */ -struct user{ -/* We start with the registers, to mimic the way that "memory" is returned - from the ptrace(3,...) function. */ - struct pt_regs regs; /* Where the registers are actually stored */ -/* ptrace does not yet supply these. Someday.... */ - int u_fpvalid; /* True if math co-processor being used. */ - /* for this mess. Not yet used. */ - struct user_i387_struct i387; /* Math Co-processor registers. */ -/* The rest of this junk is to help gdb figure out what goes where */ - unsigned long int u_tsize; /* Text segment size (pages). */ - unsigned long int u_dsize; /* Data segment size (pages). */ - unsigned long int u_ssize; /* Stack segment size (pages). */ - unsigned long start_code; /* Starting virtual address of text. */ - unsigned long start_stack; /* Starting virtual address of stack area. - This is actually the bottom of the stack, - the top of the stack is always found in the - esp register. */ - long int signal; /* Signal that caused the core dump. */ - int reserved; /* No longer used */ - struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ - /* the registers. */ - struct user_i387_struct* u_fpstate; /* Math Co-processor pointer. */ - unsigned long magic; /* To uniquely identify a core file */ - char u_comm[32]; /* User command that was responsible */ - int u_debugreg[8]; -}; -#define NBPG 4096 -#define UPAGES 1 -#define HOST_TEXT_START_ADDR (u.start_code) -#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) - -#endif +#include <asm/user.h> diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h new file mode 100644 index 000000000..7fc973198 --- /dev/null +++ b/include/linux/vmalloc.h @@ -0,0 +1,32 @@ +#ifndef __LINUX_VMALLOC_H +#define __LINUX_VMALLOC_H + +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/pgtable.h> + +struct vm_struct { + unsigned long flags; + void * addr; + unsigned long size; + struct vm_struct * next; +}; + +struct vm_struct * get_vm_area(unsigned long size); +void vfree(void * addr); +void * vmalloc(unsigned long size); +int vread(char *buf, char *addr, int count); + +extern inline void set_pgdir(unsigned long address, pgd_t entry) +{ + struct task_struct * p; + + for_each_task(p) { + if (!p->mm) + continue; + *pgd_offset(p->mm,address) = entry; + } +} + +#endif diff --git a/include/linux/vt.h b/include/linux/vt.h index 33f1ad659..9f95b0bea 100644 --- a/include/linux/vt.h +++ b/include/linux/vt.h @@ -19,9 +19,9 @@ struct vt_mode { #define VT_ACKACQ 0x02 /* acknowledge switch */ struct vt_stat { - ushort v_active; /* active vt */ - ushort v_signal; /* signal to send */ - ushort v_state; /* vt bitmask */ + unsigned short v_active; /* active vt */ + unsigned short v_signal; /* signal to send */ + unsigned short v_state; /* vt bitmask */ }; #define VT_GETSTATE 0x5603 /* get global vt state info */ #define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */ @@ -33,10 +33,22 @@ struct vt_stat { #define VT_DISALLOCATE 0x5608 /* free memory associated to vt */ struct vt_sizes { - ushort v_rows; /* number of rows */ - ushort v_cols; /* number of columns */ - ushort v_scrollsize; /* number of lines of scrollback */ + unsigned short v_rows; /* number of rows */ + unsigned short v_cols; /* number of columns */ + unsigned short v_scrollsize; /* number of lines of scrollback */ }; #define VT_RESIZE 0x5609 /* set kernel's idea of screensize */ +struct vt_consize { + unsigned short v_rows; /* number of rows */ + unsigned short v_cols; /* number of columns */ + unsigned short v_vlin; /* number of pixel rows on screen */ + unsigned short v_clin; /* number of pixel rows per character */ + unsigned short v_vcol; /* number of pixel columns on screen */ + unsigned short v_ccol; /* number of pixel columns per character */ +}; +#define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */ +#define VT_LOCKSWITCH 0x560B /* disallow vt switching */ +#define VT_UNLOCKSWITCH 0x560C /* allow vt switching */ + #endif /* _LINUX_VT_H */ diff --git a/include/linux/wait.h b/include/linux/wait.h index 90ffe7b3b..be24fa242 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -8,18 +8,25 @@ #ifdef __KERNEL__ +#include <asm/page.h> + struct wait_queue { struct task_struct * task; struct wait_queue * next; }; -struct semaphore { - int count; - struct wait_queue * wait; -}; +#define WAIT_QUEUE_HEAD(x) ((struct wait_queue *)((x)-1)) + +static inline void init_waitqueue(struct wait_queue **q) +{ + *q = WAIT_QUEUE_HEAD(q); +} -#define MUTEX ((struct semaphore) { 1, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { 0, NULL }) +static inline int waitqueue_active(struct wait_queue **q) +{ + struct wait_queue *head = *q; + return head && head != WAIT_QUEUE_HEAD(q); +} struct select_table_entry { struct wait_queue wait; @@ -27,11 +34,11 @@ struct select_table_entry { }; typedef struct select_table_struct { - int nr; + unsigned int nr; struct select_table_entry * entry; } select_table; -#define __MAX_SELECT_TABLE_ENTRIES (4096 / sizeof (struct select_table_entry)) +#define __MAX_SELECT_TABLE_ENTRIES (PAGE_SIZE / sizeof (struct select_table_entry)) #endif /* __KERNEL__ */ diff --git a/include/linux/wrapper.h b/include/linux/wrapper.h new file mode 100644 index 000000000..13de8d4ae --- /dev/null +++ b/include/linux/wrapper.h @@ -0,0 +1,40 @@ +#ifndef _WRAPPER_H_ +#define _WRAPPER_H_ +#define wait_handle struct wait_queue +#define file_handle struct file +#define inode_handle struct inode +#define select_table_handle select_table +#define vm_area_handle struct vm_area_struct +#define file_operation_handle file_operations + +#define connect_wrapper(x) 0 +#define current_got_fatal_signal() (current->signal & ~current->blocked) +#define current_set_timeout(val) current->timeout = val + +#define module_interruptible_sleep_on interruptible_sleep_on +#define module_wake_up wake_up +#define module_select_wait select_wait +#define module_register_chrdev register_chrdev +#define module_unregister_chrdev unregister_chrdev +#define module_register_blkdev register_blkdev +#define module_unregister_blkdev unregister_blkdev + +#define inode_get_rdev(i) i->i_rdev +#define inode_get_count(i) i->i_count +#define inode_inc_count(i) i->i_count++ +#define inode_dec_count(i) i->i_count-- + +#define file_get_flags(f) f->f_flags + +#define vma_set_inode(v,i) v->vm_inode = i +#define vma_get_flags(v) v->vm_flags +#define vma_get_offset(v) v->vm_offset +#define vma_get_start(v) v->vm_start +#define vma_get_end(v) v->vm_end +#define vma_get_page_prot(v) v->vm_page_prot + +#define mem_map_reserve(p) set_bit(PG_reserved, &mem_map[p].flags) +#define mem_map_unreserve(p) clear_bit(PG_reserved, &mem_map[p].flags) +#define mem_map_inc_count(p) mem_map[p].count++ +#define mem_map_dec_count(p) mem_map[p].count-- +#endif diff --git a/include/linux/xd.h b/include/linux/xd.h deleted file mode 100644 index 6daf3e951..000000000 --- a/include/linux/xd.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef _LINUX_XD_H -#define _LINUX_XD_H - -/* - * This file contains the definitions for the IO ports and errors etc. for XT hard disk controllers (at least the DTC 5150X). - * - * Author: Pat Mackinlay, pat@it.com.au - * Date: 29/09/92 - * - * Revised: 01/01/93, ... - * - * Ref: DTC 5150X Controller Specification (thanks to Kevin Fowler, kevinf@agora.rain.com) - * Also thanks to: Salvador Abreu, Dave Thaler, Risto Kankkunen and Wim Van Dorst. - */ - -/* XT hard disk controller registers */ -#define XD_DATA (xd_iobase + 0x00) /* data RW register */ -#define XD_RESET (xd_iobase + 0x01) /* reset WO register */ -#define XD_STATUS (xd_iobase + 0x01) /* status RO register */ -#define XD_SELECT (xd_iobase + 0x02) /* select WO register */ -#define XD_JUMPER (xd_iobase + 0x02) /* jumper RO register */ -#define XD_CONTROL (xd_iobase + 0x03) /* DMAE/INTE WO register */ -#define XD_RESERVED (xd_iobase + 0x03) /* reserved */ - -/* XT hard disk controller commands (incomplete list) */ -#define CMD_TESTREADY 0x00 /* test drive ready */ -#define CMD_RECALIBRATE 0x01 /* recalibrate drive */ -#define CMD_SENSE 0x03 /* request sense */ -#define CMD_FORMATDRV 0x04 /* format drive */ -#define CMD_VERIFY 0x05 /* read verify */ -#define CMD_FORMATTRK 0x06 /* format track */ -#define CMD_FORMATBAD 0x07 /* format bad track */ -#define CMD_READ 0x08 /* read */ -#define CMD_WRITE 0x0A /* write */ -#define CMD_SEEK 0x0B /* seek */ - -/* Controller specific commands */ -#define CMD_DTCSETPARAM 0x0C /* set drive parameters (DTC 5150X only?) */ -#define CMD_DTCGETECC 0x0D /* get ecc error length (DTC 5150X only?) */ -#define CMD_DTCREADBUF 0x0E /* read sector buffer (DTC 5150X only?) */ -#define CMD_DTCWRITEBUF 0x0F /* write sector buffer (DTC 5150X only?) */ -#define CMD_DTCREMAPTRK 0x11 /* assign alternate track (DTC 5150X only?) */ -#define CMD_DTCGETPARAM 0xFB /* get drive parameters (DTC 5150X only?) */ -#define CMD_DTCSETSTEP 0xFC /* set step rate (DTC 5150X only?) */ -#define CMD_DTCSETGEOM 0xFE /* set geometry data (DTC 5150X only?) */ -#define CMD_DTCGETGEOM 0xFF /* get geometry data (DTC 5150X only?) */ -#define CMD_ST11GETGEOM 0xF8 /* get geometry data (Seagate ST11R/M only?) */ -#define CMD_WDSETPARAM 0x0C /* set drive parameters (WD 1004A27X only?) */ - -/* Bits for command status byte */ -#define CSB_ERROR 0x02 /* error */ -#define CSB_LUN 0x20 /* logical Unit Number */ - -/* XT hard disk controller status bits */ -#define STAT_READY 0x01 /* controller is ready */ -#define STAT_INPUT 0x02 /* data flowing from controller to host */ -#define STAT_COMMAND 0x04 /* controller in command phase */ -#define STAT_SELECT 0x08 /* controller is selected */ -#define STAT_REQUEST 0x10 /* controller requesting data */ -#define STAT_INTERRUPT 0x20 /* controller requesting interrupt */ - -/* XT hard disk controller control bits */ -#define PIO_MODE 0x00 /* control bits to set for PIO */ -#define DMA_MODE 0x03 /* control bits to set for DMA & interrupt */ - -#define XD_MAXDRIVES 2 /* maximum 2 drives */ -#define XD_TIMEOUT 100 /* 1 second timeout */ -#define XD_RETRIES 4 /* maximum 4 retries */ - -#undef DEBUG /* define for debugging output */ - -#ifdef DEBUG - #define DEBUG_STARTUP /* debug driver initialisation */ - #define DEBUG_OVERRIDE /* debug override geometry detection */ - #define DEBUG_READWRITE /* debug each read/write command */ - #define DEBUG_OTHER /* debug misc. interrupt/DMA stuff */ - #define DEBUG_COMMAND /* debug each controller command */ -#endif /* DEBUG */ - -/* this structure defines the XT drives and their types */ -typedef struct { - u_char heads; - u_short cylinders; - u_char sectors; - u_char control; -} XD_INFO; - -#define HDIO_GETGEO 0x0301 /* get drive geometry */ - -/* this structure is returned to the HDIO_GETGEO ioctl */ -typedef struct { - u_char heads; - u_char sectors; - u_short cylinders; - u_long start; -} XD_GEOMETRY; - -/* this structure defines a ROM BIOS signature */ -typedef struct { - u_long offset; - char *string; - void (*init_controller)(u_char *address); - void (*init_drive)(u_char drive); - char *name; -} XD_SIGNATURE; - -u_long xd_init (u_long mem_start,u_long mem_end); -void xd_setup (char *command,int *integers); -static u_char xd_detect (u_char *controller,u_char **address); -static u_char xd_initdrives (void (*init_drive)(u_char drive)); -static void xd_geninit (void); - -static int xd_open (struct inode *inode,struct file *file); -static void do_xd_request (void); -static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg); -static void xd_release (struct inode *inode,struct file *file); -static int xd_reread_partitions (int dev); -static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count); -static void xd_recalibrate (u_char drive); - -static void xd_interrupt_handler (int irq, struct pt_regs * regs); -static u_char xd_setup_dma (u_char opcode,u_char *buffer,u_int count); -static u_char *xd_build (u_char *cmdblk,u_char command,u_char drive,u_char head,u_short cylinder,u_char sector,u_char count,u_char control); -static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout); -static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout); - -/* card specific setup and geometry gathering code */ -static void xd_dtc_init_controller (u_char *address); -static void xd_dtc_init_drive (u_char drive); -static void xd_wd_init_controller (u_char *address); -static void xd_wd_init_drive (u_char drive); -static void xd_seagate_init_controller (u_char *address); -static void xd_seagate_init_drive (u_char drive); -static void xd_omti_init_controller (u_char *address); -static void xd_omti_init_drive (u_char drive); -static void xd_setparam (u_char command,u_char drive,u_char heads,u_short cylinders,u_short rwrite,u_short wprecomp,u_char ecc); -static void xd_override_init_drive (u_char drive); - -#endif /* _LINUX_XD_H */ diff --git a/include/linux/xia_fs.h b/include/linux/xia_fs.h index 908360976..84015a2bf 100644 --- a/include/linux/xia_fs.h +++ b/include/linux/xia_fs.h @@ -79,7 +79,8 @@ extern int xiafs_mknod(struct inode * dir, const char * name, int len, int mode, int rdev); extern int xiafs_rename(struct inode * old_dir, const char * old_name, int old_len, struct inode * new_dir, - const char * new_name, int new_len); + const char * new_name, int new_len, + int must_be_dir); extern struct inode * xiafs_new_inode(struct inode * dir); extern void xiafs_free_inode(struct inode * inode); extern unsigned long xiafs_count_free_inodes(struct super_block *sb); @@ -95,6 +96,7 @@ extern struct buffer_head * xiafs_bread(struct inode *, int, int); extern void xiafs_truncate(struct inode *); extern void xiafs_put_super(struct super_block *); extern struct super_block *xiafs_read_super(struct super_block *,void *,int); +extern int init_xiafs_fs(void); extern void xiafs_read_inode(struct inode *); extern void xiafs_write_inode(struct inode *); extern void xiafs_put_inode(struct inode *); diff --git a/include/net/addrconf.h b/include/net/addrconf.h new file mode 100644 index 000000000..03f9982bd --- /dev/null +++ b/include/net/addrconf.h @@ -0,0 +1,136 @@ +#ifndef _ADDRCONF_H +#define _ADDRCONF_H + +#define RETRANS_TIMER HZ + +#define MAX_RTR_SOLICITATIONS 3 +#define RTR_SOLICITATION_INTERVAL (4*HZ) + +#define ADDR_CHECK_FREQUENCY (120*HZ) + +struct prefix_info { + __u8 type; + __u8 length; + __u8 prefix_len; + +#if defined(__BIG_ENDIAN_BITFIELD) + __u8 onlink : 1, + autoconf : 1, + reserved : 6; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + __u8 reserved : 6, + autoconf : 1, + onlink : 1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + __u32 valid; + __u32 prefered; + __u32 reserved2; + + struct in6_addr prefix; +}; + + +#ifdef __KERNEL__ + +#include <linux/in6.h> +#include <linux/netdevice.h> +#include <net/if_inet6.h> + +extern struct inet6_ifaddr *inet6_addr_lst[16]; +extern struct ipv6_mc_list *inet6_mcast_lst[16]; +extern struct inet6_dev *inet6_dev_lst; + +extern void addrconf_init(void); +extern void addrconf_cleanup(void); + +extern int addrconf_notify(struct notifier_block *this, + unsigned long event, + void * data); + +extern int addrconf_add_ifaddr(void *arg); +extern int addrconf_set_dstaddr(void *arg); +extern int addrconf_get_ifindex(void *arg); + +extern struct inet6_ifaddr * ipv6_chk_addr(struct in6_addr *addr); +extern struct inet6_ifaddr * ipv6_get_saddr(struct rt6_info *rt, + struct in6_addr *daddr); +extern struct inet6_ifaddr * ipv6_get_lladdr(struct device *dev); + +/* + * multicast prototypes (mcast.c) + */ +extern int ipv6_sock_mc_join(struct sock *sk, + struct device *dev, + struct in6_addr *addr); +extern int ipv6_sock_mc_drop(struct sock *sk, + struct device *dev, + struct in6_addr *addr); +extern void ipv6_sock_mc_close(struct sock *sk); + +extern int ipv6_dev_mc_inc(struct device *dev, + struct in6_addr *addr); +extern int ipv6_dev_mc_dec(struct device *dev, + struct in6_addr *addr); + +extern int ipv6_chk_mcast_addr(struct device *dev, + struct in6_addr *addr); + +extern void addrconf_prefix_rcv(struct device *dev, + u8 *opt, int len); + +extern struct inet6_dev * ipv6_dev_by_index(int index); +extern struct inet6_dev * ipv6_get_idev(struct device *dev); + +extern void addrconf_forwarding_on(void); +/* + * Hash function taken from net_alias.c + */ + +static __inline__ u8 ipv6_addr_hash(struct in6_addr *addr) +{ + __u32 word; + unsigned tmp; + + /* + * We perform the hash function over the last 64 bits of the address + * This will include the IEEE address token on links that support it. + */ + + word = addr->s6_addr[2] ^ addr->s6_addr32[3]; + tmp = word ^ (word>>16); + tmp ^= (tmp >> 8); + + return ((tmp ^ (tmp >> 4)) & 0x0f); +} + +/* + * compute link-local solicited-node multicast address + */ + +static __inline__ void addrconf_addr_solict_mult(struct in6_addr *addr, + struct in6_addr *solicited) +{ + ipv6_addr_set(solicited, + __constant_htonl(0xFF020000), 0, + __constant_htonl(0x1), addr->s6_addr32[3]); +} + +static __inline__ void ipv6_addr_all_nodes(struct in6_addr *addr) +{ + ipv6_addr_set(addr, + __constant_htonl(0xFF020000), 0, 0, + __constant_htonl(0x1)); +} + +static __inline__ void ipv6_addr_all_routers(struct in6_addr *addr) +{ + ipv6_addr_set(addr, + __constant_htonl(0xFF020000), 0, 0, + __constant_htonl(0x2)); +} + + +#endif +#endif diff --git a/include/net/af_unix.h b/include/net/af_unix.h new file mode 100644 index 000000000..86b0e1ea1 --- /dev/null +++ b/include/net/af_unix.h @@ -0,0 +1,14 @@ +#ifndef __LINUX_NET_AFUNIX_H +#define __LINUX_NET_AFUNIX_H +extern void unix_proto_init(struct net_proto *pro); +extern struct proto_ops unix_proto_ops; +extern void unix_inflight(struct file *fp); +extern void unix_notinflight(struct file *fp); +typedef struct sock unix_socket; +extern void unix_gc(void); + +extern unix_socket *unix_socket_list; + +#define UNIX_MAX_FD 8 + +#endif diff --git a/include/net/arp.h b/include/net/arp.h index e8fa572ea..db7a29c36 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -3,18 +3,15 @@ #define _ARP_H extern void arp_init(void); -extern void arp_destroy(unsigned long paddr, int force); -extern void arp_device_down(struct device *dev); extern int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt); -extern int arp_find(unsigned char *haddr, unsigned long paddr, - struct device *dev, unsigned long saddr, struct sk_buff *skb); -extern int arp_get_info(char *buffer, char **start, off_t origin, int length); +extern int arp_query(unsigned char *haddr, u32 paddr, struct device *dev); +extern int arp_find(unsigned char *haddr, u32 paddr, + struct device *dev, u32 saddr, struct sk_buff *skb); extern int arp_ioctl(unsigned int cmd, void *arg); -extern void arp_send(int type, int ptype, unsigned long dest_ip, - struct device *dev, unsigned long src_ip, - unsigned char *dest_hw, unsigned char *src_hw); -extern int arp_find_cache(unsigned char *dp, unsigned long daddr, struct device *dev); - -extern unsigned long arp_cache_stamp; +extern void arp_send(int type, int ptype, u32 dest_ip, + struct device *dev, u32 src_ip, + unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th); +extern int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short type, __u32 daddr); +extern int arp_update_cache(struct hh_cache * hh); #endif /* _ARP_H */ diff --git a/include/net/ax25.h b/include/net/ax25.h index 4195c1246..43cedaafb 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -7,17 +7,39 @@ #ifndef _AX25_H #define _AX25_H #include <linux/ax25.h> + +#define PR_SLOWHZ 10 /* Run timing at 1/10 second - gives us better resolution for 56kbit links */ + +#define AX25_T1CLAMPLO (1 * PR_SLOWHZ) /* If defined, clamp at 1 second **/ +#define AX25_T1CLAMPHI (30 * PR_SLOWHZ) /* If defined, clamp at 30 seconds **/ + +#define AX25_BROKEN_NETMAC + +#define AX25_BPQ_HEADER_LEN 16 +#define AX25_KISS_HEADER_LEN 1 + +#define AX25_HEADER_LEN 17 +#define AX25_ADDR_LEN 7 +#define AX25_DIGI_HEADER_LEN (AX25_MAX_DIGIS * AX25_ADDR_LEN) +#define AX25_MAX_HEADER_LEN (AX25_HEADER_LEN + AX25_DIGI_HEADER_LEN) +#define AX25_P_ROSE 0x01 #define AX25_P_IP 0xCC #define AX25_P_ARP 0xCD #define AX25_P_TEXT 0xF0 #define AX25_P_NETROM 0xCF +#define AX25_P_SEGMENT 0x08 + +#define SEG_REM 0x7F +#define SEG_FIRST 0x80 -#define LAPB_UI 0x03 -#define LAPB_C 0x80 -#define LAPB_E 0x01 +#define LAPB_UI 0x03 +#define LAPB_C 0x80 +#define LAPB_E 0x01 -#define SSID_SPARE 0x60 /* Unused bits (DAMA bit and spare must be 1) */ +#define SSSID_SPARE 0x60 /* Unused bits in SSID for standard AX.25 */ +#define ESSID_SPARE 0x20 /* Unused bits in SSID for extended AX.25 */ +#define DAMA_FLAG 0x20 /* Well, it is *NOT* unused! (dl1bke 951121 */ #define AX25_REPEATED 0x80 @@ -67,11 +89,13 @@ #define UA 0x63 /* Unnumbered acknowledge */ #define FRMR 0x87 /* Frame reject */ #define UI 0x03 /* Unnumbered information */ -#define PF 0x10 /* Poll/final bit */ +#define PF 0x10 /* Poll/final bit for standard AX.25 */ +#define EPF 0x01 /* Poll/final bit for extended AX.25 */ #define ILLEGAL 0x100 /* Impossible to be a real frame type */ -#define MMASK 7 /* Mask for modulo-8 sequence numbers */ +#define POLLOFF 0 +#define POLLON 1 /* AX25 L2 C-bit */ @@ -86,14 +110,46 @@ #define AX25_STATE_3 3 #define AX25_STATE_4 4 -#define PR_SLOWHZ 10 /* Run timing at 1/10 second - gives us better resolution for 56kbit links */ -#define DEFAULT_T1 (10 * PR_SLOWHZ) /* Outstanding frames - 10 seconds */ -#define DEFAULT_T2 (3 * PR_SLOWHZ) /* Response delay - 3 seconds */ -#define DEFAULT_T3 (300 * PR_SLOWHZ) /* Idle supervision - 300 seconds */ -#define DEFAULT_N2 10 /* Number of retries */ -#define DEFAULT_WINDOW 2 /* Default window size */ -#define MODULUS 8 -#define MAX_WINDOW_SIZE 7 /* Maximum window allowable */ +#define AX25_MAX_DEVICES 20 /* Max No of AX.25 devices */ + +#define MODULUS 8 /* Standard AX.25 modulus */ +#define EMODULUS 128 /* Extended AX.25 modulus */ + +#define AX25_DIGI_INBAND 0x01 /* Allow digipeating within port **/ +#define AX25_DIGI_XBAND 0x02 /* Allow digipeating across ports **/ + +#define AX25_VALUES_IPDEFMODE 0 /* 0=DG 1=VC */ +#define AX25_VALUES_AXDEFMODE 1 /* 0=Normal 1=Extended Seq Nos */ +#define AX25_VALUES_TEXT 2 /* Allow PID=Text - 0=No 1=Yes */ +#define AX25_VALUES_BACKOFF 3 /* 0=Linear 1=Exponential */ +#define AX25_VALUES_CONMODE 4 /* Allow connected modes - 0=No 1=Yes */ +#define AX25_VALUES_WINDOW 5 /* Default window size for standard AX.25 */ +#define AX25_VALUES_EWINDOW 6 /* Default window size for extended AX.25 */ +#define AX25_VALUES_T1 7 /* Default T1 timeout value */ +#define AX25_VALUES_T2 8 /* Default T2 timeout value */ +#define AX25_VALUES_T3 9 /* Default T3 timeout value */ +#define AX25_VALUES_IDLE 10 /* mode vc idle timer */ +#define AX25_VALUES_N2 11 /* Default N2 value */ +#define AX25_VALUES_PACLEN 12 /* AX.25 MTU */ +#define AX25_VALUES_MAXQUEUE 13 /* Maximum number of buffers enqueued */ +#define AX25_VALUES_DIGI 14 /* Digipeat mode */ +#define AX25_MAX_VALUES 15 + +#define AX25_DEF_IPDEFMODE 0 /* Datagram */ +#define AX25_DEF_AXDEFMODE 0 /* Normal */ +#define AX25_DEF_TEXT 1 /* PID=Text allowed */ +#define AX25_DEF_BACKOFF 1 /* Exponential backoff */ +#define AX25_DEF_CONMODE 1 /* Connected mode allowed */ +#define AX25_DEF_WINDOW 2 /* Window=2 */ +#define AX25_DEF_EWINDOW 32 /* Module-128 Window=32 */ +#define AX25_DEF_T1 (10 * PR_SLOWHZ) /* T1=10s */ +#define AX25_DEF_T2 (3 * PR_SLOWHZ) /* T2=3s */ +#define AX25_DEF_T3 (300 * PR_SLOWHZ) /* T3=300s */ +#define AX25_DEF_N2 10 /* N2=10 */ +#define AX25_DEF_IDLE (20 * 60 * PR_SLOWHZ) /* Idle=20 mins */ +#define AX25_DEF_PACLEN 256 /* Paclen=256 */ +#define AX25_DEF_MAXQUEUE 2 /* 1 * ax25->window */ +#define AX25_DEF_DIGI 0x03 /* All digis alowed */ typedef struct ax25_uid_assoc { struct ax25_uid_assoc *next; @@ -102,8 +158,8 @@ typedef struct ax25_uid_assoc { } ax25_uid_assoc; typedef struct { - ax25_address calls[6]; - unsigned char repeated[6]; + ax25_address calls[AX25_MAX_DIGIS]; + unsigned char repeated[AX25_MAX_DIGIS]; unsigned char ndigi; char lastrepeat; } ax25_digi; @@ -112,77 +168,126 @@ typedef struct ax25_cb { struct ax25_cb *next; ax25_address source_addr, dest_addr; struct device *device; - unsigned char state; + unsigned char dama_slave; /* dl1bke 951121 */ + unsigned char state, modulus, hdrincl; unsigned short vs, vr, va; - unsigned char condition; + unsigned char condition, backoff; unsigned char n2, n2count; - unsigned short t1, t2, t3, rtt; - unsigned short t1timer, t2timer, t3timer; + unsigned short t1, t2, t3, idle, rtt; + unsigned short t1timer, t2timer, t3timer, idletimer; + unsigned short paclen; + unsigned short maxqueue; + unsigned short fragno, fraglen; ax25_digi *digipeat; struct sk_buff_head write_queue; + struct sk_buff_head reseq_queue; struct sk_buff_head ack_queue; + struct sk_buff_head frag_queue; unsigned char window; struct timer_list timer; struct sock *sk; /* Backlink to socket */ } ax25_cb; -/* ax25.c */ +struct ax25_dev { + char name[20]; + struct device *dev; + int values[AX25_MAX_VALUES]; +}; + +/* af_ax25.c */ +extern ax25_address null_ax25_address; extern char *ax2asc(ax25_address *); +extern ax25_address *asc2ax(char *); extern int ax25cmp(ax25_address *, ax25_address *); -extern int ax25_send_frame(struct sk_buff *, ax25_address *, ax25_address *, struct device *); -extern int ax25_rcv(struct sk_buff *,struct device *,struct packet_type *); +extern int ax25_send_frame(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *, struct device *); +extern int ax25_link_up(ax25_address *, ax25_address *, struct device *); extern void ax25_destroy_socket(ax25_cb *); extern struct device *ax25rtr_get_dev(ax25_address *); -extern int ax25_encapsulate(unsigned char *, struct device *, unsigned short, - void *, void *, unsigned int, struct sk_buff *); +extern int ax25_encapsulate(struct sk_buff *, struct device *, unsigned short, + void *, void *, unsigned int); extern int ax25_rebuild_header(unsigned char *, struct device *, unsigned long, struct sk_buff *); -extern int ax25_get_info(char *, char **, off_t, int); extern ax25_uid_assoc *ax25_uid_list; extern int ax25_uid_policy; extern ax25_address *ax25_findbyuid(uid_t); +extern void ax25_queue_xmit(struct sk_buff *, struct device *, int); +extern int ax25_dev_is_dama_slave(struct device *); /* dl1bke 951121 */ -#include "ax25call.h" +#include <net/ax25call.h> /* ax25_in.c */ -extern int ax25_process_rx_frame(ax25_cb *, struct sk_buff *, int); +extern int ax25_process_rx_frame(ax25_cb *, struct sk_buff *, int, int); /* ax25_out.c */ -extern int ax25_output(ax25_cb *, struct sk_buff *); +extern void ax25_output(ax25_cb *, struct sk_buff *); extern void ax25_kick(ax25_cb *); extern void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int); extern void ax25_nr_error_recovery(ax25_cb *); extern void ax25_establish_data_link(ax25_cb *); extern void ax25_transmit_enquiry(ax25_cb *); extern void ax25_enquiry_response(ax25_cb *); +extern void ax25_timeout_response(ax25_cb *); extern void ax25_check_iframes_acked(ax25_cb *, unsigned short); extern void ax25_check_need_response(ax25_cb *, int, int); +extern void dama_enquiry_response(ax25_cb *); /* dl1bke 960114 */ +extern void dama_check_need_response(ax25_cb *, int, int); /* dl1bke 960114 */ +extern void dama_establish_data_link(ax25_cb *); /* ax25_route.c */ -extern void ax25_rt_rx_frame(ax25_address *, struct device *); -extern int ax25_rt_get_info(char *, char **, off_t, int); -extern int ax25_cs_get_info(char *, char **, off_t, int); +extern struct ax25_dev ax25_device[]; +extern int ax25_rt_get_info(char *, char **, off_t, int, int); +extern int ax25_cs_get_info(char *, char **, off_t, int, int); extern int ax25_rt_autobind(ax25_cb *, ax25_address *); +extern void ax25_rt_build_path(ax25_cb *, ax25_address *, struct device *); +extern void ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *); extern void ax25_rt_device_down(struct device *); -extern void ax25_ip_mode_set(ax25_address *, struct device *, char); +extern int ax25_rt_ioctl(unsigned int, void *); extern char ax25_ip_mode_get(ax25_address *, struct device *); +extern int ax25_dev_get_value(struct device *, int); +extern void ax25_dev_device_up(struct device *); +extern void ax25_dev_device_down(struct device *); +extern void ax25_rt_free(void); /* ax25_subr.c */ -extern void ax25_clear_tx_queue(ax25_cb *); +extern void ax25_clear_queues(ax25_cb *); extern void ax25_frames_acked(ax25_cb *, unsigned short); +extern void ax25_requeue_frames(ax25_cb *); extern int ax25_validate_nr(ax25_cb *, unsigned short); -extern int ax25_decode(unsigned char *); -extern void ax25_send_control(ax25_cb *, int, int); +extern int ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *); +extern void ax25_send_control(ax25_cb *, int, int, int); extern unsigned short ax25_calculate_t1(ax25_cb *); extern void ax25_calculate_rtt(ax25_cb *); extern unsigned char *ax25_parse_addr(unsigned char *, int, ax25_address *, - ax25_address *, ax25_digi *, int *); + ax25_address *, ax25_digi *, int *, int *); /* dl1bke 951121 */ extern int build_ax25_addr(unsigned char *, ax25_address *, ax25_address *, - ax25_digi *, int); + ax25_digi *, int, int); extern int size_ax25_addr(ax25_digi *); extern void ax25_digi_invert(ax25_digi *, ax25_digi *); extern void ax25_return_dm(struct device *, ax25_address *, ax25_address *, ax25_digi *); +extern int ax25_queue_length(ax25_cb *, struct sk_buff *); /* dl1bke 960327 */ +extern void ax25_dama_on(ax25_cb *); /* dl1bke 951121 */ +extern void ax25_dama_off(ax25_cb *); /* dl1bke 951121 */ -/* ax25_timer */ +/* ax25_timer.c */ extern void ax25_set_timer(ax25_cb *); +extern void ax25_t1_timeout(ax25_cb *); +extern void ax25_link_failed(ax25_address *, struct device *); +extern int (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *); +extern int ax25_listen_mine(ax25_address *, struct device *); + +/* sysctl_net_ax25.c */ +extern void ax25_register_sysctl(void); +extern void ax25_unregister_sysctl(void); + +/* ... */ + +extern ax25_cb *volatile ax25_list; + +/* support routines for modules that use AX.25, in ax25_timer.c */ +extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *)); +extern void ax25_protocol_release(unsigned int); +extern int ax25_linkfail_register(void (*)(ax25_address *, struct device *)); +extern void ax25_linkfail_release(void (*)(ax25_address *, struct device *)); +extern int ax25_listen_register(ax25_address *, struct device *); +extern void ax25_listen_release(ax25_address *, struct device *); #endif diff --git a/include/net/ax25call.h b/include/net/ax25call.h index 89569656b..68b8a70c0 100644 --- a/include/net/ax25call.h +++ b/include/net/ax25call.h @@ -1,2 +1,2 @@ -/* Seperate to keep compilation of protocols.c simpler */ +/* Separate to keep compilation of protocols.c simpler */ extern void ax25_proto_init(struct net_proto *pro); diff --git a/include/net/br.h b/include/net/br.h new file mode 100644 index 000000000..a1d3fa309 --- /dev/null +++ b/include/net/br.h @@ -0,0 +1,291 @@ +/* + * Constants and structure definitions for the bridging code + */ + +#if !defined(One) +#define Zero 0 +#define One 1 +#endif /* !defined(One) */ + +#if !defined(TRUE) +#define FALSE 0 +#define TRUE 1 +#endif /* !defined(TRUE) */ + +/** port states. **/ +#define Disabled 0 /* (4.4 5) */ +#define Listening 1 /* (4.4.2) */ +#define Learning 2 /* (4.4.3) */ +#define Forwarding 3 /* (4 4 4) */ +#define Blocking 4 /* (4.4.1) */ + +#define No_of_ports 8 +/* arbitrary choice, to allow the code below to compile */ + +#define All_ports (No_of_ports + 1) + +/* + * We time out our entries in the FDB after this many seconds. + */ +#define FDB_TIMEOUT 300 + +/* + * the following defines are the initial values used when the + * bridge is booted. These may be overridden when this bridge is + * not the root bridge. These are the recommended default values + * from the 802.1d specification. + */ +#define BRIDGE_MAX_AGE 20 +#define BRIDGE_HELLO_TIME 2 +#define BRIDGE_FORWARD_DELAY 15 +#define HOLD_TIME 1 + +#define Default_path_cost 10 + +/* + * minimum increment possible to avoid underestimating age, allows for BPDU + * transmission time + */ +#define Message_age_increment 1 + +#define No_port 0 +/* + * reserved value for Bridge's root port parameter indicating no root port, + * used when Bridge is the root - also used to indicate the source when + * a frame is being generated by a higher layer protocol on this host + */ + +/** Configuration BPDU Parameters (4.5.1) **/ + +typedef struct { + union { + struct { + unsigned short priority; + unsigned char ula[6]; + } p_u; + unsigned int id[2]; + } bi; +} bridge_id_t; + +#define BRIDGE_PRIORITY bi.p_u.priority +#define BRIDGE_ID_ULA bi.p_u.ula +#define BRIDGE_ID bi.id + +typedef struct { + unsigned short protocol_id; + unsigned char protocol_version_id; + unsigned char type; + unsigned char flags; +#define TOPOLOGY_CHANGE 0x01 +#define TOPOLOGY_CHANGE_ACK 0x80 + bridge_id_t root_id; /* (4.5.1.1) */ + unsigned int root_path_cost; /* (4.5.1.2) */ + bridge_id_t bridge_id; /* (4.5.1.3) */ + unsigned short port_id; /* (4.5.1.4) */ + unsigned short message_age; /* (4.5.1.5) */ + unsigned short max_age; /* (4.5.1.6) */ + unsigned short hello_time; /* (4.5.1.7) */ + unsigned short forward_delay; /* (4.5.1.8) */ +} Config_bpdu; + + +/** Topology Change Notification BPDU Parameters (4.5.2) **/ + +typedef struct { + unsigned short protocol_id; + unsigned char protocol_version_id; + unsigned char type; +} Tcn_bpdu; + +#define BPDU_TYPE_CONFIG 0 +#define BPDU_TYPE_TOPO_CHANGE 128 + +/** Bridge Parameters (4.5.3) **/ +typedef struct { + bridge_id_t designated_root; /* (4.5.3.1) */ + unsigned int root_path_cost; /* (4.5.3.2) */ + unsigned int root_port; /* (4.5.3.3) */ + unsigned short max_age; /* (4.5.3.4) */ + unsigned short hello_time; /* (4.5.3.5) */ + unsigned short forward_delay; /* (4.5.3.6) */ + bridge_id_t bridge_id; /* (4.5.3.7) */ + unsigned short bridge_max_age; /* (4.5.3.8) */ + unsigned short bridge_hello_time; /* (4.5.3.9) */ + unsigned short bridge_forward_delay; /* (4.5.3.10) */ + unsigned int topology_change_detected; /* (4.5.3.11) */ + unsigned int topology_change; /* (4.5.3.12) */ + unsigned short topology_change_time; /* (4.5.3.13) */ + unsigned short hold_time; /* (4.5.3.14) */ + unsigned int top_change; + unsigned int top_change_detected; +} Bridge_data; + +/** Port Parameters (4.5.5) **/ +typedef struct { + unsigned short port_id; /* (4.5.5.1) */ + unsigned int state; /* (4.5.5.2) */ + unsigned int path_cost; /* (4.5.5.3) */ + bridge_id_t designated_root; /* (4.5.5.4) */ + unsigned int designated_cost; /* (4.5.5.5) */ + bridge_id_t designated_bridge; /* (4.5.5.6) */ + unsigned short designated_port; /* (4.5.5.7) */ + unsigned int top_change_ack; /* (4.5.5.8) */ + unsigned int config_pending; /* (4.5.5.9) */ + struct device *dev; + struct fdb *fdb; /* head of per port fdb chain */ +} Port_data; + + + +/** types to support timers for this pseudo-implementation. **/ +typedef struct { + unsigned int active; /* timer in use. */ + unsigned int value; /* current value of timer, + * counting up. */ +} Timer; + +struct fdb { + unsigned char ula[6]; + unsigned char pad[2]; + unsigned short port; + unsigned int timer; + unsigned int flags; +#define FDB_ENT_VALID 0x01 +/* AVL tree of all addresses, sorted by address */ + short fdb_avl_height; + struct fdb *fdb_avl_left; + struct fdb *fdb_avl_right; +/* linked list of addresses for each port */ + struct fdb *fdb_next; +}; + +#define IS_BRIDGED 0x2e + + +#define BR_MAX_PROTOCOLS 32 +#define BR_MAX_PROT_STATS BR_MAX_PROTOCOLS + +/* policy values for policy field */ +#define BR_ACCEPT 1 +#define BR_REJECT 0 + +struct br_stat { + unsigned int flags; + Bridge_data bridge_data; + Port_data port_data[No_of_ports]; + unsigned int policy; + unsigned int exempt_protocols; + unsigned short protocols[BR_MAX_PROTOCOLS]; + unsigned short prot_id[BR_MAX_PROT_STATS]; /* Protocol encountered */ + unsigned int prot_counter[BR_MAX_PROT_STATS]; /* How many packets ? */ +}; + +/* defined flags for br_stat.flags */ +#define BR_UP 0x0001 /* bridging enabled */ +#define BR_DEBUG 0x0002 /* debugging enabled */ +#define BR_PROT_STATS 0x0004 /* protocol statistics enabled */ + +struct br_cf { + unsigned int cmd; + unsigned int arg1; + unsigned int arg2; +}; + +/* defined cmds */ +#define BRCMD_BRIDGE_ENABLE 1 +#define BRCMD_BRIDGE_DISABLE 2 +#define BRCMD_PORT_ENABLE 3 /* arg1 = port */ +#define BRCMD_PORT_DISABLE 4 /* arg1 = port */ +#define BRCMD_SET_BRIDGE_PRIORITY 5 /* arg1 = priority */ +#define BRCMD_SET_PORT_PRIORITY 6 /* arg1 = port, arg2 = priority */ +#define BRCMD_SET_PATH_COST 7 /* arg1 = port, arg2 = cost */ +#define BRCMD_DISPLAY_FDB 8 /* arg1 = port */ +#define BRCMD_ENABLE_DEBUG 9 +#define BRCMD_DISABLE_DEBUG 10 +#define BRCMD_SET_POLICY 11 /* arg1 = default policy (1==bridge all) */ +#define BRCMD_EXEMPT_PROTOCOL 12 /* arg1 = protocol (see net/if_ether.h) */ +#define BRCMD_ENABLE_PROT_STATS 13 +#define BRCMD_DISABLE_PROT_STATS 14 +#define BRCMD_ZERO_PROT_STATS 15 + +/* prototypes of all bridging functions... */ + +void transmit_config(int port_no); +int root_bridge(void); +int supersedes_port_info(int port_no, Config_bpdu *config); +void record_config_information(int port_no, Config_bpdu *config); +void record_config_timeout_values(Config_bpdu *config); +void config_bpdu_generation(void); +int designated_port(int port_no); +void reply(int port_no); +void transmit_tcn(void); +void configuration_update(void); +void root_selection(void); +void designated_port_selection(void); +void become_designated_port(int port_no); +void port_state_selection(void); +void make_forwarding(int port_no); +void topology_change_detection(void); +void topology_change_acknowledged(void); +void acknowledge_topology_change(int port_no); +void make_blocking(int port_no); +void set_port_state(int port_no, int state); +void received_config_bpdu(int port_no, Config_bpdu *config); +void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn); +void hello_timer_expiry(void); +void message_age_timer_expiry(int port_no); +void forward_delay_timer_expiry(int port_no); +int designated_for_some_port(void); +void tcn_timer_expiry(void); +void topology_change_timer_expiry(void); +void hold_timer_expiry(int port_no); +void br_init(void); +void br_init_port(int port_no); +void enable_port(int port_no); +void disable_port(int port_no); +void set_bridge_priority(bridge_id_t *new_bridge_id); +void set_port_priority(int port_no, unsigned short new_port_id); +void set_path_cost(int port_no, unsigned short path_cost); +void start_hello_timer(void); +void stop_hello_timer(void); +int hello_timer_expired(void); +void start_tcn_timer(void); +void stop_tcn_timer(void); +int tcn_timer_expired(void); +void start_topology_change_timer(void); +void stop_topology_change_timer(void); +int topology_change_timer_expired(void); +void start_message_age_timer(int port_no, unsigned short message_age); +void stop_message_age_timer(int port_no); +int message_age_timer_expired(int port_no); +void start_forward_delay_timer(int port_no); +void stop_forward_delay_timer(int port_no); +int forward_delay_timer_expired(int port_no); +void start_hold_timer(int port_no); +void stop_hold_timer(int port_no); +int hold_timer_expired(int port_no); + +struct fdb *br_avl_find_addr(unsigned char addr[6]); +int br_avl_insert (struct fdb * new_node); +int br_avl_remove (struct fdb * node_to_delete); + +int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu); +int send_config_bpdu(int port_no, Config_bpdu *config_bpdu); +int find_port(struct device *dev); +int br_flood(struct sk_buff *skb, int port); +int br_drop(struct sk_buff *skb); +int br_learn(struct sk_buff *skb, int port); /* 3.8 */ + +int br_receive_frame(struct sk_buff *skb); /* 3.5 */ +int br_tx_frame(struct sk_buff *skb); +int br_ioctl(unsigned int cmd, void *arg); + +int br_protocol_ok(unsigned short protocol); + +void free_fdb(struct fdb *); +struct fdb *get_fdb(void); + +/* externs */ + +extern struct br_stat br_stats; + diff --git a/include/net/checksum.h b/include/net/checksum.h index 7f9492328..2fb596b13 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -15,223 +15,78 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#ifndef _CHECKSUM_H -#define _CHECKSUM_H - -#include <asm/byteorder.h> -#include "ip.h" /* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. + * Fixes: * - * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by - * Arnt Gulbrandsen. + * Ralf Baechle : generic ipv6 checksum + * <ralf@waldorf-gmbh.de> */ -static inline unsigned short ip_fast_csum(unsigned char * iph, - unsigned int ihl) { - unsigned short int sum; - -#ifdef __i386__ - __asm__(" - movl (%%esi), %%eax - andl $15, %%ecx - subl $4, %%ecx - jbe 2f - addl 4(%%esi), %%eax - adcl 8(%%esi), %%eax - adcl 12(%%esi), %%eax -1: adcl 16(%%esi), %%eax - lea 4(%%esi), %%esi - decl %%ecx - jne 1b - adcl $0, %%eax - movl %%eax, %%ecx - shrl $16, %%eax - addw %%ecx, %%eax - adcl $0, %%eax - notl %%eax - andl $65535, %%eax -2: - " - : "=a" (sum) - : "S" (iph), "c"(ihl) - : "ax", "cx", "si"); -#elif defined (__mips__) - unsigned long dummy1, dummy2; - /* - * This is optimized for 32-bit MIPS processors. - * I tried it in plain C but the generated code looks to bad to - * use with old first generation MIPS CPUs. - * Using 64-bit code could even further improve these routines. - */ - __asm__(" - .set noreorder - .set noat - lw %0,(%3) - subu %1,4 - blez %1,2f - sll %1,%4,2 # delay slot - lw %2,4(%3) - addu %1,%3 # delay slot - addu %0,%2 - sltu $1,%0,%2 - lw %2,8(%3) - addu %0,$1 - addu %0,%2 - sltu $1,%0,%2 - lw %2,12(%3) - addu %0,$1 - addu %0,%2 - sltu $1,%0,%2 - addu %0,$1 -1: lw %2,16(%3) - addu %1,4 - addu %0,%2 - sltu $1,%0,%2 - bne %1,%3,1b - addu %0,$1 # delay slot - srl $1,%0,16 - addu %0,$1 - sltu $1,%0,$1 - addu %0,$1 - nor %0,$0,%0 - andi %0,0xffff -2: .set at - .set reorder" - : "=r" (sum), "=r" (dummy1), "=r" (dummy2) - : "r" (iph), "r"(ihl) - : "$1"); -#else -#error Not implemented for this CPU -#endif - return(sum); -} - - +#ifndef _CHECKSUM_H +#define _CHECKSUM_H -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ - -static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, - unsigned long daddr, - unsigned short len, - unsigned short proto, - unsigned int sum) { -#ifdef __i386__ - __asm__(" - addl %2, %0 - adcl %3, %0 - adcl %4, %0 - adcl $0, %0 - movl %0, %2 - shrl $16, %2 - addw %2, %0 - adcl $0, %0 - notl %0 - andl $65535, %0 - " - : "=r" (sum) - : "0" (daddr), "S"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum) - : "si" ); -#elif defined (__mips__) - __asm__(" - .set noat - addu %0,%2 - sltu $1,%0,%2 - addu %0,$1 - addu %0,%3 - sltu $1,%0,%3 - addu %0,$1 - addu %0,%4 - sltu $1,%0,%4 - addu %0,$1 - srl $1,%0,16 - addu %0,$1 - sltu $1,%0,$1 - addu %0,$1 - nor %0,$0,%0 - andi %0,0xffff - .set at" - : "=r" (sum) - : "0" (daddr), "r"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum) - : "$1"); -#else -#error Not implemented for this CPU -#endif - return((unsigned short)sum); +#include <asm/byteorder.h> +#include <net/ip.h> +#include <asm/checksum.h> + +#ifndef _HAVE_ARCH_IPV6_CSUM + +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int csum) +{ + int carry; + __u32 ulen; + __u32 uproto; + + csum += saddr->s6_addr32[0]; + carry = (csum < saddr->s6_addr32[0]); + csum += carry; + + csum += saddr->s6_addr32[1]; + carry = (csum < saddr->s6_addr32[1]); + csum += carry; + + csum += saddr->s6_addr32[2]; + carry = (csum < saddr->s6_addr32[2]); + csum += carry; + + csum += saddr->s6_addr32[3]; + carry = (csum < saddr->s6_addr32[3]); + csum += carry; + + csum += daddr->s6_addr32[0]; + carry = (csum < daddr->s6_addr32[0]); + csum += carry; + + csum += daddr->s6_addr32[1]; + carry = (csum < daddr->s6_addr32[1]); + csum += carry; + + csum += daddr->s6_addr32[2]; + carry = (csum < daddr->s6_addr32[2]); + csum += carry; + + csum += daddr->s6_addr32[3]; + carry = (csum < daddr->s6_addr32[3]); + csum += carry; + + ulen = htonl((__u32) len); + csum += ulen; + carry = (csum < ulen); + csum += carry; + + uproto = htonl(proto); + csum += uproto; + carry = (csum < uproto); + csum += carry; + + return csum_fold(csum); } - - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum); - - - -/* - * the same as csum_partial, but copies from fs:src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -unsigned int csum_partial_copyffs( char *src, char *dst, int len, int sum); - - - - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline unsigned short ip_compute_csum(unsigned char * buff, int len) { - unsigned short int sum; - -#ifdef __i386__ - __asm__(" - movl %%eax, %%ecx - shrl $16, %%ecx - addw %%cx, %%ax - adcl $0, %%eax - notl %%eax - andl $65535, %%eax - " - : "=a"(sum) - : "a" (csum_partial(buff, len, 0)) - : "cx"); -#elif defined (__mips__) - __asm__(" - .set noat - srl $1,%0,16 - addu %0,$1 - sltu $1,%0,$1 - nor %0,$0,%0 - andi %0,0xffff - .set at" - : "=r"(sum) - : "r" (csum_partial(buff, len, 0)) - : "$1"); -#else -#error Not implemented for this CPU #endif - return(sum); -} #endif diff --git a/include/net/datalink.h b/include/net/datalink.h index 34ae08daa..44e56990c 100644 --- a/include/net/datalink.h +++ b/include/net/datalink.h @@ -4,7 +4,7 @@ struct datalink_proto { unsigned short type_len; unsigned char type[8]; - char *string_name; + const char *string_name; unsigned short header_length; int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *); @@ -14,4 +14,3 @@ struct datalink_proto { }; #endif - diff --git a/include/net/eth.h b/include/net/eth.h deleted file mode 100644 index 3c11603e0..000000000 --- a/include/net/eth.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. NET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Definitions for the Ethernet handlers. - * - * Version: @(#)eth.h 1.0.4 05/13/93 - * - * Authors: Ross Biro, <bir7@leland.Stanford.Edu> - * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _ETH_H -#define _ETH_H - - -#include <linux/if_ether.h> - - -extern char *eth_print(unsigned char *ptr); -extern void eth_dump(struct ethhdr *eth); -extern int eth_header(unsigned char *buff, struct device *dev, - unsigned short type, unsigned long daddr, - unsigned long saddr, unsigned len); -extern int eth_rebuild_header(void *buff, struct device *dev); -extern void eth_add_arp(unsigned long addr, struct sk_buff *skb, - struct device *dev); -extern unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev); -extern int eth_header_cache(struct device *dev, struct sock *sk, unsigned long saddr, unsigned long daddr); - -#endif /* _ETH_H */ diff --git a/include/net/gc.h b/include/net/gc.h new file mode 100644 index 000000000..0b28c098e --- /dev/null +++ b/include/net/gc.h @@ -0,0 +1,46 @@ +/* + * Interface routines assumed by gc() + * + * Copyright (C) Barak A. Pearlmutter. + * Released under the GPL version 2 or later. + * + */ + +typedef struct object *pobj; /* pointer to a guy of the type we gc */ + +/* + * How to mark and unmark objects + */ + +extern void gc_mark(pobj); +extern void gc_unmark(pobj); +extern int gc_marked(pobj); + +/* + * How to count and access an object's children + */ + +extern int n_children(pobj); /* how many children */ +extern pobj child_n(pobj, int); /* child i, numbered 0..n-1 */ + +/* + * How to access the root set + */ + +extern int root_size(void); /* number of things in root set */ +extern pobj root_elt(int); /* element i of root set, numbered 0..n-1 */ + +/* + * How to access the free list + */ + +extern void clear_freelist(void); +extern void add_to_free_list(pobj); + +/* + * How to iterate through all objects in memory + */ + +extern int N_OBJS; +extern pobj obj_number(int); + diff --git a/include/net/head_explode.h b/include/net/head_explode.h deleted file mode 100644 index 90276fafe..000000000 --- a/include/net/head_explode.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Header exploders. We inline those only appearing once. - * - * We assume 8 bit bytes. - * - * This is oriented to getting good code out of GCC. It may need - * tuning for other processors. - * - * Note only IGMP uses this so far. Just as an experiment. - */ - - -extern __inline__ unsigned char *exp_getu16(unsigned char *bp, unsigned short *u) -{ - *u=(*bp<<8)|bp[1]; - return bp+2; -} - -extern __inline__ unsigned char *exp_getn16(unsigned char *bp, unsigned short *u) -{ - unsigned char *tp=(unsigned char *)u; - *tp++=*bp++; - *tp++=*bp++; - return bp; -} - -extern __inline__ unsigned char *imp_putu16(unsigned char *bp, unsigned short n) -{ - *bp=(n>>8); - bp[1]=n&0xFF; - return bp+2; -} - -extern __inline__ unsigned char *imp_putn16(unsigned char *bp, unsigned short n) -{ - unsigned char *sp=(unsigned char *)&n; - *bp++=*sp++; - *bp++=*sp++; - return bp; -} - -extern __inline__ unsigned char *exp_getu32(unsigned char *bp, unsigned long *u) -{ - *u=(bp[0]<<24)|(bp[1]<<16)|(bp[2]<<8)|bp[3]; - return bp+4; -} - -extern __inline__ unsigned char *exp_getn32(unsigned char *bp, unsigned long *u) -{ - unsigned char *tp=(unsigned char *)u; - *tp++=*bp++; - *tp++=*bp++; - *tp++=*bp++; - *tp++=*bp++; - return bp; -} - -extern __inline__ unsigned char *imp_putu32(unsigned char *bp, unsigned long n) -{ - bp[0]=n>>24; - bp[1]=(n>>16)&0xFF; - bp[2]=(n>>8)&0xFF; - bp[3]=n&0xFF; - return bp+4; -} - -extern __inline__ unsigned char *imp_putn32(unsigned char *bp, unsigned long n) -{ - unsigned char *sp=(unsigned char *)&n; - *bp++=*sp++; - *bp++=*sp++; - *bp++=*sp++; - *bp++=*sp++; - return bp; -} - -#if 0 - -extern __inline__ unsigned char *ip_explode(unsigned char *iph, struct ip_header *ip) -{ - ip->version=*iph>>4; /* Avoid the shift. We do our equality checks shifted too */ - ip->ihl=(*iph++)&0xF; /* Length in long words */ - ip->tos=*iph++; /* Service type */ - iph=exp_getu16(iph,&ip->tot_len); /* Length of packet */ - iph=exp_getu16(iph,&ip->id); /* Packet identity */ - iph=exp_getu16(iph,&ip->frag_off); /* Fragment offset */ - ip->ttl=*iph++; - ip->protocol=*iph++; - iph=exp_getn16(iph,&ip->check); - iph=exp_getn32(iph,&ip->saddr); - iph=exp_getn32(iph,&ip->daddr); - return iph; -} - -extern __inline__ unsigned char *icmp_explode(unsigned char *icmph, struct icmp_header *icmp) -{ - icmp->type=*icmp++; - icmp->code=*icmp++; - icmph=exp_getn16(icmph,&icmp->checksum); - /* These two pairs are a union... expand both */ - exp_getu32(icmph,&icmp->gateway); - icmph=exp_getu16(icmph,&icmp->id); - icmph=exp_getu16(icmph,&icmp->sequence); - return icmph; -} - -#endif - -extern __inline__ unsigned char *igmp_explode(unsigned char *igmph, struct igmp_header *igmp) -{ - igmp->type=*igmph++; - igmph++; /* unused */ - igmph=exp_getn16(igmph,&igmp->csum); - igmph=exp_getn32(igmph,&igmp->group); - return igmph; -} - -#if 0 -extern __inline__ unsigned char *tcp_explode(unsigned char *tcph, struct tcp_header *tcp) -{ - tcph=exp_getu16(tcph,&tcp->source); - tcph=exp_getu16(tcph,&tcp->dest); - tcph=exp_getu32(tcph,&tcp->seq); - tcph=exp_getu32(tcph,&tcp->ack_seq); - tcph=exp_getu16(tcph,&tcp->u.bitmask); - tcph=exp_getu16(tcph,&tcp->window); - tcph=exp_getn16(tcph,&tcp->check); - tcph=exp_getu16(tcph,&tcp->urg_ptr); - return tcph; -} - -extern __inline__ unsigned char *udp_explode(unsigned char *udph, struct udp_header *udp) -{ - udph=exp_getu16(tcph,&udp->source); - udph=exp_getu16(udph,&udp->dest); - udph=exp_getu16(udph,&udp->len); - udph=exp_getn16(udph,&udp->check); - return udph; -} -#endif diff --git a/include/net/icmp.h b/include/net/icmp.h index 8f1c34983..fa770d238 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h @@ -19,20 +19,25 @@ #define _ICMP_H #include <linux/icmp.h> +#include <linux/skbuff.h> +#include <net/sock.h> +#include <net/protocol.h> extern struct icmp_err icmp_err_convert[]; extern struct icmp_mib icmp_statistics; - extern void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info, struct device *dev); extern int icmp_rcv(struct sk_buff *skb1, struct device *dev, - struct options *opt, unsigned long daddr, - unsigned short len, unsigned long saddr, + struct options *opt, __u32 daddr, + unsigned short len, __u32 saddr, int redo, struct inet_protocol *protocol); - extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); +extern void icmp_init(struct proto_ops *ops); + +/* CONFIG_IP_TRANSPARENT_PROXY */ +extern int icmp_chkaddr(struct sk_buff *skb); #endif /* _ICMP_H */ diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h new file mode 100644 index 000000000..048243c33 --- /dev/null +++ b/include/net/if_inet6.h @@ -0,0 +1,109 @@ +/* + * inet6 interface/address list definitions + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _NET_IF_INET6_H +#define _NET_IF_INET6_H + +#define DAD_COMPLETE 0x00 +#define DAD_INCOMPLETE 0x01 +#define DAD_STATUS 0x01 + +#define ADDR_STATUS 0x06 +#define ADDR_DEPRECATED 0x02 +#define ADDR_INVALID 0x04 + +#define ADDR_PERMANENT 0x80 + +#define IF_RA_RCVD 0x20 +#define IF_RS_SENT 0x10 + +#ifdef __KERNEL__ + +struct inet6_ifaddr +{ + struct in6_addr addr; + __u32 prefix_len; + + __u32 valid_lft; + __u32 prefered_lft; + unsigned long tstamp; + + __u8 probes; + __u8 flags; + + __u16 scope; + + struct timer_list timer; + + struct inet6_dev *idev; + + struct inet6_ifaddr *lst_next; /* next addr in addr_lst */ + struct inet6_ifaddr *if_next; /* next addr in inet6_dev */ +}; + + +struct ipv6_mc_socklist { + struct in6_addr addr; + struct device *dev; + struct ipv6_mc_socklist *next; +}; + +struct ipv6_mc_list { + struct in6_addr addr; + struct device *dev; + struct ipv6_mc_list *next; + struct ipv6_mc_list *if_next; + struct timer_list timer; + int tm_running; + atomic_t users; +}; + +#define IFA_HOST IPV6_ADDR_LOOPBACK +#define IFA_LINK IPV6_ADDR_LINKLOCAL +#define IFA_SITE IPV6_ADDR_SITELOCAL +#define IFA_GLOBAL 0x0000U + +extern int in6_ifnum; + +struct inet6_dev +{ + struct device *dev; + + struct inet6_ifaddr *addr_list; + struct ipv6_mc_list *mc_list; + + __u32 if_index; + __u32 if_flags; + __u32 router:1, + unused:31; + + struct inet6_dev *next; +}; + + +extern __inline__ void ipv6_mc_map(struct in6_addr *addr, char *buf) +{ + /* + * +-------+-------+-------+-------+-------+-------+ + * | 33 | 33 | DST13 | DST14 | DST15 | DST16 | + * +-------+-------+-------+-------+-------+-------+ + */ + + buf[0]= 0x33; + buf[1]= 0x33; + + memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32)); +} +#endif +#endif diff --git a/include/net/inet_common.h b/include/net/inet_common.h new file mode 100644 index 000000000..c72c75333 --- /dev/null +++ b/include/net/inet_common.h @@ -0,0 +1,47 @@ +#ifndef _INET_COMMON_H +#define _INET_COMMON_H + +extern struct proto_ops inet_proto_ops; +extern struct sock * tcp_sock_array[SOCK_ARRAY_SIZE]; +extern struct sock * udp_sock_array[SOCK_ARRAY_SIZE]; + + +/* + * INET4 prototypes used by INET6 + */ + +extern void inet_remove_sock(struct sock *sk1); +extern void inet_put_sock(unsigned short num, + struct sock *sk); +extern int inet_release(struct socket *sock, + struct socket *peer); +extern int inet_connect(struct socket *sock, + struct sockaddr * uaddr, + int addr_len, int flags); +extern int inet_accept(struct socket *sock, + struct socket *newsock, int flags); +extern int inet_recvmsg(struct socket *sock, + struct msghdr *ubuf, + int size, int noblock, + int flags, int *addr_len ); +extern int inet_sendmsg(struct socket *sock, + struct msghdr *msg, + int size, int noblock, + int flags); +extern int inet_shutdown(struct socket *sock, int how); +extern int inet_select(struct socket *sock, int sel_type, + select_table *wait); +extern int inet_setsockopt(struct socket *sock, int level, + int optname, char *optval, + int optlen); +extern int inet_getsockopt(struct socket *sock, int level, + int optname, char *optval, + int *optlen); +extern int inet_fcntl(struct socket *sock, + unsigned int cmd, + unsigned long arg); +extern int inet_listen(struct socket *sock, int backlog); + +#endif + + diff --git a/include/net/ip.h b/include/net/ip.h index 6726e8a48..f7bb04c53 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -25,12 +25,13 @@ #include <linux/socket.h> #include <linux/ip.h> #include <linux/netdevice.h> +#include <net/route.h> #ifndef _SNMP_H -#include "snmp.h" +#include <net/snmp.h> #endif -#include "sock.h" /* struct sock */ +#include <net/sock.h> /* struct sock */ /* IP flags. */ #define IP_CE 0x8000 /* Flag: "Congestion" */ @@ -43,73 +44,111 @@ #ifdef CONFIG_IP_MULTICAST extern void ip_mc_dropsocket(struct sock *); extern void ip_mc_dropdevice(struct device *dev); -extern int ip_mc_procinfo(char *, char **, off_t, int); -#define MULTICAST(x) (IN_MULTICAST(htonl(x))) +extern int ip_mc_procinfo(char *, char **, off_t, int, int); #endif - + +#include <net/ip_forward.h> /* Describe an IP fragment. */ -struct ipfrag { - int offset; /* offset of fragment in IP datagram */ - int end; /* last byte of data in datagram */ - int len; /* length of this fragment */ - struct sk_buff *skb; /* complete received fragment */ - unsigned char *ptr; /* pointer into real fragment data */ - struct ipfrag *next; /* linked list pointers */ - struct ipfrag *prev; +struct ipfrag +{ + int offset; /* offset of fragment in IP datagram */ + int end; /* last byte of data in datagram */ + int len; /* length of this fragment */ + struct sk_buff *skb; /* complete received fragment */ + unsigned char *ptr; /* pointer into real fragment data */ + struct ipfrag *next; /* linked list pointers */ + struct ipfrag *prev; }; -/* Describe an entry in the "incomplete datagrams" queue. */ -struct ipq { - unsigned char *mac; /* pointer to MAC header */ - struct iphdr *iph; /* pointer to IP header */ - int len; /* total length of original datagram */ - short ihlen; /* length of the IP header */ - short maclen; /* length of the MAC header */ - struct timer_list timer; /* when will this queue expire? */ - struct ipfrag *fragments; /* linked list of received fragments */ - struct ipq *next; /* linked list pointers */ - struct ipq *prev; - struct device *dev; /* Device - for icmp replies */ +/* + * Describe an entry in the "incomplete datagrams" queue. + */ + +struct ipq +{ + unsigned char *mac; /* pointer to MAC header */ + struct iphdr *iph; /* pointer to IP header */ + int len; /* total length of original datagram */ + short ihlen; /* length of the IP header */ + short maclen; /* length of the MAC header */ + struct timer_list timer; /* when will this queue expire? */ + struct ipfrag *fragments; /* linked list of received fragments */ + struct ipq *next; /* linked list pointers */ + struct ipq *prev; + struct device *dev; /* Device - for icmp replies */ }; - -extern int backoff(int n); +/* + * Functions provided by ip.c + */ extern void ip_print(const struct iphdr *ip); -extern int ip_ioctl(struct sock *sk, int cmd, - unsigned long arg); -extern void ip_route_check(unsigned long daddr); -extern int ip_build_header(struct sk_buff *skb, - unsigned long saddr, - unsigned long daddr, +extern int ip_ioctl(struct sock *sk, int cmd, unsigned long arg); +extern void ip_route_check(__u32 daddr); +extern int ip_send(struct rtable *rt, struct sk_buff *skb, __u32 daddr, int len, struct device *dev, __u32 saddr); +extern int ip_build_header(struct sk_buff *skb, + __u32 saddr, + __u32 daddr, struct device **dev, int type, struct options *opt, int len, - int tos,int ttl); -/*extern unsigned short ip_compute_csum(unsigned char * buff, int len);*/ + int tos,int ttl,struct rtable **rp); extern int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt); -extern void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned long target_addr, int target_strict); +extern int ip_options_echo(struct options * dopt, struct options * sopt, + __u32 daddr, __u32 saddr, + struct sk_buff * skb); +extern int ip_options_compile(struct options * opt, struct sk_buff * skb); extern void ip_send_check(struct iphdr *ip); extern int ip_id_count; extern void ip_queue_xmit(struct sock *sk, struct device *dev, struct sk_buff *skb, int free); -extern int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen); -extern int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen); extern void ip_init(void); extern int ip_build_xmit(struct sock *sk, - void getfrag (void *, - int, - char *, - unsigned int, - unsigned int), - void *frag, + int getfrag (const void *, + __u32, + char *, + unsigned int, + unsigned int), + const void *frag, unsigned short int length, - int daddr, + __u32 daddr, + __u32 saddr, + struct options * opt, int flags, - int type); + int type, + int noblock); extern struct ip_mib ip_statistics; +/* + * Functions provided by ip_fragment.o + */ + +struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct device *dev); +void ip_fragment(struct sock *sk, struct sk_buff *skb, struct device *dev, int is_frag); + +/* + * Functions provided by ip_forward.c + */ + +extern int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, __u32 target_addr); + +/* + * Functions provided by ip_options.c + */ + +extern void ip_options_build(struct sk_buff *skb, struct options *opt, __u32 daddr, __u32 saddr, int is_frag); +extern int ip_options_echo(struct options *dopt, struct options *sopt, __u32 daddr, __u32 saddr, struct sk_buff *skb); +extern void ip_options_fragment(struct sk_buff *skb); +extern int ip_options_compile(struct options *opt, struct sk_buff *skb); + +/* + * Functions provided by ip_sockglue.c + */ + +extern int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen); +extern int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen); + #endif /* _IP_H */ diff --git a/include/net/ip_alias.h b/include/net/ip_alias.h new file mode 100644 index 000000000..683a04276 --- /dev/null +++ b/include/net/ip_alias.h @@ -0,0 +1,23 @@ +/* + * IP_ALIAS (AF_INET) aliasing definitions. + * + * + * Version: @(#)ip_alias.h 0.43 12/20/95 + * + * Author: Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar> + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#ifndef _IP_ALIAS_H +#define _IP_ALIAS_H + +extern int ip_alias_init(void); +extern int ip_alias_done(void); + +#endif /* _IP_ALIAS_H */ diff --git a/include/net/ip_forward.h b/include/net/ip_forward.h new file mode 100644 index 000000000..f1b532f31 --- /dev/null +++ b/include/net/ip_forward.h @@ -0,0 +1,11 @@ +#ifndef __NET_IP_FORWARD_H +#define __NET_IP_FORWARD_H + +#define IPFWD_FRAGMENT 1 +#define IPFWD_LASTFRAG 2 +#define IPFWD_MASQUERADED 4 +#define IPFWD_MULTICASTING 8 +#define IPFWD_MULTITUNNEL 0x10 +#define IPFWD_NOTTLDEC 0x20 + +#endif diff --git a/include/net/ip_masq.h b/include/net/ip_masq.h new file mode 100644 index 000000000..8b29eeb15 --- /dev/null +++ b/include/net/ip_masq.h @@ -0,0 +1,172 @@ +/* + * IP masquerading functionality definitions + */ + +#ifndef _IP_MASQ_H +#define _IP_MASQ_H + +#include <linux/types.h> +#include <linux/netdevice.h> +#include <linux/skbuff.h> + +/* + * Linux ports don't normally get allocated above 32K. + * I used an extra 4K port-space + */ + +#define PORT_MASQ_BEGIN 61000 +#define PORT_MASQ_END (PORT_MASQ_BEGIN+4096) + +#define MASQUERADE_EXPIRE_TCP 15*60*HZ +#define MASQUERADE_EXPIRE_TCP_FIN 2*60*HZ +#define MASQUERADE_EXPIRE_UDP 5*60*HZ + +#define IP_MASQ_F_OUT_SEQ 0x01 /* must do output seq adjust */ +#define IP_MASQ_F_IN_SEQ 0x02 /* must do input seq adjust */ +#define IP_MASQ_F_NO_DPORT 0x04 /* no dport set yet */ +#define IP_MASQ_F_NO_DADDR 0x08 /* no daddr yet */ +#define IP_MASQ_F_HASHED 0x10 /* hashed entry */ +#define IP_MASQ_F_SAW_RST 0x20 /* tcp rst pkt seen */ +#define IP_MASQ_F_SAW_FIN_IN 0x40 /* tcp fin pkt seen incoming */ +#define IP_MASQ_F_SAW_FIN_OUT 0x80 /* tcp fin pkt seen outgoing */ +#define IP_MASQ_F_SAW_FIN (IP_MASQ_F_SAW_FIN_IN | \ + IP_MASQ_F_SAW_FIN_OUT) + /* tcp fin pkts seen */ + +#ifdef __KERNEL__ + +/* + * Delta seq. info structure + * Each MASQ struct has 2 (output AND input seq. changes). + */ + +struct ip_masq_seq { + __u32 init_seq; /* Add delta from this seq */ + short delta; /* Delta in sequence numbers */ + short previous_delta; /* Delta in sequence numbers before last resized pkt */ +}; + +/* + * MASQ structure allocated for each masqueraded association + */ +struct ip_masq { + struct ip_masq *m_link, *s_link; /* hashed link ptrs */ + struct timer_list timer; /* Expiration timer */ + __u16 protocol; /* Which protocol are we talking? */ + __u16 sport, dport, mport; /* src, dst & masq ports */ + __u32 saddr, daddr, maddr; /* src, dst & masq addresses */ + struct ip_masq_seq out_seq, in_seq; + struct ip_masq_app *app; /* bound ip_masq_app object */ + void *app_data; /* Application private data */ + unsigned flags; /* status flags */ +}; + +/* + * timeout values + */ + +struct ip_fw_masq { + int tcp_timeout; + int tcp_fin_timeout; + int udp_timeout; +}; + +extern struct ip_fw_masq *ip_masq_expire; + +/* + * [0]: UDP free_ports + * [1]: TCP free_ports + */ + +extern int ip_masq_free_ports[2]; + +/* + * ip_masq initializer (registers symbols and /proc/net entries) + */ +extern int ip_masq_init(void); + +/* + * functions called from ip layer + */ +extern int ip_fw_masquerade(struct sk_buff **, struct device *); +extern int ip_fw_masq_icmp(struct sk_buff **, struct device *); +extern int ip_fw_demasquerade(struct sk_buff **, struct device *); + +/* + * ip_masq obj creation/deletion functions. + */ +extern struct ip_masq *ip_masq_new(struct device *dev, int proto, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned flags); +extern void ip_masq_set_expire(struct ip_masq *ms, unsigned long tout); + + +/* + * + * IP_MASQ_APP: IP application masquerading definitions + * + */ + +struct ip_masq_app +{ + struct ip_masq_app *next; + char *name; /* name of application proxy */ + unsigned type; /* type = proto<<16 | port (host byte order)*/ + int n_attach; + int (*masq_init_1) /* ip_masq initializer */ + (struct ip_masq_app *, struct ip_masq *); + int (*masq_done_1) /* ip_masq fin. */ + (struct ip_masq_app *, struct ip_masq *); + int (*pkt_out) /* output (masquerading) hook */ + (struct ip_masq_app *, struct ip_masq *, struct sk_buff **, struct device *); + int (*pkt_in) /* input (demasq) hook */ + (struct ip_masq_app *, struct ip_masq *, struct sk_buff **, struct device *); +}; + +/* + * ip_masq_app initializer + */ +extern int ip_masq_app_init(void); + +/* + * ip_masq_app object registration functions (port: host byte order) + */ +extern int register_ip_masq_app(struct ip_masq_app *mapp, unsigned short proto, __u16 port); +extern int unregister_ip_masq_app(struct ip_masq_app *mapp); + +/* + * get ip_masq_app obj by proto,port(net_byte_order) + */ +extern struct ip_masq_app * ip_masq_app_get(unsigned short proto, __u16 port); + +/* + * ip_masq TO ip_masq_app (un)binding functions. + */ +extern struct ip_masq_app * ip_masq_bind_app(struct ip_masq *ms); +extern int ip_masq_unbind_app(struct ip_masq *ms); + +/* + * output and input app. masquerading hooks. + * + */ +extern int ip_masq_app_pkt_out(struct ip_masq *, struct sk_buff **skb_p, struct device *dev); +extern int ip_masq_app_pkt_in(struct ip_masq *, struct sk_buff **skb_p, struct device *dev); + +/* + * service routine(s). + */ +extern struct ip_masq * ip_masq_out_get_2(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); +extern struct ip_masq * ip_masq_in_get_2(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); + +/* + * /proc/net entry + */ +extern int ip_masq_app_getinfo(char *buffer, char **start, off_t offset, int length, int dummy); + +/* + * skb_replace function used by "client" modules to replace + * a segment of skb. + */ +extern struct sk_buff * ip_masq_skb_replace(struct sk_buff *skb, int pri, char *o_buf, int o_len, char *n_buf, int n_len); + +#endif /* __KERNEL__ */ + +#endif /* _IP_MASQ_H */ diff --git a/include/net/ipip.h b/include/net/ipip.h index 398e375de..bba1492ed 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -1,4 +1,4 @@ extern int ipip_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, - unsigned long daddr, unsigned short len, unsigned long saddr, + __u32 daddr, unsigned short len, __u32 saddr, int redo, struct inet_protocol *protocol); diff --git a/include/net/ipv6.h b/include/net/ipv6.h new file mode 100644 index 000000000..5b1042927 --- /dev/null +++ b/include/net/ipv6.h @@ -0,0 +1,296 @@ +/* + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * $Id: ipv6.h,v 1.19 1996/09/24 17:04:20 roque Exp $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _NET_IPV6_H +#define _NET_IPV6_H + +#include <linux/ipv6.h> +#include <net/ndisc.h> + +/* + * NextHeader field of IPv6 header + */ + +#define NEXTHDR_HOP 0 /* Hop-by-hop option header. */ +#define NEXTHDR_TCP 6 /* TCP segment. */ +#define NEXTHDR_UDP 17 /* UDP message. */ +#define NEXTHDR_IPV6 41 /* IPv6 in IPv6 */ +#define NEXTHDR_ROUTING 43 /* Routing header. */ +#define NEXTHDR_FRAGMENT 44 /* Fragmentation/reassembly header. */ +#define NEXTHDR_ESP 50 /* Encapsulating security payload. */ +#define NEXTHDR_AUTH 51 /* Authentication header. */ +#define NEXTHDR_ICMP 58 /* ICMP for IPv6. */ +#define NEXTHDR_NONE 59 /* No next header */ +#define NEXTHDR_DEST 60 /* Destination options header. */ + +#define NEXTHDR_MAX 255 + + + +#define IPV6_DEFAULT_HOPLIMIT 64 +#define IPV6_DEFAULT_MCASTHOPS 1 + +/* + * Addr type + * + * type - unicast | multicast | anycast + * scope - local | site | global + * v4 - compat + * v4mapped + * any + * loopback + */ + +#define IPV6_ADDR_ANY 0x0000U + +#define IPV6_ADDR_UNICAST 0x0001U +#define IPV6_ADDR_MULTICAST 0x0002U +#define IPV6_ADDR_ANYCAST 0x0004U + +#define IPV6_ADDR_LOOPBACK 0x0010U +#define IPV6_ADDR_LINKLOCAL 0x0020U +#define IPV6_ADDR_SITELOCAL 0x0040U + +#define IPV6_ADDR_COMPATv4 0x0080U + +#define IPV6_ADDR_SCOPE_MASK 0x00f0U + +#define IPV6_ADDR_MAPPED 0x1000U +#define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */ + +/* + * fragmentation header + */ + +struct frag_hdr { + unsigned char nexthdr; + unsigned char reserved; + unsigned short frag_off; + __u32 identification; +}; + +#ifdef __KERNEL__ + +#include <net/sock.h> + +extern struct ipv6_mib ipv6_statistics; + +extern int ipv6_forwarding; /* host/router switch */ +extern int ipv6_hop_limit; /* default hop limit */ + +struct ipv6_frag { + __u16 offset; + __u16 len; + struct sk_buff *skb; + + struct frag_hdr *fhdr; + + struct ipv6_frag *next; +}; + +/* + * Equivalent of ipv4 struct ipq + */ + +struct frag_queue { + + struct frag_queue *next; + struct frag_queue *prev; + + __u32 id; /* fragment id */ + struct timer_list timer; /* expire timer */ + struct ipv6_frag *fragments; + struct device *dev; + __u8 last_in; /* has last segment arrived? */ + __u8 nexthdr; + __u8 *nhptr; +}; + +extern int ipv6_routing_header(struct sk_buff **skb, + struct device *dev, + __u8 *nhptr, + struct ipv6_options *opt); + +extern int ipv6_reassembly(struct sk_buff **skb, + struct device *dev, + __u8 *nhptr, + struct ipv6_options *opt); + +#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */ + +/* + * Function prototype for build_xmit + */ + +typedef int (*inet_getfrag_t) (const void *data, + struct in6_addr *addr, + char *, + unsigned int, unsigned int); + + +extern int ipv6_addr_type(struct in6_addr *addr); + +extern __inline__ int ipv6_addr_cmp(struct in6_addr *a1, struct in6_addr *a2) +{ + return memcmp((void *) a1, (void *) a2, sizeof(struct in6_addr)); +} + +extern __inline__ void ipv6_addr_copy(struct in6_addr *a1, struct in6_addr *a2) +{ + memcpy((void *) a1, (void *) a2, sizeof(struct in6_addr)); +} + +#ifndef __HAVE_ARCH_ADDR_SET +extern __inline__ void ipv6_addr_set(struct in6_addr *addr, + __u32 w1, __u32 w2, + __u32 w3, __u32 w4) +{ + addr->s6_addr32[0] = w1; + addr->s6_addr32[1] = w2; + addr->s6_addr32[2] = w3; + addr->s6_addr32[3] = w4; +} +#endif + +extern __inline__ int ipv6_addr_any(struct in6_addr *a) +{ + return ((a->s6_addr32[0] | a->s6_addr32[1] | + a->s6_addr32[2] | a->s6_addr32[3] ) == 0); +} + +/* + * Prototypes exported by ipv6 + */ + +#if 0 +extern int ipv6_build_header(struct sk_buff *skb, + struct device *dev, + struct in6_addr *saddr_in, + struct in6_addr *daddr_in, + int proto, int len, + struct ipv6_pinfo *np); +#endif + +extern void ipv6_redo_mac_hdr(struct sk_buff *skb, + struct neighbour *neigh, + int len); + +extern int ipv6_bld_hdr_2(struct sock *sk, + struct sk_buff *skb, + struct device *dev, + struct neighbour *neigh, + struct in6_addr *saddr, + struct in6_addr *daddr, + int proto, int len); + +extern int ipv6_xmit(struct sock *sk, + struct sk_buff *skb, + struct in6_addr *saddr, + struct in6_addr *daddr, + struct ipv6_options *opt, + int proto); + +extern void ipv6_queue_xmit(struct sock *sk, + struct device *dev, + struct sk_buff *skb, + int free); + +extern int ipv6_build_xmit(struct sock *sk, + inet_getfrag_t getfrag, + const void * data, + struct in6_addr * daddr, + unsigned short int length, + struct in6_addr * saddr, + struct device *dev, + struct ipv6_options *opt, + int proto, int noblock); + +/* + * rcv function (called from netdevice level) + */ + +extern int ipv6_rcv(struct sk_buff *skb, + struct device *dev, + struct packet_type *pt); + +extern void ipv6_forward(struct sk_buff *skb, + struct device *dev, + int flags); + +#define IP6_FW_SRCRT 0x1 +#define IP6_FW_STRICT 0x2 + +/* + * Extension header (options) processing + */ +extern int ipv6opt_bld_rthdr(struct sk_buff *skb, + struct ipv6_options *opt, + struct in6_addr *addr, + int proto); + +extern int ipv6opt_srcrt_co(struct sockaddr_in6 *sin6, + int len, + struct ipv6_options *opt); + +extern int ipv6opt_srcrt_cl(struct sockaddr_in6 *sin6, + int num_addrs, + struct ipv6_options *opt); + +extern int ipv6opt_srt_tosin(struct ipv6_options *opt, + struct sockaddr_in6 *sin6, + int len); + +extern void ipv6opt_free(struct ipv6_options *opt); + + +/* + * socket lookup (af_inet6.c) + */ + +extern struct sock * inet6_get_sock(struct proto *prot, + struct in6_addr *loc_addr, + struct in6_addr *rmt_addr, + unsigned short loc_port, + unsigned short rmt_port); + +extern struct sock * inet6_get_sock_raw(struct sock *sk, + unsigned short num, + struct in6_addr *loc_addr, + struct in6_addr *rmt_addr); + +extern struct sock * inet6_get_sock_mcast(struct sock *sk, + unsigned short num, + unsigned short rmt_port, + struct in6_addr *loc_addr, + struct in6_addr *rmt_addr); + +/* + * socket options (ipv6_sockglue.c) + */ + +extern int ipv6_setsockopt(struct sock *sk, int level, + int optname, char *optval, + int optlen); +extern int ipv6_getsockopt(struct sock *sk, int level, + int optname, char *optval, + int *optlen); + + +extern void ipv6_init(void); +extern void ipv6_cleanup(void); +#endif +#endif + + + diff --git a/include/net/ipv6_route.h b/include/net/ipv6_route.h new file mode 100644 index 000000000..aaa1ba0a2 --- /dev/null +++ b/include/net/ipv6_route.h @@ -0,0 +1,200 @@ +/* + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _NET_IPV6_ROUTE_H +#define _NET_IPV6_ROUTE_H + +#include <linux/ipv6_route.h> + + +#ifdef __KERNEL__ + + +struct fib6_node { + struct fib6_node *parent; + struct fib6_node *left; + struct fib6_node *right; + + struct rt6_info *leaf; + + __u16 fn_bit; /* bit key */ + __u16 fn_flags; + __u32 fn_sernum; +}; + + +struct rt6_info; + +typedef void (*rt6_output_method_t) (struct sk_buff *skb, struct rt6_info *rt); + +struct rt6_info { + struct fib6_node *fib_node; + struct rt6_info *next; + + struct in6_addr rt_dst; + + atomic_t rt_use; /* dcache references */ + atomic_t rt_ref; /* fib references */ + + struct neighbour *rt_nexthop; + struct device *rt_dev; + + rt6_output_method_t rt_output_method; + + __u16 rt_metric; + __u16 rt_prefixlen; + __u32 rt_flags; + unsigned long rt_expires; +}; + +extern struct rt6_info *default_rt_list; +extern struct rt6_info *last_resort_rt; + +struct dest_entry { + struct rt6_info rt; + + __u32 dc_irtt; + __u32 dc_window; + __u16 dc_pmtu; + + unsigned long dc_tstamp; /* for garbage collection */ + +#define dc_addr rt.rt_dst +#define dc_usecnt rt.rt_use +#define dc_nexthop rt.rt_nexthop +#define dc_flags rt.rt_flags +}; + +/* + * Structure for assync processing of operations on the routing + * table + */ + +struct rt6_req { + int operation; + struct rt6_info *ptr; + + struct rt6_req *next; + struct rt6_req *prev; + +#define RT_OPER_ADD 1 +#define RT_OPER_DEL 2 +}; + +struct rt6_statistics { + __u32 fib_nodes; + __u32 fib_route_nodes; + __u32 fib_rt_alloc; + __u32 fib_rt_entries; + __u32 fib_dc_alloc; +}; + +#define RTN_ROOT 0x0001 /* root node */ +#define RTN_BACKTRACK 0x0002 /* backtrack point */ +#define RTN_TAG 0x0010 + +/* + * Values for destination cache garbage colection + * These are wild guesses for now... + */ + +#define DC_WATER_MARK 512 +#define DC_SHORT_TIMEOUT (5*HZ) +#define DC_LONG_TIMEOUT (15*HZ) + +#define DC_TIME_RUN (5*HZ) +#define DC_TIME_RETRY HZ + +#define RT6_FILTER_NONE 0 +#define RT6_FILTER_RTNODES 1 +/* + * Prototypes + */ + +/* + * check/obtain destination cache from routing table + */ + +extern struct dest_entry * ipv6_dst_check(struct dest_entry *dc, + struct in6_addr * daddr, + __u32 sernum, int flags); + +extern struct dest_entry * ipv6_dst_route(struct in6_addr * daddr, + struct device *src_dev, + int flags); + +extern void ipv6_dst_unlock(struct dest_entry *dest); + +extern struct rt6_info * fibv6_lookup(struct in6_addr *addr, + struct device *dev, + int flags); + +/* + * user space set/del route + */ + +extern int ipv6_route_ioctl(unsigned int cmd, void *arg); + + +extern void ipv6_route_init(void); +extern void ipv6_route_cleanup(void); + +extern void rt6_ifdown(struct device *dev); + +extern int ipv6_route_add(struct in6_rtmsg *rt); + +extern int fib6_del_rt(struct rt6_info *rt); + +extern void rt6_sndmsg(__u32 type, struct in6_addr *dst, + struct in6_addr *gw, __u16 plen, + struct device *dev, + __u16 metric, __u16 flags); +/* + * ICMP interface + */ + +extern struct rt6_info * ipv6_rt_redirect(struct device *dev, + struct in6_addr *dest, + struct in6_addr *target, + int on_link); + +extern void rt6_handle_pmtu(struct in6_addr *addr, + int pmtu); +/* + * + */ + +extern struct fib6_node routing_table; +extern struct rt6_statistics rt6_stats; + +static __inline__ void rt_release(struct rt6_info *rt) +{ + atomic_dec(&rt->rt_ref); + if ((rt->rt_use | rt->rt_ref) == 0) + { + if (rt->rt_nexthop) + { + ndisc_dec_neigh(rt->rt_nexthop); + } + + if (rt->rt_flags & RTI_DCACHE) + { + rt6_stats.fib_dc_alloc--; + } + rt6_stats.fib_rt_alloc--; + kfree(rt); + } +} + +#endif + +#endif diff --git a/include/net/ipx.h b/include/net/ipx.h index 6842c8325..f23800901 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h @@ -11,8 +11,9 @@ #ifndef _NET_INET_IPX_H_ #define _NET_INET_IPX_H_ +#include <linux/netdevice.h> #include <linux/skbuff.h> -#include "datalink.h" +#include <net/datalink.h> #include <linux/ipx.h> typedef struct @@ -23,12 +24,13 @@ typedef struct } ipx_address; #define ipx_broadcast_node "\377\377\377\377\377\377" +#define ipx_this_node "\0\0\0\0\0\0" typedef struct ipx_packet { - unsigned short ipx_checksum; + unsigned short ipx_checksum __attribute__ ((packed)); #define IPX_NO_CHECKSUM 0xFFFF - unsigned short ipx_pktsize; + unsigned short ipx_pktsize __attribute__ ((packed)); unsigned char ipx_tctrl; unsigned char ipx_type; #define IPX_TYPE_UNKNOWN 0x00 @@ -44,7 +46,7 @@ typedef struct ipx_packet typedef struct sock ipx_socket; -#include "ipxcall.h" +#include <net/ipxcall.h> extern int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt); extern void ipxrtr_device_down(struct device *dev); diff --git a/include/net/ndisc.h b/include/net/ndisc.h new file mode 100644 index 000000000..3605997e7 --- /dev/null +++ b/include/net/ndisc.h @@ -0,0 +1,184 @@ +#ifndef _NDISC_H +#define _NDISC_H + + +/* + * Neighbor Cache Entry States (7.3.2.) + */ + +/* + * The lsb is set for states that have a timer associated + */ + +#define NUD_NONE 0x00 +#define NUD_INCOMPLETE 0x11 +#define NUD_REACHABLE 0x20 +#define NUD_STALE 0x30 +#define NUD_DELAY 0x41 +#define NUD_PROBE 0x51 +#define NUD_FAILED 0x60 /* neighbour discovery failed */ + +#define NUD_IN_TIMER 0x01 + +#define NDISC_QUEUE_LEN 3 + +#define NCF_NOARP 0x01 /* no ARP needed on this device */ +#define NCF_SUBNET 0x02 /* NC entry for subnet */ +#define NCF_INVALID 0x04 +#define NCF_DELAY_EXPIRED 0x08 /* time to move to PROBE */ +#define NCF_ROUTER 0x10 /* neighbour is a router */ +#define NCF_HHVALID 0x20 /* Hardware header is valid */ + +/* + * ICMP codes for neighbour discovery messages + */ + +#define NDISC_ROUTER_SOLICITATION 133 +#define NDISC_ROUTER_ADVERTISEMENT 134 +#define NDISC_NEIGHBOUR_SOLICITATION 135 +#define NDISC_NEIGHBOUR_ADVERTISEMENT 136 +#define NDISC_REDIRECT 137 + +/* + * ndisc options + */ + +#define ND_OPT_SOURCE_LL_ADDR 1 +#define ND_OPT_TARGET_LL_ADDR 2 +#define ND_OPT_PREFIX_INFO 3 +#define ND_OPT_REDIRECT_HDR 4 +#define ND_OPT_MTU 5 + +#define MAX_RTR_SOLICITATION_DELAY HZ + +#define RECHABLE_TIME (30*HZ) +#define RETRANS_TIMER HZ + +#define MIN_RANDOM_FACTOR (1/2) +#define MAX_RANDOM_FACTOR (3/2) + +#define REACH_RANDOM_INTERVAL (60*60*HZ) /* 1 hour */ + +#ifdef __KERNEL__ + +#include <linux/skbuff.h> +#include <linux/netdevice.h> +#include <linux/icmpv6.h> +#include <asm/atomic.h> + +/* + * neighbour cache entry + * used by neighbour discovery module + * as similar functions of "struct hh_cache" used in ipv4 + */ +struct neighbour { + struct in6_addr addr; /* next hop addr */ + __u8 len; /* prefix len */ + __u8 type; /* {unicast, multicast} */ + + struct device * dev; + + __u8 flags; + + + __u8 hh_data[MAX_ADDR_LEN]; /* cached hdr */ + __u8 *h_dest; /* dest addr */ + + struct sk_buff_head arp_queue; /* packets waiting for ND to + finish */ + atomic_t refcnt; + __u8 nud_state; + __u8 probes; + __u32 tstamp; /* last reachable conf */ + + unsigned long expires; /* timer expires at */ + + struct neighbour *next; /* for hash chaining */ + struct neighbour *prev; /* for hash chaining */ +}; + +struct nd_msg { + struct icmpv6hdr icmph; + struct in6_addr target; + struct { + __u8 opt_type; + __u8 opt_len; + __u8 link_addr[MAX_ADDR_LEN]; + } opt; +}; + +struct ra_msg { + struct icmpv6hdr icmph; + __u32 reachable_time; + __u32 retrans_timer; +}; + +struct ndisc_statistics { + __u32 allocs; /* allocated entries */ + __u32 free_delayed; /* zombie entries */ + __u32 snt_probes_ucast; /* ns probes sent (ucast) */ + __u32 snt_probes_mcast; /* ns probes sent (mcast) */ + __u32 rcv_probes_ucast; /* ns probes rcv (ucast) */ + __u32 rcv_probes_mcast; /* ns probes rcv (mcast) */ + __u32 rcv_upper_conf; /* confirmations from upper layers */ + __u32 res_failed; /* address resolution failures */ +}; + +extern struct neighbour * ndisc_get_neigh(struct device *dev, + struct in6_addr *addr); + +extern void ndisc_validate(struct neighbour *neigh); + +extern void ndisc_init(struct proto_ops *ops); +extern void ndisc_cleanup(void); + +extern int ndisc_eth_resolv(unsigned char *, + struct device *, + struct sk_buff *); + +extern int ndisc_rcv(struct sk_buff *skb, + struct device *dev, + struct in6_addr *saddr, + struct in6_addr *daddr, + struct ipv6_options *opt, + unsigned short len); + +extern void ndisc_event_send(struct neighbour *neigh, + struct sk_buff *skb); + +extern void ndisc_send_ns(struct device *dev, + struct neighbour *neigh, + struct in6_addr *solicit, + struct in6_addr *daddr, + struct in6_addr *saddr); + +extern void ndisc_send_rs(struct device *dev, + struct in6_addr *saddr, + struct in6_addr *daddr); + +extern int (*ndisc_eth_hook) (unsigned char *, + struct device *, + struct sk_buff *); + +extern void ndisc_forwarding_on(void); +extern void ndisc_forwarding_off(void); + +extern void ndisc_send_redirect(struct sk_buff *skb, + struct neighbour *neigh, + struct in6_addr *target); + +struct rt6_info * dflt_rt_lookup(void); + +extern unsigned long nd_rand_seed; +extern int ipv6_random(void); + + +static __inline__ void ndisc_dec_neigh(struct neighbour *neigh) +{ + atomic_dec(&neigh->refcnt); +} + +#endif /* __KERNEL__ */ + + +#endif diff --git a/include/net/netlink.h b/include/net/netlink.h new file mode 100644 index 000000000..f0b9c9d74 --- /dev/null +++ b/include/net/netlink.h @@ -0,0 +1,35 @@ +#ifndef __NET_NETLINK_H +#define __NET_NETLINK_H + +#define NET_MAJOR 36 /* Major 18 is reserved for networking */ +#define MAX_LINKS 16 /* 18,0 for route updates, 18,1 for SKIP, 18,2 debug tap 18,3 PPP reserved */ + /* 4-7 are psi0-psi3 8 is arpd 9 is ppp */ + /* 10 is for IPSEC <John Ioannidis> */ + /* 11 IPv6 route updates */ + /* 12 is for firewall trapout */ +#define MAX_QBYTES 32768 /* Maximum bytes in the queue */ + +#include <linux/config.h> + +extern int netlink_attach(int unit, int (*function)(int,struct sk_buff *skb)); +extern int netlink_donothing(int, struct sk_buff *skb); +extern void netlink_detach(int unit); +extern int netlink_post(int unit, struct sk_buff *skb); +extern int init_netlink(void); + +#define NETLINK_ROUTE 0 /* Routing/device hook */ +#define NETLINK_SKIP 1 /* Reserved for ENskip */ +#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ +#define NETLINK_FIREWALL 3 /* Firewalling hook */ +#define NETLINK_PSI 4 /* PSI devices - 4 to 7 */ +#define NETLINK_ARPD 8 +#define NETLINK_IPSEC 10 /* IPSEC */ +#define NETLINK_ROUTE6 11 /* af_inet6 route comm channel */ +#define NETLINK_ + +#ifdef CONFIG_RTNETLINK +extern void ip_netlink_msg(unsigned long, __u32, __u32, __u32, short, short, char *); +#else +#define ip_netlink_msg(a,b,c,d,e,f,g) +#endif +#endif diff --git a/include/net/netrom.h b/include/net/netrom.h index c6f772920..ce398d23c 100644 --- a/include/net/netrom.h +++ b/include/net/netrom.h @@ -7,6 +7,12 @@ #ifndef _NETROM_H #define _NETROM_H #include <linux/netrom.h> + +#define NR_T1CLAMPLO (1 * PR_SLOWHZ) /* If defined, clamp at 1 second **/ +#define NR_T1CLAMPHI (300 * PR_SLOWHZ) /* If defined, clamp at 30 seconds **/ + +#define NR_NETWORK_LEN 15 +#define NR_TRANSPORT_LEN 5 #define NR_PROTO_IP 0x0C @@ -29,35 +35,51 @@ #define NR_STATE_2 2 #define NR_STATE_3 3 -#define NR_DEFAULT_T1 (120 * PR_SLOWHZ) /* Outstanding frames - 10 seconds */ -#define NR_DEFAULT_T2 (5 * PR_SLOWHZ) /* Response delay - 3 seconds */ -#define NR_DEFAULT_N2 3 /* Number of Retries */ -#define NR_DEFAULT_T4 (180 * PR_SLOWHZ) /* Transport Busy Delay */ -#define NR_DEFAULT_WINDOW 4 /* Default Window Size */ -#define NR_DEFAULT_OBS 6 /* Default Obscolesence Count */ -#define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality */ -#define NR_DEFAULT_TTL 16 /* Default Time To Live */ +#define NR_DEFAULT_T1 (120 * PR_SLOWHZ) /* Outstanding frames - 120 seconds */ +#define NR_DEFAULT_T2 (5 * PR_SLOWHZ) /* Response delay - 5 seconds */ +#define NR_DEFAULT_N2 3 /* Number of Retries - 3 */ +#define NR_DEFAULT_T4 (180 * PR_SLOWHZ) /* Busy Delay - 180 seconds */ +#define NR_DEFAULT_IDLE (20* 60 * PR_SLOWHZ) /* No Activuty Timeout - 900 seconds*/ +#define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */ +#define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */ +#define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */ +#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */ #define NR_MODULUS 256 -#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable */ +#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */ +#define NR_DEFAULT_PACLEN 236 /* Default Packet Length - 236 */ typedef struct { ax25_address user_addr, source_addr, dest_addr; - unsigned char my_index, my_id; - unsigned char your_index, your_id; - unsigned char state; + struct device *device; + unsigned char my_index, my_id; + unsigned char your_index, your_id; + unsigned char state, condition, bpqext, hdrincl; unsigned short vs, vr, va, vl; - unsigned char condition; unsigned char n2, n2count; - unsigned short t1, t2, rtt; - unsigned short t1timer, t2timer, t4timer; - struct sk_buff_head ack_queue, reseq_queue; + unsigned short t1, t2, t4, idle, rtt; + unsigned short t1timer, t2timer, t4timer, idletimer; + unsigned short fraglen, paclen; + struct sk_buff_head ack_queue; + struct sk_buff_head reseq_queue; + struct sk_buff_head frag_queue; struct sock *sk; /* Backlink to socket */ } nr_cb; +struct nr_neigh { + struct nr_neigh *next; + ax25_address callsign; + ax25_digi *digipeat; + struct device *dev; + unsigned char quality; + unsigned char locked; + unsigned short count; + unsigned int number; +}; + struct nr_route { - unsigned char quality; - unsigned char obs_count; - unsigned short neighbour; + unsigned char quality; + unsigned char obs_count; + struct nr_neigh *neighbour; }; struct nr_node { @@ -69,37 +91,35 @@ struct nr_node { struct nr_route routes[3]; }; -struct nr_neigh { - struct nr_neigh *next; - ax25_address callsign; - struct device *dev; - unsigned char quality; - unsigned char locked; - unsigned short count; - unsigned short number; -}; - -/* netrom.c */ -extern struct nr_parms_struct nr_default; +/* af_netrom.c */ +extern int sysctl_netrom_default_path_quality; +extern int sysctl_netrom_obsolescence_count_initialiser; +extern int sysctl_netrom_network_ttl_initialiser; +extern int sysctl_netrom_transport_timeout; +extern int sysctl_netrom_transport_maximum_tries; +extern int sysctl_netrom_transport_acknowledge_delay; +extern int sysctl_netrom_transport_busy_delay; +extern int sysctl_netrom_transport_requested_window_size; +extern int sysctl_netrom_transport_no_activity_timeout; +extern int sysctl_netrom_transport_packet_length; +extern int sysctl_netrom_routing_control; extern int nr_rx_frame(struct sk_buff *, struct device *); extern void nr_destroy_socket(struct sock *); -extern int nr_get_info(char *, char **, off_t, int); /* nr_dev.c */ extern int nr_rx_ip(struct sk_buff *, struct device *); extern int nr_init(struct device *); -#include "nrcall.h" +#include <net/nrcall.h> /* nr_in.c */ extern int nr_process_rx_frame(struct sock *, struct sk_buff *); /* nr_out.c */ -extern int nr_output(struct sock *, struct sk_buff *); +extern void nr_output(struct sock *, struct sk_buff *); extern void nr_send_nak_frame(struct sock *); extern void nr_kick(struct sock *); extern void nr_transmit_buffer(struct sock *, struct sk_buff *); -extern void nr_nr_error_recovery(struct sock *); extern void nr_establish_data_link(struct sock *); extern void nr_enquiry_response(struct sock *); extern void nr_check_iframes_acked(struct sock *, unsigned short); @@ -110,12 +130,13 @@ extern struct device *nr_dev_first(void); extern struct device *nr_dev_get(ax25_address *); extern int nr_rt_ioctl(unsigned int, void *); extern void nr_link_failed(ax25_address *, struct device *); -extern int nr_route_frame(struct sk_buff *, struct device *); -extern int nr_nodes_get_info(char *, char **, off_t, int); -extern int nr_neigh_get_info(char *, char **, off_t, int); +extern int nr_route_frame(struct sk_buff *, ax25_cb *); +extern int nr_nodes_get_info(char *, char **, off_t, int, int); +extern int nr_neigh_get_info(char *, char **, off_t, int, int); +extern void nr_rt_free(void); /* nr_subr.c */ -extern void nr_clear_tx_queue(struct sock *); +extern void nr_clear_queues(struct sock *); extern void nr_frames_acked(struct sock *, unsigned short); extern void nr_requeue_frames(struct sock *); extern int nr_validate_nr(struct sock *, unsigned short); @@ -125,7 +146,11 @@ extern void nr_transmit_dm(struct sk_buff *); extern unsigned short nr_calculate_t1(struct sock *); extern void nr_calculate_rtt(struct sock *); -/* ax25_timer */ +/* nr_timer.c */ extern void nr_set_timer(struct sock *); +/* sysctl_net_netrom.c */ +extern void nr_register_sysctl(void); +extern void nr_unregister_sysctl(void); + #endif diff --git a/include/net/nrcall.h b/include/net/nrcall.h index f58c2d4fe..09ee699d8 100644 --- a/include/net/nrcall.h +++ b/include/net/nrcall.h @@ -1,2 +1,2 @@ -/* Seperate to keep compilation of protocols.c simpler */ +/* Separate to keep compilation of protocols.c simpler */ extern void nr_proto_init(struct net_proto *pro); diff --git a/include/net/p8022.h b/include/net/p8022.h index 52c676be2..03d7c3d66 100644 --- a/include/net/p8022.h +++ b/include/net/p8022.h @@ -1,2 +1,7 @@ -struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *)); +#ifndef _NET_P8022_H +#define _NET_P8022_H +extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *)); +extern void unregister_8022_client(unsigned char type); + +#endif diff --git a/include/net/p8022tr.h b/include/net/p8022tr.h new file mode 100644 index 000000000..f4231ecee --- /dev/null +++ b/include/net/p8022tr.h @@ -0,0 +1,8 @@ +#ifndef _NET_P8022TR_H +#define _NET_P8022TR_H + +extern struct datalink_proto *register_8022tr_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *)); +extern void unregister_8022tr_client(unsigned char type); + +#endif + diff --git a/include/net/p8022trcall.h b/include/net/p8022trcall.h new file mode 100644 index 000000000..3ce6f3cdb --- /dev/null +++ b/include/net/p8022trcall.h @@ -0,0 +1,3 @@ +/* Separate to keep compilation of Space.c simpler */ +extern void p8022tr_proto_init(struct net_proto *); + diff --git a/include/net/protocol.h b/include/net/protocol.h index 3e0b6fb3c..979298832 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -17,11 +17,18 @@ * Changes: * Alan Cox : Added a name field and a frag handler * field for later. + * Alan Cox : Cleaned up, and sorted types. + * Pedro Roque : inet6 protocols */ #ifndef _PROTOCOL_H #define _PROTOCOL_H +#include <linux/config.h> +#include <linux/in6.h> +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +#include <linux/ipv6.h> +#endif #define MAX_INET_PROTOS 32 /* Must be a power of 2 */ @@ -29,31 +36,54 @@ /* This is used to register protocols. */ struct inet_protocol { int (*handler)(struct sk_buff *skb, struct device *dev, - struct options *opt, unsigned long daddr, - unsigned short len, unsigned long saddr, + struct options *opt, __u32 daddr, + unsigned short len, __u32 saddr, int redo, struct inet_protocol *protocol); - int (*frag_handler)(struct sk_buff *skb, struct device *dev, - struct options *opt, unsigned long daddr, - unsigned short len, unsigned long saddr, - int redo, struct inet_protocol *protocol); - void (*err_handler)(int err, unsigned char *buff, - unsigned long daddr, - unsigned long saddr, - struct inet_protocol *protocol); + void (*err_handler)(int type, int code, unsigned char *buff, + __u32 info, __u32 daddr, __u32 saddr, + struct inet_protocol *protocol, int len); struct inet_protocol *next; unsigned char protocol; unsigned char copy:1; void *data; - char *name; + const char *name; }; +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +struct inet6_protocol { + int (*handler)(struct sk_buff *skb, struct device *dev, + struct in6_addr *saddr, + struct in6_addr *daddr, + struct ipv6_options *opt, + unsigned short len, + int redo, struct inet6_protocol *protocol); + + void (*err_handler)(int type, int code, unsigned char *buff, + __u32 info, struct in6_addr *saddr, + struct in6_addr *daddr, + struct inet6_protocol *protocol); + struct inet6_protocol *next; + unsigned char protocol; + unsigned char copy:1; + void *data; + const char *name; +}; +#endif extern struct inet_protocol *inet_protocol_base; extern struct inet_protocol *inet_protos[MAX_INET_PROTOS]; +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +extern struct inet6_protocol *inet6_protocol_base; +extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; +#endif extern void inet_add_protocol(struct inet_protocol *prot); extern int inet_del_protocol(struct inet_protocol *prot); +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +extern void inet6_add_protocol(struct inet6_protocol *prot); +extern int inet6_del_protocol(struct inet6_protocol *prot); +#endif #endif /* _PROTOCOL_H */ diff --git a/include/net/psnap.h b/include/net/psnap.h index b69859dbd..49a68f7e9 100644 --- a/include/net/psnap.h +++ b/include/net/psnap.h @@ -1,2 +1,7 @@ -struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *)); +#ifndef _NET_PSNAP_H +#define _NET_PSNAP_H +extern struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *)); +extern void unregister_snap_client(unsigned char *desc); + +#endif diff --git a/include/net/rarp.h b/include/net/rarp.h index 02ee7784f..7bfb08ef1 100644 --- a/include/net/rarp.h +++ b/include/net/rarp.h @@ -3,12 +3,10 @@ #define _RARP_H extern int rarp_ioctl(unsigned int cmd, void *arg); -extern int rarp_rcv(struct sk_buff *skb, - struct device *dev, - struct packet_type *pt); extern int rarp_get_info(char *buffer, char **start, off_t offset, - int length); + int length, + int dummy); #endif /* _RARP_H */ diff --git a/include/net/raw.h b/include/net/raw.h index 8f1cf0c22..4b4248790 100644 --- a/include/net/raw.h +++ b/include/net/raw.h @@ -21,14 +21,14 @@ extern struct proto raw_prot; -extern void raw_err(int err, unsigned char *header, unsigned long daddr, - unsigned long saddr, struct inet_protocol *protocol); +extern void raw_err(int type, int code, unsigned char *header, __u32 daddr, + __u32 saddr, struct inet_protocol *protocol); extern int raw_recvfrom(struct sock *sk, unsigned char *to, int len, int noblock, unsigned flags, struct sockaddr_in *sin, int *addr_len); extern int raw_read(struct sock *sk, unsigned char *buff, int len, int noblock, unsigned flags); extern int raw_rcv(struct sock *, struct sk_buff *, struct device *, - long, long); + __u32, __u32); #endif /* _RAW_H */ diff --git a/include/net/rawv6.h b/include/net/rawv6.h new file mode 100644 index 000000000..30ecc7962 --- /dev/null +++ b/include/net/rawv6.h @@ -0,0 +1,21 @@ +#ifndef _NET_RAWV6_H +#define _NET_RAWV6_H + +#ifdef __KERNEL__ +extern int rawv6_rcv(struct sk_buff *skb, + struct device *dev, + struct in6_addr *saddr, + struct in6_addr *daddr, + struct ipv6_options *opt, + unsigned short len); + + +extern void rawv6_err(struct sock *sk, + int type, int code, + unsigned char *buff, + struct in6_addr *saddr, + struct in6_addr *daddr); + +#endif + +#endif diff --git a/include/net/rose.h b/include/net/rose.h new file mode 100644 index 000000000..84d4e9654 --- /dev/null +++ b/include/net/rose.h @@ -0,0 +1,183 @@ +/* + * Declarations of Rose type objects. + * + * Jonathan Naylor G4KLX 25/8/96 + */ + +#ifndef _ROSE_H +#define _ROSE_H +#include <linux/rose.h> + +#define ROSE_ADDR_LEN 5 + +#define ROSE_MIN_LEN 3 + +#define GFI 0x10 +#define Q_BIT 0x80 +#define D_BIT 0x40 +#define M_BIT 0x10 + +#define ROSE_CALL_REQUEST 0x0B +#define ROSE_CALL_ACCEPTED 0x0F +#define ROSE_CLEAR_REQUEST 0x13 +#define ROSE_CLEAR_CONFIRMATION 0x17 +#define ROSE_DATA 0x00 +#define ROSE_INTERRUPT 0x23 +#define ROSE_INTERRUPT_CONFIRMATION 0x27 +#define ROSE_RR 0x01 +#define ROSE_RNR 0x05 +#define ROSE_REJ 0x09 +#define ROSE_RESET_REQUEST 0x1B +#define ROSE_RESET_CONFIRMATION 0x1F +#define ROSE_REGISTRATION_REQUEST 0xF3 +#define ROSE_REGISTRATION_CONFIRMATION 0xF7 +#define ROSE_RESTART_REQUEST 0xFB +#define ROSE_RESTART_CONFIRMATION 0xFF +#define ROSE_DIAGNOSTIC 0xF1 +#define ROSE_ILLEGAL 0xFD + +/* Define Link State constants. */ + +#define ROSE_STATE_0 0 /* Ready */ +#define ROSE_STATE_1 1 /* Awaiting Call Accepted */ +#define ROSE_STATE_2 2 /* Awaiting Clear Confirmation */ +#define ROSE_STATE_3 3 /* Data Transfer */ +#define ROSE_STATE_4 4 /* Awaiting Reset Confirmation */ + +#define ROSE_DEFAULT_T0 (180 * PR_SLOWHZ) /* Default T10 T20 value */ +#define ROSE_DEFAULT_T1 (200 * PR_SLOWHZ) /* Default T11 T21 value */ +#define ROSE_DEFAULT_T2 (180 * PR_SLOWHZ) /* Default T12 T22 value */ +#define ROSE_DEFAULT_T3 (180 * PR_SLOWHZ) /* Default T13 T23 value */ +#define ROSE_DEFAULT_IDLE (20 * 60 * PR_SLOWHZ) /* Default No Activity value */ +#define ROSE_DEFAULT_WINDOW 2 /* Default Window Size */ +#define ROSE_MODULUS 8 +#define ROSE_MAX_WINDOW_SIZE 7 /* Maximum Window Allowable */ +#define ROSE_PACLEN 128 /* Default Packet Length */ + +#define FAC_NATIONAL 0x00 +#define FAC_CCITT 0x0F + +#define FAC_NATIONAL_RAND 0x7F +#define FAC_NATIONAL_FLAGS 0x3F +#define FAC_NATIONAL_DEST_DIGI 0xE9 +#define FAC_NATIONAL_SRC_DIGI 0xEB + +#define FAC_CCITT_DEST_NSAP 0xC9 +#define FAC_CCITT_SRC_NSAP 0xCB + +struct rose_neigh { + struct rose_neigh *next; + ax25_address callsign; + ax25_digi *digipeat; + struct device *dev; + unsigned short count; + unsigned int number; + int restarted; + struct sk_buff_head queue; + unsigned short t0, t0timer; + struct timer_list timer; +}; + +struct rose_node { + struct rose_node *next; + rose_address address; + unsigned char which; + unsigned char count; + struct rose_neigh *neighbour[3]; +}; + +struct rose_route { + struct rose_route *next; + unsigned int lci1, lci2; + struct rose_neigh *neigh1, *neigh2; + unsigned int rand; +}; + +typedef struct { + rose_address source_addr, dest_addr; + ax25_address source_call, dest_call; + unsigned char source_ndigis, dest_ndigis; + ax25_address source_digi, dest_digi; + struct rose_neigh *neighbour; + struct device *device; + unsigned int lci, rand; + unsigned char state, condition, hdrincl; + unsigned short vs, vr, va, vl; + unsigned short timer; + unsigned short t1, t2, t3, idle; + unsigned short fraglen; + struct sk_buff_head ack_queue; + struct sk_buff_head frag_queue; + struct sock *sk; /* Backlink to socket */ +} rose_cb; + +/* af_rose.c */ +extern int sysctl_rose_restart_request_timeout; +extern int sysctl_rose_call_request_timeout; +extern int sysctl_rose_reset_request_timeout; +extern int sysctl_rose_clear_request_timeout; +extern int sysctl_rose_no_activity_timeout; +extern int sysctl_rose_routing_control; +extern int rosecmp(rose_address *, rose_address *); +extern char *rose2asc(rose_address *); +extern struct sock *rose_find_socket(unsigned int, struct device *); +extern unsigned int rose_new_lci(struct device *); +extern int rose_rx_call_request(struct sk_buff *, struct device *, struct rose_neigh *, unsigned int); +extern void rose_destroy_socket(struct sock *); + +/* rose_dev.c */ +extern int rose_rx_ip(struct sk_buff *, struct device *); +extern int rose_init(struct device *); + +#include <net/rosecall.h> + +/* rose_in.c */ +extern int rose_process_rx_frame(struct sock *, struct sk_buff *); + +/* rose_link.c */ +extern void rose_link_rx_restart(struct sk_buff *, struct rose_neigh *, unsigned short); +extern void rose_transmit_restart_request(struct rose_neigh *); +extern void rose_transmit_restart_confirmation(struct rose_neigh *); +extern void rose_transmit_diagnostic(struct rose_neigh *, unsigned char); +extern void rose_transmit_clear_request(struct rose_neigh *, unsigned int, unsigned char); +extern void rose_transmit_link(struct sk_buff *, struct rose_neigh *); + +/* rose_out.c */ +extern void rose_output(struct sock *, struct sk_buff *); +extern void rose_kick(struct sock *); +extern void rose_enquiry_response(struct sock *); +extern void rose_check_iframes_acked(struct sock *, unsigned short); + +/* rose_route.c */ +extern void rose_rt_device_down(struct device *); +extern void rose_link_device_down(struct device *); +extern struct device *rose_dev_first(void); +extern struct device *rose_dev_get(rose_address *); +extern struct device *rose_ax25_dev_get(char *); +extern struct rose_neigh *rose_get_neigh(rose_address *); +extern int rose_rt_ioctl(unsigned int, void *); +extern void rose_link_failed(ax25_address *, struct device *); +extern int rose_route_frame(struct sk_buff *, ax25_cb *); +extern int rose_nodes_get_info(char *, char **, off_t, int, int); +extern int rose_neigh_get_info(char *, char **, off_t, int, int); +extern int rose_routes_get_info(char *, char **, off_t, int, int); +extern void rose_rt_free(void); + +/* rose_subr.c */ +extern void rose_clear_queues(struct sock *); +extern void rose_frames_acked(struct sock *, unsigned short); +extern void rose_requeue_frames(struct sock *); +extern int rose_validate_nr(struct sock *, unsigned short); +extern void rose_write_internal(struct sock *, int); +extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *); +extern int rose_parse_facilities(struct sk_buff *, rose_cb *); +extern int rose_create_facilities(unsigned char *, rose_cb *); + +/* rose_timer.c */ +extern void rose_set_timer(struct sock *); + +/* sysctl_net_rose.c */ +extern void rose_register_sysctl(void); +extern void rose_unregister_sysctl(void); + +#endif diff --git a/include/net/rosecall.h b/include/net/rosecall.h new file mode 100644 index 000000000..5bbe69cce --- /dev/null +++ b/include/net/rosecall.h @@ -0,0 +1,2 @@ +/* Separate to keep compilation of protocols.c simpler */ +extern void rose_proto_init(struct net_proto *pro); diff --git a/include/net/route.h b/include/net/route.h index d85fefdcd..de59bda48 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -12,6 +12,10 @@ * Fixes: * Alan Cox : Reformatted. Added ip_rt_local() * Alan Cox : Support for TCP parameters. + * Alexey Kuznetsov: Major changes for new routing code. + * + * FIXME: + * Make atomic ops more generic and hide them in asm/... * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -21,36 +25,153 @@ #ifndef _ROUTE_H #define _ROUTE_H +#include <linux/config.h> + +/* + * 0 - no debugging messages + * 1 - rare events and bugs situations (default) + * 2 - trace mode. + */ +#define RT_CACHE_DEBUG 0 + +#define RT_HASH_DIVISOR 256 +#define RT_CACHE_SIZE_MAX 256 + +#define RTZ_HASH_DIVISOR 256 + +#if RT_CACHE_DEBUG >= 2 +#define RTZ_HASHING_LIMIT 0 +#else +#define RTZ_HASHING_LIMIT 16 +#endif + +/* + * Maximal time to live for unused entry. + */ +#define RT_CACHE_TIMEOUT (HZ*300) + +/* + * Prevents LRU trashing, entries considered equivalent, + * if the difference between last use times is less then this number. + */ +#define RT_CACHE_BUBBLE_THRESHOLD (HZ*5) #include <linux/route.h> +#ifdef __KERNEL__ +#define RTF_LOCAL 0x8000 +#endif -/* This is an entry in the IP routing table. */ struct rtable { struct rtable *rt_next; - unsigned long rt_dst; - unsigned long rt_mask; - unsigned long rt_gateway; - unsigned char rt_flags; - unsigned char rt_metric; - short rt_refcnt; - unsigned long rt_use; - unsigned short rt_mss; - unsigned short rt_irtt; + __u32 rt_dst; + __u32 rt_src; + __u32 rt_gateway; + atomic_t rt_refcnt; + atomic_t rt_use; unsigned long rt_window; + atomic_t rt_lastuse; + struct hh_cache *rt_hh; struct device *rt_dev; + unsigned short rt_flags; + unsigned short rt_mtu; + unsigned short rt_irtt; + unsigned char rt_tos; }; - extern void ip_rt_flush(struct device *dev); -extern void ip_rt_add(short flags, unsigned long addr, unsigned long mask, - unsigned long gw, struct device *dev, unsigned short mss, unsigned long window, unsigned short irtt); -extern struct rtable *ip_rt_route(unsigned long daddr, struct options *opt, unsigned long *src_addr); -extern struct rtable *ip_rt_local(unsigned long daddr, struct options *opt, unsigned long *src_addr); -extern int rt_get_info(char * buffer, char **start, off_t offset, int length); +extern void ip_rt_update(int event, struct device *dev); +extern void ip_rt_redirect(__u32 src, __u32 dst, __u32 gw, struct device *dev); +extern struct rtable *ip_rt_slow_route(__u32 daddr, int local); +extern int rt_get_info(char * buffer, char **start, off_t offset, int length, int dummy); +extern int rt_cache_get_info(char *buffer, char **start, off_t offset, int length, int dummy); extern int ip_rt_ioctl(unsigned int cmd, void *arg); +extern int ip_rt_new(struct rtentry *rt); +extern int ip_rt_kill(struct rtentry *rt); +extern void ip_rt_check_expire(void); +extern void ip_rt_advice(struct rtable **rp, int advice); + +extern void ip_rt_run_bh(void); +extern atomic_t ip_rt_lock; +extern unsigned ip_rt_bh_mask; +extern struct rtable *ip_rt_hash_table[RT_HASH_DIVISOR]; + +extern __inline__ void ip_rt_fast_lock(void) +{ + atomic_inc(&ip_rt_lock); +} + +extern __inline__ void ip_rt_fast_unlock(void) +{ + atomic_dec(&ip_rt_lock); +} + +extern __inline__ void ip_rt_unlock(void) +{ + if (atomic_dec_and_test(&ip_rt_lock) && ip_rt_bh_mask) + ip_rt_run_bh(); +} + +extern __inline__ unsigned ip_rt_hash_code(__u32 addr) +{ + unsigned tmp = addr + (addr>>16); + return (tmp + (tmp>>8)) & 0xFF; +} + + +extern __inline__ void ip_rt_put(struct rtable * rt) +#ifndef MODULE +{ + if (rt) + atomic_dec(&rt->rt_refcnt); +} +#else +; +#endif + +#ifdef CONFIG_KERNELD +extern struct rtable * ip_rt_route(__u32 daddr, int local); +#else +extern __inline__ struct rtable * ip_rt_route(__u32 daddr, int local) +#ifndef MODULE +{ + struct rtable * rth; + + ip_rt_fast_lock(); + + for (rth=ip_rt_hash_table[ip_rt_hash_code(daddr)^local]; rth; rth=rth->rt_next) + { + if (rth->rt_dst == daddr) + { + rth->rt_lastuse = jiffies; + atomic_inc(&rth->rt_use); + atomic_inc(&rth->rt_refcnt); + ip_rt_unlock(); + return rth; + } + } + return ip_rt_slow_route (daddr, local); +} +#else +; +#endif +#endif + +extern __inline__ struct rtable * ip_check_route(struct rtable ** rp, + __u32 daddr, int local) +{ + struct rtable * rt = *rp; + + if (!rt || rt->rt_dst != daddr || !(rt->rt_flags&RTF_UP) + || ((local==1)^((rt->rt_flags&RTF_LOCAL) != 0))) + { + ip_rt_put(rt); + rt = ip_rt_route(daddr, local); + *rp = rt; + } + return rt; +} -extern unsigned long rt_stamp; #endif /* _ROUTE_H */ diff --git a/include/net/sit.h b/include/net/sit.h new file mode 100644 index 000000000..98bb5b386 --- /dev/null +++ b/include/net/sit.h @@ -0,0 +1,39 @@ +/* + * SIT tunneling device - definitions + * Linux INET6 implementation + * + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _NET_SIT_H +#define _NET_SIT_H + +struct sit_mtu_info { + __u32 addr; /* IPv4 destination */ + unsigned long tstamp; /* last use tstamp */ + __u32 mtu; /* Path MTU */ + struct sit_mtu_info *next; +}; + +struct sit_vif { + char name[8]; + struct device *dev; + struct sit_vif *next; +}; + +extern int sit_init(void); +extern void sit_cleanup(void); + +extern struct device * sit_add_tunnel(__u32 dstaddr); + +#define SIT_GC_TIMEOUT (3*60*HZ) +#define SIT_GC_FREQUENCY (2*60*HZ) + +#endif diff --git a/include/net/slhc.h b/include/net/slhc.h new file mode 100644 index 000000000..c7b39db55 --- /dev/null +++ b/include/net/slhc.h @@ -0,0 +1,6 @@ +#ifndef __NET_SLHC_H +#define __NET_SLHC_H + +extern void slhc_install(void); + +#endif diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h new file mode 100644 index 000000000..387b848d8 --- /dev/null +++ b/include/net/slhc_vj.h @@ -0,0 +1,187 @@ +#ifndef _SLHC_H +#define _SLHC_H +/* + * Definitions for tcp compression routines. + * + * $Header: slcompress.h,v 1.10 89/12/31 08:53:02 van Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + * + * + * modified for KA9Q Internet Software Package by + * Katie Stevens (dkstevens@ucdavis.edu) + * University of California, Davis + * Computing Services + * - 01-31-90 initial adaptation + * + * - Feb 1991 Bill_Simpson@um.cc.umich.edu + * variable number of conversation slots + * allow zero or one slots + * separate routines + * status display + */ + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowledgment, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + +/* SLIP compression masks for len/vers byte */ +#define SL_TYPE_IP 0x40 +#define SL_TYPE_UNCOMPRESSED_TCP 0x70 +#define SL_TYPE_COMPRESSED_TCP 0x80 +#define SL_TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + +/* + * data type and sizes conversion assumptions: + * + * VJ code KA9Q style generic + * u_char byte_t unsigned char 8 bits + * u_short int16 unsigned short 16 bits + * u_int int16 unsigned short 16 bits + * u_long unsigned long unsigned long 32 bits + * int int32 long 32 bits + */ + +typedef unsigned char byte_t; +typedef unsigned long int32; + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + byte_t cs_this; /* connection id number (xmit) */ + struct cstate *next; /* next in ring (xmit) */ + struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ + struct tcphdr cs_tcp; + unsigned char cs_ipopt[64]; + unsigned char cs_tcpopt[64]; + int cs_hsize; +}; +#define NULLSLSTATE (struct cstate *)0 + +/* + * all the state data for one serial line (we need one of these per line). + */ +struct slcompress { + struct cstate *tstate; /* transmit connection states (array)*/ + struct cstate *rstate; /* receive connection states (array)*/ + + byte_t tslot_limit; /* highest transmit slot id (0-l)*/ + byte_t rslot_limit; /* highest receive slot id (0-l)*/ + + byte_t xmit_oldest; /* oldest xmit in ring */ + byte_t xmit_current; /* most recent xmit id */ + byte_t recv_current; /* most recent rcvd id */ + + byte_t flags; +#define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ + + int32 sls_o_nontcp; /* outbound non-TCP packets */ + int32 sls_o_tcp; /* outbound TCP packets */ + int32 sls_o_uncompressed; /* outbound uncompressed packets */ + int32 sls_o_compressed; /* outbound compressed packets */ + int32 sls_o_searches; /* searches for connection state */ + int32 sls_o_misses; /* times couldn't find conn. state */ + + int32 sls_i_uncompressed; /* inbound uncompressed packets */ + int32 sls_i_compressed; /* inbound compressed packets */ + int32 sls_i_error; /* inbound error packets */ + int32 sls_i_tossed; /* inbound packets tossed because of error */ + + int32 sls_i_runt; + int32 sls_i_badcheck; +}; +#define NULLSLCOMPR (struct slcompress *)0 + +#define __ARGS(x) x + +/* In slhc.c: */ +struct slcompress *slhc_init __ARGS((int rslots, int tslots)); +void slhc_free __ARGS((struct slcompress *comp)); + +int slhc_compress __ARGS((struct slcompress *comp, unsigned char *icp, + int isize, unsigned char *ocp, unsigned char **cpp, + int compress_cid)); +int slhc_uncompress __ARGS((struct slcompress *comp, unsigned char *icp, + int isize)); +int slhc_remember __ARGS((struct slcompress *comp, unsigned char *icp, + int isize)); +int slhc_toss __ARGS((struct slcompress *comp)); + +void slhc_i_status __ARGS((struct slcompress *comp)); +void slhc_o_status __ARGS((struct slcompress *comp)); + +#endif /* _SLHC_H */ diff --git a/include/net/snmp.h b/include/net/snmp.h index 552292be6..a9dd844d1 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -48,6 +48,26 @@ struct ip_mib unsigned long IpFragCreates; }; +struct ipv6_mib +{ + unsigned long Ip6InReceives; + unsigned long Ip6InHdrErrors; + unsigned long Ip6InAddrErrors; + unsigned long Ip6ForwDatagrams; + unsigned long Ip6InUnknownProtos; + unsigned long Ip6InDiscards; + unsigned long Ip6InDelivers; + unsigned long Ip6OutRequests; + unsigned long Ip6OutDiscards; + unsigned long Ip6OutNoRoutes; + unsigned long Ip6ReasmTimeout; + unsigned long Ip6ReasmReqds; + unsigned long Ip6ReasmOKs; + unsigned long Ip6ReasmFails; + unsigned long Ip6FragOKs; + unsigned long Ip6FragFails; + unsigned long Ip6FragCreates; +}; struct icmp_mib { diff --git a/include/net/sock.h b/include/net/sock.h index be7c84591..eeb364159 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -21,6 +21,7 @@ * a socket is reset and must stay shut up * Alan Cox : New fields for options * Pauline Middelink : identd support + * Alan Cox : Eliminate low level recv/recvfrom * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,57 +31,289 @@ #ifndef _SOCK_H #define _SOCK_H +#include <linux/config.h> #include <linux/timer.h> #include <linux/ip.h> /* struct options */ #include <linux/in.h> /* struct sockaddr_in */ + +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +#include <linux/in6.h> /* struct sockaddr_in6 */ +#include <linux/ipv6.h> /* dest_cache, inet6_options */ +#include <linux/icmpv6.h> +#include <net/if_inet6.h> /* struct ipv6_mc_socklist */ +#endif + #include <linux/tcp.h> /* struct tcphdr */ #include <linux/config.h> +#include <linux/netdevice.h> #include <linux/skbuff.h> /* struct sk_buff */ -#include "protocol.h" /* struct inet_protocol */ -#ifdef CONFIG_AX25 -#include "ax25.h" -#ifdef CONFIG_NETROM -#include "netrom.h" +#include <net/protocol.h> /* struct inet_protocol */ +#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) +#/* notyet */include <net/x25.h> +#endif +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) +#include <net/ax25.h> +#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE) +#include <net/netrom.h> #endif +#if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE) +#include <net/rose.h> #endif -#ifdef CONFIG_IPX -#include "ipx.h" #endif -#ifdef CONFIG_ATALK -#include "atalk.h" + +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) +#include <net/ipx.h> +#endif + +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) +#include <linux/atalk.h> #endif #include <linux/igmp.h> -#define SOCK_ARRAY_SIZE 256 /* Think big (also on some systems a byte is faster */ +#include <asm/atomic.h> + +/* Think big (also on some systems a byte is faster) */ +#define SOCK_ARRAY_SIZE 256 /* + * The AF_UNIX specific socket options + */ + +struct unix_opt +{ + int family; + char * name; + int locks; + struct inode * inode; + struct semaphore readsem; + struct sock * other; + int marksweep; +#define MARKED 1 + int inflight; +}; + +/* + * IP packet socket options + */ + +struct inet_packet_opt +{ + struct notifier_block notifier; /* Used when bound */ + struct device *bound_dev; + unsigned long dev_stamp; + struct packet_type *prot_hook; + char device_name[15]; +}; + +/* + * Once the IPX ncpd patches are in these are going into protinfo + */ + +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) +struct ipx_opt +{ + ipx_address dest_addr; + ipx_interface *intrfc; + unsigned short port; +#ifdef CONFIG_IPX_INTERN + unsigned char node[IPX_NODE_LEN]; +#endif + unsigned short type; +/* + * To handle asynchronous messages from the NetWare server, we have to + * know the connection this socket belongs to. + */ + struct ncp_server *ncp_server; + +}; +#endif + +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +struct ipv6_pinfo +{ + struct in6_addr saddr; + struct in6_addr rcv_saddr; + struct in6_addr daddr; + + __u32 flow_lbl; + __u8 priority; + __u8 hop_limit; + + __u8 mcast_hops; + + /* sockopt flags */ + + __u8 recvsrcrt:1, + rxinfo:1, + mc_loop:1, + unused:4; + + /* device for outgoing mcast packets */ + + struct device *mc_if; + + struct ipv6_mc_socklist *ipv6_mc_list; + /* + * destination cache entry pointer + * contains a pointer to neighbour cache + * and other info related to network level + * (ex. PMTU) + */ + + struct dest_entry *dest; + __u32 dc_sernum; + + struct ipv6_options *opt; +}; + +struct raw6_opt { + __u32 checksum; /* perform checksum */ + __u32 offset; /* checksum offset */ + + struct icmp6_filter filter; +}; + +#endif /* IPV6 */ + +struct tcp_opt +{ +/* + * RFC793 variables by their proper names. This means you can + * read the code and the spec side by side (and laugh ...) + * See RFC793 and RFC1122. The RFC writes these in capitals. + */ + __u32 rcv_nxt; /* What we want to receive next */ + __u32 rcv_up; /* The urgent point (may not be valid) */ + __u32 rcv_wnd; /* Current receiver window */ + __u32 snd_nxt; /* Next sequence we send */ + __u32 snd_una; /* First byte we want an ack for */ + __u32 snd_up; /* Outgoing urgent pointer */ + __u32 snd_wl1; /* Sequence for window update */ + __u32 snd_wl2; /* Ack sequence for update */ + + __u32 rcv_wup; /* rcv_nxt on last window update sent */ + + + __u32 srtt; /* smothed round trip time << 3 */ + __u32 mdev; /* medium deviation */ + __u32 rto; /* retransmit timeout */ + __u32 backoff; /* backoff */ +/* + * Slow start and congestion control (see also Nagle, and Karn & Partridge) + */ + __u32 snd_cwnd; /* Sending congestion window */ + __u32 snd_ssthresh; /* Slow start size threshold */ +/* + * Timers used by the TCP protocol layer + */ + struct timer_list delack_timer; /* Ack delay */ + struct timer_list idle_timer; /* Idle watch */ + struct timer_list completion_timer; /* Up/Down timer */ + struct timer_list probe_timer; /* Probes */ + struct timer_list retransmit_timer; /* Resend (no ack) */ + + __u32 basertt; /* Vegas baseRTT */ + + __u8 delayed_acks; + __u8 dup_acks; + + __u32 lrcvtime; /* timestamp of last received data packet */ + __u32 rcv_tstamp; /* timestamp of last received packet */ + __u32 iat_mdev; /* interarrival time medium deviation */ + __u32 iat; /* interarrival time */ + __u32 ato; /* delayed ack timeout */ + + __u32 high_seq; +/* + * new send pointers + */ + struct sk_buff * send_head; + struct sk_buff * retrans_head; /* retrans head can be + * different to the head of + * write queue if we are doing + * fast retransmit + */ +/* + * pending events + */ + __u8 pending; + +/* + * Header prediction flags + * 0x5?10 << 16 + snd_wnd in net byte order + */ + __u32 pred_flags; + __u32 snd_wnd; /* The window we expect to receive */ + + __u32 probes_out; /* unanswered 0 window probes */ + + struct open_request *syn_wait_queue; + struct tcp_func *af_specific; +}; + + +/* * This structure really needs to be cleaned up. * Most of it is for TCP, and not used by any of * the other protocols. */ -struct sock { - struct options *opt; - volatile unsigned long wmem_alloc; - volatile unsigned long rmem_alloc; - unsigned long write_seq; - unsigned long sent_seq; - unsigned long acked_seq; - unsigned long copied_seq; - unsigned long rcv_ack_seq; - unsigned long window_seq; - unsigned long fin_seq; - unsigned long urg_seq; - unsigned long urg_data; +/* + * The idea is to start moving to a newer struct gradualy + * + * IMHO the newer struct should have the following format: + * + * struct sock { + * sockmem [mem, proto, callbacks] + * + * union or struct { + * netrom; + * ax_25; + * } ll_pinfo; + * + * union { + * ipv4; + * ipv6; + * ipx; + * } net_pinfo; + * + * union { + * tcp; + * udp; + * spx; + * } tp_pinfo; + * + * } + */ + +/* + * TCP will start to use the new protinfo while *still using the old* fields + */ + +struct sock +{ + struct options *opt; + atomic_t wmem_alloc; + atomic_t rmem_alloc; + unsigned long allocation; /* Allocation mode */ + __u32 write_seq; + __u32 copied_seq; + __u32 fin_seq; + __u32 syn_seq; + __u32 urg_seq; + __u32 urg_data; + int users; /* user count */ + + unsigned char delayed_acks, + dup_acks; /* - * Not all are volatile, but some are, so we - * might as well say they all are. + * Not all are volatile, but some are, so we + * might as well say they all are. */ - volatile char inuse, - dead, + volatile char dead, urginline, intr, blog, @@ -88,209 +321,338 @@ struct sock { reuse, keepopen, linger, - delay_acks, destroy, ack_timed, no_check, zapped, /* In ax25 & ipx means not linked */ broadcast, - nonagle; - unsigned long lingertime; - int proc; - struct sock *next; - struct sock *prev; /* Doubly linked chain.. */ - struct sock *pair; - struct sk_buff * volatile send_head; - struct sk_buff * volatile send_tail; - struct sk_buff_head back_log; - struct sk_buff *partial; - struct timer_list partial_timer; - long retransmits; - struct sk_buff_head write_queue, - receive_queue; - struct proto *prot; - struct wait_queue **sleep; - unsigned long daddr; - unsigned long saddr; - unsigned short max_unacked; - unsigned short window; - unsigned short bytes_rcv; -/* mss is min(mtu, max_window) */ - unsigned short mtu; /* mss negotiated in the syn's */ - volatile unsigned short mss; /* current eff. mss - can change */ - volatile unsigned short user_mss; /* mss requested by user in ioctl */ - volatile unsigned short max_window; - unsigned long window_clamp; - unsigned short num; - volatile unsigned short cong_window; - volatile unsigned short cong_count; - volatile unsigned short ssthresh; - volatile unsigned short packets_out; - volatile unsigned short shutdown; - volatile unsigned long rtt; - volatile unsigned long mdev; - volatile unsigned long rto; -/* currently backoff isn't used, but I'm maintaining it in case - * we want to go back to a backoff formula that needs it + nonagle, + bsdism; + unsigned long lingertime; + int proc; + struct sock *next; + struct sock *prev; /* Doubly linked chain.. */ + struct sock *pair; + + struct sk_buff * send_head; + struct sk_buff * send_tail; + + struct sk_buff_head back_log; + struct sk_buff *partial; + struct timer_list partial_timer; + atomic_t retransmits; + + struct sk_buff_head write_queue, + receive_queue, + out_of_order_queue; + + unsigned short family; + struct proto *prot; + struct wait_queue **sleep; + + __u32 daddr; + __u32 saddr; /* Sending source */ + __u32 rcv_saddr; /* Bound address */ + + unsigned short max_unacked; + + + unsigned short bytes_rcv; +/* + * mss is min(mtu, max_window) */ - volatile unsigned short backoff; - volatile short err; - unsigned char protocol; - volatile unsigned char state; - volatile unsigned char ack_backlog; - unsigned char max_ack_backlog; - unsigned char priority; - unsigned char debug; - unsigned short rcvbuf; - unsigned short sndbuf; - unsigned short type; - unsigned char localroute; /* Route locally only */ -#ifdef CONFIG_IPX - ipx_address ipx_dest_addr; - ipx_interface *ipx_intrfc; - unsigned short ipx_port; - unsigned short ipx_type; + unsigned short mtu; /* mss negotiated in the syn's */ + unsigned short mss; /* current eff. mss - can change */ + unsigned short user_mss; /* mss requested by user in ioctl */ + unsigned short max_window; + unsigned long window_clamp; + unsigned int ssthresh; + unsigned short num; + + unsigned short cong_window; + unsigned short cong_count; + atomic_t packets_out; + unsigned short shutdown; + + unsigned short window; /* used by netrom/ax.25 */ + +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + union { + struct ipv6_pinfo af_inet6; + } net_pinfo; +#endif + + union { + struct tcp_opt af_tcp; +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + struct raw6_opt tp_raw; +#endif + } tp_pinfo; +/* + * currently backoff isn't used, but I'm maintaining it in case + * we want to go back to a backoff formula that needs it + */ +/* + unsigned short backoff; + */ + int err, err_soft; /* Soft holds errors that don't + cause failure but are the cause + of a persistent failure not just + 'timed out' */ + unsigned char protocol; + volatile unsigned char state; + unsigned char ack_backlog; + unsigned char max_ack_backlog; + unsigned char priority; + unsigned char debug; + int rcvbuf; + int sndbuf; + unsigned short type; + unsigned char localroute; /* Route locally only */ + +/* + * This is where all the private (optional) areas that don't + * overlap will eventually live. + */ + + union + { + struct unix_opt af_unix; +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) + struct atalk_sock af_at; +#endif +#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) + struct ipx_opt af_ipx; +#endif +#ifdef CONFIG_INET + struct inet_packet_opt af_packet; +#ifdef CONFIG_NUTCP + struct tcp_opt af_tcp; +#endif #endif -#ifdef CONFIG_AX25 - ax25_cb *ax25; -#ifdef CONFIG_NETROM - nr_cb *nr; +#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) + x25_cb *x25; #endif +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) + ax25_cb *ax25; +#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE) + nr_cb *nr; #endif -#ifdef CONFIG_ATALK - struct atalk_sock at; +#if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE) + rose_cb *rose; #endif +#endif + } protinfo; -/* IP 'private area' or will be eventually */ - int ip_ttl; /* TTL setting */ - int ip_tos; /* TOS */ - struct tcphdr dummy_th; - struct timer_list keepalive_timer; /* TCP keepalive hack */ - struct timer_list retransmit_timer; /* TCP retransmit timer */ - struct timer_list ack_timer; /* TCP delayed ack timer */ - int ip_xmit_timeout; /* Why the timeout is running */ - struct rtable *ip_route_cache; /* Cached output route */ - unsigned long ip_route_stamp; /* Route cache stamp */ - unsigned long ip_route_daddr; /* Target address */ - unsigned long ip_route_saddr; /* Source address */ - int ip_route_local; /* State of locality flag */ - unsigned long ip_hcache_stamp; /* Header cache stamp */ - unsigned long *ip_hcache_ver; /* Pointer to version of cache */ - char ip_hcache_data[16]; /* Cached header */ - int ip_hcache_state; /* Have we a cached header */ - unsigned char ip_option_len; /* Length of IP options */ - unsigned char ip_option_flen; /* Second fragment option length */ - unsigned char ip_opt_next_strict; /* Next hop is strict route */ - unsigned long ip_opt_next_hop; /* Next hop if forced */ - unsigned char *ip_opt_ptr[2]; /* IP option pointers */ +/* + * IP 'private area' or will be eventually + */ + int ip_ttl; /* TTL setting */ + int ip_tos; /* TOS */ + struct tcphdr dummy_th; + struct timer_list keepalive_timer; /* TCP keepalive hack */ + struct timer_list retransmit_timer; /* TCP retransmit timer */ + struct timer_list delack_timer; /* TCP delayed ack timer */ + int ip_xmit_timeout; /* Why the timeout is running */ + struct rtable *ip_route_cache; /* Cached output route */ + unsigned char ip_hdrincl; /* Include headers ? */ #ifdef CONFIG_IP_MULTICAST - int ip_mc_ttl; /* Multicasting TTL */ - int ip_mc_loop; /* Loopback */ - char ip_mc_name[MAX_ADDR_LEN]; /* Multicast device name */ - struct ip_mc_socklist *ip_mc_list; /* Group array */ + int ip_mc_ttl; /* Multicasting TTL */ + int ip_mc_loop; /* Loopback */ + char ip_mc_name[MAX_ADDR_LEN];/* Multicast device name */ + struct ip_mc_socklist *ip_mc_list; /* Group array */ #endif - /* This part is used for the timeout functions (timer.c). */ - int timeout; /* What are we waiting for? */ - struct timer_list timer; /* This is the TIME_WAIT/receive timer when we are doing IP */ - struct timeval stamp; +/* + * This part is used for the timeout functions (timer.c). + */ + + int timeout; /* What are we waiting for? */ + struct timer_list timer; /* This is the TIME_WAIT/receive timer + * when we are doing IP + */ + struct timeval stamp; - /* identd */ - struct socket *socket; + /* + * Identd + */ - /* Callbacks */ - void (*state_change)(struct sock *sk); - void (*data_ready)(struct sock *sk,int bytes); - void (*write_space)(struct sock *sk); - void (*error_report)(struct sock *sk); + struct socket *socket; + /* + * Callbacks + */ + + void (*state_change)(struct sock *sk); + void (*data_ready)(struct sock *sk,int bytes); + void (*write_space)(struct sock *sk); + void (*error_report)(struct sock *sk); + + int (*backlog_rcv) (struct sock *sk, + struct sk_buff *skb); +}; + +#if 0 +/* + * Inet protocol options + */ +struct inet_options { + __u8 version; + union { + struct options opt_v4; + struct ipv6_options opt_v6; + } u; }; +#endif + +/* + * IP protocol blocks we attach to sockets. + * socket layer -> transport layer interface + * transport -> network interface is defined by struct inet_proto + */ + +struct proto +{ + void (*close)(struct sock *sk, + unsigned long timeout); + int (*connect)(struct sock *sk, + struct sockaddr *uaddr, + int addr_len); + + struct sock * (*accept) (struct sock *sk, int flags); + void (*retransmit)(struct sock *sk, int all); + void (*write_wakeup)(struct sock *sk); + void (*read_wakeup)(struct sock *sk); + + int (*select)(struct sock *sk, int which, + select_table *wait); + + int (*ioctl)(struct sock *sk, int cmd, + unsigned long arg); + int (*init)(struct sock *sk); + int (*destroy)(struct sock *sk); + void (*shutdown)(struct sock *sk, int how); + int (*setsockopt)(struct sock *sk, int level, + int optname, char *optval, int optlen); + int (*getsockopt)(struct sock *sk, int level, + int optname, char *optval, + int *option); + int (*sendmsg)(struct sock *sk, struct msghdr *msg, + int len, int noblock, int flags); + int (*recvmsg)(struct sock *sk, struct msghdr *msg, + int len, int noblock, int flags, + int *addr_len); + int (*bind)(struct sock *sk, + struct sockaddr *uaddr, int addr_len); + + int (*backlog_rcv) (struct sock *sk, + struct sk_buff *skb); -struct proto { - struct sk_buff * (*wmalloc)(struct sock *sk, - unsigned long size, int force, - int priority); - struct sk_buff * (*rmalloc)(struct sock *sk, - unsigned long size, int force, - int priority); - void (*wfree)(struct sock *sk, struct sk_buff *skb, - unsigned long size); - void (*rfree)(struct sock *sk, struct sk_buff *skb, - unsigned long size); - unsigned long (*rspace)(struct sock *sk); - unsigned long (*wspace)(struct sock *sk); - void (*close)(struct sock *sk, int timeout); - int (*read)(struct sock *sk, unsigned char *to, - int len, int nonblock, unsigned flags); - int (*write)(struct sock *sk, unsigned char *to, - int len, int nonblock, unsigned flags); - int (*sendto)(struct sock *sk, - unsigned char *from, int len, int noblock, - unsigned flags, struct sockaddr_in *usin, - int addr_len); - int (*recvfrom)(struct sock *sk, - unsigned char *from, int len, int noblock, - unsigned flags, struct sockaddr_in *usin, - int *addr_len); - int (*build_header)(struct sk_buff *skb, - unsigned long saddr, - unsigned long daddr, - struct device **dev, int type, - struct options *opt, int len, int tos, int ttl); - int (*connect)(struct sock *sk, - struct sockaddr_in *usin, int addr_len); - struct sock * (*accept) (struct sock *sk, int flags); - void (*queue_xmit)(struct sock *sk, - struct device *dev, struct sk_buff *skb, - int free); - void (*retransmit)(struct sock *sk, int all); - void (*write_wakeup)(struct sock *sk); - void (*read_wakeup)(struct sock *sk); - int (*rcv)(struct sk_buff *buff, struct device *dev, - struct options *opt, unsigned long daddr, - unsigned short len, unsigned long saddr, - int redo, struct inet_protocol *protocol); - int (*select)(struct sock *sk, int which, - select_table *wait); - int (*ioctl)(struct sock *sk, int cmd, - unsigned long arg); - int (*init)(struct sock *sk); - void (*shutdown)(struct sock *sk, int how); - int (*setsockopt)(struct sock *sk, int level, int optname, - char *optval, int optlen); - int (*getsockopt)(struct sock *sk, int level, int optname, - char *optval, int *option); - unsigned short max_header; - unsigned long retransmits; - char name[32]; - int inuse, highestinuse; -#ifndef PACKET_C /* Hack to save 1K for packet sockets */ - struct sock * sock_array[SOCK_ARRAY_SIZE]; -#endif PACKET_C + unsigned short max_header; + unsigned long retransmits; + char name[32]; + int inuse, highestinuse; + struct sock ** sock_array; }; -#define TIME_WRITE 1 -#define TIME_CLOSE 2 -#define TIME_KEEPOPEN 3 -#define TIME_DESTROY 4 -#define TIME_DONE 5 /* used to absorb those last few packets */ -#define TIME_PROBE0 6 -#define SOCK_DESTROY_TIME 1000 /* about 10 seconds */ +#define TIME_WRITE 1 /* Not yet used */ +#define TIME_RETRANS 2 /* Retransmit timer */ +#define TIME_DACK 3 /* Delayed ack timer */ +#define TIME_CLOSE 4 +#define TIME_KEEPOPEN 5 +#define TIME_DESTROY 6 +#define TIME_DONE 7 /* Used to absorb those last few packets */ +#define TIME_PROBE0 8 -#define PROT_SOCK 1024 /* Sockets 0-1023 can't be bound too unless you are superuser */ +/* + * About 10 seconds + */ + +#define SOCK_DESTROY_TIME (10*HZ) + +/* + * Sockets 0-1023 can't be bound to unless you are superuser + */ + +#define PROT_SOCK 1024 #define SHUTDOWN_MASK 3 #define RCV_SHUTDOWN 1 #define SEND_SHUTDOWN 2 +/* + * Used by processes to "lock" a socket state, so that + * interrupts and bottom half handlers won't change it + * from under us. It essentially blocks any incoming + * packets, so that we won't get any new data or any + * packets that change the state of the socket. + * + * Note the 'barrier()' calls: gcc may not move a lock + * "downwards" or a unlock "upwards" when optimizing. + */ +extern void __release_sock(struct sock *sk); +static inline void lock_sock(struct sock *sk) +{ +#if 0 +/* debugging code: the test isn't even 100% correct, but it can catch bugs */ +/* Note that a double lock is ok in theory - it's just _usually_ a bug */ + if (sk->users) { + __label__ here; + printk("double lock on socket at %p\n", &&here); +here: + } +#endif + sk->users++; + barrier(); +} + +static inline void release_sock(struct sock *sk) +{ + barrier(); +#if 0 +/* debugging code: remove me when ok */ + if (sk->users == 0) { + __label__ here; + sk->users = 1; + printk("trying to unlock unlocked socket at %p\n", &&here); +here: + } +#endif + if ((sk->users = sk->users-1) == 0) + __release_sock(sk); +} + +/* + * This might not be the most apropriate place for this two + * but since they are used by a lot of the net related code + * at least they get declared on a include that is common to all + */ + +static __inline__ int min(unsigned int a, unsigned int b) +{ + if (a > b) + a = b; + return a; +} + +static __inline__ int max(unsigned int a, unsigned int b) +{ + if (a < b) + a = b; + return a; +} + +extern struct sock * sk_alloc(int priority); +extern void sk_free(struct sock *sk); extern void destroy_sock(struct sock *sk); -extern unsigned short get_new_socknum(struct proto *, unsigned short); -extern void put_sock(unsigned short, struct sock *); -extern void release_sock(struct sock *sk); +extern unsigned short get_new_socknum(struct proto *, + unsigned short); +extern void inet_put_sock(unsigned short, struct sock *); extern struct sock *get_sock(struct proto *, unsigned short, unsigned long, unsigned short, - unsigned long); + unsigned long, + unsigned long, unsigned short); extern struct sock *get_sock_mcast(struct sock *, unsigned short, unsigned long, unsigned short, unsigned long); @@ -303,52 +665,84 @@ extern struct sk_buff *sock_wmalloc(struct sock *sk, extern struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority); -extern void sock_wfree(struct sock *sk, struct sk_buff *skb, - unsigned long size); -extern void sock_rfree(struct sock *sk, struct sk_buff *skb, - unsigned long size); +extern void sock_wfree(struct sock *sk, + struct sk_buff *skb); +extern void sock_rfree(struct sock *sk, + struct sk_buff *skb); extern unsigned long sock_rspace(struct sock *sk); extern unsigned long sock_wspace(struct sock *sk); -extern int sock_setsockopt(struct sock *sk,int level,int op,char *optval,int optlen); +extern int sock_setsockopt(struct sock *sk, int level, + int op, char *optval, + int optlen); -extern int sock_getsockopt(struct sock *sk,int level,int op,char *optval,int *optlen); -extern struct sk_buff *sock_alloc_send_skb(struct sock *skb, unsigned long size, int noblock, int *errcode); +extern int sock_getsockopt(struct sock *sk, int level, + int op, char *optval, + int *optlen); +extern struct sk_buff *sock_alloc_send_skb(struct sock *skb, + unsigned long size, + unsigned long fallback, + int noblock, + int *errcode); /* - * Queue a received datagram if it will fit. Stream and sequenced protocols - * can't normally use this as they need to fit buffers in and play with them. + * Queue a received datagram if it will fit. Stream and sequenced + * protocols can't normally use this as they need to fit buffers in + * and play with them. * - * Inlined as its very short and called for pretty much every packet ever - * received. + * Inlined as it's very short and called for pretty much every + * packet ever received. */ extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) { - unsigned long flags; - if(sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) + if (sk->rmem_alloc + skb->truesize >= sk->rcvbuf) return -ENOMEM; - save_flags(flags); - cli(); - sk->rmem_alloc+=skb->mem_len; + atomic_add(skb->truesize, &sk->rmem_alloc); skb->sk=sk; - restore_flags(flags); skb_queue_tail(&sk->receive_queue,skb); - if(!sk->dead) + if (!sk->dead) + sk->data_ready(sk,skb->len); + return 0; +} + +extern __inline__ int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) +{ + if (sk->rmem_alloc + skb->truesize >= sk->rcvbuf) + return -ENOMEM; + atomic_add(skb->truesize, &sk->rmem_alloc); + skb->sk=sk; + __skb_queue_tail(&sk->receive_queue,skb); + if (!sk->dead) sk->data_ready(sk,skb->len); return 0; } -/* declarations from timer.c */ +/* + * Recover an error report and clear atomically + */ + +extern __inline__ int sock_error(struct sock *sk) +{ + int err=xchg(&sk->err,0); + return -err; +} + +/* + * Declarations from timer.c + */ + extern struct sock *timer_base; -void delete_timer (struct sock *); -void reset_timer (struct sock *, int, unsigned long); -void net_timer (unsigned long); +extern void net_delete_timer (struct sock *); +extern void net_reset_timer (struct sock *, int, unsigned long); +extern void net_timer (unsigned long); -/* Enable debug/info messages */ +/* + * Enable debug/info messages + */ -#define NETDEBUG(x) x +#define NETDEBUG(x) do { } while (0) #endif /* _SOCK_H */ diff --git a/include/net/spx.h b/include/net/spx.h new file mode 100644 index 000000000..3e9b1d185 --- /dev/null +++ b/include/net/spx.h @@ -0,0 +1,38 @@ +#ifndef __NET_SPX_H +#define __NET_SPX_H + +/* + * Internal definitions for the SPX protocol. + */ + +/* + * The SPX header following an IPX header. + */ + +struct spxhdr +{ + __u8 cctl; +#define CCTL_SPXII_XHD 0x01 /* SPX2 extended header */ +#define CCTL_SPX_UNKNOWN 0x02 /* Unknown (unused ??) */ +#define CCTL_SPXII_NEG 0x04 /* Negotiate size */ +#define CCTL_SPXII 0x08 /* Set for SPX2 */ +#define CCTL_EOM 0x10 /* End of message marker */ +#define CCTL_URG 0x20 /* Urgent marker in SPP (not used in SPX?) */ +#define CCTL_ACK 0x40 /* Send me an ACK */ +#define CCTL_CTL 0x80 /* Control message */ + __u8 dtype; +#define SPX_DTYPE_ECONN 0xFE /* Finished */ +#define SPX_DTYPE_ECACK 0xFF /* Ok */ + __u16 sconn; /* Connection ID */ + __u16 dconn; /* Connection ID */ + __u16 sequence; + __u16 ackseq; + __u16 allocseq; +}; + +#define IPXTYPE_SPX 5 + + + + +#endif diff --git a/include/net/tcp.h b/include/net/tcp.h index efeaac0da..23fd54501 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -18,15 +18,33 @@ #ifndef _TCP_H #define _TCP_H +#include <linux/config.h> #include <linux/tcp.h> +#include <net/checksum.h> -#define MAX_SYN_SIZE 44 + MAX_HEADER -#define MAX_FIN_SIZE 40 + MAX_HEADER -#define MAX_ACK_SIZE 40 + MAX_HEADER -#define MAX_RESET_SIZE 40 + MAX_HEADER -#define MAX_WINDOW 16384 + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#define NETHDR_SIZE sizeof(struct ipv6hdr) +#else +#define NETHDR_SIZE sizeof(struct iphdr) + 40 +#endif + +/* + * 40 is maximal IP options size + * 4 is TCP option size (MSS) + */ + +#define MAX_SYN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 4 + MAX_HEADER + 15) +#define MAX_FIN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) +#define MAX_ACK_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) +#define MAX_RESET_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) + +#define MAX_WINDOW 32767 /* Never offer a window over 32767 without using + window scaling (not yet supported). Some poor + stacks do signed 16bit maths! */ #define MIN_WINDOW 2048 #define MAX_ACK_BACKLOG 2 +#define MAX_DELAY_ACK 2 #define MIN_WRITE_SPACE 2048 #define TCP_WINDOW_DIFF 2048 @@ -49,22 +67,26 @@ #define TCP_TIMEOUT_LEN (15*60*HZ) /* should be about 15 mins */ #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to successfully * close the socket, about 60 seconds */ -#define TCP_FIN_TIMEOUT (3*60*HZ) /* BSD style FIN_WAIT2 deadlock breaker */ +#define TCP_FIN_TIMEOUT (3*60*HZ) /* BSD style FIN_WAIT2 deadlock breaker */ + #define TCP_ACK_TIME (3*HZ) /* time to delay before sending an ACK */ -#define TCP_DONE_TIME 250 /* maximum time to wait before actually +#define TCP_DONE_TIME (5*HZ/2)/* maximum time to wait before actually * destroying a socket */ -#define TCP_WRITE_TIME 3000 /* initial time to wait for an ACK, +#define TCP_WRITE_TIME (30*HZ) /* initial time to wait for an ACK, * after last transmit */ #define TCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial timeout value */ #define TCP_SYN_RETRIES 10 /* number of times to retry opening a * connection (TCP_RETR2-....) */ -#define TCP_PROBEWAIT_LEN 100 /* time to wait between probes when +#define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when * I've got something to write and * there is no window */ - +#define TCP_KEEPALIVE_TIME (180*60*HZ) /* two hours */ +#define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ +#define TCP_KEEPALIVE_PERIOD (75*HZ) /* period of keepalive check */ #define TCP_NO_CHECK 0 /* turn to one if you want the default * to be no checksum */ +#define TCP_SYNACK_PERIOD (HZ/2) /* * TCP option @@ -79,64 +101,428 @@ #define TCPOPT_WINDOW 3 /* Window scaling */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ +/* + * TCP option lengths + */ + +#define TCPOLEN_MSS 4 +#define TCPOLEN_WINDOW 3 +#define TCPOLEN_TIMESTAMP 10 + + +/* + * TCP Vegas constants + */ + +#define TCP_VEGAS_ALPHA 2 /* v_cong_detect_top_nseg */ +#define TCP_VEGAS_BETA 4 /* v_cong_detect_bot_nseg */ +#define TCP_VEGAS_GAMMA 1 /* v_exp_inc_nseg */ + +struct open_request; + +struct or_calltable { + void (*rtx_syn_ack) (struct sock *sk, struct open_request *req); + void (*destructor) (struct open_request *req); +}; + +struct open_request { + struct open_request *dl_next; + struct open_request *dl_prev; + __u32 rcv_isn; + __u32 snt_isn; + __u16 mss; + __u16 rmt_port; + unsigned long expires; + int retrans; + struct or_calltable *class; + struct sock *sk; +}; + +struct tcp_v4_open_req { + struct open_request req; + __u32 loc_addr; + __u32 rmt_addr; + struct options *opt; +}; + +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +struct tcp_v6_open_req { + struct open_request req; + struct in6_addr loc_addr; + struct in6_addr rmt_addr; + struct ipv6_options *opt; + struct device *dev; +}; +#endif + +/* + * Pointers to address related TCP functions + * (i.e. things that depend on the address family) + */ + +struct tcp_func { + int (*build_net_header) (struct sock *sk, + struct sk_buff *skb); + + void (*queue_xmit) (struct sock *sk, + struct device *dev, + struct sk_buff *skb, + int free); + + void (*send_check) (struct sock *sk, + struct tcphdr *th, + int len, + struct sk_buff *skb); + + int (*rebuild_header) (struct sock *sk, + struct sk_buff *skb); + + int (*conn_request) (struct sock *sk, + struct sk_buff *skb, + void *opt, + __u32 isn); + + struct sock * (*syn_recv_sock) (struct sock *sk, + struct sk_buff *skb, + struct open_request *req); + + __u32 (*init_sequence) (struct sock *sk, + struct sk_buff *skb); + + struct sock * (*get_sock) (struct sk_buff *skb, + struct tcphdr *th); + + int (*setsockopt) (struct sock *sk, + int level, + int optname, + char *optval, + int optlen); + + int (*getsockopt) (struct sock *sk, + int level, + int optname, + char *optval, + int *optlen); + + + void (*addr2sockaddr) (struct sock *sk, + struct sockaddr *); + + int sockaddr_len; +}; /* * The next routines deal with comparing 32 bit unsigned ints * and worry about wraparound (automatic with unsigned arithmetic). */ -extern __inline int before(unsigned long seq1, unsigned long seq2) +extern __inline int before(__u32 seq1, __u32 seq2) { - return (long)(seq1-seq2) < 0; + return (__s32)(seq1-seq2) < 0; } -extern __inline int after(unsigned long seq1, unsigned long seq2) +extern __inline int after(__u32 seq1, __u32 seq2) { - return (long)(seq1-seq2) > 0; + return (__s32)(seq2-seq1) < 0; } /* is s2<=s1<=s3 ? */ -extern __inline int between(unsigned long seq1, unsigned long seq2, unsigned long seq3) +extern __inline int between(__u32 seq1, __u32 seq2, __u32 seq3) { return (after(seq1+1, seq2) && before(seq1, seq3+1)); } +extern struct proto tcp_prot; +extern struct tcp_mib tcp_statistics; + +extern void tcp_v4_err(int type, int code, + unsigned char *header, __u32 info, + __u32 daddr, __u32 saddr, + struct inet_protocol *protocol, + int len); + +extern void tcp_shutdown (struct sock *sk, int how); + +extern int tcp_v4_rcv(struct sk_buff *skb, + struct device *dev, + struct options *opt, __u32 daddr, + unsigned short len, __u32 saddr, + int redo, + struct inet_protocol *protocol); + +extern int tcp_do_sendmsg(struct sock *sk, + int iovlen, struct iovec *iov, + int len, int nonblock, + int flags); + +extern int tcp_ioctl(struct sock *sk, + int cmd, + unsigned long arg); + +extern int tcp_rcv_state_process(struct sock *sk, + struct sk_buff *skb, + struct tcphdr *th, + void *opt, __u16 len); + +extern void tcp_rcv_established(struct sock *sk, + struct sk_buff *skb, + struct tcphdr *th, + __u16 len); + +extern void tcp_close(struct sock *sk, + unsigned long timeout); +extern struct sock * tcp_accept(struct sock *sk, int flags); +extern int tcp_select(struct sock *sk, int sel_type, + select_table *wait); +extern int tcp_getsockopt(struct sock *sk, int level, + int optname, char *optval, + int *optlen); +extern int tcp_setsockopt(struct sock *sk, int level, + int optname, char *optval, + int optlen); +extern void tcp_set_keepalive(struct sock *sk, int val); +extern int tcp_recvmsg(struct sock *sk, + struct msghdr *msg, + int len, int nonblock, + int flags, int *addr_len); + +extern int tcp_parse_options(struct tcphdr *th); + +/* + * TCP v4 functions exported for the inet6 API + */ + +extern int tcp_v4_rebuild_header(struct sock *sk, + struct sk_buff *skb); + +extern int tcp_v4_build_header(struct sock *sk, + struct sk_buff *skb); + +extern void tcp_v4_send_check(struct sock *sk, + struct tcphdr *th, int len, + struct sk_buff *skb); + +extern int tcp_v4_conn_request(struct sock *sk, + struct sk_buff *skb, + void *ptr, __u32 isn); + +extern struct sock * tcp_v4_syn_recv_sock(struct sock *sk, + struct sk_buff *skb, + struct open_request *req); + +extern int tcp_v4_backlog_rcv(struct sock *sk, + struct sk_buff *skb); +extern int tcp_v4_connect(struct sock *sk, + struct sockaddr *uaddr, + int addr_len); + + +extern void tcp_read_wakeup(struct sock *); +extern void tcp_write_xmit(struct sock *); +extern void tcp_time_wait(struct sock *); +extern void tcp_do_retransmit(struct sock *, int); + +/* tcp_output.c */ + +extern void tcp_send_probe0(struct sock *); +extern void tcp_send_partial(struct sock *); +extern void tcp_write_wakeup(struct sock *); +extern void tcp_send_fin(struct sock *sk); +extern int tcp_send_synack(struct sock *); +extern int tcp_send_skb(struct sock *, struct sk_buff *); +extern void tcp_send_ack(struct sock *sk); +extern void tcp_send_delayed_ack(struct sock *sk, int max_timeout); + +/* tcp_input.c */ +extern void tcp_cache_zap(void); + +/* CONFIG_IP_TRANSPARENT_PROXY */ +extern int tcp_chkaddr(struct sk_buff *); + +/* tcp_timer.c */ +#define tcp_reset_msl_timer(x,y,z) net_reset_timer(x,y,z) +extern void tcp_reset_xmit_timer(struct sock *, int, unsigned long); +extern void tcp_clear_xmit_timer(struct sock *, int); +extern int tcp_timer_is_set(struct sock *, int); +extern void tcp_init_xmit_timers(struct sock *); +extern void tcp_clear_xmit_timers(struct sock *); + +extern void tcp_retransmit_timer(unsigned long); +extern void tcp_delack_timer(unsigned long); +extern void tcp_probe_timer(unsigned long); + + +/* + * TCP slow timer + */ +extern struct timer_list tcp_slow_timer; + +struct tcp_sl_timer { + atomic_t count; + unsigned long period; + unsigned long last; + void (*handler) (unsigned long); +}; + +#define TCP_SLT_SYNACK 0 +#define TCP_SLT_KEEPALIVE 1 +#define TCP_SLT_MAX 2 + +extern struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX]; + +static __inline__ unsigned short tcp_raise_window(struct sock *sk) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + long cur_win; + int res = 0; + + /* + * compute the actual window i.e. + * old_window - received_bytes_on_that_win + */ + + cur_win = tp->rcv_wup - (tp->rcv_nxt - tp->rcv_wnd); + + + /* + * We need to send an ack right away if + * our rcv window is blocking the sender and + * we have more free space to offer. + */ + + if (cur_win < (sk->mss << 1)) + res = 1; + return res; +} + +extern unsigned short tcp_select_window(struct sock *sk); + /* * List all states of a TCP socket that can be viewed as a "connected" * state. This now includes TCP_SYN_RECV, although I am not yet fully * convinced that this is the solution for the 'getpeername(2)' * problem. Thanks to Stephen A. Wood <saw@cebaf.gov> -FvK */ -extern __inline const int -tcp_connected(const int state) + +extern __inline const int tcp_connected(const int state) { return(state == TCP_ESTABLISHED || state == TCP_CLOSE_WAIT || state == TCP_FIN_WAIT1 || state == TCP_FIN_WAIT2 || state == TCP_SYN_RECV); } +/* + * Calculate(/check) TCP checksum + */ +static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len, + unsigned long saddr, unsigned long daddr, + unsigned long base) +{ + return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); +} + -extern struct proto tcp_prot; +#undef STATE_TRACE +#ifdef STATE_TRACE +static char *statename[]={ + "Unused","Established","Syn Sent","Syn Recv", + "Fin Wait 1","Fin Wait 2","Time Wait", "Close", + "Close Wait","Last ACK","Listen","Closing" +}; +#endif -extern void tcp_err(int err, unsigned char *header, unsigned long daddr, - unsigned long saddr, struct inet_protocol *protocol); -extern void tcp_shutdown (struct sock *sk, int how); -extern int tcp_rcv(struct sk_buff *skb, struct device *dev, - struct options *opt, unsigned long daddr, - unsigned short len, unsigned long saddr, int redo, - struct inet_protocol *protocol); +static __inline__ void tcp_set_state(struct sock *sk, int state) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + int oldstate = sk->state; -extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); + sk->state = state; -extern int tcp_select_window(struct sock *sk); -extern void tcp_send_check(struct tcphdr *th, unsigned long saddr, - unsigned long daddr, int len, struct sock *sk); -extern void tcp_send_probe0(struct sock *sk); -extern void tcp_enqueue_partial(struct sk_buff *, struct sock *); -extern struct sk_buff * tcp_dequeue_partial(struct sock *); -extern void tcp_cache_zap(void); +#ifdef STATE_TRACE + if(sk->debug) + printk("TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]); +#endif + + switch (state) { + case TCP_ESTABLISHED: + if (oldstate != TCP_ESTABLISHED) { + tcp_statistics.TcpCurrEstab++; + } + break; + + case TCP_CLOSE: + tcp_cache_zap(); + /* Should be about 2 rtt's */ + net_reset_timer(sk, TIME_DONE, min(tp->srtt * 2, TCP_DONE_TIME)); + /* fall through */ + default: + if (oldstate==TCP_ESTABLISHED) + tcp_statistics.TcpCurrEstab--; + } +} + +extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req) +{ + if (req->dl_next == req) + { + tp->syn_wait_queue = NULL; + } + else + { + req->dl_prev->dl_next = req->dl_next; + req->dl_next->dl_prev = req->dl_prev; + + if (tp->syn_wait_queue == req) + { + tp->syn_wait_queue = req->dl_next; + } + } + + req->dl_prev = req->dl_next = NULL; +} + +extern __inline__ void tcp_synq_queue(struct tcp_opt *tp, struct open_request *req) +{ + if (!tp->syn_wait_queue) + { + req->dl_next = req; + req->dl_prev = req; + tp->syn_wait_queue = req; + } + else + { + struct open_request *list = tp->syn_wait_queue; + + req->dl_next = list; + req->dl_prev = list->dl_prev; + list->dl_prev->dl_next = req; + list->dl_prev = req; + } + +} + +extern void __tcp_inc_slow_timer(struct tcp_sl_timer *slt); +extern __inline__ void tcp_inc_slow_timer(int timer) +{ + struct tcp_sl_timer *slt = &tcp_slt_array[timer]; + + if (slt->count == 0) + { + __tcp_inc_slow_timer(slt); + } + + atomic_inc(&slt->count); +} + +extern __inline__ void tcp_dec_slow_timer(int timer) +{ + struct tcp_sl_timer *slt = &tcp_slt_array[timer]; + + atomic_dec(&slt->count); +} #endif /* _TCP_H */ + diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h new file mode 100644 index 000000000..412943e4d --- /dev/null +++ b/include/net/transp_v6.h @@ -0,0 +1,42 @@ +#ifndef _TRANSP_V6_H +#define _TRANSP_V6_H + +#include <net/checksum.h> + +/* + * IPv6 transport protocols + */ + +#ifdef __KERNEL__ + +extern struct proto rawv6_prot; +extern struct proto udpv6_prot; +extern struct proto tcpv6_prot; + +extern void rawv6_init(void); +extern void udpv6_init(void); +extern void tcpv6_init(void); + +extern int udpv6_connect(struct sock *sk, + struct sockaddr *uaddr, + int addr_len); + +extern int datagram_recv_ctl(struct sock *sk, + struct msghdr *msg, + struct sk_buff *skb); + +extern int datagram_send_ctl(struct msghdr *msg, + struct device **src_dev, + struct in6_addr **src_addr, + struct ipv6_options *opt); + +#define LOOPBACK4_IPV6 __constant_htonl(0x7f000006) + +/* + * address family specific functions + */ +extern struct tcp_func ipv4_specific; + +#endif + +#endif diff --git a/include/net/udp.h b/include/net/udp.h index 62f0c7a0e..d834feb6d 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -31,22 +31,25 @@ extern struct proto udp_prot; -extern void udp_err(int err, unsigned char *header, unsigned long daddr, - unsigned long saddr, struct inet_protocol *protocol); -extern void udp_send_check(struct udphdr *uh, unsigned long saddr, - unsigned long daddr, int len, struct sock *sk); -extern int udp_recvfrom(struct sock *sk, unsigned char *to, - int len, int noblock, unsigned flags, - struct sockaddr_in *sin, int *addr_len); -extern int udp_read(struct sock *sk, unsigned char *buff, - int len, int noblock, unsigned flags); +extern void udp_err(int type, int code, unsigned char *header, + __u32 info, __u32 daddr, __u32 saddr, + struct inet_protocol *protocol, int len); +extern void udp_send_check(struct udphdr *uh, __u32 saddr, + __u32 daddr, int len, struct sock *sk); extern int udp_connect(struct sock *sk, - struct sockaddr_in *usin, int addr_len); + struct sockaddr *usin, int addr_len); + +extern int udp_sendmsg(struct sock *sk, struct msghdr *msg, + int len, int noblock, int flags); + extern int udp_rcv(struct sk_buff *skb, struct device *dev, - struct options *opt, unsigned long daddr, - unsigned short len, unsigned long saddr, int redo, + struct options *opt, __u32 daddr, + unsigned short len, __u32 saddr, int redo, struct inet_protocol *protocol); extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); extern void udp_cache_zap(void); /* Remove udp last socket cache */ +/* CONFIG_IP_TRANSPARENT_PROXY */ +extern int udp_chkaddr(struct sk_buff *skb); + #endif /* _UDP_H */ diff --git a/include/net/unix.h b/include/net/unix.h deleted file mode 100644 index dba43800f..000000000 --- a/include/net/unix.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * UNIX An implementation of the AF_UNIX network domain for the - * LINUX operating system. UNIX is implemented using the - * BSD Socket interface as the means of communication with - * the user level. - * - * This file describes some things of the UNIX protocol family - * module. It is mainly used for the "proc" sub-module now, - * but it may be useful for cleaning up the UNIX module as a - * whole later. - * - * Version: @(#)unix.h 1.0.3 05/25/93 - * - * Authors: Orest Zborowski, <obz@Kodak.COM> - * Ross Biro, <bir7@leland.Stanford.Edu> - * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> - * - * Fixes: - * Dmitry Gorodchanin - proc locking - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - - -#ifdef _LINUX_UN_H - - -struct unix_proto_data { - int refcnt; /* cnt of reference 0=free */ - /* -1=not initialised -bgm */ - struct socket *socket; /* socket we're bound to */ - int protocol; - struct sockaddr_un sockaddr_un; - short sockaddr_len; /* >0 if name bound */ - char *buf; - int bp_head, bp_tail; - struct inode *inode; - struct unix_proto_data *peerupd; - struct wait_queue *wait; /* Lock across page faults (FvK) */ - int lock_flag; -}; - -extern struct unix_proto_data unix_datas[NSOCKETS_UNIX]; - - -#define last_unix_data (unix_datas + NSOCKETS_UNIX - 1) - - -#define UN_DATA(SOCK) ((struct unix_proto_data *)(SOCK)->data) -#define UN_PATH_OFFSET ((unsigned long)((struct sockaddr_un *)0) \ - ->sun_path) - -/* - * Buffer size must be power of 2. buffer mgmt inspired by pipe code. - * note that buffer contents can wraparound, and we can write one byte less - * than full size to discern full vs empty. - */ -#define BUF_SIZE PAGE_SIZE -#define UN_BUF_AVAIL(UPD) (((UPD)->bp_head - (UPD)->bp_tail) & \ - (BUF_SIZE-1)) -#define UN_BUF_SPACE(UPD) ((BUF_SIZE-1) - UN_BUF_AVAIL(UPD)) - -#endif /* _LINUX_UN_H */ - - -extern void unix_proto_init(struct net_proto *pro); diff --git a/include/net/x25call.h b/include/net/x25call.h new file mode 100644 index 000000000..7c478a1d9 --- /dev/null +++ b/include/net/x25call.h @@ -0,0 +1,2 @@ +/* Separate to keep compilation of protocols.c simpler */ +extern void x25_proto_init(struct net_proto *pro); diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h new file mode 100644 index 000000000..8328210e8 --- /dev/null +++ b/include/scsi/scsi.h @@ -0,0 +1,200 @@ +#ifndef _LINUX_SCSI_H +#define _LINUX_SCSI_H + +/* + * This header file contains public constants and structures used by + * the scsi code for linux. + */ + +/* + $Header: /usr/src/linux/include/linux/RCS/scsi.h,v 1.3 1993/09/24 12:20:33 drew Exp $ + + For documentation on the OPCODES, MESSAGES, and SENSE values, + please consult the SCSI standard. + +*/ + +/* + * SCSI opcodes + */ + +#define TEST_UNIT_READY 0x00 +#define REZERO_UNIT 0x01 +#define REQUEST_SENSE 0x03 +#define FORMAT_UNIT 0x04 +#define READ_BLOCK_LIMITS 0x05 +#define REASSIGN_BLOCKS 0x07 +#define READ_6 0x08 +#define WRITE_6 0x0a +#define SEEK_6 0x0b +#define READ_REVERSE 0x0f +#define WRITE_FILEMARKS 0x10 +#define SPACE 0x11 +#define INQUIRY 0x12 +#define RECOVER_BUFFERED_DATA 0x14 +#define MODE_SELECT 0x15 +#define RESERVE 0x16 +#define RELEASE 0x17 +#define COPY 0x18 +#define ERASE 0x19 +#define MODE_SENSE 0x1a +#define START_STOP 0x1b +#define RECEIVE_DIAGNOSTIC 0x1c +#define SEND_DIAGNOSTIC 0x1d +#define ALLOW_MEDIUM_REMOVAL 0x1e + +#define SET_WINDOW 0x24 +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a +#define SEEK_10 0x2b +#define WRITE_VERIFY 0x2e +#define VERIFY 0x2f +#define SEARCH_HIGH 0x30 +#define SEARCH_EQUAL 0x31 +#define SEARCH_LOW 0x32 +#define SET_LIMITS 0x33 +#define PRE_FETCH 0x34 +#define READ_POSITION 0x34 +#define SYNCHRONIZE_CACHE 0x35 +#define LOCK_UNLOCK_CACHE 0x36 +#define READ_DEFECT_DATA 0x37 +#define MEDIUM_SCAN 0x38 +#define COMPARE 0x39 +#define COPY_VERIFY 0x3a +#define WRITE_BUFFER 0x3b +#define READ_BUFFER 0x3c +#define UPDATE_BLOCK 0x3d +#define READ_LONG 0x3e +#define WRITE_LONG 0x3f +#define CHANGE_DEFINITION 0x40 +#define WRITE_SAME 0x41 +#define READ_TOC 0x43 +#define LOG_SELECT 0x4c +#define LOG_SENSE 0x4d +#define MODE_SELECT_10 0x55 +#define MODE_SENSE_10 0x5a +#define READ_12 0xa8 +#define WRITE_12 0xaa +#define WRITE_VERIFY_12 0xae +#define SEARCH_HIGH_12 0xb0 +#define SEARCH_EQUAL_12 0xb1 +#define SEARCH_LOW_12 0xb2 +#define SEND_VOLUME_TAG 0xb6 +#define WRITE_LONG_2 0xea + +/* + * Status codes + */ + +#define GOOD 0x00 +#define CHECK_CONDITION 0x01 +#define CONDITION_GOOD 0x02 +#define BUSY 0x04 +#define INTERMEDIATE_GOOD 0x08 +#define INTERMEDIATE_C_GOOD 0x0a +#define RESERVATION_CONFLICT 0x0c +#define COMMAND_TERMINATED 0x11 +#define QUEUE_FULL 0x14 + +#define STATUS_MASK 0x3e + +/* + * SENSE KEYS + */ + +#define NO_SENSE 0x00 +#define RECOVERED_ERROR 0x01 +#define NOT_READY 0x02 +#define MEDIUM_ERROR 0x03 +#define HARDWARE_ERROR 0x04 +#define ILLEGAL_REQUEST 0x05 +#define UNIT_ATTENTION 0x06 +#define DATA_PROTECT 0x07 +#define BLANK_CHECK 0x08 +#define COPY_ABORTED 0x0a +#define ABORTED_COMMAND 0x0b +#define VOLUME_OVERFLOW 0x0d +#define MISCOMPARE 0x0e + + +/* + * DEVICE TYPES + */ + +#define TYPE_DISK 0x00 +#define TYPE_TAPE 0x01 +#define TYPE_PROCESSOR 0x03 /* HP scanners use this */ +#define TYPE_WORM 0x04 /* Treated as ROM by our system */ +#define TYPE_ROM 0x05 +#define TYPE_SCANNER 0x06 +#define TYPE_MOD 0x07 /* Magneto-optical disk - + * - treated as TYPE_DISK */ +#define TYPE_NO_LUN 0x7f + + +/* + * MESSAGE CODES + */ + +#define COMMAND_COMPLETE 0x00 +#define EXTENDED_MESSAGE 0x01 +#define EXTENDED_MODIFY_DATA_POINTER 0x00 +#define EXTENDED_SDTR 0x01 +#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */ +#define EXTENDED_WDTR 0x03 +#define SAVE_POINTERS 0x02 +#define RESTORE_POINTERS 0x03 +#define DISCONNECT 0x04 +#define INITIATOR_ERROR 0x05 +#define ABORT 0x06 +#define MESSAGE_REJECT 0x07 +#define NOP 0x08 +#define MSG_PARITY_ERROR 0x09 +#define LINKED_CMD_COMPLETE 0x0a +#define LINKED_FLG_CMD_COMPLETE 0x0b +#define BUS_DEVICE_RESET 0x0c + +#define INITIATE_RECOVERY 0x0f /* SCSI-II only */ +#define RELEASE_RECOVERY 0x10 /* SCSI-II only */ + +#define SIMPLE_QUEUE_TAG 0x20 +#define HEAD_OF_QUEUE_TAG 0x21 +#define ORDERED_QUEUE_TAG 0x22 + +/* + * Here are some scsi specific ioctl commands which are sometimes useful. + */ +/* These are a few other constants only used by scsi devices */ + +#define SCSI_IOCTL_GET_IDLUN 0x5382 + +/* Used to turn on and off tagged queuing for scsi devices */ + +#define SCSI_IOCTL_TAGGED_ENABLE 0x5383 +#define SCSI_IOCTL_TAGGED_DISABLE 0x5384 + +/* Used to obtain the host number of a device. */ +#define SCSI_IOCTL_PROBE_HOST 0x5385 + + +/* + * 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-indent-level: 4 + * c-brace-imaginary-offset: 0 + * c-brace-offset: -4 + * c-argdecl-indent: 4 + * c-label-offset: -4 + * c-continued-statement-offset: 4 + * c-continued-brace-offset: 0 + * indent-tabs-mode: nil + * tab-width: 8 + * End: + */ + +#endif diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h new file mode 100644 index 000000000..57f439dfb --- /dev/null +++ b/include/scsi/scsi_ioctl.h @@ -0,0 +1,40 @@ +#ifndef _SCSI_IOCTL_H +#define _SCSI_IOCTL_H + +#define SCSI_IOCTL_SEND_COMMAND 1 +#define SCSI_IOCTL_TEST_UNIT_READY 2 +#define SCSI_IOCTL_BENCHMARK_COMMAND 3 +#define SCSI_IOCTL_SYNC 4 /* Request synchronous parameters */ +/* The door lock/unlock constants are compatible with Sun constants for + the cdrom */ +#define SCSI_IOCTL_DOORLOCK 0x5380 /* lock the eject mechanism */ +#define SCSI_IOCTL_DOORUNLOCK 0x5381 /* unlock the mechanism */ + +#define SCSI_REMOVAL_PREVENT 1 +#define SCSI_REMOVAL_ALLOW 0 + +#ifdef __KERNEL__ + +extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg); +extern int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg); + +/* + * Structures used for scsi_ioctl et al. + */ + +typedef struct scsi_ioctl_command { + unsigned int inlen; + unsigned int outlen; + unsigned char data[0]; +} Scsi_Ioctl_Command; + +typedef struct scsi_idlun { + __u32 dev_id; + __u32 host_unique_id; +} Scsi_Idlun; + +#endif + +#endif + + diff --git a/include/linux/scsicam.h b/include/scsi/scsicam.h index d78dc71c4..954e1407e 100644 --- a/include/linux/scsicam.h +++ b/include/scsi/scsicam.h @@ -12,5 +12,6 @@ #ifndef SCSICAM_H #define SCSICAM_H -extern int scsicam_bios_param (Disk *disk, int dev, int *ip); +#include <linux/kdev_t.h> +extern int scsicam_bios_param (Disk *disk, kdev_t dev, int *ip); #endif /* def SCSICAM_H */ diff --git a/include/scsi/sg.h b/include/scsi/sg.h new file mode 100644 index 000000000..ff6cfbe93 --- /dev/null +++ b/include/scsi/sg.h @@ -0,0 +1,41 @@ +/* + History: + Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user + process control of SCSI devices. + Development Sponsored by Killy Corp. NY NY +*/ + +#ifndef _SCSI_GENERIC_H +#define _SCSI_GENERIC_H + +/* + An SG device is accessed by writing "packets" to it, the replies + are then read using the read call. The same header is used for + reply, just ignore reply_len field. +*/ + +struct sg_header + { + int pack_len; /* length of incoming packet <4096 (including header) */ + int reply_len; /* maximum length <4096 of expected reply */ + int pack_id; /* id number of packet */ + int result; /* 0==ok, otherwise refer to errno codes */ + unsigned int twelve_byte:1; /* Force 12 byte command length for group 6 & 7 commands */ + unsigned int other_flags:31; /* for future use */ + unsigned char sense_buffer[16]; /* used only by reads */ + /* command follows then data for command */ + }; + +/* ioctl's */ +#define SG_SET_TIMEOUT 0x2201 /* set timeout *(int *)arg==timeout */ +#define SG_GET_TIMEOUT 0x2202 /* get timeout return timeout */ + +#define SG_DEFAULT_TIMEOUT (60*HZ) /* 1 minute timeout */ +#define SG_DEFAULT_RETRIES 1 + +#define SG_MAX_QUEUE 4 /* maximum outstanding request, arbitrary, may be + changed if sufficient DMA buffer room available */ + +#define SG_BIG_BUFF 32768 + +#endif diff --git a/include/sgidefs.h b/include/sgidefs.h new file mode 100644 index 000000000..05994371a --- /dev/null +++ b/include/sgidefs.h @@ -0,0 +1,17 @@ +/* + * include/sgidefs.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + * + * This file is here to satisfy GCC's expectations. + */ +#ifndef __SGIDEFS_H +#define __SGIDEFS_H + +#include <asm/sgidefs.h> + +#endif /* __SGIDEFS_H */ |