Commit 933ade85 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.40pre3

parent caec3863
......@@ -11788,6 +11788,84 @@ CONFIG_SUN_MOSTEK_RTC
### Please someone fill these in.
###
IEEE 1394 (aka FireWire) support
CONFIG_IEEE1394
IEEE 1394 describes a high performance serial bus, which is also
known as FireWire(tm) or i.Link(tm) and is used for connecting all
sorts of devices (most notably digital video cameras).
If you have FireWire hardware and want to use it, say Y here. This
is the core support only, you will also need to select a driver for
your IEEE 1394 adapter.
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read Documentation/modules.txt. The module will be
called ieee1394.o.
FireWire is a trademark by Apple Inc. and i.Link is a trademark by
Sony.
TI PCILynx IEEE 1394 support
CONFIG_IEEE1394_PCILYNX
Say Y here if you have a IEEE-1394 controller with the Texas
Instruments PCILynx chip. Note: this driver is written for revision
2 of this chip and may not work with revision 0.
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read Documentation/modules.txt. The module will be
called pcilynx.o.
Use local RAM on PCILynx board
CONFIG_IEEE1394_PCILYNX_LOCALRAM
This option makes the PCILynx driver use local RAM available on some
PCILynx setups for Packet Control Lists. Local RAM may speed up
command processing because no PCI transfers are necessary during
use of the Packet Control Lists.
Note that there are no known PCILynx systems providing local RAM
except for the evaluation boards by Texas Instruments and that the
PCILynx does not reliably report missing RAM.
Unless you are absolutely sure that you have 64kB of local RAM and
that you want to use it or if you don't know what this is all about,
say N here.
Adaptec AIC-5800 IEEE 1394 support
CONFIG_IEEE1394_AIC5800
Say Y here if you have a IEEE 1394 controller using the Adaptec
AIC-5800 chip. All Adaptec host adapters (89xx series) use this
chip, as well as miro's DV boards.
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read Documentation/modules.txt. The module will be
called aic5800.o.
OHCI (Open Host Controller Interface) support
CONFIG_IEEE1394_OHCI1394
Say Y here if you have a IEEE 1394 controller based on OHCI.
The current driver was only tested with OHCI chipsets made
by Texas Instruments. However, most third-party vendors use
TI chips.
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read Documentation/modules.txt. The module will be
called ohci1394.o.
RAW IEEE 1394 I/O support
CONFIG_IEEE1394_RAWIO
Say Y here if you want support for the raw device. This is generally
a good idea, so you should say Y here. The raw device enables
direct communication of user programs to the IEEE 1394 bus.
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read Documentation/modules.txt. The module will be
called raw1394.o.
#
# m68k-specific kernel options
# Documented by Chris Lawrence <quango@themall.net> et al.
......
......@@ -158,6 +158,10 @@ ifeq ($(CONFIG_SCSI),y)
DRIVERS := $(DRIVERS) drivers/scsi/scsi.a
endif
ifeq ($(CONFIG_IEEE1394),y)
DRIVERS := $(DRIVERS) drivers/ieee1394/ieee1394.a
endif
ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),)
DRIVERS := $(DRIVERS) drivers/cdrom/cdrom.a
endif
......@@ -397,6 +401,7 @@ modules_install:
if [ -f IRDA_MODULES ]; then inst_mod IRDA_MODULES net; fi; \
if [ -f SK98LIN_MODULES ]; then inst_mod SK98LIN_MODULES net; fi; \
if [ -f USB_MODULES ]; then inst_mod USB_MODULES usb; fi; \
if [ -f IEEE1394_MODULES ]; then inst_mod IEEE1394_MODULES ieee1394; fi; \
if [ -f PCMCIA_MODULES ]; then inst_mod PCMCIA_MODULES pcmcia; fi; \
if [ -f PCMCIA_NET_MODULES ]; then inst_mod PCMCIA_NET_MODULES pcmcia; fi; \
if [ -f PCMCIA_CHAR_MODULES ]; then inst_mod PCMCIA_CHAR_MODULES pcmcia; fi; \
......
......@@ -169,6 +169,8 @@ if [ "$CONFIG_SCSI" != "n" ]; then
fi
endmenu
source drivers/ieee1394/Config.in
source drivers/i2o/Config.in
if [ "$CONFIG_NET" = "y" ]; then
......
......@@ -91,10 +91,9 @@ if [ "$CONFIG_OAK" = "y" ]; then
fi
if [ "$CONFIG_8xx" = "y" ]; then
bool 'QSpan PCI' CONFIG_PCI
else
if [ "$CONFIG_APUS" != "y" ]; then
fi
if [ "$CONFIG_6xx" = "y" -a "$CONFIG_APUS" != "y" ]; then
define_bool CONFIG_PCI y
fi
fi
bool 'Networking support' CONFIG_NET
......@@ -192,6 +191,8 @@ if [ "$CONFIG_SCSI" != "n" ]; then
fi
endmenu
source drivers/ieee1394/Config.in
if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment
comment 'Network device support'
......
......@@ -265,30 +265,20 @@ _GLOBAL(_switch)
SYNC
rfi
/*
* ret_from_int():
*
* Return from an interrupt (external interrupt and
* decrementer). This checks the first argument so
* we know if rtl_intercept wants us to check for
* a bottom half, signals and so on (normal return) or
* we're returning from a real-time interrupt or have
* interrupts soft disabled so we cannot enter Linux.
* -- Cort
*/
.globl ret_from_int
ret_from_int:
cmpi 0,r3,0
beq 10f
/* we're allowed to do signal/bh checks */
b ret_from_syscall
#ifdef __SMP__
.globl ret_from_smpfork
ret_from_smpfork:
bl schedule_tail
b ret_from_except
#endif
.globl ret_from_syscall
ret_from_syscall:
.globl ret_from_intercept
ret_from_intercept:
/*
* We may be returning from RTL and cannot do the normal checks
* -- Cort
*/
cmpi 0,r3,0
beq 10f
.globl ret_from_except
ret_from_except:
0: /* disable interrupts */
......
......@@ -375,7 +375,7 @@ HardwareInterrupt:
.globl do_IRQ_intercept
do_IRQ_intercept:
.long do_IRQ;
.long ret_from_int
.long ret_from_intercept
#else
bl apus_interrupt_entry
#endif /* CONFIG_APUS */
......@@ -425,7 +425,7 @@ Decrementer:
.globl timer_interrupt_intercept
timer_interrupt_intercept:
.long timer_interrupt
.long ret_from_int
.long ret_from_intercept
STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
......
......@@ -266,7 +266,7 @@ label:
bl transfer_to_handler
_GLOBAL(do_IRQ_intercept)
.long do_IRQ
.long ret_from_except
.long ret_from_intercept
### 0x0600 - Alignment Exception
......@@ -320,7 +320,7 @@ _GLOBAL(do_IRQ_intercept)
bl transfer_to_handler
_GLOBAL(timer_interrupt_intercept)
.long timer_interrupt
.long ret_from_except
.long ret_from_intercept
#if 0
### 0x1010 - Fixed Interval Timer (FIT) Exception
......@@ -474,7 +474,7 @@ _GLOBAL(giveup_fpu)
_GLOBAL(abort)
mfspr r13,SPRN_DBCR
oris r13,r13,DBCR_RST(SYSTEM)@h
oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h
mtspr SPRN_DBCR,r13
......
......@@ -266,34 +266,6 @@ InstructionAccess:
. = 0x500;
HardwareInterrupt:
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
......@@ -301,7 +273,7 @@ HardwareInterrupt:
.globl do_IRQ_intercept
do_IRQ_intercept:
.long do_IRQ;
.long ret_from_except
.long ret_from_intercept
/* Alignment exception */
......@@ -343,7 +315,7 @@ Decrementer:
.globl timer_interrupt_intercept
timer_interrupt_intercept:
.long timer_interrupt
.long ret_from_except
.long ret_from_intercept
STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
......
......@@ -70,6 +70,7 @@ struct pci_ops generic_pci_ops =
void __init pcibios_init(void)
{
printk("PCI: Probing PCI hardware\n");
ioport_resource.end = ~0L;
pci_scan_bus(0, &generic_pci_ops, NULL);
pcibios_claim_resources(&pci_root_buses);
if (ppc_md.pcibios_fixup)
......
......@@ -260,10 +260,8 @@ EXPORT_SYMBOL(screen_info);
#endif
EXPORT_SYMBOL(int_control);
#if !defined(CONFIG_4xx)
EXPORT_SYMBOL(timer_interrupt_intercept);
EXPORT_SYMBOL(timer_interrupt);
#endif
extern unsigned long do_IRQ_intercept;
EXPORT_SYMBOL(do_IRQ_intercept);
EXPORT_SYMBOL(irq_desc);
......
......@@ -292,7 +292,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
#ifdef __SMP__
extern void ret_from_smpfork(void);
#else
extern void ret_from_syscall(void);
extern void ret_from_except(void);
#endif
/* Copy registers */
childregs = ((struct pt_regs *)
......@@ -309,7 +309,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
#ifdef __SMP__
kregs->nip = (unsigned long)ret_from_smpfork;
#else
kregs->nip = (unsigned long)ret_from_syscall;
kregs->nip = (unsigned long)ret_from_except;
#endif
asm volatile("mfmsr %0" : "=r" (msr):);
kregs->msr = msr;
......
......@@ -446,6 +446,8 @@ void __init smp_callin(void)
*/
if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
do_openpic_setup_cpu();
if ( _machine == _MACH_gemini )
gemini_init_l2();
while(!smp_commenced)
barrier();
__sti();
......
......@@ -469,7 +469,7 @@ backtrace(struct pt_regs *excp)
unsigned sp;
unsigned stack[2];
struct pt_regs regs;
extern char ret_from_int, ret_from_syscall_1, ret_from_syscall_2;
extern char ret_from_intercept, ret_from_syscall_1, ret_from_syscall_2;
extern char lost_irq_ret, do_bottom_half_ret, do_signal_ret;
extern char ret_from_except;
......@@ -483,7 +483,7 @@ backtrace(struct pt_regs *excp)
if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
break;
printf("%x ", stack[1]);
if (stack[1] == (unsigned) &ret_from_int
if (stack[1] == (unsigned) &ret_from_intercept
|| stack[1] == (unsigned) &ret_from_except
|| stack[1] == (unsigned) &ret_from_syscall_1
|| stack[1] == (unsigned) &ret_from_syscall_2
......
......@@ -9,7 +9,7 @@
SUB_DIRS := block char net parport sound misc
MOD_SUB_DIRS := $(SUB_DIRS)
ALL_SUB_DIRS := $(SUB_DIRS) pci sgi scsi sbus cdrom isdn pnp i2o \
ALL_SUB_DIRS := $(SUB_DIRS) pci sgi scsi sbus cdrom isdn pnp i2o ieee1394 \
macintosh video dio zorro fc4 usb \
nubus tc ap1000 atm pcmcia i2c telephony
......@@ -100,6 +100,15 @@ else
endif
endif
ifeq ($(CONFIG_IEEE1394),y)
SUB_DIRS += ieee1394
MOD_SUB_DIRS += ieee1394
else
ifeq ($(CONFIG_IEEE1394),m)
MOD_SUB_DIRS += ieee1394
endif
endif
ifeq ($(CONFIG_PNP),y)
SUB_DIRS += pnp
MOD_SUB_DIRS += pnp
......
......@@ -28,6 +28,7 @@ extern int soc_probe(void);
extern int atmdev_init(void);
extern int i2o_init(void);
extern int cpqarray_init(void);
extern void ieee1394_init(void);
void __init device_init(void)
{
......@@ -54,6 +55,9 @@ void __init device_init(void)
#ifdef CONFIG_SCSI
scsi_dev_init();
#endif
#ifdef CONFIG_IEEE1394
ieee1394_init();
#endif
#ifdef CONFIG_BLK_CPQ_DA
cpqarray_init();
#endif
......
......@@ -2598,7 +2598,7 @@ void __exit ide_cdrom_exit(void)
}
#endif /* MODULE */
int __init ide_cdrom_init (void)
int ide_cdrom_init (void)
{
ide_drive_t *drive;
struct cdrom_info *info;
......
......@@ -2460,7 +2460,7 @@ int __init i2o_init(void)
#endif
if(i2o_num_controllers)
i2o_init();
i2o_sys_init();
i2o_config_init();
#ifdef CONFIG_I2O_BLOCK
......
# -*- shell-script -*-
if [ "$CONFIG_PCI" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
mainmenu_option next_comment
comment 'IEEE 1394 (FireWire) support'
tristate 'IEEE 1394 (FireWire) support (EXPERIMENTAL)' CONFIG_IEEE1394 $CONFIG_PCI
if [ "$CONFIG_IEEE1394" != "n" ]; then
dep_tristate 'Texas Instruments PCILynx support' CONFIG_IEEE1394_PCILYNX $CONFIG_IEEE1394
if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then
bool ' Use PCILynx local RAM' CONFIG_IEEE1394_PCILYNX_LOCALRAM
fi
dep_tristate 'Adaptec AIC-5800 (AHA-89xx) support' CONFIG_IEEE1394_AIC5800 $CONFIG_IEEE1394
dep_tristate 'OHCI (Open Host Controller Interface) support' CONFIG_IEEE1394_OHCI1394 $CONFIG_IEEE1394
dep_tristate 'Raw IEEE1394 I/O support' CONFIG_IEEE1394_RAWIO $CONFIG_IEEE1394
fi
endmenu
fi
#
# Makefile for the Linux IEEE 1394 implementation
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile.
#
SUB_DIRS :=
MOD_SUB_DIRS := $(SUB_DIRS)
ALL_SUB_DIRS := $(SUB_DIRS)
MOD_LIST_NAME := IEEE1394_MODULES
L_TARGET := ieee1394.a
L_OBJS :=
LX_OBJS :=
M_OBJS :=
MX_OBJS :=
MI_OBJS :=
MIX_OBJS :=
O_OBJS :=
OX_OBJS :=
ifeq ($(CONFIG_IEEE1394),y)
L_OBJS += ieee1394.o hosts.o highlevel.o csr.o
O_TARGET = ieee1394.o
O_OBJS += ieee1394_core.o ieee1394_transactions.o
OX_OBJS += ieee1394_syms.o
else
ifeq ($(CONFIG_IEEE1394),m)
M_OBJS += ieee1394.o
O_TARGET = ieee1394.o
O_OBJS += ieee1394_core.o ieee1394_transactions.o hosts.o highlevel.o csr.o
OX_OBJS += ieee1394_syms.o
endif
endif
ifeq ($(CONFIG_IEEE1394_PCILYNX),y)
L_OBJS += pcilynx.o
else
ifeq ($(CONFIG_IEEE1394_PCILYNX),m)
M_OBJS += pcilynx.o
endif
endif
ifeq ($(CONFIG_IEEE1394_AIC5800),y)
L_OBJS += aic5800.o
else
ifeq ($(CONFIG_IEEE1394_AIC5800),m)
M_OBJS += aic5800.o
endif
endif
ifeq ($(CONFIG_IEEE1394_OHCI1394),y)
L_OBJS += ohci1394.o
else
ifeq ($(CONFIG_IEEE1394_OHCI1394),m)
M_OBJS += ohci1394.o
endif
endif
ifeq ($(CONFIG_IEEE1394_RAWIO),y)
L_OBJS += raw1394.o
else
ifeq ($(CONFIG_IEEE1394_RAWIO),m)
M_OBJS += raw1394.o
endif
endif
include $(TOPDIR)/Rules.make
This diff is collapsed.
/*
** aic5800.h - Adaptec AIC-5800 PCI-IEEE1394 chip driver header file
** Copyright (C)1999 Emanuel Pirker <epirker@edu.uni-klu.ac.at>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
*/
#ifndef AIC5800_H
#define AIC5800_H
#define AIC5800_DRIVER_NAME "aic5800"
#define MAX_AIC5800_CARDS 4
#define AIC5800_REGSPACE_SIZE 512
#define AIC5800_PBUF_SIZE 512
#define MAX_AT_PROGRAM_SIZE 10
#define AIC5800_ARFIFO_SIZE 128
struct dma_cmd {
u32 control;
u32 address;
u32 branchAddress;
u32 status;
};
struct aic5800 {
int id; /* sequential card number */
struct pci_dev *dev;
/* remapped memory spaces */
void *registers;
struct hpsb_host *host;
int phyid, isroot;
void *rcv_page;
void *pbuf;
struct dma_cmd *AT_program;
u32 *AT_status;
struct dma_cmd *AR_program;
u32 *AR_status;
int AR_active;
struct hpsb_packet *async_queue;
spinlock_t async_queue_lock;
unsigned long NumInterrupts, NumBusResets;
unsigned long TxPackets, RxPackets;
unsigned long TxErrors, RxErrors;
unsigned long TxRdy, ATError, HdrErr, TCodeErr, SendRej;
};
/*
* Register read and write helper functions.
*/
inline static void reg_write(const struct aic5800 *aic, int offset, u32 data)
{
writel(data, aic->registers + offset);
}
inline static u32 reg_read(const struct aic5800 *aic, int offset)
{
return readl(aic->registers + offset);
}
inline static void reg_set_bits(const struct aic5800 *aic, int offset,
u32 mask)
{
reg_write(aic, offset, (reg_read(aic, offset) | mask));
}
inline static void reg_clear_bits(const struct aic5800 *aic, int offset,
u32 mask)
{
reg_write(aic, offset, (reg_read(aic, offset) & ~mask));
}
/* AIC-5800 Registers */
#define AT_ChannelControl 0x0
#define AT_ChannelStatus 0x4
#define AT_CommandPtr 0xC
#define AT_InterruptSelect 0x10
#define AT_BranchSelect 0x14
#define AT_WaitSelect 0x18
/* Asynchronous receive */
#define AR_ChannelControl 0x20
#define AR_ChannelStatus 0x24
#define AR_CommandPtr 0x2C
/* ITA */
#define ITA_ChannelControl 0x40
#define ITA_ChannelStatus 0x44
#define ITA_CommandPtr 0x4C
/* ITB */
#define ITB_ChannelControl 0x60
#define ITB_ChannelStatus 0x64
#define ITB_CommandPtr 0x6C
/* IRA */
#define IRA_ChannelControl 0x80
#define IRA_ChannelStatus 0x84
#define IRA_CommandPtr 0x8C
/* IRB */
#define IRB_ChannelControl 0xA0
#define IRB_ChannelStatus 0xA4
#define IRB_CommandPtr 0xAC
/* miscellaneous */
#define misc_Version 0x100
#define misc_Control 0x104
#define misc_NodeID 0x108
#define misc_Reset 0x10C
#define misc_PacketControl 0x110
#define misc_Diagnostic 0x114
#define misc_PhyControl 0x118
#define misc_ATRetries 0x11C
#define misc_SSNinterface 0x120
#define misc_CycleTimer 0x124
/* ITA */
#define ITA_EventCycle 0x130
#define ITA_Configuration 0x134
#define ITA_Bandwidth 0x138
/* ITB */
#define ITB_EventCycle 0x140
#define ITB_Configuration 0x144
#define ITB_Bandwidth 0x148
/* IRA */
#define IRA_EventCycle 0x150
#define IRA_Configuration 0x154
/* IRB */
#define IRB_EventCycle 0x160
#define IRB_Configuration 0x164
/* RSU */
#define RSU_Enable 0x170
#define RSU_Interrupt 0x174
#define RSU_TablePtr 0x178
#define RSU_InterruptSet 0x17C
/* misc */
#define misc_InterruptEvents 0x180
#define misc_InterruptMask 0x184
#define misc_InterruptClear 0x188
#define misc_CardBusEvent 0x1E0
#define misc_CardBusMask 0x1E4
#define misc_CardBusState 0x1E8
#define misc_CardBusForce 0x1EC
#define misc_SEEPCTL 0x1F0
/* Interrupts */
#define INT_DmaAT 1
#define INT_DmaAR (1<<1)
#define INT_DmaITA (1<<2)
#define INT_DmaITB (1<<3)
#define INT_DmaIRA (1<<4)
#define INT_DmaIRB (1<<5)
#define INT_PERResponse (1<<7)
#define INT_CycleEventITA (1<<8)
#define INT_CycleEventITB (1<<9)
#define INT_CycleEventIRA (1<<10)
#define INT_CycleEventIRB (1<<11)
#define INT_BusReset (1<<12)
#define INT_CmdReset (1<<13)
#define INT_PhyInt (1<<14)
#define INT_RcvData (1<<15)
#define INT_TxRdy (1<<16)
#define INT_CycleStart (1<<17)
#define INT_CycleSeconds (1<<18)
#define INT_CycleLost (1<<19)
#define INT_ATError (1<<20)
#define INT_SendRej (1<<21)
#define INT_HdrErr (1<<22)
#define INT_TCodeErr (1<<23)
#define INT_PRQUxferErr (1<<24)
#define INT_PWQUxferErr (1<<25)
#define INT_RSUxferErr (1<<26)
#define INT_RSDone (1<<27)
#define INT_PSOutOfRetries (1<<28)
#define INT_cycleTooLong (1<<29)
/* DB DMA constants */
#define DMA_CMD_OUTPUTMORE 0
#define DMA_CMD_OUTPUTLAST 0x10000000
#define DMA_CMD_INPUTMORE 0x20000000
#define DMA_CMD_INPUTLAST 0x30000000
#define DMA_CMD_STOREQUAD 0x40000000
#define DMA_CMD_LOADQUAD 0x50000000
#define DMA_CMD_NOP 0x60000000
#define DMA_CMD_STOP 0x70000000
#define DMA_KEY_STREAM0 0
#define DMA_KEY_STREAM1 (1<<24)
#define DMA_KEY_STREAM2 (2<<24)
#define DMA_KEY_STREAM3 (3<<24)
#define DMA_KEY_REGS (5<<24)
#define DMA_KEY_SYSTEM (6<<24)
#define DMA_KEY_DEVICE (7<<24)
#define DMA_INTR_NEVER 0
#define DMA_INTR_TRUE (1<<20)
#define DMA_INTR_FALSE (2<<20)
#define DMA_INTR_ALWAYS (3<<20)
#define DMA_WAIT_NEVER 0
#define DMA_WAIT_TRUE (1<<16)
#define DMA_WAIT_FALSE (2<<16)
#define DMA_WAIT_ALWAYS (3<<16)
#define DMA_BRANCH_NEVER 0
#define DMA_BRANCH_TRUE (1<<18)
#define DMA_BRANCH_FALSE (2<<18)
#define DMA_BRANCH_ALWAYS (3<<18)
#define DMA_SPEED_100 0
#define DMA_SPEED_200 (1<<16)
#define DMA_SPEED_400 (2<<16)
/* PHY access */
#define LINK_PHY_READ (1<<15)
#define LINK_PHY_WRITE (1<<14)
#define LINK_PHY_ADDR(addr) (addr<<8)
#define LINK_PHY_WDATA(data) (data)
#define LINK_PHY_RADDR(addr) (addr<<24)
quadlet_t aic5800_csr_rom[] = {
/* bus info block */
0x041ffb82, // length of bus info block, CRC
0x31333934, // 1394 designator
0xf005a000, // various capabilites
0x0000d189, // node_vendor_id, chip_id_hi
0x401010fc, // chip_id_lo
/* root directory */
0x00040e54, // length of root directory, CRC
0x030000d1, // module_vendor_id
0x0c008000, // various capabilities
0x8d000006, // offset of node unique id leaf
0xd1000001, // offset of unit directory
/* unit directory */
0x0003e60d, // length of unit directory, CRC
0x12000000, // unit_spec_id
0x13000000, // unit_sw_version
0xd4000004, // offset of unit dependent directory
/* node unique id leaf */
0x00026ba7, // length of leaf, CRC
0x0000d189, // node_vendor_id, chip_id_hi
0x401010fc, // chip_id_lo
/* unit dependent directory */
0x0002ae47, // length of directory, CRC
0x81000002, // offset of vendor name leaf
0x82000006, // offset of model name leaf
/* vendor name leaf */
0x000486a3, // length of leaf, CRC
0x00000000,
0x00000000,
0x41444150, // ADAP
0x54454300, // TEC
/* model name leaf */
0x0004f420, // length of leaf, CRC
0x00000000,
0x00000000,
0x4148412d, // AHA-
0x38393430 // 8940
};
#endif
This diff is collapsed.
#ifndef _IEEE1394_CSR_H
#define _IEEE1394_CSR_H
#define CSR_REGISTER_BASE 0xfffff0000000ULL
/* register offsets relative to CSR_REGISTER_BASE */
#define CSR_STATE_CLEAR 0x0
#define CSR_STATE_SET 0x4
#define CSR_NODE_IDS 0x8
#define CSR_RESET_START 0xc
#define CSR_SPLIT_TIMEOUT_HI 0x18
#define CSR_SPLIT_TIMEOUT_LO 0x1c
#define CSR_CYCLE_TIME 0x200
#define CSR_BUS_TIME 0x204
#define CSR_BUSY_TIMEOUT 0x210
#define CSR_BUS_MANAGER_ID 0x21c
#define CSR_BANDWIDTH_AVAILABLE 0x220
#define CSR_CHANNELS_AVAILABLE_HI 0x224
#define CSR_CHANNELS_AVAILABLE_LO 0x228
#define CSR_CONFIG_ROM 0x400
#define CSR_CONFIG_ROM_END 0x800
#define CSR_FCP_COMMAND 0xB00
#define CSR_FCP_RESPONSE 0xD00
#define CSR_FCP_END 0xF00
#define CSR_TOPOLOGY_MAP 0x1000
#define CSR_TOPOLOGY_MAP_END 0x1400
#define CSR_SPEED_MAP 0x2000
#define CSR_SPEED_MAP_END 0x3000
struct csr_control {
spinlock_t lock;
quadlet_t state;
quadlet_t node_ids;
quadlet_t split_timeout_hi, split_timeout_lo;
quadlet_t cycle_time;
quadlet_t bus_time;
quadlet_t bus_manager_id;
quadlet_t bandwidth_available;
quadlet_t channels_available_hi, channels_available_lo;
const quadlet_t *rom;
size_t rom_size;
quadlet_t topology_map[256];
quadlet_t speed_map[1024];
quadlet_t fcp_data[1024];
};
void init_csr(void);
#endif /* _IEEE1394_CSR_H */
This diff is collapsed.
#ifndef IEEE1394_HIGHLEVEL_H
#define IEEE1394_HIGHLEVEL_H
struct hpsb_highlevel {
struct list_head hl_list;
/* List of hpsb_address_serve. */
struct list_head addr_list;
const char *name;
struct hpsb_highlevel_ops *op;
};
struct hpsb_address_serve {
struct list_head as_list; /* global list */
struct list_head addr_list; /* hpsb_highlevel list */
struct hpsb_address_ops *op;
/* first address handled and first address behind, quadlet aligned */
u64 start, end;
};
/*
* The above structs are internal to highlevel driver handling. Only the
* following structures are of interest to actual highlevel drivers.
*/
struct hpsb_highlevel_ops {
/* Any of the following pointers can legally be NULL, except for
* iso_receive which can only be NULL when you don't request
* channels. */
/* New host initialized. Will also be called during
* hpsb_register_highlevel for all hosts already installed. */
void (*add_host) (struct hpsb_host *host);
/* Host about to be removed. Will also be called during
* hpsb_unregister_highlevel once for each host. */
void (*remove_host) (struct hpsb_host *host);
/* Host experienced bus reset with possible configuration changes. Note
* that this one may occur during interrupt/bottom half handling. You
* can not expect to be able to do stock hpsb_reads. */
void (*host_reset) (struct hpsb_host *host);
/* An isochronous packet was received. Channel contains the channel
* number for your convenience, it is also contained in the included
* packet header (first quadlet, CRCs are missing). You may get called
* for channel/host combinations you did not request. */
void (*iso_receive) (struct hpsb_host *host, int channel,
quadlet_t *data, unsigned int length);
};
struct hpsb_address_ops {
/*
* Null function pointers will make the respective operation complete
* with RCODE_TYPE_ERROR. Makes for easy to implement read-only
* registers (just leave everything but read NULL).
*
* All functions shall return appropriate IEEE 1394 rcodes.
*/
/* These functions have to implement block reads for themselves. */
int (*read) (struct hpsb_host *host, quadlet_t *buffer, u64 addr,
unsigned int length);
int (*write) (struct hpsb_host *host, quadlet_t *data, u64 addr,
unsigned int length);
/* Lock transactions: write results of ext_tcode operation into
* *store. */
int (*lock) (struct hpsb_host *host, quadlet_t *store, u64 addr,
quadlet_t data, quadlet_t arg, int ext_tcode);
int (*lock64) (struct hpsb_host *host, octlet_t *store, u64 addr,
octlet_t data, octlet_t arg, int ext_tcode);
};
void init_hpsb_highlevel(void);
void highlevel_add_host(struct hpsb_host *host);
void highlevel_remove_host(struct hpsb_host *host);
void highlevel_host_reset(struct hpsb_host *host);
int highlevel_read(struct hpsb_host *host, quadlet_t *buffer, u64 addr,
unsigned int length);
int highlevel_write(struct hpsb_host *host, quadlet_t *data, u64 addr,
unsigned int length);
int highlevel_lock(struct hpsb_host *host, quadlet_t *store, u64 addr,
quadlet_t data, quadlet_t arg, int ext_tcode);
int highlevel_lock64(struct hpsb_host *host, octlet_t *store, u64 addr,
octlet_t data, octlet_t arg, int ext_tcode);
void highlevel_iso_receive(struct hpsb_host *host, quadlet_t *data,
unsigned int length);
/*
* Register highlevel driver. The name pointer has to stay valid at all times
* because the string is not copied.
*/
struct hpsb_highlevel *hpsb_register_highlevel(const char *name,
struct hpsb_highlevel_ops *ops);
void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
/*
* Register handlers for host address spaces. Start and end are 48 bit pointers
* and have to be quadlet aligned (end points to the first address behind the
* handled addresses. This function can be called multiple times for a single
* hpsb_highlevel to implement sparse register sets. The requested region must
* not overlap any previously allocated region, otherwise registering will fail.
*
* It returns true for successful allocation. There is no unregister function,
* all address spaces are deallocated together with the hpsb_highlevel.
*/
int hpsb_register_addrspace(struct hpsb_highlevel *hl,
struct hpsb_address_ops *ops, u64 start, u64 end);
/*
* Enable or disable receving a certain isochronous channel through the
* iso_receive op.
*/
void hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel);
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel);
#endif /* IEEE1394_HIGHLEVEL_H */
/*
* IEEE 1394 for Linux
*
* Low level (host adapter) management.
*
* Copyright (C) 1999 Andreas E. Bombe
* Copyright (C) 1999 Emanuel Pirker
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
#include "ieee1394_types.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
static struct hpsb_host_template *templates = NULL;
spinlock_t templates_lock = SPIN_LOCK_UNLOCKED;
/*
* The following function is exported for module usage. It will
* be called from high-level drivers such as the raw driver.
*/
int hpsb_get_host_list(struct hpsb_host *list[], int list_size)
{
struct hpsb_host *host, **ptr;
struct hpsb_host_template *tmpl;
int count=0;
ptr = list;
for (tmpl = templates ; tmpl != NULL; tmpl = tmpl->next) {
for (host = tmpl->hosts; (host != NULL) && (count < list_size);
host = host->next) {
*ptr = host;
ptr++;
count++;
}
}
return count;
}
/*
* This function calls the add_host/remove_host hooks for every host currently
* registered. Init == TRUE means add_host.
*/
void hl_all_hosts(struct hpsb_highlevel *hl, int init)
{
struct hpsb_host_template *tmpl;
struct hpsb_host *host;
spin_lock(&templates_lock);
for (tmpl = templates; tmpl != NULL; tmpl = tmpl->next) {
for (host = tmpl->hosts; host != NULL; host = host->next) {
if (host->initialized) {
if (init) {
if (hl->op->add_host) {
hl->op->add_host(host);
}
} else {
if (hl->op->remove_host) {
hl->op->remove_host(host);
}
}
}
}
}
spin_unlock(&templates_lock);
}
int hpsb_inc_host_usage(struct hpsb_host *host)
{
struct hpsb_host_template *tmpl;
struct hpsb_host *h;
int retval = 0;
spin_lock(&templates_lock);
for (tmpl = templates; (tmpl != NULL) && !retval; tmpl = tmpl->next) {
for (h = tmpl->hosts; h != NULL; h = h->next) {
if (h == host) {
tmpl->devctl(h, MODIFY_USAGE, 1);
retval = 1;
break;
}
}
}
spin_unlock(&templates_lock);
return retval;
}
void hpsb_dec_host_usage(struct hpsb_host *host)
{
host->template->devctl(host, MODIFY_USAGE, 0);
}
/*
* The following function is exported for module usage. It will be called from
* the detect function of a adapter driver.
*/
struct hpsb_host *hpsb_get_host(struct hpsb_host_template *tmpl,
size_t hd_size)
{
struct hpsb_host *h;
h = vmalloc(sizeof(struct hpsb_host) + hd_size);
if (h == NULL) {
return NULL;
}
memset(h, 0, sizeof(struct hpsb_host) + hd_size);
h->tlabel_count = 64;
INIT_LIST_HEAD(&h->pending_packets);
spin_lock_init(&h->pending_pkt_lock);
spin_lock_init(&h->tlabel_lock);
init_waitqueue_head(&h->tlabel_wait);
h->timeout_tq.routine = (void (*)(void*))abort_timedouts;
h->timeout_tq.data = h;
h->topology_map = h->csr.topology_map + 3;
h->speed_map = h->csr.speed_map + 2;
h->template = tmpl;
if (hd_size) {
h->hostdata = &h->embedded_hostdata[0];
}
if (tmpl->hosts == NULL) {
tmpl->hosts = h;
} else {
struct hpsb_host *last = tmpl->hosts;
while (last->next != NULL) {
last = last->next;
}
last->next = h;
}
return h;
}
static void free_all_hosts(struct hpsb_host_template *tmpl)
{
struct hpsb_host *next, *host = tmpl->hosts;
while (host) {
next = host->next;
vfree(host);
host = next;
}
}
static void init_hosts(struct hpsb_host_template *tmpl)
{
int count;
struct hpsb_host *host;
count = tmpl->detect_hosts(tmpl);
for (host = tmpl->hosts; host != NULL; host = host->next) {
if (tmpl->initialize_host(host)) {
host->initialized = 1;
highlevel_add_host(host);
reset_host_bus(host);
//kernel_thread(hpsb_host_thread, host,
// CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
}
}
tmpl->number_of_hosts = count;
HPSB_INFO("detected %d %s adapter%c", count, tmpl->name,
(count != 1 ? 's' : ' '));
}
static void shutdown_hosts(struct hpsb_host_template *tmpl)
{
struct hpsb_host *host;
for (host = tmpl->hosts; host != NULL; host = host->next) {
if (host->initialized) {
host->initialized = 0;
abort_requests(host);
highlevel_remove_host(host);
tmpl->release_host(host);
while (test_bit(0, &host->timeout_tq.sync)) {
schedule();
}
}
}
free_all_hosts(tmpl);
tmpl->release_host(NULL);
tmpl->number_of_hosts = 0;
}
static int add_template(struct hpsb_host_template *new)
{
new->next = NULL;
new->hosts = NULL;
new->number_of_hosts = 0;
spin_lock(&templates_lock);
if (templates == NULL) {
templates = new;
} else {
struct hpsb_host_template *last = templates;
while (last->next != NULL) {
last = last->next;
}
last->next = new;
}
spin_unlock(&templates_lock);
return 0;
}
static int remove_template(struct hpsb_host_template *tmpl)
{
int retval = 0;
if (tmpl->number_of_hosts) {
HPSB_ERR("attempted to remove busy host template "
"of %s at address 0x%p", tmpl->name, tmpl);
return 1;
}
spin_lock(&templates_lock);
if (templates == tmpl) {
templates = tmpl->next;
} else {
struct hpsb_host_template *t;
t = templates;
while (t->next != tmpl && t->next != NULL) {
t = t->next;
}
if (t->next == NULL) {
HPSB_ERR("attempted to remove unregistered host template "
"of %s at address 0x%p", tmpl->name, tmpl);
retval = -1;
} else {
t->next = tmpl->next;
}
}
spin_unlock(&templates_lock);
inc_hpsb_generation();
return retval;
}
/*
* The following two functions are exported symbols for module usage.
*/
int hpsb_register_lowlevel(struct hpsb_host_template *tmpl)
{
add_template(tmpl);
HPSB_INFO("registered %s driver, initializing now", tmpl->name);
init_hosts(tmpl);
return 0;
}
void hpsb_unregister_lowlevel(struct hpsb_host_template *tmpl)
{
shutdown_hosts(tmpl);
if (remove_template(tmpl)) {
HPSB_PANIC("remove_template failed on %s", tmpl->name);
}
}
#ifndef MODULE
/*
* This is the init function for builtin lowlevel drivers. To add new drivers
* put their setup code (get and register template) here. Module only
* drivers don't need to touch this.
*/
#define SETUP_TEMPLATE(name, visname) \
do { \
extern struct hpsb_host_template *get_ ## name ## _template(void); \
t = get_ ## name ## _template(); \
\
if (t != NULL) { \
if(!hpsb_register_lowlevel(t)) { \
count++; \
} \
} else { \
HPSB_WARN(visname " driver returned no host template"); \
} \
} while (0)
void __init register_builtin_lowlevels()
{
struct hpsb_host_template *t;
int count = 0;
/* Touch t to avoid warning if no drivers are configured to
* be built directly into the kernel. */
t = NULL;
#ifdef CONFIG_IEEE1394_PCILYNX
SETUP_TEMPLATE(lynx, "Lynx");
#endif
#ifdef CONFIG_IEEE1394_AIC5800
SETUP_TEMPLATE(aic, "AIC-5800");
#endif
#ifdef CONFIG_IEEE1394_OHCI1394
SETUP_TEMPLATE(ohci, "OHCI-1394");
#endif
HPSB_INFO("%d host adapter%s initialized", count,
(count != 1 ? "s" : ""));
}
#undef SETUP_TEMPLATE
#endif /* !MODULE */
#ifndef _IEEE1394_HOSTS_H
#define _IEEE1394_HOSTS_H
#include <linux/wait.h>
#include <linux/tqueue.h>
#include "ieee1394_types.h"
#include "csr.h"
struct hpsb_packet;
struct hpsb_host {
/* private fields (hosts, do not use them) */
struct hpsb_host *next;
struct list_head pending_packets;
spinlock_t pending_pkt_lock;
struct tq_struct timeout_tq;
/* A bitmask where a set bit means that this tlabel is in use.
* FIXME - should be handled per node instead of per bus. */
u32 tlabel_pool[2];
int tlabel_count;
spinlock_t tlabel_lock;
wait_queue_head_t tlabel_wait;
int reset_retries;
quadlet_t *topology_map, *speed_map;
struct csr_control csr;
unsigned char iso_listen_count[64];
/* readonly fields for hosts */
struct hpsb_host_template *template;
int node_count; /* number of identified nodes on this bus */
int selfid_count; /* total number of SelfIDs received */
nodeid_t node_id; /* node ID of this host */
nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
nodeid_t busmgr_id; /* ID of this bus' bus manager */
unsigned initialized:1; /* initialized and usable */
unsigned in_bus_reset:1; /* in bus reset / SelfID stage */
unsigned attempt_root:1; /* attempt to become root during next reset */
/* this nodes' duties on the bus */
unsigned is_root:1;
unsigned is_cycmst:1;
unsigned is_irm:1;
unsigned is_busmgr:1;
/* fields readable and writeable by the hosts */
void *hostdata;
int embedded_hostdata[0];
};
enum devctl_cmd {
/* Host is requested to reset its bus and cancel all outstanding async
* requests. If arg == 1, it shall also attempt to become root on the
* bus. Return void. */
RESET_BUS,
/* Arg is void, return value is the hardware cycle counter value. */
GET_CYCLE_COUNTER,
/* Set the hardware cycle counter to the value in arg, return void.
* FIXME - setting is probably not required. */
SET_CYCLE_COUNTER,
/* Configure hardware for new bus ID in arg, return void. */
SET_BUS_ID,
/* If arg true, start sending cycle start packets, stop if arg == 0.
* Return void. */
ACT_CYCLE_MASTER,
/* Cancel all outstanding async requests without resetting the bus.
* Return void. */
CANCEL_REQUESTS,
/* Decrease module usage count if arg == 0, increase otherwise. Return
* void. */
MODIFY_USAGE,
/* Start or stop receiving isochronous channel in arg. Return void.
* This acts as an optimization hint, hosts are not required not to
* listen on unrequested channels. */
ISO_LISTEN_CHANNEL,
ISO_UNLISTEN_CHANNEL
};
struct hpsb_host_template {
struct hpsb_host_template *next;
struct hpsb_host *hosts;
int number_of_hosts;
/* fields above will be ignored and overwritten after registering */
/* This should be the name of the driver (single word) and must not be
* NULL. */
const char *name;
/* This function shall detect all available adapters of this type and
* call hpsb_get_host for each one. The initialize_host function will
* be called to actually set up these adapters. The number of detected
* adapters or zero if there are none must be returned.
*/
int (*detect_hosts) (struct hpsb_host_template *template);
/* After detecting and registering hosts, this function will be called
* for every registered host. It shall set up the host to be fully
* functional for bus operations and return 0 for failure.
*/
int (*initialize_host) (struct hpsb_host *host);
/* To unload modules, this function is provided. It shall free all
* resources this host is using (if host is not NULL) or free all
* resources globally allocated by the driver (if host is NULL).
*/
void (*release_host) (struct hpsb_host *host);
/* This function must store a pointer to the configuration ROM into the
* location referenced to by pointer and return the size of the ROM. It
* may not fail. If any allocation is required, it must be done
* earlier.
*/
size_t (*get_rom) (struct hpsb_host *host, const quadlet_t **pointer);
/* This function shall implement packet transmission based on
* packet->type. It shall CRC both parts of the packet (unless
* packet->type == raw) and do byte-swapping as necessary or instruct
* the hardware to do so. It can return immediately after the packet
* was queued for sending. After sending, hpsb_sent_packet() has to be
* called. Return 0 for failure.
* NOTE: The function must be callable in interrupt context.
*/
int (*transmit_packet) (struct hpsb_host *host,
struct hpsb_packet *packet);
/* This function requests miscellanous services from the driver, see
* above for command codes and expected actions. Return -1 for unknown
* command, though that should never happen.
*/
int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg);
};
/* mid level internal use */
void register_builtin_lowlevels(void);
/* high level internal use */
struct hpsb_highlevel;
void hl_all_hosts(struct hpsb_highlevel *hl, int init);
/*
* These functions are for lowlevel (host) driver use.
*/
int hpsb_register_lowlevel(struct hpsb_host_template *tmpl);
void hpsb_unregister_lowlevel(struct hpsb_host_template *tmpl);
/*
* Get a initialized host structure with hostdata_size bytes allocated in
* embedded_hostdata for free usage. Returns NULL for failure.
*/
struct hpsb_host *hpsb_get_host(struct hpsb_host_template *tmpl,
size_t hostdata_size);
/*
* Write pointers to all available hpsb_hosts into list.
* Return number of host adapters (i.e. elements in list).
*
* DEPRECATED - register with highlevel instead.
*/
int hpsb_get_host_list(struct hpsb_host *list[], int max_list_size);
/*
* Increase / decrease host usage counter. Increase function will return true
* only if successful (host still existed). Decrease function expects host to
* exist.
*/
int hpsb_inc_host_usage(struct hpsb_host *host);
void hpsb_dec_host_usage(struct hpsb_host *host);
#endif /* _IEEE1394_HOSTS_H */
/*
* Generic IEEE 1394 definitions
*/
#ifndef _IEEE1394_IEEE1394_H
#define _IEEE1394_IEEE1394_H
#define TCODE_WRITEQ 0x0
#define TCODE_WRITEB 0x1
#define TCODE_WRITE_RESPONSE 0x2
#define TCODE_READQ 0x4
#define TCODE_READB 0x5
#define TCODE_READQ_RESPONSE 0x6
#define TCODE_READB_RESPONSE 0x7
#define TCODE_CYCLE_START 0x8
#define TCODE_LOCK_REQUEST 0x9
#define TCODE_ISO_DATA 0xa
#define TCODE_LOCK_RESPONSE 0xb
#define RCODE_COMPLETE 0x0
#define RCODE_CONFLICT_ERROR 0x4
#define RCODE_DATA_ERROR 0x5
#define RCODE_TYPE_ERROR 0x6
#define RCODE_ADDRESS_ERROR 0x7
#define EXTCODE_MASK_SWAP 0x1
#define EXTCODE_COMPARE_SWAP 0x2
#define EXTCODE_FETCH_ADD 0x3
#define EXTCODE_LITTLE_ADD 0x4
#define EXTCODE_BOUNDED_ADD 0x5
#define EXTCODE_WRAP_ADD 0x6
#define ACK_COMPLETE 0x1
#define ACK_PENDING 0x2
#define ACK_BUSY_X 0x4
#define ACK_BUSY_A 0x5
#define ACK_BUSY_B 0x6
#define ACK_DATA_ERROR 0xd
#define ACK_TYPE_ERROR 0xe
/* Non-standard "ACK codes" for internal use */
#define ACKX_NONE -1
#define ACKX_SEND_ERROR -2
#define ACKX_ABORTED -3
#define ACKX_TIMEOUT -4
#define SPEED_100 0x0
#define SPEED_200 0x1
#define SPEED_400 0x2
#define SELFID_PWRCL_NO_POWER 0x0
#define SELFID_PWRCL_PROVIDE_15W 0x1
#define SELFID_PWRCL_PROVIDE_30W 0x2
#define SELFID_PWRCL_PROVIDE_45W 0x3
#define SELFID_PWRCL_USE_1W 0x4
#define SELFID_PWRCL_USE_3W 0x5
#define SELFID_PWRCL_USE_6W 0x6
#define SELFID_PWRCL_USE_10W 0x7
#define SELFID_PORT_CHILD 0x3
#define SELFID_PORT_PARENT 0x2
#define SELFID_PORT_NCONN 0x1
#define SELFID_PORT_NONE 0x0
#endif /* _IEEE1394_IEEE1394_H */
This diff is collapsed.
#ifndef _IEEE1394_CORE_H
#define _IEEE1394_CORE_H
#include <linux/tqueue.h>
#include <asm/semaphore.h>
#include "hosts.h"
struct hpsb_packet {
/* This struct is basically read-only for hosts with the exception of
* the data buffer contents and xnext - see below. */
struct list_head list;
/* This can be used for host driver internal linking. */
struct hpsb_packet *xnext;
nodeid_t node_id;
/* Async and Iso types should be clear, raw means send-as-is, do not
* CRC! Byte swapping shall still be done in this case. */
enum { async, iso, raw } __attribute__((packed)) type;
/* Okay, this is core internal and a no care for hosts.
* queued = queued for sending
* pending = sent, waiting for response
* complete = processing completed, successful or not
* incoming = incoming packet
*/
enum {
unused, queued, pending, complete, incoming
} __attribute__((packed)) state;
/* These are core internal. */
char tlabel;
char ack_code;
char tcode;
unsigned expect_response:1;
unsigned no_waiter:1;
/* Data big endianness flag - may vary from request to request. The
* header is always in machine byte order. */
unsigned data_be:1;
/* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */
unsigned speed_code:2;
/* --- 16 bytes (one cacheline) --- */
/* *header and *data are guaranteed to be 32-bit DMAable and may be
* overwritten to allow in-place byte swapping. Neither of these is
* CRCed (the sizes also don't include CRC), but contain space for at
* least one additional quadlet to allow in-place CRCing. The memory is
* also guaranteed to have physical mapping (virt_to_bus() is meaningful
* on these pointers).
* NOTE: The 32-bit DMA guarantee is currently not enforced.
* That's a Linux 2.3 issue.
*/
quadlet_t *header;
quadlet_t *data;
size_t header_size;
size_t data_size;
/* --- 32 bytes --- */
struct hpsb_host *host;
unsigned int generation;
/* Very core internal, don't care. */
struct semaphore state_change;
task_queue complete_tq;
/* Store jiffies for implementing bus timeouts. */
unsigned long sendtime;
};
void reset_host_bus(struct hpsb_host *host);
void abort_timedouts(struct hpsb_host *host);
void abort_requests(struct hpsb_host *host);
struct hpsb_packet *alloc_hpsb_packet(size_t data_size);
void free_hpsb_packet(struct hpsb_packet *packet);
/*
* Generation counter for the complete 1394 subsystem. Generation gets
* incremented on every change in the subsystem (e.g. bus reset).
*
* Use the functions, not the variable.
*/
#include <asm/atomic.h>
extern atomic_t hpsb_generation;
inline static unsigned int get_hpsb_generation(void)
{
return atomic_read(&hpsb_generation);
}
inline static void inc_hpsb_generation(void)
{
atomic_inc(&hpsb_generation);
}
/*
* Queue packet for transmitting, return 0 for failure.
*/
int hpsb_send_packet(struct hpsb_packet *packet);
/*
* The following functions are exported for host driver module usage. All of
* them are safe to use in interrupt contexts, although some are quite
* complicated so you may want to run them in bottom halves instead of calling
* them directly.
*/
/* Notify a bus reset to the core. */
void hpsb_bus_reset(struct hpsb_host *host);
/*
* Hand over received selfid packet to the core. Complement check (second
* quadlet is complement of first) is expected to be done and succesful.
*/
void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid);
/*
* Notify completion of SelfID stage to the core and report new physical ID
* and whether host is root now.
*/
void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot);
/*
* Notify core of sending a packet. Ackcode is the ack code returned for async
* transmits or ACKX_SEND_ERROR if the transmission failed completely; ACKX_NONE
* for other cases (internal errors that don't justify a panic). Safe to call
* from within a transmit packet routine.
*/
void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, int ackcode);
/*
* Hand over received packet to the core. The contents of data are expected to
* be the full packet but with the CRCs left out (data block follows header
* immediately) and in machine byte order. *data can be safely overwritten
* after this call.
*/
void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size);
#endif /* _IEEE1394_CORE_H */
/*
* IEEE 1394 for Linux
*
* Exported symbols for module usage.
*
* Copyright (C) 1999 Andreas E. Bombe
*/
#include <linux/types.h>
#include <linux/module.h>
#include "ieee1394_types.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "ieee1394_transactions.h"
/* #include "events.h" */
#include "highlevel.h"
EXPORT_SYMBOL(hpsb_register_lowlevel);
EXPORT_SYMBOL(hpsb_unregister_lowlevel);
EXPORT_SYMBOL(hpsb_get_host);
EXPORT_SYMBOL(hpsb_get_host_list);
EXPORT_SYMBOL(hpsb_inc_host_usage);
EXPORT_SYMBOL(hpsb_dec_host_usage);
EXPORT_SYMBOL(alloc_hpsb_packet);
EXPORT_SYMBOL(free_hpsb_packet);
EXPORT_SYMBOL(hpsb_send_packet);
EXPORT_SYMBOL(hpsb_bus_reset);
EXPORT_SYMBOL(hpsb_selfid_received);
EXPORT_SYMBOL(hpsb_selfid_complete);
EXPORT_SYMBOL(hpsb_packet_sent);
EXPORT_SYMBOL(hpsb_packet_received);
EXPORT_SYMBOL(hpsb_generation);
EXPORT_SYMBOL(get_tlabel);
EXPORT_SYMBOL(free_tlabel);
EXPORT_SYMBOL(hpsb_make_readqpacket);
EXPORT_SYMBOL(hpsb_make_readbpacket);
EXPORT_SYMBOL(hpsb_make_writeqpacket);
EXPORT_SYMBOL(hpsb_make_writebpacket);
EXPORT_SYMBOL(hpsb_read);
EXPORT_SYMBOL(hpsb_write);
EXPORT_SYMBOL(hpsb_lock);
EXPORT_SYMBOL(hpsb_register_highlevel);
EXPORT_SYMBOL(hpsb_unregister_highlevel);
EXPORT_SYMBOL(hpsb_register_addrspace);
EXPORT_SYMBOL(hpsb_listen_channel);
EXPORT_SYMBOL(hpsb_unlisten_channel);
EXPORT_SYMBOL(highlevel_read);
EXPORT_SYMBOL(highlevel_write);
EXPORT_SYMBOL(highlevel_lock);
EXPORT_SYMBOL(highlevel_lock64);
/*
EXPORT_SYMBOL(hpsb_dispatch_event);
EXPORT_SYMBOL(hpsb_reg_event_handler);
*/
This diff is collapsed.
#ifndef _IEEE1394_TRANSACTIONS_H
#define _IEEE1394_TRANSACTIONS_H
#include "ieee1394_core.h"
/*
* Utility functions to fill out packet headers.
*/
void fill_async_readquad(struct hpsb_packet *packet, u64 addr);
void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode,
quadlet_t data);
void fill_async_readblock(struct hpsb_packet *packet, u64 addr, int length);
void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode,
int length);
void fill_async_writequad(struct hpsb_packet *packet, u64 addr, quadlet_t data);
void fill_async_writeblock(struct hpsb_packet *packet, u64 addr, int length);
void fill_async_write_resp(struct hpsb_packet *packet, int rcode);
void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode,
int length);
void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode,
int length);
void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
int tag, int sync);
/*
* Get and free transaction labels.
*/
int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait);
void free_tlabel(struct hpsb_host *host, nodeid_t nodeid, int tlabel);
struct hpsb_packet *hpsb_make_readqpacket(struct hpsb_host *host, nodeid_t node,
u64 addr);
struct hpsb_packet *hpsb_make_readbpacket(struct hpsb_host *host, nodeid_t node,
u64 addr, size_t length);
struct hpsb_packet *hpsb_make_writeqpacket(struct hpsb_host *host,
nodeid_t node, u64 addr,
quadlet_t data);
struct hpsb_packet *hpsb_make_writebpacket(struct hpsb_host *host,
nodeid_t node, u64 addr,
size_t length);
/*
* hpsb_packet_success - Make sense of the ack and reply codes and
* return more convenient error codes:
* 0 success
* -EBUSY node is busy, try again
* -EAGAIN error which can probably resolved by retry
* -EREMOTEIO node suffers from an internal error
* -EACCES this transaction is not allowed on requested address
* -EINVAL invalid address at node
*/
int hpsb_packet_success(struct hpsb_packet *packet);
/*
* The generic read, write and lock functions. All recognize the local node ID
* and act accordingly. Read and write automatically use quadlet commands if
* length == 4 and and block commands otherwise (however, they do not yet
* support lengths that are not a multiple of 4).
*/
int hpsb_read(struct hpsb_host *host, nodeid_t node, u64 addr,
quadlet_t *buffer, size_t length);
int hpsb_write(struct hpsb_host *host, nodeid_t node, u64 addr,
quadlet_t *buffer, size_t length);
int hpsb_lock(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode,
quadlet_t *data, quadlet_t arg);
#endif /* _IEEE1394_TRANSACTIONS_H */
#ifndef _IEEE1394_TYPES_H
#define _IEEE1394_TYPES_H
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/list.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
#define DECLARE_WAITQUEUE(name, task) struct wait_queue name = { task, NULL }
typedef struct wait_queue *wait_queue_head_t;
inline static void init_waitqueue_head(wait_queue_head_t *wh)
{
*wh = NULL;
}
static __inline__ void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
#include <asm/spinlock.h>
#else
#include <linux/spinlock.h>
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
typedef __u32 quadlet_t;
typedef __u64 octlet_t;
typedef __u16 nodeid_t;
#define BUS_MASK 0xffc0
#define NODE_MASK 0x003f
#define LOCAL_BUS 0xffc0
#define ALL_NODES 0x003f
#define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args)
#define HPSB_DEBUG(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
#define HPSB_INFO(fmt, args...) HPSB_PRINT(KERN_INFO, fmt , ## args)
#define HPSB_NOTICE(fmt, args...) HPSB_PRINT(KERN_NOTICE, fmt , ## args)
#define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args)
#define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args)
#define HPSB_PANIC(fmt, args...) panic("ieee1394: " fmt "\n" , ## args)
#define HPSB_TRACE() HPSB_PRINT(KERN_INFO, "TRACE - %s, %s(), line %d", __FILE__, __FUNCTION__, __LINE__)
#ifdef __BIG_ENDIAN
static __inline__ void *memcpy_le32(u32 *dest, const u32 *src, size_t count)
{
void *tmp = dest;
count /= 4;
while (count--) {
*dest++ = swab32p(src++);
}
return tmp;
}
#else
static __inline__ void *memcpy_le32(u32 *dest, const u32 *src, size_t count)
{
return memcpy(dest, src, count);
}
#endif /* __BIG_ENDIAN */
#endif /* _IEEE1394_TYPES_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef IEEE1394_RAW1394_H
#define IEEE1394_RAW1394_H
#define RAW1394_DEVICE_MAJOR 171
#define RAW1394_DEVICE_NAME "raw1394"
#define RAW1394_KERNELAPI_VERSION 1
/* state: opened */
#define RAW1394_REQ_INITIALIZE 1
/* state: initialized */
#define RAW1394_REQ_LIST_CARDS 2
#define RAW1394_REQ_SET_CARD 3
/* state: connected */
#define RAW1394_REQ_ASYNC_READ 100
#define RAW1394_REQ_ASYNC_WRITE 101
#define RAW1394_REQ_LOCK 102
#define RAW1394_REQ_LOCK64 103
#define RAW1394_REQ_ISO_LISTEN 200
/* kernel to user */
#define RAW1394_REQ_BUS_RESET 10000
#define RAW1394_REQ_ISO_RECEIVE 10001
/* error codes */
#define RAW1394_ERROR_NONE 0
#define RAW1394_ERROR_COMPAT (-1001)
#define RAW1394_ERROR_STATE_ORDER (-1002)
#define RAW1394_ERROR_GENERATION (-1003)
#define RAW1394_ERROR_INVALID_ARG (-1004)
#define RAW1394_ERROR_MEMFAULT (-1005)
#define RAW1394_ERROR_ALREADY (-1006)
#define RAW1394_ERROR_EXCESSIVE (-1020)
#define RAW1394_ERROR_UNTIDY_LEN (-1021)
#define RAW1394_ERROR_SEND_ERROR (-1100)
#define RAW1394_ERROR_ABORTED (-1101)
#define RAW1394_ERROR_TIMEOUT (-1102)
struct raw1394_request {
int type;
int error;
int misc;
unsigned int generation;
octlet_t address;
unsigned long tag;
size_t length;
quadlet_t *sendb;
quadlet_t *recvb;
};
struct raw1394_khost_list {
int nodes;
char name[32];
};
#ifdef __KERNEL__
struct iso_block_store {
atomic_t refcount;
quadlet_t data[0];
};
struct file_info {
struct list_head list;
enum { opened, initialized, connected } state;
struct hpsb_host *host;
struct list_head req_pending;
struct list_head req_complete;
struct semaphore complete_sem;
spinlock_t reqlists_lock;
wait_queue_head_t poll_wait_complete;
u64 listen_channels;
quadlet_t *iso_buffer;
size_t iso_buffer_length;
};
struct pending_request {
struct list_head list;
struct file_info *file_info;
struct hpsb_packet *packet;
struct tq_struct tq;
struct iso_block_store *ibs;
quadlet_t *data;
int free_data;
struct raw1394_request req;
};
struct host_info {
struct list_head list;
struct hpsb_host *host;
struct list_head file_info_list;
};
#endif /* __KERNEL__ */
#endif /* IEEE1394_RAW1394_H */
......@@ -34,6 +34,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
tristate ' MACE (Power Mac ethernet) support' CONFIG_MACE
tristate ' BMAC (G3 ethernet) support' CONFIG_BMAC
tristate ' Symbios 53c885 (Synergy ethernet) support' CONFIG_NCR885E
tristate ' National DP83902AV (Oak ethernet) support' CONFIG_OAKNET
fi
if [ "$CONFIG_ZORRO" = "y" ]; then
tristate ' Ariadne support' CONFIG_ARIADNE
......
......@@ -250,6 +250,7 @@ obj-$(CONFIG_MACSONIC) += macsonic.o
obj-$(CONFIG_BMAC) += bmac.o
obj-$(CONFIG_NCR885E) += ncr885e.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
obj-$(CONFIG_OAKNET) += oaknet.o 8390.o
#
# HIPPI adapters
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -30,6 +30,7 @@
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/locks.h>
......
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