Commit b82f08ce authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.22pre1

parent 90ff4d27
......@@ -2,15 +2,15 @@ Intro
=====
This document is designed to provide a list of the minimum levels of
software necessary to run the 2.2 kernels, as well as provide brief
software necessary to run the 2.3 kernels, as well as provide brief
instructions regarding any other "Gotchas" users may encounter when
trying life on the Bleeding Edge. If upgrading from a pre-2.0.x
kernel, please consult the Changes file included with 2.0.x kernels for
trying life on the Bleeding Edge. If upgrading from a pre-2.2.x
kernel, please consult the Changes file included with 2.2.x kernels for
additional information; most of that information will not be repeated
here. Basically, this document assumes that your system is already
functional and running at least 2.0.x kernels.
functional and running at least 2.2.x kernels.
It is originally based on my "Changes" file for 2.0.x kernels and
It is originally based on my "Changes" file for 2.2.x kernels and
therefore owes credit to the same people as that file (Jared Mauch,
Axel Boldt, Alessandro Sigala, and countless other users all over the
'net). Please feel free to submit changes, corrections, gripes,
......@@ -43,7 +43,7 @@ Current Minimal Requirements
encountered a bug! If you're unsure what version you're currently
running, the suggested command should tell you.
- Kernel modutils 2.1.121 ; insmod -V
- Kernel modutils 2.3.5 ; insmod -V
- Gnu C 2.7.2.3 ; gcc --version
- Binutils 2.8.1.0.23 ; ld -v
- Linux libc5 C Library 5.4.46 ; ls -l /lib/libc*
......@@ -168,7 +168,7 @@ Modules
=======
You need to upgrade to the latest version of modutils for the Linux
2.2 kernel. This version will also work with your 2.0 kernel.
2.3 kernel. This version will also work with your 2.0 kernel.
As of 2.1.90-pre1, kerneld has been replaced by a kernel thread,
kmod. See Documentation/kmod.txt for more information. The main
......@@ -567,8 +567,8 @@ ftp://metalab.unc.edu/pub/Linux/GCC/ld.so-1.9.9.tar.gz
Modules utilities
=================
The 2.1.121 release:
ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.121.tar.gz
The 2.3.5 release:
ftp://ftp.ocs.com.au/pub/modutils/v2.3/modutils-2.3.5.tar.gz
Procps utilities
================
......
......@@ -2,47 +2,7 @@ Smbfs is a filesystem that implements the SMB protocol, which is the
protocol used by Windows for Workgroups, Windows 95 and Windows NT.
Smbfs was inspired by Samba, the program written by Andrew Tridgell
that turns any Unix host into a file server for DOS or Windows clients.
See ftp://nimbus.anu.edu.au/pub/tridge/samba/ for this interesting
program suite and much more information on SMB, NetBIOS over TCP/IP,
and explanations for concepts like netbios name or share.
To use smbfs, you must first install the Samba package (Samba-1.9.18p1 or
later). This package includes the special smbmount utility needed to mount
smbfs volumes. Refer to the smbmount(8) and smbmnt(8) manpages for the
details regarding smbfs mounts.
The smbmount utility reads the Samba smb.conf config file for some of its
options, and at least one of these is important for smbfs operation. You
should enable the TCP_NODELAY socket option, or else directory listings
will be dramatically slower (under Win NT at least).
Mount-Time Options
Windows 95 has several bugs that affect SMB operations, and smbfs includes
work-arounds for all of the bugs found (so far, at least.) These can be
enabled at compile-time with the CONFIG_SMB_WIN95 kernel option.
Unfortunately, some of the Win 95 work-arounds interact with Win NT bugs,
so if you're using several different types of servers on your network you
probably want to enable the work-arounds at mount time. To do this, answer
`N' to the CONFIG_SMB_WIN95 option, and add the needed options listed below
to the file mode argument of the mount command for the Win 95 servers.
Option Value Effect
Identify Win 95 Server 1 Enables bug fixes
Use Core Attributes 2 Speeds up directory scans, only mtime
Use Dir Attributes 4 Alternate way to get file attributes
To apply the options, sum the values and prepend it to the file mode. For
example, to use options 1 and 2 with file mode 755, you would specify 3755:
mount /mnt/tmp -f 3755
Smbfs will print a message at mount time confirming the selected options.
Note that _only_ Windows 95 servers require special treatment; using the
"core attributes" option with Win NT will give trash timestamp values.
To summarize, if your network includes both Win 95 and NT servers:
(1) Do _not_ enable the CONFIG_SMB_WIN95 kernel option
(2) Add the desired work-around options to the mount command for your
Win 95 server(s).
Smbfs is a SMB client, but uses parts of samba for it's operation. For
more info on samba, including documentation, please go to
http://www.samba.org/ and then on to your nearest mirror.
VERSION = 2
PATCHLEVEL = 3
SUBLEVEL = 21
SUBLEVEL = 22
EXTRAVERSION =
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
......
......@@ -17,7 +17,6 @@
#
LD=$(CROSS_COMPILE)ld -m elf_i386
CPP=$(CC) -E
OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
LDFLAGS=-e stext
LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
......@@ -80,10 +79,13 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
vmlinux: arch/i386/vmlinux.lds
arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE
gcc -E -C -P -I$(HPATH) -imacros $(HPATH)/asm-i386/page_offset.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds
$(CPP) -C -P -imacros $(HPATH)/asm-i386/page_offset.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds
FORCE: ;
.PHONY: zImage bzImge compressed zlilo bzlilo zdisk bzdisk install \
clean archclean archmrproper archdep
zImage: vmlinux
@$(MAKEBOOT) zImage
......
......@@ -247,7 +247,7 @@ die: jne die # es must be at 64kB boundary
xorw %bx, %bx # bx is starting address within segment
rp_read:
#ifdef __BIG_KERNEL__
lcall bootsect_kludge # in setup.S
.word 0x1eff, 0x0220 # lcall *bootsect_kludge in setup.S
#else
movw %es, %ax
subw $SYSSEG, %ax
......@@ -401,7 +401,7 @@ kill_motor:
pushw %dx
movw $0x3f2, %dx
xorb %al, %al
outw %al, %dx
outb %al, %dx
popw %dx
ret
......
......@@ -203,6 +203,7 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_NCR53C8XX is not set
CONFIG_SCSI_SYM53C8XX=y
......
......@@ -237,8 +237,11 @@ tracesys:
movl $-ENOSYS,EAX(%esp)
call SYMBOL_NAME(syscall_trace)
movl ORIG_EAX(%esp),%eax
cmpl $(NR_syscalls),%eax
jae tracesys_exit
call *SYMBOL_NAME(sys_call_table)(,%eax,4)
movl %eax,EAX(%esp) # save the return value
tracesys_exit:
call SYMBOL_NAME(syscall_trace)
jmp ret_from_sys_call
badsys:
......
......@@ -71,8 +71,6 @@ static int putreg(struct task_struct *child,
unsigned long regno, unsigned long value)
{
switch (regno >> 2) {
case ORIG_EAX:
return -EIO;
case FS:
if (value && (value & 3) != 3)
return -EIO;
......
......@@ -88,6 +88,7 @@ $(BOOT_TARGETS): $(CHECKS) vmlinux
@$(MAKECHRPBOOT) $@
znetboot: $(CHECKS) vmlinux
ifdef CONFIG_ALL_PPC
ifdef CONFIG_SMP
ifdef CONFIG_PPC64
cp -f vmlinux /tftpboot/vmlinux.smp.64
......@@ -100,6 +101,7 @@ ifdef CONFIG_PPC64
else
cp -f vmlinux /tftpboot/vmlinux
endif
endif
endif
@$(MAKECOFFBOOT) $@
@$(MAKEBOOT) $@
......
......@@ -35,6 +35,12 @@ else
TFTPIMAGE=/tftpboot/zImage.prep$(MSIZE)
endif
ifeq ($(CONFIG_SMP),y)
TFTPSIMAGE=/tftpboot/sImage.smp
else
TFTPSIMAGE=/tftpboot/sImage
endif
ifeq ($(CONFIG_PPC64),y)
MSIZE=.64
else
......@@ -121,7 +127,7 @@ ifdef CONFIG_PREP
cp zImage $(TFTPIMAGE)
endif
ifdef CONFIG_GEMINI
cp sImage /tftpboot/
cp sImage $(TFTPSIMAGE)
endif
znetboot.initrd : zImage.initrd
......
......@@ -82,6 +82,8 @@ define_bool CONFIG_BINFMT_ELF y
define_bool CONFIG_KERNEL_ELF y
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
source drivers/pcmcia/Config.in
source drivers/parport/Config.in
if [ "$CONFIG_8xx" != "y" ]; then
......
......@@ -14,7 +14,7 @@ O_TARGET := kernel.o
OX_OBJS := ppc_ksyms.o setup.o
KHEAD := head.o
ifdef CONFIG_PPC_ALL
ifdef CONFIG_ALL_PPC
CONFIG_PMAC=y
CONFIG_PREP=y
CONFIG_CHRP=y
......@@ -65,10 +65,13 @@ O_OBJS += apus_setup.o prom.o open_pic.o
else
ifneq ($(CONFIG_8xx),y)
O_OBJS += chrp_setup.o chrp_pci.o chrp_time.o \
pmac_time.o pmac_support.o pmac_pci.o pmac_setup.o \
pmac_time.o pmac_pci.o pmac_setup.o \
prom.o open_pic.o feature.o \
i8259.o pmac_pic.o indirect_pci.o \
gemini_pci.o gemini_prom.o gemini_setup.o
ifeq ($(CONFIG_NVRAM),y)
O_OBJS += pmac_support.o
endif
ifeq ($(CONFIG_PREP), y)
O_OBJS += prep_pci.o prep_setup.o prep_nvram.o prep_time.o residual.o
......
......@@ -498,7 +498,9 @@ void __init chrp_init_IRQ(void)
void __init
chrp_init2(void)
{
#ifdef CONFIG_NVRAM
pmac_nvram_init();
#endif
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
......@@ -599,12 +601,6 @@ chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_
hw->irq = chrp_ide_irq;
}
#if defined(CONFIG_BLK_DEV_IDE_MODULE)
EXPORT_SYMBOL(chrp_ide_irq);
EXPORT_SYMBOL(chrp_ide_ports_known);
EXPORT_SYMBOL(chrp_ide_regbase);
EXPORT_SYMBOL(chrp_ide_probe);
#endif
#endif
void __init
......
/*
* arch/ppc/kernel/hashtable.S
*
* $Id: hashtable.S,v 1.3 1999/09/05 11:56:27 paulus Exp $
* $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
......@@ -35,7 +35,7 @@
* _PAGE_RW (2) if a write. r20 contains DSISR or SRR1,
* so bit 1 (0x40000000) is set if the exception was due
* to no matching PTE being found in the hash table.
* r5 contains the physical address of the current task's thread.
* SPRG3 contains the physical address of the current task's thread.
*
* Returns to the caller if the access is illegal or there is no
* mapping for the address. Otherwise it places an appropriate PTE
......@@ -53,12 +53,14 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64)
.globl hash_page
hash_page:
#ifdef __SMP__
SAVE_2GPRS(7,r21)
eieio
lis r2,hash_table_lock@h
ori r2,r2,hash_table_lock@l
tophys(r2,r2)
lis r6,100000000@h
lis r6,0x0fff0000@h
mtctr r6
mfspr r5,SPRG3
lwz r0,PROCESSOR-THREAD(r5)
or r0,r0,r6
10: lwarx r6,0,r2
......@@ -66,10 +68,18 @@ hash_page:
bne- 12f
stwcx. r0,0,r2
beq+ 11f
12: cmpw r6,r0
/* spin here a bit */
12: mfctr r7
li r8,1000
mtctr r8
13:
bdnz 13b
mtctr r7
cmpw r6,r0
bdnzf 2,10b
tw 31,31,31
11: eieio
REST_2GPRS(7, r21)
#endif
/* Get PTE (linux-style) and check access */
mfspr r2,SPRG3 /* current task's THREAD (phys) */
......@@ -182,7 +192,7 @@ hash_page_patch_B:
10: mtctr r2
addi r3,r4,-8 /* search primary PTEG */
1: lwzu r0,8(r3) /* get next PTE */
srwi. r0,r0,31 /* only want to check valid bit */
rlwinm. r0,r0,0,0,0 /* only want to check valid bit */
bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
beq+ found_empty
......@@ -195,7 +205,7 @@ hash_page_patch_C:
addi r3,r3,-8
mtctr r2
2: lwzu r0,8(r3)
srwi. r0,r0,31 /* only want to check valid bit */
rlwinm. r0,r0,0,0,0 /* only want to check valid bit */
bdnzf 2,2b
beq+ found_empty
......@@ -209,19 +219,20 @@ hash_page_patch_C:
* put the PTE in the primary PTEG.
*/
xori r5,r5,0x40 /* clear H bit again */
lwz r2,next_slot@l(0)
lis r3,next_slot@ha
tophys(r3,r3)
lwz r2,next_slot@l(r3)
addi r2,r2,8
andi. r2,r2,0x38
stw r2,next_slot@l(0)
stw r2,next_slot@l(r3)
add r3,r4,r2
11:
/* update counter of evicted pages */
lis r2,htab_evicts@h
ori r2,r2,htab_evicts@l
lis r2,htab_evicts@ha
tophys(r2,r2)
lwz r4,0(r2)
lwz r4,htab_evicts@l(r2)
addi r4,r4,1
stw r4,0(r2)
stw r4,htab_evicts@l(r2)
#ifndef __SMP__
/* Store PTE in PTEG */
......@@ -271,12 +282,11 @@ found_slot:
* update the htab misses count
* -- Cort
*/
lis r2,htab_reloads@h
ori r2,r2,htab_reloads@l
lis r2,htab_reloads@ha
tophys(r2,r2)
lwz r3,0(r2)
lwz r3,htab_reloads@l(r2)
addi r3,r3,1
stw r3,0(r2)
stw r3,htab_reloads@l(r2)
#ifdef __SMP__
lis r2,hash_table_lock@ha
......@@ -322,13 +332,13 @@ hash_page_out:
.globl hash_table_lock
hash_table_lock:
.long 0
.text
#endif /* __SMP__ */
/* next_slot is assumed to be within the first 32kB of physical RAM */
.data
next_slot:
.long 0
.text
/*
* Flush entries from the hash table with VSIDs in the range
* given.
......
/*
* arch/ppc/kernel/head.S
*
* $Id: head.S,v 1.147 1999/09/15 23:58:53 cort Exp $
* $Id: head.S,v 1.154 1999/10/12 00:33:31 cort Exp $
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
......@@ -51,6 +51,10 @@
/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
#define LOAD_BAT(n, reg, RA, RB) \
/* see the comment for clear_bats() -- Cort */ \
li RA,0; \
mtspr IBAT##n##U,RA; \
mtspr DBAT##n##U,RA; \
lwz RA,(n*16)+0(reg); \
lwz RB,(n*16)+4(reg); \
mtspr IBAT##n##U,RA; \
......@@ -150,7 +154,7 @@ __start:
*/
mr r4,r30
bl fix_mem_constants
#endif
#endif /* CONFIG_APUS */
/*
* Use the first pair of BAT registers to map the 1st 16MB
......@@ -158,7 +162,7 @@ __start:
* call OF any more.
*/
lis r11,KERNELBASE@h
#ifndef CONFIG_PPC64xxx
#ifndef CONFIG_PPC64
mfspr r9,PVR
rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
cmpi 0,r9,1
......@@ -173,10 +177,19 @@ __start:
mtspr IBAT1L,r10
b 5f
#endif /* CONFIG_PPC64 */
4:
tophys(r8,r11)
4: tophys(r8,r11)
#ifdef __SMP__
ori r8,r8,0x12 /* R/W access, M=1 */
#else
ori r8,r8,2 /* R/W access */
#endif /* __SMP__ */
#ifdef CONFIG_APUS
ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */
#else
ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
#endif /* CONFIG_APUS */
#ifdef CONFIG_PPC64
/* clear out the high 32 bits in the BAT */
clrldi r11,r11,32
......@@ -185,32 +198,14 @@ __start:
clrldi r16,r16,63
mtsdr1 r16
#else /* CONFIG_PPC64 */
/*
* allow secondary cpus to get at all of ram in early bootup
* since their init_task may be up there -- Cort
/*
* If the MMU is off clear the bats. See clear_bat() -- Cort
*/
#if 0
oris r18,r8,0x10000000@h
oris r21,r11,(KERNELBASE+0x10000000)@h
#else
lis r18,0x9000
ori r18,r18,0x12
lis r21,0x9000
ori r21,r21,0x7fe
#endif
mtspr DBAT1L,r18 /* N.B. 6xx (not 601) have valid */
mtspr DBAT1U,r21 /* bit in upper BAT register */
mtspr IBAT1L,r18
mtspr IBAT1U,r21
#if 0 /* for now, otherwise we overflow the 0x100 bytes we have here */
oris r18,r8,0x20000000@h
oris r21,r11,(KERNELBASE+0x20000000)@h
mtspr DBAT2L,r18 /* N.B. 6xx (not 601) have valid */
mtspr DBAT2U,r21 /* bit in upper BAT register */
mtspr IBAT2L,r18
mtspr IBAT2U,r21
#endif /* 0 */
mfmsr r20
andi. r20,r20,MSR_DR
bne 100f
bl clear_bats
100:
#endif /* CONFIG_PPC64 */
mtspr DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
mtspr DBAT0U,r11 /* bit in upper BAT register */
......@@ -218,27 +213,7 @@ __start:
mtspr IBAT0U,r11
5: isync
#ifdef CONFIG_APUS
/* Unfortunately the APUS specific instructions bloat the
* code so it cannot fit in the 0x100 bytes available. We have
* to do it the crude way. */
/* Map 0xfff00000 so we can access VTOP/PTOV constant when
MMU is enabled. */
lis r8,0xfff0
ori r11,r8,0x2 /* r/w */
ori r8,r8,0x2 /* 128KB, supervisor */
mtspr DBAT3U,r8
mtspr DBAT3L,r11
/* Copy exception code to exception vector base. */
lis r3,KERNELBASE@h
tophys(r4,r3)
lis r3,0xfff0 /* Copy to 0xfff00000 on APUS */
li r5,0x4000 /* # bytes of memory to copy */
li r6,0
bl copy_and_flush /* copy the first 0x4000 bytes */
#else /* CONFIG_APUS */
#ifndef CONFIG_APUS
/*
* We need to run with _start at physical address 0.
* On CHRP, we are loaded at 0x10000 since OF on CHRP uses
......@@ -267,7 +242,6 @@ __start:
* this shouldn't bother the pmac since it just gets turned on again
* as we jump to our code at KERNELBASE. -- Cort
*/
turn_on_mmu:
mfmsr r0
ori r0,r0,MSR_DR|MSR_IR
......@@ -335,7 +309,8 @@ label: \
/* System reset */
#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */
#ifdef CONFIG_GEMINI
STD_EXCEPTION(0x100, Reset, __secondary_start_gemini)
. = 0x100
b __secondary_start_gemini
#else /* CONFIG_GEMINI */
STD_EXCEPTION(0x100, Reset, __secondary_start_psurge)
#endif /* CONFIG_GEMINI */
......@@ -356,7 +331,6 @@ DataAccess:
mfspr r3,DAR /* into the hash table */
rlwinm r4,r23,32-13,30,30 /* MSR_PR -> _PAGE_USER */
rlwimi r4,r20,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */
mfspr r5,SPRG3 /* phys addr of THREAD */
bl hash_page
1: stw r20,_DSISR(r21)
mr r5,r20
......@@ -378,7 +352,6 @@ InstructionAccess:
mr r3,r22 /* into the hash table */
rlwinm r4,r23,32-13,30,30 /* MSR_PR -> _PAGE_USER */
mr r20,r23 /* SRR1 has reason bits */
mfspr r5,SPRG3 /* phys addr of THREAD */
bl hash_page
1: addi r3,r1,STACK_FRAME_OVERHEAD
mr r4,r22
......@@ -392,35 +365,8 @@ InstructionAccess:
/* External interrupt */
. = 0x500;
HardwareInterrupt:
#ifndef CONFIG_APUS
EXCEPTION_PROLOG;
#ifdef CONFIG_APUS
/* This is horrible, but there's no way around it. Enable the
data cache so the IRQ hardware register can be accessed
without cache intervention. Then disable interrupts and get
the current emulated m68k IPL value. */
mfmsr 20
xori r20,r20,MSR_DR
sync
mtmsr r20
sync
lis r3,APUS_IPL_EMU@h
li r20,(IPLEMU_SETRESET|IPLEMU_DISABLEINT)
stb r20,APUS_IPL_EMU@l(r3)
eieio
lbz r3,APUS_IPL_EMU@l(r3)
mfmsr r20
xori r20,r20,MSR_DR
sync
mtmsr r20
sync
stw r3,(_CCR+4)(r21);
#endif
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
li r4,0
......@@ -429,7 +375,12 @@ HardwareInterrupt:
do_IRQ_intercept:
.long do_IRQ;
.long ret_from_except
#else
EXCEPTION_PROLOG;
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
bl apus_interrupt_entry
#endif /* CONFIG_APUS */
/* Alignment exception */
. = 0x600
......@@ -723,8 +674,6 @@ DataStoreTLBMiss:
.globl transfer_to_handler
transfer_to_handler:
stw r22,_NIP(r21)
lis r22,MSR_POW@h
andc r23,r23,r22
stw r23,_MSR(r21)
SAVE_GPR(7, r21)
SAVE_4GPRS(8, r21)
......@@ -974,6 +923,19 @@ fix_mem_constants:
cmpw r12,r13
bne 1b
/*
* Map the memory where the exception handlers will
* be copied to when hash constants have been patched.
*/
#ifdef CONFIG_APUS_FAST_EXCEPT
lis r8,0xfff0
#else
lis r8,0
#endif
ori r8,r8,0x2 /* 128KB, supervisor */
mtspr DBAT3U,r8
mtspr DBAT3L,r8
lis r12,__ptov_table_begin@h
ori r12,r12,__ptov_table_begin@l
add r12,r12,r10 /* table begin phys address */
......@@ -1026,11 +988,9 @@ __secondary_hold:
mtlr r5
mr r24,r3 /* cpu # */
blr
#ifdef CONFIG_GEMINI
.globl __secondary_start_gemini
__secondary_start_gemini:
1011: b 1011b
mfspr r4,HID0
ori r4,r4,HID0_ICFI
li r3,0
......@@ -1040,6 +1000,7 @@ __secondary_start_gemini:
sync
bl prom_init
b __secondary_start
#endif /* CONFIG_GEMINI */
.globl __secondary_start_psurge
__secondary_start_psurge:
......@@ -1281,3 +1242,44 @@ swapper_pg_dir:
.globl cmd_line
cmd_line:
.space 512
/*
* An undocumented "feature" of 604e requires that the v bit
* be cleared before changing BAT values.
*
* Also, newer IBM firmware does not clear bat3 and 4 so
* this makes sure it's done.
* -- Cort
*/
clear_bats:
mfmsr r20
andi. r19,r20,MSR_DR
beqlr
li r20,0
mtspr DBAT0U,r20
mtspr DBAT0L,r20
mtspr IBAT0U,r20
mtspr IBAT0L,r20
sync
isync
mtspr DBAT1U,r20
mtspr DBAT1L,r20
mtspr IBAT1U,r20
mtspr IBAT1L,r20
sync
isync
mtspr DBAT2U,r20
mtspr DBAT2L,r20
mtspr IBAT2U,r20
mtspr IBAT2L,r20
mtspr DBAT3U,r20
mtspr DBAT3L,r20
mtspr IBAT3U,r20
mtspr IBAT3L,r20
blr
......@@ -53,13 +53,29 @@ _GLOBAL(__no_use_save_flags)
/* void __no_use_restore_flags(unsigned long flags) */
_GLOBAL(__no_use_restore_flags)
andi. r4,r3,MSR_EE
bne 10f
lis r4,ppc_n_lost_interrupts@ha
lwz r4,ppc_n_lost_interrupts@l(r4)
cmpi 0,r4,0 /* lost interrupts to process first? */
/*
* Just set/clear the MSR_EE bit through restore/flags but do not
* change anything else. This is needed by the RT system and makes
* sense anyway.
* -- Cort
*/
mfmsr r4
/* Copy all except the MSR_EE bit from r4 (current MSR value)
to r3. This is the sort of thing the rlwimi instruction is
designed for. -- paulus. */
rlwimi r3,r4,0,17,15
/* Check if things are setup the way we want _already_. */
cmpw 0,r3,r4
beqlr
/* are we enabling interrupts? */
rlwinm. r0,r3,0,16,16
beq 1f
/* if so, check if there are any lost interrupts */
lis r7,ppc_n_lost_interrupts@ha
lwz r7,ppc_n_lost_interrupts@l(r7)
cmpi 0,r7,0 /* lost interrupts to process first? */
bne- do_lost_interrupts
10: sync
1: sync
mtmsr r3
isync
blr
......
......@@ -92,7 +92,7 @@ static void __init pcibios_claim_resources(struct pci_bus *bus)
struct resource *pr;
if (!r->start)
continue;
pr = pci_find_parent_resource(dev, r, 0);
pr = pci_find_parent_resource(dev, r);
if (!pr || request_resource(pr, r) < 0)
{
printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", idx, dev->name);
......@@ -141,3 +141,8 @@ void __init fix_intr(struct device_node *node, struct pci_dev *dev)
}
}
#endif
int pcibios_assign_resource(struct pci_dev *pdev, int resource)
{
return 0;
}
......@@ -371,11 +371,18 @@ int boot_target;
int boot_part;
kdev_t boot_dev;
extern void via_pmu_start(void);
void __init
pmac_init2(void)
{
#ifdef CONFIG_ADB_PMU
via_pmu_start();
#endif
#ifdef CONFIG_NVRAM
pmac_nvram_init();
#ifdef CONFIG_PMAC_PBOOK
#endif
#ifdef CONFIG_PMAC_PBOOK
media_bay_init();
#endif
}
......@@ -411,7 +418,7 @@ note_scsi_host(struct device_node *node, void *host)
}
#endif
#ifdef CONFIG_BLK_DEV_IDE_PMAC
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
extern int pmac_ide_count;
extern struct device_node *pmac_ide_node[];
static int ide_majors[] = { 3, 22, 33, 34, 56, 57, 88, 89 };
......@@ -441,7 +448,7 @@ kdev_t __init find_ide_boot(void)
return 0;
}
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
void __init find_boot_device(void)
{
......@@ -452,7 +459,7 @@ void __init find_boot_device(void)
return;
}
#endif
#ifdef CONFIG_BLK_DEV_IDE_PMAC
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
boot_dev = find_ide_boot();
#endif
}
......@@ -564,7 +571,7 @@ pmac_ide_default_irq(ide_ioreg_t base)
ide_ioreg_t
pmac_ide_default_io_base(int index)
{
#if defined(CONFIG_BLK_DEV_IDE_PMAC)
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
return pmac_ide_regbase[index];
#else
return 0;
......@@ -602,7 +609,7 @@ pmac_ide_fix_driveid(struct hd_driveid *id)
ppc_generic_ide_fix_driveid(id);
}
#if defined(CONFIG_BLK_DEV_IDE_PMAC)
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
/* This is declared in drivers/block/ide-pmac.c */
void pmac_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq);
#else
......@@ -659,7 +666,7 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif
#endif
#if defined(CONFIG_BLK_DEV_IDE_PMAC)
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
ppc_ide_md.insw = pmac_ide_insw;
ppc_ide_md.outsw = pmac_ide_outsw;
ppc_ide_md.default_irq = pmac_ide_default_irq;
......
......@@ -55,7 +55,6 @@ void pmac_nvram_init(void)
}
}
#ifdef CONFIG_NVRAM
unsigned char nvram_read_byte(int addr)
{
struct adb_request req;
......@@ -101,4 +100,3 @@ void nvram_write_byte(unsigned char val, int addr)
}
eieio();
}
#endif /* CONFIG_NVRAM */
......@@ -34,6 +34,7 @@
#ifdef __SMP__
#include <asm/smplock.h>
#endif /* __SMP__ */
#include "time.h"
/* Tell string.h we don't want memcpy etc. as cpp defines */
#define EXPORT_SYMTAB_STROPS
......@@ -134,7 +135,7 @@ EXPORT_SYMBOL(csum_tcpudp_magic);
EXPORT_SYMBOL(__copy_tofrom_user);
EXPORT_SYMBOL(__clear_user);
EXPORT_SYMBOL(__strncpy_from_user);
EXPORT_SYMBOL(strlen_user);
EXPORT_SYMBOL(__strnlen_user);
/*
EXPORT_SYMBOL(inb);
......@@ -162,6 +163,12 @@ EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(ide_insw);
EXPORT_SYMBOL(ide_outsw);
EXPORT_SYMBOL(ppc_ide_md);
#ifdef CONFIG_BLK_DEV_IDE_MODULE
EXPORT_SYMBOL(chrp_ide_irq);
EXPORT_SYMBOL(chrp_ide_ports_known);
EXPORT_SYMBOL(chrp_ide_regbase);
EXPORT_SYMBOL(chrp_ide_probe);
#endif
EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(kernel_thread);
......@@ -257,3 +264,6 @@ EXPORT_SYMBOL(timer_interrupt);
extern unsigned long do_IRQ_intercept;
EXPORT_SYMBOL(do_IRQ_intercept);
EXPORT_SYMBOL(irq_desc);
void ppc_irq_dispatch_handler(struct pt_regs *, int);
EXPORT_SYMBOL(ppc_irq_dispatch_handler);
EXPORT_SYMBOL(decrementer_count);
/*
* $Id: prom.c,v 1.77 1999/09/14 01:13:19 cort Exp $
* $Id: prom.c,v 1.79 1999/10/08 01:56:32 paulus Exp $
*
* Procedures for interfacing to the Open Firmware PROM on
* Power Macintosh computers.
......@@ -147,6 +147,7 @@ extern unsigned long reloc_offset(void);
extern char cmd_line[512]; /* XXX */
boot_infos_t *boot_infos = 0; /* init it so it's in data segment not bss */
unsigned long dev_tree_size;
/*
* prom_init() is called very early on, before the kernel text
......@@ -557,7 +558,7 @@ prom_init(int r3, int r4, prom_entry pp)
else
prom_print(RELOC("...failed\n"));
}
#endif
#endif
}
/*
......@@ -754,8 +755,7 @@ finish_device_tree(void)
unsigned long mem = (unsigned long) klimit;
mem = finish_node(allnodes, mem, NULL);
printk(KERN_INFO "device tree used %lu bytes\n",
mem - (unsigned long) allnodes);
dev_tree_size = mem - (unsigned long) allnodes;
klimit = (char *) mem;
}
......@@ -1494,6 +1494,7 @@ void
drawchar(char c)
{
unsigned long offset = reloc_offset();
int cline = 0, x;
switch (c) {
case '\b':
......@@ -1509,6 +1510,7 @@ drawchar(char c)
case '\n':
RELOC(g_loc_X) = 0;
RELOC(g_loc_Y)++;
cline = 1;
break;
default:
draw_byte(c, RELOC(g_loc_X)++, RELOC(g_loc_Y));
......@@ -1516,11 +1518,23 @@ drawchar(char c)
if (RELOC(g_loc_X) >= RELOC(g_max_loc_X)) {
RELOC(g_loc_X) = 0;
RELOC(g_loc_Y)++;
cline = 1;
}
#if 0
while (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) {
scrollscreen();
RELOC(g_loc_Y)--;
}
#else
/* wrap around from bottom to top of screen so we don't
waste time scrolling each line. -- paulus. */
if (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y))
RELOC(g_loc_Y) = 0;
if (cline) {
for (x = 0; x < RELOC(g_max_loc_X); ++x)
draw_byte(' ', x, RELOC(g_loc_Y));
}
#endif
}
__pmac
......
/*
* $Id: residual.c,v 1.16 1999/09/17 17:23:09 cort Exp $
* $Id: residual.c,v 1.17 1999/09/27 18:40:23 cort Exp $
*
* Code to deal with the PReP residual data.
*
......@@ -41,12 +41,13 @@
#include <linux/blk.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <asm/init.h>
#include <asm/mmu.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <linux/ide.h>
#include <asm/ide.h>
......
/*
* $Id: setup.c,v 1.159 1999/09/18 18:40:38 dmalek Exp $
* $Id: setup.c,v 1.160 1999/10/08 01:56:38 paulus Exp $
* Common prep/pmac/chrp boot and setup code.
*/
......@@ -489,6 +489,28 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
m8xx_init(r3, r4, r5, r6, r7);
#endif
/* Look for mem= option on command line */
if (strstr(cmd_line, "mem=")) {
char *p, *q;
unsigned long maxmem = 0;
extern unsigned long __max_memory;
for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
q = p + 4;
if (p > cmd_line && p[-1] != ' ')
continue;
maxmem = simple_strtoul(q, &q, 0);
if (*q == 'k' || *q == 'K') {
maxmem <<= 10;
++q;
} else if (*q == 'm' || *q == 'M') {
maxmem <<= 20;
++q;
}
}
__max_memory = maxmem;
}
/* this is for modules since _machine can be a define -- Cort */
ppc_md.ppc_machine = _machine;
......@@ -533,7 +555,7 @@ void __init setup_arch(char **cmdline_p,
if (strstr(cmd_line, "xmon"))
xmon(0);
#endif /* CONFIG_XMON */
/* reboot on panic */
panic_timeout = 180;
......
......@@ -101,30 +101,27 @@ MachineCheckException(struct pt_regs *regs)
}
#endif
printk("Machine check in kernel mode.\n");
printk("Caused by (from msr): ");
printk("regs %p ",regs);
switch( regs->msr & 0x0000F000)
{
case (1<<12) :
printk("Machine check signal - probably due to mm fault\n"
"with mmu off\n");
printk("Caused by (from SRR1=%lx): ", regs->msr);
switch (regs->msr & 0xF0000) {
case 0x80000:
printk("Machine check signal\n");
break;
case (1<<13) :
case 0x40000:
printk("Transfer error ack signal\n");
break;
case (1<<14) :
printk("Data parity signal\n");
case 0x20000:
printk("Data parity error signal\n");
break;
case (1<<15) :
printk("Address parity signal\n");
case 0x10000:
printk("Address parity error signal\n");
break;
default:
printk("Unknown values in msr\n");
}
show_regs(regs);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
debugger(regs);
#endif
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("machine check");
}
......
......@@ -380,16 +380,26 @@ __strncpy_from_user:
.long 1b,99b
.text
.globl strlen_user
strlen_user:
addi r4,r3,-1
1: lbzu r0,1(r4)
/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
.globl __strnlen_user
__strnlen_user:
addi r7,r3,-1
subf r6,r7,r5 /* top+1 - str */
cmplw 0,r4,r6
bge 0f
mr r6,r4
0: mtctr r6 /* ctr = min(len, top - str) */
1: lbzu r0,1(r7) /* get next byte */
cmpwi 0,r0,0
bne 1b
subf r3,r3,r4
addi r3,r3,1
bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
addi r7,r7,1
subf r3,r3,r7 /* number of bytes we have looked at */
beqlr /* return if we found a 0 byte */
cmpw 0,r3,r4 /* did we look at all len bytes? */
blt 99f /* if not, must have hit top */
addi r3,r4,1 /* return len + 1 to indicate no null found */
blr
99: li r3,0
99: li r3,0 /* bad address, return 0 */
blr
.section __ex_table,"a"
.align 2
......
/*
* $Id: init.c,v 1.188 1999/09/18 18:40:44 dmalek Exp $
* $Id: init.c,v 1.193 1999/10/11 18:50:35 geert Exp $
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
......@@ -113,7 +113,9 @@ struct mem_pieces prom_mem;
static void remove_mem_piece(struct mem_pieces *, unsigned, unsigned, int);
void *find_mem_piece(unsigned, unsigned);
static void print_mem_pieces(struct mem_pieces *);
#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
static void append_mem_piece(struct mem_pieces *, unsigned, unsigned);
#endif
extern struct task_struct *current_set[NR_CPUS];
......@@ -182,6 +184,8 @@ static inline unsigned long p_mapped_by_bats(unsigned long pa)
*/
int __map_without_bats = 0;
/* max amount of RAM to use */
unsigned long __max_memory;
void __bad_pte(pmd_t *pmd)
{
......@@ -677,6 +681,7 @@ static void __init print_mem_pieces(struct mem_pieces *mp)
printk("\n");
}
#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_PPC_ALL)
/*
* Add some memory to an array of pieces
*/
......@@ -691,6 +696,7 @@ append_mem_piece(struct mem_pieces *mp, unsigned start, unsigned size)
rp->address = start;
rp->size = size;
}
#endif
#ifndef CONFIG_8xx
static void hash_init(void);
......@@ -738,6 +744,7 @@ static void __init coalesce_mem_pieces(struct mem_pieces *mp)
mp->n_regions = d;
}
#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)
/*
* Read in a property describing some pieces of memory.
*/
......@@ -760,6 +767,7 @@ static void __init get_mem_prop(char *name, struct mem_pieces *mp)
sort_mem_pieces(mp);
coalesce_mem_pieces(mp);
}
#endif /* CONFIG_PMAC || CONFIG_CHRP || CONFIG_ALL_PPC */
/*
* Set up one of the I/D BAT (block address translation) register pairs.
......@@ -933,7 +941,7 @@ void __init free_initmem(void)
a = (unsigned long)(&START); \
for (; a < (unsigned long)(&END); a += PAGE_SIZE) { \
clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags); \
atomic_set(&mem_map[MAP_NR(a)].count, 1); \
set_page_count(mem_map+MAP_NR(a), 1); \
free_page(a); \
CNT++; \
} \
......@@ -1005,8 +1013,10 @@ void __init MMU_init(void)
else if (_machine == _MACH_apus )
end_of_DRAM = apus_find_end_of_memory();
#endif
#ifdef CONFIG_GEMINI
else if ( _machine == _MACH_gemini )
end_of_DRAM = gemini_find_end_of_memory();
#endif /* CONFIG_GEMINI */
else /* prep */
end_of_DRAM = prep_find_end_of_memory();
......@@ -1037,14 +1047,16 @@ void __init MMU_init(void)
setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
break;
case _MACH_Pmac:
#if 0
{
unsigned long base = 0xf3000000;
struct device_node *macio = find_devices("mac-io");
if (macio && macio->n_addrs)
base = macio->addrs[0].address;
setbat(0, base, base, 0x100000, IO_PAGE);
ioremap_base = 0xf0000000;
}
#endif
ioremap_base = 0xf0000000;
break;
case _MACH_apus:
/* Map PPC exception vectors. */
......@@ -1172,17 +1184,13 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
remove_mem_piece(&phys_avail, __pa(avail_start),
start_mem - avail_start, 1);
for (addr = PAGE_OFFSET; addr < end_mem; addr += PAGE_SIZE)
set_bit(PG_reserved, &mem_map[MAP_NR(addr)].flags);
for (i = 0; i < phys_avail.n_regions; ++i) {
a = (unsigned long) __va(phys_avail.regions[i].address);
lim = a + phys_avail.regions[i].size;
lim = (a + phys_avail.regions[i].size) & PAGE_MASK;
a = PAGE_ALIGN(a);
for (; a < lim; a += PAGE_SIZE)
clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags);
}
phys_avail.n_regions = 0;
#ifdef CONFIG_BLK_DEV_INITRD
/* if we are booted from BootX with an initial ramdisk,
......@@ -1196,7 +1204,7 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
/* free the prom's memory - no-op on prep */
for (i = 0; i < prom_mem.n_regions; ++i) {
a = (unsigned long) __va(prom_mem.regions[i].address);
lim = a + prom_mem.regions[i].size;
lim = (a + prom_mem.regions[i].size) & PAGE_MASK;
a = PAGE_ALIGN(a);
for (; a < lim; a += PAGE_SIZE)
clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags);
......@@ -1215,12 +1223,12 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
datapages++;
continue;
}
atomic_set(&mem_map[MAP_NR(addr)].count, 1);
set_page_count(mem_map + MAP_NR(addr), 1);
#ifdef CONFIG_BLK_DEV_INITRD
if (!initrd_start ||
addr < (initrd_start & PAGE_MASK) || addr >= initrd_end)
#endif /* CONFIG_BLK_DEV_INITRD */
#ifndef CONFIG_8xx
#ifndef CONFIG_8xx
if ( !rtas_data ||
addr < (rtas_data & PAGE_MASK) ||
addr >= (rtas_data+rtas_size))
......@@ -1238,7 +1246,7 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
}
#ifndef CONFIG_8xx
#if defined(CONFIG_PMAC) || defined(CONFIG_PPC_ALL)
#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)
/*
* On systems with Open Firmware, collect information about
* physical RAM and which pieces are already in use.
......@@ -1286,8 +1294,12 @@ unsigned long __init *pmac_find_end_of_memory(void)
* to our nearest IO area.
* -- Cort
*/
if ( phys_mem.regions[0].size >= RAM_LIMIT )
phys_mem.regions[0].size = RAM_LIMIT;
if (__max_memory == 0 || __max_memory > RAM_LIMIT)
__max_memory = RAM_LIMIT;
if (phys_mem.regions[0].size >= __max_memory) {
phys_mem.regions[0].size = __max_memory;
phys_mem.n_regions = 1;
}
total = phys_mem.regions[0].size;
if (phys_mem.n_regions > 1) {
......@@ -1300,20 +1312,15 @@ unsigned long __init *pmac_find_end_of_memory(void)
if (boot_infos == 0) {
/* record which bits the prom is using */
get_mem_prop("available", &phys_avail);
prom_mem = phys_mem;
for (i = 0; i < phys_avail.n_regions; ++i)
remove_mem_piece(&prom_mem,
phys_avail.regions[i].address,
phys_avail.regions[i].size, 0);
} else {
/* booted from BootX - it's all available (after klimit) */
phys_avail = phys_mem;
}
prom_mem = phys_mem;
for (i = 0; i < phys_avail.n_regions; ++i)
{
if ( phys_avail.regions[i].address >= RAM_LIMIT )
continue;
if ( (phys_avail.regions[i].address+phys_avail.regions[i].size)
>= RAM_LIMIT )
phys_avail.regions[i].size = RAM_LIMIT - phys_avail.regions[i].address;
remove_mem_piece(&prom_mem, phys_avail.regions[i].address,
phys_avail.regions[i].size, 1);
prom_mem.n_regions = 0;
}
/*
......@@ -1331,9 +1338,9 @@ unsigned long __init *pmac_find_end_of_memory(void)
#undef RAM_LIMIT
return __va(total);
}
#endif /* defined(CONFIG_PMAC) || defined(CONFIG_PPC_ALL) */
#endif /* CONFIG_PMAC || CONFIG_CHRP || CONFIG_ALL_PPC */
#if defined(CONFIG_PREP) || defined(CONFIG_PPC_ALL)
#if defined(CONFIG_PREP) || defined(CONFIG_ALL_PPC)
/*
* This finds the amount of physical ram and does necessary
* setup for prep. This is pretty architecture specific so
......@@ -1365,10 +1372,10 @@ unsigned long __init *prep_find_end_of_memory(void)
return (__va(total));
}
#endif /* defined(CONFIG_PREP) || defined(CONFIG_PPC_ALL) */
#endif /* defined(CONFIG_PREP) || defined(CONFIG_ALL_PPC) */
#if defined(CONFIG_GEMINI) || defined(CONFIG_PPC_ALL)
#if defined(CONFIG_GEMINI)
unsigned long __init *gemini_find_end_of_memory(void)
{
unsigned long total, kstart, ksize, *ret;
......@@ -1389,7 +1396,7 @@ unsigned long __init *gemini_find_end_of_memory(void)
remove_mem_piece( &phys_avail, kstart, ksize, 0 );
return ret;
}
#endif /* defined(CONFIG_GEMINI) || defined(CONFIG_PPC_ALL) */
#endif /* defined(CONFIG_GEMINI) || defined(CONFIG_ALL_PPC) */
#ifdef CONFIG_APUS
#define HARDWARE_MAPPED_SIZE (512*1024)
......
This diff is collapsed.
......@@ -571,7 +571,7 @@ static int pcd_reset( int unit )
WR(0,6,0xa0 + 0x10*PCD.drive);
WR(0,7,8);
pcd_sleep(2); /* delay a bit */
pcd_sleep(20*HZ/1000); /* delay a bit */
k = 0;
while ((k++ < PCD_RESET_TMO) && (RR(1,6)&IDE_BUSY))
......@@ -609,7 +609,7 @@ static int pcd_ready_wait( int unit, int tmo )
if (!p) return 0;
if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
k++;
pcd_sleep(100);
pcd_sleep(HZ);
}
return 0x000020; /* timeout */
}
......
......@@ -666,11 +666,11 @@ static int pf_reset( int unit )
WR(0,6,DRIVE);
WR(0,7,8);
pf_sleep(2);
pf_sleep(20*HZ/1000);
k = 0;
while ((k++ < PF_RESET_TMO) && (RR(1,6)&STAT_BUSY))
pf_sleep(10);
pf_sleep(HZ/10);
flg = 1;
for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
......
......@@ -463,7 +463,7 @@ static int pg_reset( int unit )
WR(0,6,DRIVE);
WR(0,7,8);
pg_sleep(2);
pg_sleep(20*HZ/1000);
k = 0;
while ((k++ < PG_RESET_TMO) && (RR(1,6)&STAT_BUSY))
......
......@@ -498,7 +498,7 @@ static void pt_media_access_cmd( int unit, int tmo, char *cmd, char *fun)
return;
}
pi_disconnect(PI);
pt_poll_dsc(unit,100,tmo,fun);
pt_poll_dsc(unit,HZ,tmo,fun);
}
static void pt_rewind( int unit )
......@@ -526,11 +526,11 @@ static int pt_reset( int unit )
WR(0,6,DRIVE);
WR(0,7,8);
pt_sleep(2);
pt_sleep(20*HZ/1000);
k = 0;
while ((k++ < PT_RESET_TMO) && (RR(1,6)&STAT_BUSY))
pt_sleep(10);
pt_sleep(HZ/10);
flg = 1;
for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
......@@ -559,7 +559,7 @@ static int pt_ready_wait( int unit, int tmo )
if (!p) return 0;
if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
k++;
pt_sleep(100);
pt_sleep(HZ);
}
return 0x000020; /* timeout */
}
......@@ -809,7 +809,7 @@ static ssize_t pt_read(struct file * filp, char * buf,
while (count > 0) {
if (!pt_poll_dsc(unit,1,PT_TMO,"read")) return -EIO;
if (!pt_poll_dsc(unit,HZ/100,PT_TMO,"read")) return -EIO;
n = count;
if (n > 32768) n = 32768; /* max per command */
......@@ -895,7 +895,7 @@ static ssize_t pt_write(struct file * filp, const char * buf,
while (count > 0) {
if (!pt_poll_dsc(unit,1,PT_TMO,"write")) return -EIO;
if (!pt_poll_dsc(unit,HZ/100,PT_TMO,"write")) return -EIO;
n = count;
if (n > 32768) n = 32768; /* max per command */
......
......@@ -69,7 +69,7 @@ if [ "$CONFIG_BUSMOUSE" != "n" ]; then
dep_tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE $CONFIG_BUSMOUSE
dep_tristate 'Logitech busmouse support' CONFIG_LOGIBUSMOUSE $CONFIG_BUSMOUSE
dep_tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE $CONFIG_BUSMOUSE
if [ "$CONFIG_PPC" = "y" ] ; then
if [ "$CONFIG_ADB" = "y" ]; then
dep_tristate 'Apple Desktop Bus mouse support' CONFIG_ADBMOUSE $CONFIG_BUSMOUSE
fi
fi
......
......@@ -158,6 +158,8 @@ int __init adb_mouse_init(void)
if (!MACH_IS_MAC)
return -ENODEV;
#endif
/* all buttons up */
memset(adb_mouse_buttons, 7, sizeof(adb_mouse_buttons));
msedev = register_busmouse(&adb_mouse);
if (msedev < 0)
......
......@@ -453,7 +453,7 @@ bus_mouse_init(void)
#ifdef CONFIG_SUN_MOUSE
sun_mouse_init();
#endif
#ifdef CONFIG_ADB_MOUSE
#ifdef CONFIG_ADBMOUSE
adb_mouse_init();
#endif
#ifdef CONFIG_RPCMOUSE
......
......@@ -156,6 +156,7 @@ struct pt_regs * kbd_pt_regs;
#ifdef CONFIG_MAGIC_SYSRQ
static int sysrq_pressed;
int sysrq_enabled = 1;
#endif
/*
......
......@@ -871,6 +871,8 @@ static int open_aux(struct inode * inode, struct file * file)
aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
send_data(KBD_CMD_ENABLE); /* try to workaround toshiba4030cdt problem */
return 0;
}
......
......@@ -369,7 +369,7 @@ ssize_t rw_raw_dev(int rw, struct file *filp, char *buf,
for (i=0; i < blocks; i++)
b[i] = blocknr++;
err = brw_kiovec(rw, 1, &iobuf, dev, b, sector_size, 0);
err = brw_kiovec(rw, 1, &iobuf, dev, b, sector_size);
if (err >= 0) {
transferred += err;
......
This diff is collapsed.
......@@ -643,27 +643,9 @@ static int i2ob_ioctl(struct inode *inode, struct file *file,
dev = &i2ob_dev[minor];
switch (cmd) {
case BLKRASET:
if(!capable(CAP_SYS_ADMIN)) return -EACCES;
if(arg > 0xff) return -EINVAL;
read_ahead[MAJOR(inode->i_rdev)] = arg;
return 0;
case BLKRAGET:
if (!arg) return -EINVAL;
return put_user(read_ahead[MAJOR(inode->i_rdev)],
(long *) arg);
case BLKGETSIZE:
return put_user(i2ob[minor].nr_sects, (long *) arg);
case BLKFLSBUF:
if(!capable(CAP_SYS_ADMIN))
return -EACCES;
fsync_dev(inode->i_rdev);
invalidate_buffers(inode->i_rdev);
return 0;
case HDIO_GETGEO:
{
struct hd_geometry g;
......@@ -679,8 +661,16 @@ static int i2ob_ioctl(struct inode *inode, struct file *file,
return -EACCES;
return do_i2ob_revalidate(inode->i_rdev,1);
default:
case BLKFLSBUF:
case BLKROSET:
case BLKROGET:
case BLKRASET:
case BLKRAGET:
case BLKPG:
return blk_ioctl(inode->i_rdev, cmd, arg);
default:
return -EINVAL;
}
}
......
......@@ -2,77 +2,76 @@
# ISDN device configuration
#
if [ "$CONFIG_INET" != "n" ]; then
bool 'Support synchronous PPP' CONFIG_ISDN_PPP
if [ "$CONFIG_ISDN_PPP" != "n" ]; then
bool 'Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
bool 'Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
fi
bool ' Support synchronous PPP' CONFIG_ISDN_PPP
if [ "$CONFIG_ISDN_PPP" != "n" ]; then
bool ' Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
bool ' Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
fi
fi
bool 'Support audio via ISDN' CONFIG_ISDN_AUDIO
bool ' Support audio via ISDN' CONFIG_ISDN_AUDIO
if [ "$CONFIG_ISDN_AUDIO" != "n" ]; then
bool 'Support AT-Fax Class 2 commands' CONFIG_ISDN_TTY_FAX
bool ' Support AT-Fax Class 2 commands' CONFIG_ISDN_TTY_FAX
fi
bool 'Support isdn diversion services' CONFIG_ISDN_DIVERSION
if [ "$CONFIG_X25" != "n" ]; then
bool 'X.25 PLP on top of ISDN (EXPERIMENTAL)' CONFIG_ISDN_X25
bool ' Support isdn diversion services' CONFIG_ISDN_DIVERSION
if [ "$CONFIG_X25" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' X.25 PLP on top of ISDN (EXPERIMENTAL)' CONFIG_ISDN_X25
fi
dep_tristate 'ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN
dep_tristate 'isdnloop support' CONFIG_ISDN_DRV_LOOP $CONFIG_ISDN
dep_tristate 'PCBIT-D support' CONFIG_ISDN_DRV_PCBIT $CONFIG_ISDN
dep_tristate 'HiSax SiemensChipSet driver support' CONFIG_ISDN_DRV_HISAX $CONFIG_ISDN
dep_tristate ' ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN
dep_tristate ' isdnloop support' CONFIG_ISDN_DRV_LOOP $CONFIG_ISDN
dep_tristate ' PCBIT-D support' CONFIG_ISDN_DRV_PCBIT $CONFIG_ISDN
dep_tristate ' HiSax SiemensChipSet driver support' CONFIG_ISDN_DRV_HISAX $CONFIG_ISDN
if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
bool 'HiSax Support for EURO/DSS1' CONFIG_HISAX_EURO
if [ "$CONFIG_HISAX_EURO" != "n" ]; then
bool 'Support for german chargeinfo' CONFIG_DE_AOC
bool 'Disable sending complete' CONFIG_HISAX_NO_SENDCOMPLETE
bool 'Disable sending low layer compatibility' CONFIG_HISAX_NO_LLC
fi
bool 'HiSax Support for german 1TR6' CONFIG_HISAX_1TR6
bool 'HiSax Support for Teles 16.0/8.0' CONFIG_HISAX_16_0
bool 'HiSax Support for Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3
bool 'HiSax Support for Teles PCI' CONFIG_HISAX_TELESPCI
bool 'HiSax Support for Teles S0Box' CONFIG_HISAX_S0BOX
bool 'HiSax Support for AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1
bool 'HiSax Support for AVM PnP/PCI (Fritz!PnP/PCI)' CONFIG_HISAX_FRITZPCI
bool 'HiSax Support for AVM A1 PCMCIA (Fritz)' CONFIG_HISAX_AVM_A1_PCMCIA
bool 'HiSax Support for Elsa cards' CONFIG_HISAX_ELSA
bool 'HiSax Support for ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2
bool 'HiSax Support for Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA
bool 'HiSax Support for ASUSCOM cards' CONFIG_HISAX_ASUSCOM
bool 'HiSax Support for TELEINT cards' CONFIG_HISAX_TELEINT
bool 'HiSax Support for HFC-S based cards' CONFIG_HISAX_HFCS
bool 'HiSax Support for Sedlbauer cards' CONFIG_HISAX_SEDLBAUER
bool 'HiSax Support for USR Sportster internal TA' CONFIG_HISAX_SPORTSTER
bool 'HiSax Support for MIC card' CONFIG_HISAX_MIC
bool 'HiSax Support for NETjet card' CONFIG_HISAX_NETJET
bool 'HiSax Support for Niccy PnP/PCI card' CONFIG_HISAX_NICCY
bool 'HiSax Support for Siemens I-Surf card' CONFIG_HISAX_ISURF
bool 'HiSax Support for HST Saphir card' CONFIG_HISAX_HSTSAPHIR
bool 'HiSax Support for Telekom A4T card' CONFIG_HISAX_BKM_A4T
bool 'HiSax Support for Scitel Quadro card' CONFIG_HISAX_SCT_QUADRO
bool 'HiSax Support for Gazel cards' CONFIG_HISAX_GAZEL
bool 'HiSax Support for HFC PCI-Bus cards' CONFIG_HISAX_HFC_PCI
if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
# bool 'HiSax Support for TESTEMULATOR (EXPERIMENTAL)' CONFIG_HISAX_TESTEMU
if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
bool 'HiSax Support for Am7930' CONFIG_HISAX_AMD7930
fi
fi
bool ' HiSax Support for EURO/DSS1' CONFIG_HISAX_EURO
if [ "$CONFIG_HISAX_EURO" != "n" ]; then
bool ' Support for german chargeinfo' CONFIG_DE_AOC
bool ' Disable sending complete' CONFIG_HISAX_NO_SENDCOMPLETE
bool ' Disable sending low layer compatibility' CONFIG_HISAX_NO_LLC
fi
bool ' HiSax Support for german 1TR6' CONFIG_HISAX_1TR6
bool ' HiSax Support for Teles 16.0/8.0' CONFIG_HISAX_16_0
bool ' HiSax Support for Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3
bool ' HiSax Support for Teles PCI' CONFIG_HISAX_TELESPCI
bool ' HiSax Support for Teles S0Box' CONFIG_HISAX_S0BOX
bool ' HiSax Support for AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1
bool ' HiSax Support for AVM PnP/PCI (Fritz!PnP/PCI)' CONFIG_HISAX_FRITZPCI
bool ' HiSax Support for AVM A1 PCMCIA (Fritz)' CONFIG_HISAX_AVM_A1_PCMCIA
bool ' HiSax Support for Elsa cards' CONFIG_HISAX_ELSA
bool ' HiSax Support for ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2
bool ' HiSax Support for Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA
bool ' HiSax Support for ASUSCOM cards' CONFIG_HISAX_ASUSCOM
bool ' HiSax Support for TELEINT cards' CONFIG_HISAX_TELEINT
bool ' HiSax Support for HFC-S based cards' CONFIG_HISAX_HFCS
bool ' HiSax Support for Sedlbauer cards' CONFIG_HISAX_SEDLBAUER
bool ' HiSax Support for USR Sportster internal TA' CONFIG_HISAX_SPORTSTER
bool ' HiSax Support for MIC card' CONFIG_HISAX_MIC
bool ' HiSax Support for NETjet card' CONFIG_HISAX_NETJET
bool ' HiSax Support for Niccy PnP/PCI card' CONFIG_HISAX_NICCY
bool ' HiSax Support for Siemens I-Surf card' CONFIG_HISAX_ISURF
bool ' HiSax Support for HST Saphir card' CONFIG_HISAX_HSTSAPHIR
bool ' HiSax Support for Telekom A4T card' CONFIG_HISAX_BKM_A4T
bool ' HiSax Support for Scitel Quadro card' CONFIG_HISAX_SCT_QUADRO
bool ' HiSax Support for Gazel cards' CONFIG_HISAX_GAZEL
bool ' HiSax Support for HFC PCI-Bus cards' CONFIG_HISAX_HFC_PCI
if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
# bool ' HiSax Support for TESTEMULATOR (EXPERIMENTAL)' CONFIG_HISAX_TESTEMU
if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
bool ' HiSax Support for Am7930' CONFIG_HISAX_AMD7930
fi
fi
fi
if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
dep_tristate 'Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN
dep_tristate 'IBM Active 2000 support (EXPERIMENTAL)' CONFIG_ISDN_DRV_ACT2000 $CONFIG_ISDN
dep_tristate ' Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN
dep_tristate ' IBM Active 2000 support (EXPERIMENTAL)' CONFIG_ISDN_DRV_ACT2000 $CONFIG_ISDN
fi
dep_tristate 'Eicon.Diehl active card support' CONFIG_ISDN_DRV_EICON $CONFIG_ISDN
dep_tristate ' Eicon.Diehl active card support' CONFIG_ISDN_DRV_EICON $CONFIG_ISDN
if [ "$CONFIG_ISDN_DRV_EICON" != "n" ]; then
bool 'Eicon S,SX,SCOM,Quadro,S2M support' CONFIG_ISDN_DRV_EICON_ISA
bool ' Eicon S, SX, SCOM, Quadro, S2M support' CONFIG_ISDN_DRV_EICON_ISA
fi
dep_tristate 'AVM CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN
dep_tristate ' AVM CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN
if [ "$CONFIG_ISDN_DRV_AVMB1" != "n" ]; then
bool 'AVM B1 ISA support' CONFIG_ISDN_DRV_AVMB1_B1ISA
bool 'AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI
bool 'AVM T1/T1B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA
bool 'AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
bool 'Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
bool ' AVM B1 ISA support' CONFIG_ISDN_DRV_AVMB1_B1ISA
bool ' AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI
bool ' AVM T1/T1B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA
bool ' AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
bool ' Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
fi
......@@ -240,7 +240,7 @@ static void init_trackball(int id);
static void init_turbomouse(int id);
static void init_microspeed(int id);
#ifdef CONFIG_ADB_MOUSE
#ifdef CONFIG_ADBMOUSE
/* XXX: Hook for mouse driver */
void (*adb_mouse_interrupt_hook)(unsigned char *, int);
int adb_emulate_buttons = 0;
......@@ -336,7 +336,7 @@ input_keycode(int keycode, int repeat)
if (!repeat)
del_timer(&repeat_timer);
#ifdef CONFIG_ADB_MOUSE
#ifdef CONFIG_ADBMOUSE
/*
* XXX: Add mouse button 2+3 fake codes here if mouse open.
* Keep track of 'button' states here as we only send
......@@ -366,7 +366,7 @@ input_keycode(int keycode, int repeat)
}
return;
}
#endif /* CONFIG_ADB_MOUSE */
#endif /* CONFIG_ADBMOUSE */
if (kbd->kbdmode != VC_RAW) {
if (!up_flag && !dont_repeat[keycode]) {
......@@ -422,7 +422,7 @@ static void mac_put_queue(int ch)
}
}
#ifdef CONFIG_ADB_MOUSE
#ifdef CONFIG_ADBMOUSE
static void
mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
{
......@@ -554,7 +554,7 @@ mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
}
}
}
#endif /* CONFIG_ADB_MOUSE */
#endif /* CONFIG_ADBMOUSE */
/* XXX Needs to get rid of this, see comments in pmu.c */
extern int backlight_level;
......@@ -700,7 +700,7 @@ void __init mackbd_init_hw(void)
memcpy(key_maps[8], macalt_map, sizeof(plain_map));
memcpy(key_maps[12], macctrl_alt_map, sizeof(plain_map));
#ifdef CONFIG_ADB_MOUSE
#ifdef CONFIG_ADBMOUSE
/* initialize mouse interrupt hook */
adb_mouse_interrupt_hook = NULL;
#endif
......@@ -736,9 +736,9 @@ mackeyb_probe(void)
struct adb_request req;
int i;
#ifdef CONFIG_ADB_MOUSE
#ifdef CONFIG_ADBMOUSE
adb_register(ADB_MOUSE, 0, &mouse_ids, mouse_input);
#endif /* CONFIG_ADB_MOUSE */
#endif /* CONFIG_ADBMOUSE */
adb_register(ADB_KEYBOARD, 0, &keyboard_ids, keyboard_input);
adb_register(0x07, 0x1F, &buttons_ids, buttons_input);
......
......@@ -418,8 +418,10 @@ mb_notify_sleep(struct pmu_sleep_notifier *self, int when)
middle of a wait loop */
if (bay->reset_timer)
bay->reset_timer = MB_RESET_COUNT;
#ifdef CONFIG_BLK_DEV_IDE
if (bay->cd_timer)
bay->cd_timer = MB_IDE_WAIT;
#endif
}
}
}
......
......@@ -150,7 +150,7 @@ extern int grackle_pcibios_write_config_word(unsigned char bus,
* - the number of response bytes which the PMU will return, or
* -1 if it will send a length byte.
*/
static s8 pmu_data_len[256][2] __openfirmwaredata = {
static const s8 pmu_data_len[256][2] __openfirmwaredata = {
/* 0 1 2 3 4 5 6 7 */
/*00*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
/*08*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
......@@ -263,6 +263,20 @@ pmu_init(void)
{
if (vias == NULL)
return -ENXIO;
return 0;
}
/*
* We can't wait until pmu_init gets called, that happens too late.
* It happens after IDE and SCSI initialization, which can take a few
* seconds, and by that time the PMU could have given up on us and
* turned us off.
* This is called from arch/ppc/kernel/pmac_setup.c:pmac_init2().
*/
void via_pmu_start(void)
{
if (vias == NULL)
return;
bright_req_1.complete = 1;
bright_req_2.complete = 1;
......@@ -272,7 +286,7 @@ pmu_init(void)
(void *)0)) {
printk(KERN_ERR "VIA-PMU: can't get irq %d\n",
vias->intrs[0].line);
return -ENXIO;
return;
}
/* Enable interrupts */
......@@ -282,8 +296,6 @@ pmu_init(void)
/* Enable backlight */
pmu_enable_backlight(1);
return 0;
}
static int __openfirmware
......
This diff is collapsed.
......@@ -19,10 +19,10 @@
* PPP driver, written by Michael Callahan and Al Longyear, and
* subsequently hacked by Paul Mackerras.
*
* ==FILEVERSION 990806==
* ==FILEVERSION 990915==
*/
/* $Id: ppp_generic.c,v 1.3 1999/09/02 05:30:12 paulus Exp $ */
/* $Id: ppp_generic.c,v 1.5 1999/09/15 11:21:48 paulus Exp $ */
#include <linux/config.h>
#include <linux/module.h>
......@@ -131,7 +131,7 @@ struct channel {
#define PPP_MAX_RQLEN 32
/* Prototypes. */
static void ppp_xmit_unlock(struct ppp *ppp);
static void ppp_xmit_unlock(struct ppp *ppp, int do_mark_bh);
static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
static void ppp_push(struct ppp *ppp);
static void ppp_recv_unlock(struct ppp *ppp);
......@@ -199,6 +199,13 @@ static const int npindex_to_ethertype[NUM_NP] = {
/*
* Routines for locking and unlocking the transmit and receive paths
* of each unit.
*
* On the transmit side, we have threads of control coming into the
* driver from (at least) three places: the core net code, write calls
* on /dev/ppp from pppd, and wakeup calls from channels. There is
* possible concurrency even on UP systems (between mainline and
* BH processing). The XMIT_BUSY bit in ppp->busy serializes the
* transmit-side processing for each ppp unit.
*/
static inline void
lock_path(struct ppp *ppp, int bit)
......@@ -329,16 +336,20 @@ static ssize_t ppp_write(struct file *file, const char *buf,
struct ppp *ppp = (struct ppp *) file->private_data;
struct sk_buff *skb;
ssize_t ret;
int extra;
ret = -ENXIO;
if (ppp == 0)
goto out;
ret = -ENOMEM;
skb = alloc_skb(count + 2, GFP_KERNEL);
extra = PPP_HDRLEN - 2;
if (ppp->dev && ppp->dev->hard_header_len > PPP_HDRLEN)
extra = ppp->dev->hard_header_len - 2;
skb = alloc_skb(count + extra, GFP_KERNEL);
if (skb == 0)
goto out;
skb_reserve(skb, 2);
skb_reserve(skb, extra);
ret = -EFAULT;
if (copy_from_user(skb_put(skb, count), buf, count)) {
kfree_skb(skb);
......@@ -347,7 +358,7 @@ static ssize_t ppp_write(struct file *file, const char *buf,
skb_queue_tail(&ppp->xq, skb);
if (trylock_xmit_path(ppp))
ppp_xmit_unlock(ppp);
ppp_xmit_unlock(ppp, 1);
ret = count;
......@@ -490,7 +501,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
slhc_free(ppp->vj);
ppp->vj = slhc_init(val2+1, val+1);
ppp_recv_unlock(ppp);
ppp_xmit_unlock(ppp);
ppp_xmit_unlock(ppp, 1);
err = -ENOMEM;
if (ppp->vj == 0) {
printk(KERN_ERR "PPP: no memory (VJ compressor)\n");
......@@ -580,10 +591,6 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
int npi, proto;
unsigned char *pp;
if (skb == 0)
return 0;
/* can skb->data ever be 0? */
npi = ethertype_to_npindex(ntohs(skb->protocol));
if (npi < 0)
goto outf;
......@@ -601,30 +608,15 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto outf;
}
/* The transmit side of the ppp interface is serialized by
the XMIT_BUSY bit in ppp->busy. */
if (!trylock_xmit_path(ppp)) {
dev->tbusy = 1;
return 1;
}
if (ppp->xmit_pending)
ppp_push(ppp);
if (ppp->xmit_pending) {
dev->tbusy = 1;
ppp_xmit_unlock(ppp);
return 1;
}
dev->tbusy = 0;
/* Put the 2-byte PPP protocol number on the front,
making sure there is room for the address and control fields. */
if (skb_headroom(skb) < PPP_HDRLEN) {
struct sk_buff *ns;
ns = alloc_skb(skb->len + PPP_HDRLEN, GFP_ATOMIC);
ns = alloc_skb(skb->len + dev->hard_header_len, GFP_ATOMIC);
if (ns == 0)
goto outnbusy;
skb_reserve(ns, PPP_HDRLEN);
goto outf;
skb_reserve(ns, dev->hard_header_len);
memcpy(skb_put(ns, skb->len), skb->data, skb->len);
kfree_skb(skb);
skb = ns;
......@@ -634,13 +626,16 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
pp[0] = proto >> 8;
pp[1] = proto;
ppp_send_frame(ppp, skb);
ppp_xmit_unlock(ppp);
/*
* ppp->xq should only ever have more than 1 data packet on it
* if the core net code calls us when dev->tbusy == 1.
*/
dev->tbusy = 1;
skb_queue_tail(&ppp->xq, skb);
if (trylock_xmit_path(ppp))
ppp_xmit_unlock(ppp, 0);
return 0;
outnbusy:
ppp_xmit_unlock(ppp);
outf:
kfree_skb(skb);
return 0;
......@@ -723,20 +718,34 @@ ppp_net_init(struct net_device *dev)
* making sure that any work queued up gets done.
*/
static void
ppp_xmit_unlock(struct ppp *ppp)
ppp_xmit_unlock(struct ppp *ppp, int do_mark_bh)
{
struct sk_buff *skb;
for (;;) {
/* Do whatever work is waiting to be done. */
if (test_and_clear_bit(XMIT_WAKEUP, &ppp->busy))
ppp_push(ppp);
/* If there's no work left to do, tell the core net
code that we can accept some more. */
while (ppp->xmit_pending == 0
&& (skb = skb_dequeue(&ppp->xq)) != 0)
ppp_send_frame(ppp, skb);
if (ppp->xmit_pending == 0 && skb_peek(&ppp->xq) == 0
&& ppp->dev->tbusy) {
ppp->dev->tbusy = 0;
if (do_mark_bh)
mark_bh(NET_BH);
}
/* Now unlock the transmit path, let others in. */
unlock_xmit_path(ppp);
/* Check whether any work was queued up
between our last check and the unlock. */
if (!(test_bit(XMIT_WAKEUP, &ppp->busy)
|| (ppp->xmit_pending == 0 && skb_peek(&ppp->xq))))
break;
/* If so, lock again and do the work. If we can't get
the lock, someone else has it and they'll do the work. */
if (!trylock_xmit_path(ppp))
break;
}
......@@ -763,12 +772,13 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
if (ppp->vj == 0 || (ppp->flags & SC_COMP_TCP) == 0)
break;
/* try to do VJ TCP header compression */
new_skb = alloc_skb(skb->len + 2, GFP_ATOMIC);
new_skb = alloc_skb(skb->len + ppp->dev->hard_header_len - 2,
GFP_ATOMIC);
if (new_skb == 0) {
printk(KERN_ERR "PPP: no memory (VJ comp pkt)\n");
goto drop;
}
skb_reserve(new_skb, 2);
skb_reserve(new_skb, ppp->dev->hard_header_len - 2);
cp = skb->data + 2;
len = slhc_compress(ppp->vj, cp, skb->len - 2,
new_skb->data + 2, &cp,
......@@ -801,11 +811,15 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
/* try to do packet compression */
if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
&& proto != PPP_LCP && proto != PPP_CCP) {
new_skb = alloc_skb(ppp->dev->mtu + PPP_HDRLEN, GFP_ATOMIC);
new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
GFP_ATOMIC);
if (new_skb == 0) {
printk(KERN_ERR "PPP: no memory (comp pkt)\n");
goto drop;
}
if (ppp->dev->hard_header_len > PPP_HDRLEN)
skb_reserve(new_skb,
ppp->dev->hard_header_len - PPP_HDRLEN);
/* compressor still expects A/C bytes in hdr */
len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
......@@ -1120,6 +1134,8 @@ ppp_register_channel(struct ppp_channel *chan, int unit)
list_add(&pch->list, &ppp->channels);
chan->ppp = pch;
++ppp->n_channels;
if (ppp->dev && chan->hdrlen + PPP_HDRLEN > ppp->dev->hard_header_len)
ppp->dev->hard_header_len = chan->hdrlen + PPP_HDRLEN;
ret = 0;
out:
spin_unlock(&all_ppp_lock);
......@@ -1160,11 +1176,7 @@ ppp_output_wakeup(struct ppp_channel *chan)
pch->blocked = 0;
set_bit(XMIT_WAKEUP, &ppp->busy);
if (trylock_xmit_path(ppp))
ppp_xmit_unlock(ppp);
if (ppp->xmit_pending == 0) {
ppp->dev->tbusy = 0;
mark_bh(NET_BH);
}
ppp_xmit_unlock(ppp, 1);
}
/*
......@@ -1215,7 +1227,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
ppp->xcomp = cp;
ppp->xc_state = cp->comp_alloc(ccp_option, data.length);
ppp_xmit_unlock(ppp);
ppp_xmit_unlock(ppp, 1);
if (ppp->xc_state == 0)
goto out;
......@@ -1321,7 +1333,7 @@ ppp_ccp_closed(struct ppp *ppp)
ppp->xcomp->comp_free(ppp->xc_state);
ppp->xc_state = 0;
}
ppp_xmit_unlock(ppp);
ppp_xmit_unlock(ppp, 1);
lock_recv_path(ppp);
ppp->xstate &= ~SC_DECOMP_RUN;
......
......@@ -11,6 +11,10 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
* 1999/10/09 acme chan_disc renamed to chan_disconnect,
* began adding support for X.25 sockets:
* conf->protocol in new_if
* 1999/10/05 acme fixed return E... to return -E...
* 1999/08/10 acme serialized access to the card thru a spinlock
* in x25_exec
* 1999/08/09 acme removed per channel spinlocks
......@@ -132,16 +136,19 @@ static int x25_configure (cycx_t *card, TX25Config *conf),
x25_connect_response (cycx_t *card, x25_channel_t *chan),
x25_disconnect_response (cycx_t *card, u8 link, u8 lcn);
/* Miscellaneous functions */
static int chan_connect (struct net_device *dev),
chan_send (struct net_device *dev, struct sk_buff *skb);
/* channel functions */
int chan_connect (struct net_device *dev),
chan_send (struct net_device *dev, struct sk_buff *skb);
static void chan_disconnect (struct net_device *dev);
/* Miscellaneous functions */
static void set_chan_state (struct net_device *dev, u8 state),
nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble),
reset_timer (struct net_device *dev),
chan_disc (struct net_device *dev),
chan_timer (unsigned long d);
static void nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble),
reset_timer (struct net_device *dev);
static u8 bps_to_speed_code (u32 bps);
static u8 log2 (u32 n);
......@@ -334,7 +341,7 @@ static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *c
strcpy(chan->name, conf->name);
chan->card = card;
chan->link = conf->port;
chan->protocol = ETH_P_IP;
chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
chan->rx_skb = NULL;
/* only used in svc connected thru crossover cable */
chan->local_addr = NULL;
......@@ -353,7 +360,7 @@ static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *c
if (!chan->local_addr) {
kfree(chan);
return ENOMEM;
return -ENOMEM;
}
}
......@@ -505,7 +512,7 @@ static int if_close (struct net_device *dev)
dev->start = 0;
if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
chan_disc(dev);
chan_disconnect(dev);
cyclomx_close(card);
return 0;
......@@ -763,7 +770,7 @@ static void rx_intr (cycx_t *card, TX25Cmd *cmd)
dev->last_rx = jiffies; /* timestamp */
chan->rx_skb = NULL; /* dequeue packet */
skb->protocol = htons(ETH_P_IP);
skb->protocol = htons(chan->protocol);
skb->dev = dev;
skb->mac.raw = skb->data;
netif_rx(skb);
......@@ -799,6 +806,7 @@ static void connect_intr (cycx_t *card, TX25Cmd *cmd)
dprintk(KERN_INFO "connect_intr:lcn=%d, local=%s, remote=%s\n",
lcn, loc, rem);
if ((dev = get_dev_by_dte_addr(wandev, rem)) == NULL) {
/* Invalid channel, discard packet */
printk(KERN_INFO "%s: connect not expected: remote %s!\n",
......@@ -824,6 +832,7 @@ static void connect_confirm_intr (cycx_t *card, TX25Cmd *cmd)
cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
dprintk(KERN_INFO "%s: connect_confirm_intr:lcn=%d, key=%d\n",
card->devname, lcn, key);
if ((dev = get_dev_by_lcn(wandev, -key)) == NULL) {
/* Invalid channel, discard packet */
clear_bit(--key, (void*)&card->u.x.connection_keys);
......@@ -1139,10 +1148,8 @@ static int x25_place_call (cycx_t *card, x25_channel_t *chan)
if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
&d, 7 + len + 1, NULL, 0)) != 0)
clear_bit(--key, (void*)&card->u.x.connection_keys);
else {
else
chan->lcn = -key;
chan->protocol = ETH_P_IP;
}
return err;
}
......@@ -1229,7 +1236,7 @@ static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte)
* Return: 0 connected
* >0 connection in progress
* <0 failure */
static int chan_connect (struct net_device *dev)
int chan_connect (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
......@@ -1251,7 +1258,7 @@ static int chan_connect (struct net_device *dev)
/* Disconnect logical channel.
* o if SVC then clear X.25 call */
static void chan_disc (struct net_device *dev)
static void chan_disconnect (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
......@@ -1270,7 +1277,7 @@ static void chan_timer (unsigned long d)
switch (chan->state) {
case WAN_CONNECTED:
chan_disc(dev);
chan_disconnect(dev);
break;
default:
printk (KERN_ERR "%s: chan_timer for svc (%s) not "
......@@ -1345,7 +1352,7 @@ static void set_chan_state (struct net_device *dev, u8 state)
* the packet into 'complete sequence' using M-bit.
* 2. When transmission is complete, an event notification should be issued
* to the router. */
static int chan_send (struct net_device *dev, struct sk_buff *skb)
int chan_send (struct net_device *dev, struct sk_buff *skb)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
......@@ -1473,14 +1480,15 @@ static void x25_dump_devs(wan_device_t *wandev)
struct net_device *dev = wandev->dev;
printk (KERN_INFO "x25 dev states\n");
printk (KERN_INFO "name: addr: tbusy:\n");
printk (KERN_INFO "----------------------------\n");
printk (KERN_INFO "name: addr: tbusy: protocol:\n");
printk (KERN_INFO "---------------------------------------\n");
for (; dev; dev = dev->slave) {
x25_channel_t *chan = dev->priv;
printk (KERN_INFO "%-5.5s %-15.15s %ld\n",
chan->name, chan->addr, dev->tbusy);
printk (KERN_INFO "%-5.5s %-15.15s %ld ETH_P_%s\n",
chan->name, chan->addr, dev->tbusy,
chan->protocol == ETH_P_IP ? "IP" : "X25");
}
}
......
......@@ -1280,10 +1280,12 @@ static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EPERM;
if(copy_from_user( tmpstr, ifr->ifr_data, 6))
return -EFAULT;
slave=dev_get(tmpstr);
slave = dev_get_by_name(tmpstr);
if(!(slave && slave->flags & IFF_UP && dev->flags & IFF_UP))
{
printk("%s: Both devices should be UP to enslave!\n",dev->name);
if (slave)
dev_put(slave);
return -EINVAL;
}
......@@ -1304,8 +1306,9 @@ static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
else
{
printk("%s: one of devices is already slave!\n",dev->name);
return -EBUSY;
error = -EBUSY;
}
dev_put(slave);
}
else
{
......@@ -1359,7 +1362,7 @@ static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
unsigned long calc_crc(char *mem, int len, unsigned initial)
{
unsigned crc, dummy_len;
__asm__ (
"xorl %%eax,%%eax\n\t"
"1:\n\t"
......@@ -1367,13 +1370,12 @@ unsigned long calc_crc(char *mem, int len, unsigned initial)
"xorb %%dl,%%al\n\t"
"shrl $8,%%edx\n\t"
"xorl (%%edi,%%eax,4),%%edx\n\t"
"loop 1b\n\t"
"movl %%edx,%%eax"
:
: "S" (mem), "D" (&crc32tab[0]), "c" (len), "d" (initial)
: "eax", "edx", "ecx"
"loop 1b"
: "=d" (crc), "=c" (dummy_len)
: "S" (mem), "D" (&crc32tab[0]), "1" (len), "0" (initial)
: "eax"
);
/* return crc; */
return crc;
}
#else
......
......@@ -7,41 +7,43 @@
tristate 'Parallel port support' CONFIG_PARPORT
if [ "$CONFIG_PARPORT" != "n" ]; then
dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
if [ "$CONFIG_PARPORT_PC" != "n" ]; then
bool ' Use FIFO/DMA if available' CONFIG_PARPORT_PC_FIFO
fi
if [ "$CONFIG_PARPORT_PC" = "y" ]; then
# Don't bother with this if parport_pc is a module; it only affects
# the presence or not of some __init's, which are no-ops for modules.
bool ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA
fi
if [ "$CONFIG_ARM" = "y" ]; then
dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT
fi
if [ "$CONFIG_AMIGA" = "y" ]; then
dep_tristate ' Amiga builtin port' CONFIG_PARPORT_AMIGA $CONFIG_PARPORT
if [ "$CONFIG_ZORRO" != "n" ]; then
dep_tristate ' Multiface III parallel port' CONFIG_PARPORT_MFC3 $CONFIG_PARPORT
fi
else
define_bool CONFIG_PARPORT_AMIGA n
define_bool CONFIG_PARPORT_MFC3 n
fi
if [ "$CONFIG_ATARI" = "y" ]; then
dep_tristate ' Atari hardware' CONFIG_PARPORT_ATARI $CONFIG_PARPORT
else
define_bool CONFIG_PARPORT_ATARI n
fi
if [ "$CONFIG_SBUS" = "y" ]; then
dep_tristate ' Sparc hardware (EXPERIMENTAL)' CONFIG_PARPORT_SUNBPP $CONFIG_PARPORT
else
define_bool CONFIG_PARPORT_SUNBPP n
fi
dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
if [ "$CONFIG_PARPORT_PC" != "n" ]; then
bool ' Use FIFO/DMA if available' CONFIG_PARPORT_PC_FIFO
fi
if [ "$CONFIG_PARPORT_PC" = "y" ]; then
# Don't bother with this if parport_pc is a module; it only affects
# the presence or not of some __init's, which are no-ops for modules.
if [ "$CONFIG_PCMCIA" != "n" ]; then
bool ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA
fi
fi
if [ "$CONFIG_ARM" = "y" ]; then
dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT
fi
if [ "$CONFIG_AMIGA" = "y" ]; then
dep_tristate ' Amiga builtin port' CONFIG_PARPORT_AMIGA $CONFIG_PARPORT
if [ "$CONFIG_ZORRO" != "n" ]; then
dep_tristate ' Multiface III parallel port' CONFIG_PARPORT_MFC3 $CONFIG_PARPORT
fi
else
define_bool CONFIG_PARPORT_AMIGA n
define_bool CONFIG_PARPORT_MFC3 n
fi
if [ "$CONFIG_ATARI" = "y" ]; then
dep_tristate ' Atari hardware' CONFIG_PARPORT_ATARI $CONFIG_PARPORT
else
define_bool CONFIG_PARPORT_ATARI n
fi
if [ "$CONFIG_SBUS" = "y" ]; then
dep_tristate ' Sparc hardware (EXPERIMENTAL)' CONFIG_PARPORT_SUNBPP $CONFIG_PARPORT
else
define_bool CONFIG_PARPORT_SUNBPP n
fi
# If exactly one hardware type is selected then parport will optimise away
# support for loading any others. Defeat this if the user is keen.
bool ' Support foreign hardware' CONFIG_PARPORT_OTHER
# If exactly one hardware type is selected then parport will optimise away
# support for loading any others. Defeat this if the user is keen.
bool ' Support foreign hardware' CONFIG_PARPORT_OTHER
bool ' IEEE 1284 transfer modes' CONFIG_PARPORT_1284
bool ' IEEE 1284 transfer modes' CONFIG_PARPORT_1284
fi
......@@ -1207,7 +1207,7 @@ static int __maybe_init parport_ECP_supported(struct parport *pb)
outb (ECR_SPP << 5, ECONTROL (pb)); /* Reset FIFO */
outb (0xf4, ECONTROL (pb)); /* Configuration mode */
config = inb (FIFO (pb));
config = inb (CONFIGA (pb));
pword = (config >> 4) & 0x7;
switch (pword) {
case 0:
......@@ -1230,10 +1230,10 @@ static int __maybe_init parport_ECP_supported(struct parport *pb)
priv->pword = pword;
printk (KERN_DEBUG "0x%lx: PWord is %d bits\n", pb->base, 8 * pword);
config = inb (CONFIGB (pb));
printk (KERN_DEBUG "0x%lx: Interrupts are ISA-%s\n", pb->base,
config & 0x80 ? "Level" : "Pulses");
config = inb (CONFIGB (pb));
if (!(config & 0x40)) {
printk (KERN_WARNING "0x%lx: IRQ conflict!\n", pb->base);
pb->irq = PARPORT_IRQ_NONE;
......
......@@ -56,6 +56,47 @@ static void __init quirk_isa_dma_hangs(struct pci_dev *dev)
}
}
int pci_pci_problems = 0;
/*
* Chipsets where PCI->PCI transfers vanish or hang
*/
static void __init quirk_nopcipci(struct pci_dev *dev)
{
if((pci_pci_problems&PCIPCI_FAIL)==0)
{
printk(KERN_INFO "Disabling direct PCI/PCI transfers.\n");
pci_pci_problems|=PCIPCI_FAIL;
}
}
/*
* Triton requires workarounds to be used by the drivers
*/
static void __init quirk_triton(struct pci_dev *dev)
{
if((pci_pci_problems&PCIPCI_TRITON)==0)
{
printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
pci_pci_problems|=PCIPCI_TRITON;
}
}
/*
* Natoma has some interesting boundary conditions with Zoran stuff
* at least
*/
static void __init quirk_natoma(struct pci_dev *dev)
{
if((pci_pci_problems&PCIPCI_NATOMA)==0)
{
printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
pci_pci_problems|=PCIPCI_NATOMA;
}
}
/*
* S3 868 and 968 chips report region size equal to 32M, but they decode 64M.
......@@ -78,6 +119,7 @@ static void __init quirk_s3_64M(struct pci_dev *dev)
*/
static struct pci_fixup pci_fixups[] __initdata = {
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release },
/*
* Its not totally clear which chipsets are the problematic ones
......@@ -88,6 +130,18 @@ static struct pci_fixup pci_fixups[] __initdata = {
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, quirk_isa_dma_hangs },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, quirk_triton },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX, quirk_triton },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439, quirk_triton },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quirk_triton },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_natoma },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_0, quirk_natoma },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_1, quirk_natoma },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0, quirk_natoma },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_1, quirk_natoma },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, quirk_natoma },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci },
{ 0 }
};
......
Change Log
~~~~~~~~~~
1.00.00 - Initial Public Release
- Functionally equivalent to 0.99.05
0.99.05 - Fix an oops on certain passthru commands
0.99.04 - Fix race condition in the passthru mechanism
-- this required the interface to the utilities to change
- Fix error recovery code
0.99.03 - Make interrupt routine handle all completed request on the
adapter not just the first one
- Make sure passthru commands get woken up if we run out of
SCBs
- Send all of the commands on the queue at once rather than
one at a time since the card will support it.
0.99.02 - Added some additional debug statements to print out
errors if an error occurs while trying to read/write
to a logical drive (IPS_DEBUG).
Fixed read/write errors when the adapter is using an
8K stripe size.
This diff is collapsed.
/*
* dec_esp.c: Driver for SCSI chips on IOASIC based TURBOchannel DECstations
*
* TURBOchannel changes by Harald Koerfgen
*
* based on jazz_esp.c:
* Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
*
* jazz_esp is based on David S. Miller's ESP driver and cyber_esp
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/malloc.h>
#include <linux/blk.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include "scsi.h"
#include "hosts.h"
#include "NCR53C9x.h"
#include "dec_esp.h"
#include <asm/irq.h>
#include <asm/jazz.h>
#include <asm/jazzdma.h>
#include <asm/dma.h>
#include <asm/pgtable.h>
#include <asm/dec/tc.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/ioasic_ints.h>
#include <asm/dec/machtype.h>
static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
static void dma_drain(struct NCR_ESP *esp);
static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp);
static void dma_dump_state(struct NCR_ESP *esp);
static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
static void dma_ints_off(struct NCR_ESP *esp);
static void dma_ints_on(struct NCR_ESP *esp);
static int dma_irq_p(struct NCR_ESP *esp);
static int dma_ports_p(struct NCR_ESP *esp);
static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp);
static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp);
static void dma_advance_sg(Scsi_Cmnd * sp);
volatile unsigned char cmd_buffer[16];
/* This is where all commands are put
* before they are trasfered to the ESP chip
* via PIO.
*/
volatile unsigned long *scsi_dma_ptr;
volatile unsigned long *scsi_next_ptr;
volatile unsigned long *scsi_scr;
volatile unsigned long *ioasic_ssr;
volatile unsigned long *scsi_sdr0;
volatile unsigned long *scsi_sdr1;
static void scsi_dma_int(int, void *, struct pt_regs *);
/***************************************************************** Detection */
int dec_esp_detect(Scsi_Host_Template * tpnt)
{
struct NCR_ESP *esp;
struct ConfigDev *esp_dev;
if (IOASIC) {
esp_dev = 0;
esp = esp_allocate(tpnt, (void *) esp_dev);
scsi_dma_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_P);
scsi_next_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_BP);
scsi_scr = (unsigned long *) (system_base + IOCTL + SCSI_SCR);
ioasic_ssr = (unsigned long *) (system_base + IOCTL + SSR);
scsi_sdr0 = (unsigned long *) (system_base + IOCTL + SCSI_SDR0);
scsi_sdr1 = (unsigned long *) (system_base + IOCTL + SCSI_SDR1);
/* Do command transfer with programmed I/O */
esp->do_pio_cmds = 1;
/* Required functions */
esp->dma_bytes_sent = &dma_bytes_sent;
esp->dma_can_transfer = &dma_can_transfer;
esp->dma_dump_state = &dma_dump_state;
esp->dma_init_read = &dma_init_read;
esp->dma_init_write = &dma_init_write;
esp->dma_ints_off = &dma_ints_off;
esp->dma_ints_on = &dma_ints_on;
esp->dma_irq_p = &dma_irq_p;
esp->dma_ports_p = &dma_ports_p;
esp->dma_setup = &dma_setup;
/* Optional functions */
esp->dma_barrier = 0;
esp->dma_drain = &dma_drain;
esp->dma_invalidate = 0;
esp->dma_irq_entry = 0;
esp->dma_irq_exit = 0;
esp->dma_poll = 0;
esp->dma_reset = 0;
esp->dma_led_off = 0;
esp->dma_led_on = 0;
/* virtual DMA functions */
esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
esp->dma_mmu_release_scsi_one = 0;
esp->dma_mmu_release_scsi_sgl = 0;
esp->dma_advance_sg = &dma_advance_sg;
/* SCSI chip speed */
esp->cfreq = 25000000;
/*
* we don't give the address of DMA channel, but the number
* of DMA channel, so we can use the jazz DMA functions
*
*/
esp->dregs = JAZZ_SCSI_DMA;
/* ESP register base */
esp->eregs = (struct ESP_regs *) (system_base + SCSI);
/* Set the command buffer */
esp->esp_command = (volatile unsigned char *) cmd_buffer;
/* get virtual dma address for command buffer */
esp->esp_command_dvma = KSEG1ADDR((volatile unsigned char *) cmd_buffer);
esp->irq = SCSI_INT;
request_irq(esp->irq, esp_intr, SA_INTERRUPT, "NCR 53C94 SCSI",
NULL);
request_irq(SCSI_DMA_INT, scsi_dma_int, SA_INTERRUPT, "JUNKIO SCSI DMA",
NULL);
/*
* FIXME, look if the scsi id is availabe from NVRAM
*/
esp->scsi_id = 7;
/* Check for differential SCSI-bus */
/* What is this stuff? */
esp->diff = 0;
esp_initialize(esp);
printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
esps_running = esps_in_use;
return esps_in_use;
}
return 0;
}
/************************************************************* DMA Functions */
static void scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs)
{
extern volatile unsigned int *isr;
unsigned int dummy;
if (*isr & SCSI_PTR_LOADED) {
/* next page */
*scsi_next_ptr = ((*scsi_dma_ptr + PAGE_SIZE) & PAGE_MASK) << 3;
*isr &= ~SCSI_PTR_LOADED;
} else {
printk("Got unexpected SCSI DMA Interrupt! < ");
if (*isr & SCSI_PAGOVRRUN)
printk("SCSI_PAGOVRRUN ");
if (*isr & SCSI_DMA_MEMRDERR)
printk("SCSI_DMA_MEMRDERR ");
printk(">\n");
// panic("stop");
*isr &= ~(SCSI_PAGOVRRUN || SCSI_DMA_MEMRDERR);
}
/*
* This driver will only work on IOASIC machines
* so we can avoid an indirect function call here
* and flush the writeback buffer the fast way
*/
dummy = *isr;
dummy = *isr;
}
static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
{
return fifo_count;
}
static void dma_drain(struct NCR_ESP *esp)
{
unsigned long nw;
unsigned short *p = KSEG1ADDR((unsigned short *) ((*scsi_dma_ptr) >> 3));
/*
* Is there something in the dma buffers left?
*/
if (nw = *scsi_scr) {
switch (nw) {
case 1:
*p = (unsigned short) *scsi_sdr0;
break;
case 2:
*p++ = (unsigned short) (*scsi_sdr0);
*p = (unsigned short) ((*scsi_sdr0) >> 16);
break;
case 3:
*p++ = (unsigned short) (*scsi_sdr0);
*p++ = (unsigned short) ((*scsi_sdr0) >> 16);
*p = (unsigned short) (*scsi_sdr1);
break;
default:
printk("Strange: %d words in dma buffer left\n", (int) nw);
break;
}
}
}
static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp)
{
return sp->SCp.this_residual;;
}
static void dma_dump_state(struct NCR_ESP *esp)
{
/*
ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n",
esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_resdiue((int)esp->dregs)));
*/
}
static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
{
extern volatile unsigned int *isr;
unsigned int dummy;
if (vaddress & 3)
panic("dec_efs.c: unable to handle partial word transfers, yet...");
dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length);
*ioasic_ssr &= ~SCSI_DMA_EN;
*scsi_scr = 0;
*scsi_dma_ptr = vaddress << 3;
/* prepare for next page */
*scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
*ioasic_ssr |= (SCSI_DMA_DIR | SCSI_DMA_EN);
/*
* see above
*/
dummy = *isr;
dummy = *isr;
}
static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
{
extern volatile unsigned int *isr;
unsigned int dummy;
if (vaddress & 3)
panic("dec_efs.c: unable to handle partial word transfers, yet...");
dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length);
*ioasic_ssr &= ~(SCSI_DMA_DIR | SCSI_DMA_EN);
*scsi_scr = 0;
*scsi_dma_ptr = vaddress << 3;
/* prepare for next page */
*scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
*ioasic_ssr |= SCSI_DMA_EN;
/*
* see above
*/
dummy = *isr;
dummy = *isr;
}
static void dma_ints_off(struct NCR_ESP *esp)
{
disable_irq(SCSI_DMA_INT);
}
static void dma_ints_on(struct NCR_ESP *esp)
{
enable_irq(SCSI_DMA_INT);
}
static int dma_irq_p(struct NCR_ESP *esp)
{
return (esp->eregs->esp_status & ESP_STAT_INTR);
}
static int dma_ports_p(struct NCR_ESP *esp)
{
/*
* FIXME: what's this good for?
*/
return 1;
}
static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
{
/*
* On the Sparc, DMA_ST_WRITE means "move data from device to memory"
* so when (write) is true, it actually means READ!
*/
if (write) {
dma_init_read(esp, addr, count);
} else {
dma_init_write(esp, addr, count);
}
}
/*
* These aren't used yet
*/
static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp)
{
sp->SCp.have_data_in = PHYSADDR(sp->SCp.buffer);
sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.have_data_in);
}
static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp)
{
int sz = sp->SCp.buffers_residual;
struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer;
while (sz >= 0) {
sg[sz].dvma_addr = PHYSADDR(sg[sz].addr);
sz--;
}
sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dvma_address);
}
static void dma_advance_sg(Scsi_Cmnd * sp)
{
sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dvma_address);
}
/* dec_esp.h: Defines and structures for the JAZZ SCSI driver.
*
* DECstation changes Copyright (C) 1998 Harald Koerfgen
*
* based on jazz_esp.h:
* Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
*/
#ifndef DEC_ESP_H
#define DEC_ESP_H
#define EREGS_PAD(n) unchar n[3];
#include "NCR53C9x.h"
extern int dec_esp_detect(struct SHT *);
extern const char *esp_info(struct Scsi_Host *);
extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
extern int esp_command(Scsi_Cmnd *);
extern int esp_abort(Scsi_Cmnd *);
extern int esp_reset(Scsi_Cmnd *, unsigned int);
extern int esp_proc_info(char *buffer, char **start, off_t offset, int length,
int hostno, int inout);
#define SCSI_DEC_ESP { \
proc_dir: &proc_scsi_esp, \
proc_info: &esp_proc_info, \
name: "PMAZ-AA", \
detect: dec_esp_detect, \
info: esp_info, \
command: esp_command, \
queuecommand: esp_queue, \
abort: esp_abort, \
reset: esp_reset, \
can_queue: 7, \
this_id: 7, \
sg_tablesize: SG_ALL, \
cmd_per_lun: 1, \
use_clustering: DISABLE_CLUSTERING, }
#endif /* DEC_ESP_H */
......@@ -85,7 +85,9 @@ mac53c94_detect(Scsi_Host_Template *tp)
if (host == 0)
panic("couldn't register 53c94 host");
host->unique_id = nfscs;
#ifndef MODULE
note_scsi_host(node, host);
#endif
state = (struct fsc_state *) host->hostdata;
if (state == 0)
......
......@@ -28,6 +28,7 @@ int mac53c94_reset(Scsi_Cmnd *, unsigned int);
sg_tablesize: SG_ALL, \
cmd_per_lun: 1, \
use_clustering: DISABLE_CLUSTERING, \
use_new_eh_code: 1, \
}
/*
......
......@@ -5,13 +5,14 @@
*
* (In all truth, Jed Schimmel wrote all this code.)
*
* $Id: sgiwd93.c,v 1.1 1998/05/01 01:35:42 ralf Exp $
* $Id: sgiwd93.c,v 1.13 1999/03/28 23:06:06 tsbogend Exp $
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/blk.h>
#include <linux/version.h>
#include <linux/delay.h>
#include <asm/page.h>
#include <asm/pgtable.h>
......@@ -21,6 +22,7 @@
#include <asm/sgihpc.h>
#include <asm/sgint23.h>
#include <asm/irq.h>
#include <asm/spinlock.h>
#include <asm/io.h>
#include "scsi.h"
......@@ -65,14 +67,40 @@ static inline unsigned long read_wd33c93_count(wd33c93_regs *regp)
/* XXX woof! */
static void sgiwd93_intr(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long flags;
spin_lock_irqsave(&io_request_lock, flags);
wd33c93_intr(sgiwd93_host);
spin_unlock_irqrestore(&io_request_lock, flags);
}
#undef DEBUG_DMA
static inline
void fill_hpc_entries (struct hpc_chunk **hcp, char *addr, unsigned long len)
{
unsigned long physaddr;
unsigned long count;
dma_cache_wback_inv((unsigned long)addr,len);
physaddr = PHYSADDR(addr);
while (len) {
/*
* even cntinfo could be up to 16383, without
* magic only 8192 works correctly
*/
count = len > 8192 ? 8192 : len;
(*hcp)->desc.pbuf = physaddr;
(*hcp)->desc.cntinfo = count;
(*hcp)++;
len -= count;
physaddr += count;
}
}
static int dma_setup(Scsi_Cmnd *cmd, int datainp)
{
struct WD33C93_hostdata *hdata = CMDHOSTDATA(cmd);
struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
wd33c93_regs *regp = hdata->regp;
struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->host->base;
struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->dma_bounce_buffer;
......@@ -84,21 +112,18 @@ static int dma_setup(Scsi_Cmnd *cmd, int datainp)
hdata->dma_dir = datainp;
if(cmd->use_sg) {
if(cmd->SCp.buffers_residual) {
struct scatterlist *slp = cmd->SCp.buffer;
int i, totlen = 0;
#ifdef DEBUG_DMA
printk("SCLIST<");
#endif
for(i = 0; i <= (cmd->use_sg - 1); i++, hcp++) {
for(i = 0; i <= cmd->SCp.buffers_residual; i++) {
#ifdef DEBUG_DMA
printk("[%p,%d]", slp[i].address, slp[i].length);
#endif
dma_cache_wback_inv((unsigned long)slp[i].address,
PAGE_SIZE);
hcp->desc.pbuf = PHYSADDR(slp[i].address);
hcp->desc.cntinfo = (slp[i].length & HPCDMA_BCNT);
fill_hpc_entries (&hcp, slp[i].address, slp[i].length);
totlen += slp[i].length;
}
#ifdef DEBUG_DMA
......@@ -111,10 +136,16 @@ static int dma_setup(Scsi_Cmnd *cmd, int datainp)
#ifdef DEBUG_DMA
printk("ONEBUF<%p,%d>", cmd->SCp.ptr, cmd->SCp.this_residual);
#endif
dma_cache_wback_inv((unsigned long)cmd->SCp.ptr, PAGE_SIZE);
hcp->desc.pbuf = PHYSADDR(cmd->SCp.ptr);
hcp->desc.cntinfo = (cmd->SCp.this_residual & HPCDMA_BCNT);
hcp++;
/*
* wd33c93 shouldn't pass us bogus dma_setups, but
* it does:-( The other wd33c93 drivers deal with
* it the same way (which isn't that obvious).
* IMHO a better fix would be, not to do these
* dma setups in the first place
*/
if (cmd->SCp.ptr == NULL)
return 1;
fill_hpc_entries (&hcp, cmd->SCp.ptr,cmd->SCp.this_residual);
write_wd33c93_count(regp, cmd->SCp.this_residual);
}
......@@ -141,9 +172,14 @@ static int dma_setup(Scsi_Cmnd *cmd, int datainp)
static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
int status)
{
struct WD33C93_hostdata *hdata = INSTHOSTDATA(instance);
struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)instance->hostdata;
wd33c93_regs *regp = hdata->regp;
struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) SCpnt->host->base;
struct hpc3_scsiregs *hregs;
if (!SCpnt)
return;
hregs = (struct hpc3_scsiregs *) SCpnt->host->base;
#ifdef DEBUG_DMA
printk("dma_stop: status<%d> ", status);
......@@ -158,7 +194,7 @@ static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
hregs->ctrl = 0;
/* See how far we got and update scatterlist state if necessary. */
if(SCpnt->use_sg) {
if(SCpnt->SCp.buffers_residual) {
struct scatterlist *slp = SCpnt->SCp.buffer;
int totlen, wd93_residual, transferred, i;
......@@ -178,7 +214,7 @@ static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
#ifdef DEBUG_DMA
printk("Jed was here...");
#endif
for(i = 0; i <= (SCpnt->use_sg - 1); i++) {
for(i = 0; i <= SCpnt->SCp.buffers_residual; i++) {
if(slp[i].length >= transferred)
break;
transferred -= slp[i].length;
......@@ -188,10 +224,10 @@ static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
#ifdef DEBUG_DMA
printk("did it all...");
#endif
i = (SCpnt->use_sg - 1);
i = SCpnt->SCp.buffers_residual;
}
SCpnt->SCp.buffer = &slp[i];
SCpnt->SCp.buffers_residual = (SCpnt->use_sg - 1 - i);
SCpnt->SCp.buffers_residual = SCpnt->SCp.buffers_residual - i;
SCpnt->SCp.ptr = (char *) slp[i].address;
SCpnt->SCp.this_residual = slp[i].length;
}
......@@ -200,6 +236,15 @@ static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
#endif
}
void sgiwd93_reset(void)
{
struct hpc3_scsiregs *hregs = &hpc3c0->scsi_chan0;
hregs->ctrl = HPC3_SCTRL_CRESET;
udelay (50);
hregs->ctrl = 0;
}
static inline void init_hpc_chain(uchar *buf)
{
struct hpc_chunk *hcp = (struct hpc_chunk *) buf;
......@@ -231,6 +276,7 @@ int __init sgiwd93_detect(Scsi_Host_Template *HPsUX)
sgiwd93_host = scsi_register(HPsUX, sizeof(struct WD33C93_hostdata));
sgiwd93_host->base = (unsigned char *) hregs;
sgiwd93_host->irq = 1;
buf = (uchar *) get_free_page(GFP_KERNEL);
init_hpc_chain(buf);
......@@ -239,7 +285,7 @@ int __init sgiwd93_detect(Scsi_Host_Template *HPsUX)
wd33c93_init(sgiwd93_host, (wd33c93_regs *) 0xbfbc0003,
dma_setup, dma_stop, WD33C93_FS_16_20);
hdata = INSTHOSTDATA(sgiwd93_host);
hdata = (struct WD33C93_hostdata *)sgiwd93_host->hostdata;
hdata->no_sync = 0;
hdata->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf));
dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
......
/* $Id: sgiwd93.h,v 1.2 1998/05/04 09:18:49 ralf Exp $
/* $Id: sgiwd93.h,v 1.5 1998/08/25 09:18:50 ralf Exp $
* sgiwd93.h: SGI WD93 scsi definitions.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
......
......@@ -6,13 +6,13 @@ comment 'SGI devices'
bool 'SGI Zilog85C30 serial support' CONFIG_SGI_SERIAL
if [ "$CONFIG_SGI_SERIAL" != "n" ]; then
define_bool CONFIG_SERIAL y
define_bool CONFIG_SERIAL y
fi
bool 'SGI DS1286 RTC support' CONFIG_SGI_DS1286
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'SGI Newport Graphics support' CONFIG_SGI_NEWPORT_GFX
tristate 'SGI Newport Graphics support (EXPERIMENTAL)' CONFIG_SGI_NEWPORT_GFX
fi
endmenu
......@@ -33,6 +33,19 @@
/* registers 0x0028 - 0x0058 are reserved */
/* AC'97 2.0 */
#define AC97_EXTENDED_ID 0x0028 /* Extended Audio ID */
#define AC97_EXTENDED_STATUS 0x002A /* Extended Audio Status */
#define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */
#define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */
#define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */
#define AC97_PCM_LR_DAC_RATE 0x0032 /* PCM LR DAC Rate */
#define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */
#define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */
#define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */
#define AC97_RESERVED_3A 0x003A /* Reserved */
/* range 0x3c-0x58 - MODEM */
/* registers 0x005a - 0x007a are vendor reserved */
#define AC97_VENDOR_ID1 0x007c
......
......@@ -89,6 +89,7 @@ for more details.
#include <linux/malloc.h>
#include <linux/sound.h>
#include <linux/init.h>
#include <linux/delay.h>
#if defined(__mc68000__) || defined(CONFIG_APUS)
#include <asm/setup.h>
......@@ -239,7 +240,7 @@ static short beep_wform[256] = {
-269, -245, -218, -187, -153, -117, -79, -40,
};
#define BEEP_SPEED 2 /* 22050 Hz sample rate */
#define BEEP_SRATE 22050 /* 22050 Hz sample rate */
#define BEEP_BUFLEN 512
#define BEEP_VOLUME 15 /* 0 - 100 */
......@@ -295,7 +296,7 @@ static int numReadBufs = 4, readbufSize = 32;
MODULE_PARM(catchRadius, "i");
MODULE_PARM(numBufs, "i");
MODULE_PARM(bufSize, "i");
MODULE_PARM(numreadBufs, "i");
MODULE_PARM(numReadBufs, "i");
MODULE_PARM(readbufSize, "i");
#define arraysize(x) (sizeof(x)/sizeof(*(x)))
......@@ -3209,6 +3210,7 @@ static void PMacSilence(void)
static int awacs_freqs[8] = {
44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
};
static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
static void PMacInit(void)
{
......@@ -3232,10 +3234,13 @@ static void PMacInit(void)
* Otherwise choose the next higher rate.
* N.B.: burgundy awacs (iMac and later) only works at 44100 Hz.
*/
i = (awacs_revision >= AWACS_BURGUNDY)? 1: 8;
i = 8;
do {
tolerance = catchRadius * awacs_freqs[--i] / 100;
} while (sound.soft.speed > awacs_freqs[i] + tolerance && i > 0);
if (awacs_freqs_ok[i]
&& sound.soft.speed <= awacs_freqs[i] + tolerance)
break;
} while (i > 0);
if (sound.soft.speed >= awacs_freqs[i] - tolerance)
sound.trans = &transAwacsNormal;
else
......@@ -3529,8 +3534,8 @@ static struct timer_list beep_timer = {
static void awacs_mksound(unsigned int hz, unsigned int ticks)
{
unsigned long flags;
int beep_speed = (awacs_revision < AWACS_BURGUNDY)? BEEP_SPEED: 0;
int srate = awacs_freqs[beep_speed];
int beep_speed = 0;
int srate;
int period, ncycles, nsamples;
int i, j, f;
short *p;
......@@ -3538,6 +3543,11 @@ static void awacs_mksound(unsigned int hz, unsigned int ticks)
static int beep_nsamples_cache;
static int beep_volume_cache;
for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i)
if (awacs_freqs_ok[i])
beep_speed = i;
srate = awacs_freqs[beep_speed];
if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
#if 1
/* this is a hack for broken X server code */
......@@ -3625,6 +3635,12 @@ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE);
enable_irq(awacs_irq);
enable_irq(awacs_tx_irq);
if (awacs_revision == 3) {
mdelay(100);
awacs_write(0x6000);
mdelay(2);
awacs_write(awacs_reg[1] | MASK_ADDR1);
}
}
return PBOOK_SLEEP_OK;
}
......@@ -3667,7 +3683,7 @@ static unsigned
awacs_burgundy_rcw(unsigned addr)
{
unsigned val = 0;
int flags;
unsigned long flags;
/* should have timeouts here */
save_flags(flags); cli();
......@@ -3709,7 +3725,7 @@ static unsigned
awacs_burgundy_rcb(unsigned addr)
{
unsigned val = 0;
int flags;
unsigned long flags;
/* should have timeouts here */
save_flags(flags); cli();
......@@ -5497,12 +5513,41 @@ void __init dmasound_init(void)
np = find_devices("davbus");
sound = find_devices("sound");
if (sound != 0 && sound->parent == np) {
int *sfprop;
sfprop = (int *) get_property(sound, "sub-frame", 0);
if (sfprop != 0 && *sfprop >= 0 && *sfprop < 16)
awacs_subframe = *sfprop;
unsigned int *prop, l, i;
prop = (unsigned int *)
get_property(sound, "sub-frame", 0);
if (prop != 0 && *prop >= 0 && *prop < 16)
awacs_subframe = *prop;
if (device_is_compatible(sound, "burgundy"))
awacs_revision = AWACS_BURGUNDY;
/* look for a property saying what sample rates
are available */
for (i = 0; i < 8; ++i)
awacs_freqs_ok[i] = 0;
prop = (unsigned int *) get_property
(sound, "sample-rates", &l);
if (prop == 0)
prop = (unsigned int *) get_property
(sound, "output-frame-rates", &l);
if (prop != 0) {
for (l /= sizeof(int); l > 0; --l) {
/* sometimes the rate is in the
high-order 16 bits (?) */
unsigned int r = *prop++;
if (r >= 0x10000)
r >>= 16;
for (i = 0; i < 8; ++i) {
if (r == awacs_freqs[i]) {
awacs_freqs_ok[i] = 1;
break;
}
}
}
} else {
/* assume just 44.1k is OK */
awacs_freqs_ok[0] = 1;
}
}
}
if (np != NULL && np->n_addrs >= 3 && np->n_intrs >= 3) {
......
This diff is collapsed.
......@@ -106,13 +106,19 @@ ifeq ($(CONFIG_USB_SERIAL),m)
MIX_OBJS += serial.o
endif
ifneq ($(CONFIG_ADB_KEYBOARD),y)
KEYMAP=keymap
else
KEYMAP=keymap-mac
endif
ifeq ($(CONFIG_USB_KBD),y)
L_OBJS += keyboard.o keymap.o
L_OBJS += keyboard.o $(KEYMAP).o
endif
ifeq ($(CONFIG_USB_KBD),m)
M_OBJS += usb-keyboard.o
MIX_OBJS += keyboard.o keymap.o
MIX_OBJS += keyboard.o $(KEYMAP).o
endif
ifeq ($(CONFIG_USB_AUDIO),y)
......@@ -177,13 +183,8 @@ keymap-mac.o: keymap-mac.c
keymap-mac.c: maps/mac.map maps/usb.map
./mkmap.adb > $@
ifneq ($(CONFIG_MAC_KEYBOARD),y)
usb-keyboard.o: keymap.o keyboard.o
$(LD) $(LD_RFLAG) -r -o $@ keymap.o keyboard.o
else
usb-keyboard.o: keymap-mac.o keyboard.o
$(LD) $(LD_RFLAG) -r -o $@ keymap-mac.o keyboard.o
endif
usb-keyboard.o: $(KEYMAP).o keyboard.o
$(LD) $(LD_RFLAG) -r -o $@ $(KEYMAP).o keyboard.o
ifeq ($(CONFIG_USB_SCSI_DEBUG),y)
usb-scsi.o: usb_scsi.o usb_scsi_debug.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -30,6 +30,7 @@
int usb_init(void)
{
usb_major_init();
#ifdef CONFIG_USB_PROC
proc_usb_init ();
#endif
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment