## Automatically generated incremental diff ## From: linux-2.4.23-bk3 ## To: linux-2.4.23-bk4 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.4.23-bk3/Documentation/Changes linux-2.4.23-bk4/Documentation/Changes --- linux-2.4.23-bk3/Documentation/Changes 2002-11-28 15:53:08.000000000 -0800 +++ linux-2.4.23-bk4/Documentation/Changes 2003-12-06 02:49:48.000000000 -0800 @@ -57,6 +57,7 @@ o jfsutils 1.0.12 # fsck.jfs -V o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs o pcmcia-cs 3.1.21 # cardmgr -V +o quota-tools 3.09 # quota -V o PPP 2.4.0 # pppd --version o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version @@ -197,6 +198,14 @@ kernel source. Pay attention when you recompile your kernel ;-). Also, be sure to upgrade to the latest pcmcia-cs release. +Quota-tools +----------- + +Support for 32 bit uid's and gid's is required if you want to use +the newer version 2 quota format. Quota-tools version 3.07 and +newer has this support. Use the recommended version or newer +from the table above. + Intel IA32 microcode -------------------- @@ -335,6 +344,10 @@ --------- o +Quota-tools +---------- +o + Jade ---- o diff -urN linux-2.4.23-bk3/Makefile linux-2.4.23-bk4/Makefile --- linux-2.4.23-bk3/Makefile 2003-12-06 02:49:45.000000000 -0800 +++ linux-2.4.23-bk4/Makefile 2003-12-06 02:49:48.000000000 -0800 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 23 -EXTRAVERSION = -bk3 +EXTRAVERSION = -bk4 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -urN linux-2.4.23-bk3/arch/cris/drivers/Config.in linux-2.4.23-bk4/arch/cris/drivers/Config.in --- linux-2.4.23-bk3/arch/cris/drivers/Config.in 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/drivers/Config.in 2003-12-06 02:49:48.000000000 -0800 @@ -11,7 +11,10 @@ "LED_on_when_link CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK \ LED_on_when_activity CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY" \ LED_on_when_activity - + choice 'Network LED behavior on no connection' \ + "RED_LED_on_no_connection CONFIG_ETRAX_NETWORK_RED_ON_NO_CONNECTION \ + LED_OFF_on_no_connection CONFIG_ETRAX_NETWORK_OFF_ON_NO_CONNECTION" \ + LED_OFF_on_no_connection else define_bool CONFIG_NET_ETHERNET n fi @@ -32,12 +35,18 @@ fi bool ' Enable external clock on PB6' CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED if [ "$CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED" = "y" ]; then - int ' Extern clock frequency (baudrate=clk/8) (Hz)' CONFIG_ETRAX_EXTERN_PB6CLK_FREQ + int ' Extern clock frequency (baudrate=clk/8) (Hz)' CONFIG_ETRAX_EXTERN_PB6CLK_FREQ 0 fi bool ' Serial port 0 enabled' CONFIG_ETRAX_SERIAL_PORT0 if [ "$CONFIG_ETRAX_SERIAL_PORT0" = "y" ]; then - bool ' Serial port 0 uses DMA6 out' CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT - bool ' Serial port 0 uses DMA7 in' CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN + choice 'Ser0 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT \ + DMA6_OUT CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT" \ + DMA6_OUT + choice 'Ser0 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN \ + DMA7_IN CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN" \ + DMA7_IN choice 'Ser0 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA \ @@ -73,8 +82,14 @@ bool ' Serial port 1 enabled' CONFIG_ETRAX_SERIAL_PORT1 if [ "$CONFIG_ETRAX_SERIAL_PORT1" = "y" ]; then - bool ' Serial port 1 uses DMA8 out' CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT - bool ' Serial port 1 uses DMA9 in' CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN + choice 'Ser1 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_OUT \ + DMA8_OUT CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT" \ + DMA8_OUT + choice 'Ser1 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_IN \ + DMA9_IN CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN" \ + DMA9_IN choice 'Ser1 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PA \ @@ -114,8 +129,14 @@ fi bool ' Serial port 2 enabled' CONFIG_ETRAX_SERIAL_PORT2 if [ "$CONFIG_ETRAX_SERIAL_PORT2" = "y" ]; then - bool ' Serial port 2 uses DMA2 out' CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT - bool ' Serial port 2 uses DMA3 in' CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN + choice 'Ser2 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT \ + DMA2_OUT CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT" \ + DMA2_OUT + choice 'Ser2 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN \ + DMA3_IN CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN" \ + DMA3_IN choice 'Ser2 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA \ @@ -149,8 +170,14 @@ fi bool ' Serial port 3 enabled' CONFIG_ETRAX_SERIAL_PORT3 if [ "$CONFIG_ETRAX_SERIAL_PORT3" = "y" ]; then - bool ' Serial port 3 uses DMA4 out' CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT - bool ' Serial port 3 uses DMA5 in' CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN + choice 'Ser3 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT \ + DMA4_OUT CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT" \ + DMA4_OUT + choice 'Ser3 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN \ + DMA5_IN CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN" \ + DMA5_IN choice 'Ser3 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PA \ @@ -194,13 +221,13 @@ bool 'Synchronous serial port support' CONFIG_ETRAX_SYNCHRONOUS_SERIAL if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL" = "y" ]; then - bool ' Synchronous serial port 0 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0 + bool ' Synchronous serial port 0 enabled (sser1)' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0 if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0" = "y" ]; then - bool ' Synchronous serial port 0 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA + bool ' Synchronous serial port 0 uses DMA 8,9' CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA fi - bool ' Synchronous serial port 1 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1 + bool ' Synchronous serial port 1 enabled (sser3)' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1 if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1" = "y" ]; then - bool ' Synchronous serial port 1 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA + bool ' Synchronous serial port 1 uses DMA 4,5' CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA fi fi @@ -253,17 +280,28 @@ # here we define the CONFIG_'s necessary to enable MTD support # for the flash define_bool CONFIG_MTD y - - define_bool CONFIG_MTD_CFI y - define_bool CONFIG_MTD_CFI_AMDSTD y - - define_bool CONFIG_MTD_OBSOLETE_CHIPS y - define_bool CONFIG_MTD_AMDSTD y - + define_bool CONFIG_MTD_PARTITIONS y define_bool CONFIG_MTD_CHAR y define_bool CONFIG_MTD_BLOCK y - define_bool CONFIG_MTD_PARTITIONS y - define_bool CONFIG_MTD_CONCAT y + + if [ "$CONFIG_MTD_CFI" = "n" ] && [ "$CONFIG_MTD_AMDSTD" = "n" ] && \ + [ "$CONFIG_MTD_MTDRAM" = "n" ]; then + # Bad initial configuration, make axisflashmap work by enabling + # all drivers it may need. + + define_bool CONFIG_MTD_CFI y + define_bool CONFIG_MTD_CFI_AMDSTD y + + define_bool CONFIG_MTD_OBSOLETE_CHIPS y + define_bool CONFIG_MTD_AMDSTD y + + define_bool CONFIG_MTD_CONCAT y + + define_bool CONFIG_MTD_MTDRAM y + define_int CONFIG_MTDRAM_TOTAL_SIZE 0 + define_int CONFIG_MTDRAM_ERASE_SIZE 64 + define_int CONFIG_MTDRAM_ABS_POS 0 + fi fi bool 'I2C support' CONFIG_ETRAX_I2C diff -urN linux-2.4.23-bk3/arch/cris/drivers/Makefile linux-2.4.23-bk4/arch/cris/drivers/Makefile --- linux-2.4.23-bk3/arch/cris/drivers/Makefile 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/drivers/Makefile 2003-12-06 02:49:48.000000000 -0800 @@ -4,6 +4,8 @@ O_TARGET := drivers.o +export-objs := axisflashmap.o + obj-y := obj-$(CONFIG_ETRAX_VIRTEX_FPGA) += virtex.o diff -urN linux-2.4.23-bk3/arch/cris/drivers/axisflashmap.c linux-2.4.23-bk4/arch/cris/drivers/axisflashmap.c --- linux-2.4.23-bk3/arch/cris/drivers/axisflashmap.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/drivers/axisflashmap.c 2003-12-06 02:49:48.000000000 -0800 @@ -11,6 +11,12 @@ * partition split defined below. * * $Log: axisflashmap.c,v $ + * Revision 1.31 2003/11/14 16:55:27 jonashg + * Made it possible to RAM boot without any flash drivers present. + * + * Revision 1.30 2003/09/29 06:37:18 mikaelp + * Exported master mtd device as axisflash_mtd. + * * Revision 1.29 2003/04/01 14:12:06 starvik * Added loglevel for lots of printks * @@ -142,6 +148,9 @@ /* From head.S */ extern unsigned long romfs_start, romfs_length, romfs_in_flash; +/* The master mtd for the entire flash. */ +struct mtd_info* axisflash_mtd = NULL; + /* Map driver functions. */ static __u8 flash_read8(struct map_info *map, unsigned long ofs) @@ -388,7 +397,7 @@ struct mtd_info *mymtd; int err = 0; int pidx = 0; - struct partitiontable_head *ptable_head; + struct partitiontable_head *ptable_head = NULL; struct partitiontable_entry *ptable; int use_default_ptable = 1; /* Until proven otherwise. */ const char *pmsg = KERN_INFO " /dev/flash%d at 0x%08x, size 0x%08x\n"; @@ -397,19 +406,22 @@ /* There's no reason to use this module if no flash chip can * be identified. Make sure that's understood. */ - panic("axisflashmap found no flash chip!\n"); + printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); + } else { + printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", + mymtd->name, mymtd->size); + axisflash_mtd = mymtd; } - printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", - mymtd->name, mymtd->size); - - mymtd->module = THIS_MODULE; - - ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + - CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET); + if (mymtd) { + mymtd->module = THIS_MODULE; + ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + + CONFIG_ETRAX_PTABLE_SECTOR + + PARTITION_TABLE_OFFSET); + } pidx++; /* First partition is always set to the default. */ - if ((ptable_head->magic == PARTITION_TABLE_MAGIC) + if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) && (ptable_head->size < (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + PARTITIONTABLE_END_MARKER_SIZE)) @@ -476,22 +488,25 @@ axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; - printk(KERN_INFO " Adding readonly flash partition for romfs image:\n"); + printk(KERN_INFO + " Adding readonly flash partition for romfs image:\n"); printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; } - if (use_default_ptable) { - printk(KERN_INFO " Using default partition table.\n"); - err = add_mtd_partitions(mymtd, axis_default_partitions, - NUM_DEFAULT_PARTITIONS); - } else { - err = add_mtd_partitions(mymtd, axis_partitions, pidx); - } + if (mymtd) { + if (use_default_ptable) { + printk(KERN_INFO " Using default partition table.\n"); + err = add_mtd_partitions(mymtd, axis_default_partitions, + NUM_DEFAULT_PARTITIONS); + } else { + err = add_mtd_partitions(mymtd, axis_partitions, pidx); + } - if (err) { - panic("axisflashmap could not add MTD partitions!\n"); + if (err) { + panic("axisflashmap could not add MTD partitions!\n"); + } } if (!romfs_in_flash) { @@ -529,3 +544,5 @@ /* This adds the above to the kernels init-call chain. */ module_init(init_axis_flash); + +EXPORT_SYMBOL(axisflash_mtd); diff -urN linux-2.4.23-bk3/arch/cris/drivers/ethernet.c linux-2.4.23-bk4/arch/cris/drivers/ethernet.c --- linux-2.4.23-bk3/arch/cris/drivers/ethernet.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/drivers/ethernet.c 2003-12-06 02:49:48.000000000 -0800 @@ -1,4 +1,4 @@ -/* $Id: ethernet.c,v 1.44 2003/07/01 10:55:07 starvik Exp $ +/* $Id: ethernet.c,v 1.48 2003/12/03 13:44:39 starvik Exp $ * * e100net.c: A network driver for the ETRAX 100LX network controller. * @@ -7,6 +7,19 @@ * The outline of this driver comes from skeleton.c. * * $Log: ethernet.c,v $ + * Revision 1.48 2003/12/03 13:44:39 starvik + * Use hardware pad for short packets. This prevents information leakage + * reported by Nessus. + * + * Revision 1.47 2003/11/25 15:12:38 anderstj + * Make sure the LED always is inititated. + * + * Revision 1.46 2003/08/28 14:35:29 jonasw + * Added support for TDK 2120C and fixed led when not connected + * + * Revision 1.45 2003/08/21 07:22:25 matsfg + * Optional behaviour on networkled when no connection. + * * Revision 1.44 2003/07/01 10:55:07 starvik * Never bring down link to make stupid POE equipment happy * @@ -430,7 +443,8 @@ struct transceiver_ops transceivers[] = { {0x1018, broadcom_check_speed, broadcom_check_duplex}, /* Broadcom */ - {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK */ + {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK 2120 */ + {0x039C, tdk_check_speed, tdk_check_duplex}, /* TDK 2120C */ {0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */ }; @@ -800,6 +814,7 @@ static void e100_check_speed(unsigned long dummy) { + static int led_initiated = 0; unsigned long data; int old_speed = current_speed; @@ -810,8 +825,10 @@ transceiver->check_speed(); } - if (old_speed != current_speed) + if ((old_speed != current_speed) || !led_initiated) { + led_initiated = 1; e100_set_network_leds(NO_NETWORK_ACTIVITY); + } /* Reinitialize the timer. */ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; @@ -957,6 +974,7 @@ break; } transceiver = ops; + return 0; } @@ -1121,7 +1139,6 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *np = (struct net_local *)dev->priv; - int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; #ifdef ETHDEBUG @@ -1133,7 +1150,7 @@ dev->trans_start = jiffies; - e100_hardware_send_packet(buf, length); + e100_hardware_send_packet(buf, skb->len); myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next); @@ -1494,7 +1511,7 @@ struct ethtool_drvinfo info; memset((void *) &info, 0, sizeof (info)); strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1); - strncpy(info.version, "$Revision: 1.44 $", sizeof(info.version) - 1); + strncpy(info.version, "$Revision: 1.48 $", sizeof(info.version) - 1); strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1); strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1); info.regdump_len = 0; @@ -1692,7 +1709,11 @@ if (!current_speed) { /* Make LED red, link is down */ +#if defined(CONFIG_ETRAX_NETWORK_RED_ON_NO_CONNECTION) + LED_NETWORK_SET(LED_RED); +#else LED_NETWORK_SET(LED_OFF); +#endif } else if (light_leds) { if (current_speed == 10) { diff -urN linux-2.4.23-bk3/arch/cris/drivers/serial.c linux-2.4.23-bk4/arch/cris/drivers/serial.c --- linux-2.4.23-bk3/arch/cris/drivers/serial.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/drivers/serial.c 2003-12-06 02:49:48.000000000 -0800 @@ -1,4 +1,4 @@ -/* $Id: serial.c,v 1.54 2003/07/08 12:42:19 johana Exp $ +/* $Id: serial.c,v 1.58 2003/08/29 17:32:50 johana Exp $ * * Serial port driver for the ETRAX 100LX chip * @@ -7,6 +7,24 @@ * Many, many authors. Based once upon a time on serial.c for 16x50. * * $Log: serial.c,v $ + * Revision 1.58 2003/08/29 17:32:50 johana + * Fixed CMSPAR (Mark/Space) support. CMSPAR|PARODD = Mark(1) parity. + * + * Revision 1.57 2003/08/26 16:53:06 johana + * Merged in change_branch--johana to get non DMA support etc. + * + * Revision 1.56 2003/07/10 13:18:03 pkj + * Corrected a copy-paste error. + * + * Revision 1.55 2003/07/10 11:00:46 starvik + * Moved all the latest stuff to a branch until it is stable + * + * Revision 1.50.2.2 2003/07/28 09:59:39 johana + * Clear tr_running so next write really starts transmission. + * + * Revision 1.50.2.1 2003/07/10 10:59:54 starvik + * Moved all the latest stuff to a branch until it is stable + * * Revision 1.54 2003/07/08 12:42:19 johana * Removed some test defines within #if 0. * Moved a comment to correct place. @@ -437,7 +455,7 @@ * */ -static char *serial_version = "$Revision: 1.54 $"; +static char *serial_version = "$Revision: 1.58 $"; #include #include @@ -3164,6 +3182,7 @@ info->last_tx_active_usec = GET_JIFFIES_USEC(); info->last_tx_active = jiffies; e100_disable_serial_tx_ready_irq(info); + info->tr_running = 0; DFLOW(DEBUG_LOG(info->line, "tx_int: stop2\n", 0)); } else { /* We must enable since it is disabled in ser_interrupt */ @@ -3657,20 +3676,14 @@ } if (cflag & CMSPAR) { - /* enable stick parity */ + /* enable stick parity, PARODD mean Mark which matches ETRAX */ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, stick); info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, stick); - if (!(cflag & PARODD)) { - /* set mark parity */ - info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); - info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); - } - } else { - if (cflag & PARODD) { - /* set odd parity */ - info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); - info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); - } + } + if (cflag & PARODD) { + /* set odd parity (or Mark if CMSPAR) */ + info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); + info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); } if (cflag & CRTSCTS) { diff -urN linux-2.4.23-bk3/arch/cris/drivers/sync_serial.c linux-2.4.23-bk4/arch/cris/drivers/sync_serial.c --- linux-2.4.23-bk3/arch/cris/drivers/sync_serial.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/drivers/sync_serial.c 2003-12-06 02:49:48.000000000 -0800 @@ -6,9 +6,9 @@ * decoder. The driver can easily be tuned to fit other audio encoder/decoders * and SPI * - * Copyright (c) 2001 Axis Communications AB + * Copyright (c) 2001-2003 Axis Communications AB * - * Author: Mikael Starvik + * Author: Mikael Starvik, Johan Adolfsson * */ #include @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -31,25 +32,26 @@ /* The receiver is a bit tricky beacuse of the continuous stream of data.*/ /* */ -/* Two DMA descriptors are linked together. Each DMA descriptor is */ -/* responsible for one half of a common buffer. */ +/* Three DMA descriptors are linked together. Each DMA descriptor is */ +/* responsible for port->bufchunk of a common buffer. */ /* */ -/* ------------------------------ */ -/* | ---------- ---------- | */ -/* --> | Descr1 |-->| Descr2 |--- */ -/* ---------- ---------- */ -/* | | */ -/* v v */ -/* ----------------------------- */ -/* | BUFFER | */ -/* ----------------------------- */ -/* | | */ +/* +---------------------------------------------+ */ +/* | +----------+ +----------+ +----------+ | */ +/* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+ */ +/* +----------+ +----------+ +----------+ */ +/* | | | */ +/* v v v */ +/* +-------------------------------------+ */ +/* | BUFFER | */ +/* +-------------------------------------+ */ +/* |<- data_avail ->| */ /* readp writep */ /* */ /* If the application keeps up the pace readp will be right after writep.*/ /* If the application can't keep the pace we have to throw away data. */ /* The idea is that readp should be ready with the data pointed out by */ -/* Descr1 when the DMA has filled in Descr2. Otherwise we will discard */ +/* Descr[i] when the DMA has filled in Descr[i+1]. */ +/* Otherwise we will discard */ /* the rest of the data pointed out by Descr1 and set readp to the start */ /* of Descr2 */ @@ -57,14 +59,22 @@ /* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */ /* words can be handled */ - +#define NUM_IN_DESCR 3 #define IN_BUFFER_SIZE 12288 #define OUT_BUFFER_SIZE 4096 #define DEFAULT_FRAME_RATE 0 #define DEFAULT_WORD_RATE 7 +/* NOTE: Enabling some debug will likely cause overrun or underrun, + * especially if manual mode is use. + */ #define DEBUG(x) +#define DEBUGREAD(x) +#define DEBUGWRITE(x) +#define DEBUGPOLL(x) +#define DEBUGRXINT(x) +#define DEBUGTXINT(x) /* Define some macros to access ETRAX 100 registers */ #define SETF(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \ @@ -75,97 +85,126 @@ typedef struct sync_port { /* Etrax registers and bits*/ - volatile unsigned * const status; + const volatile unsigned * const status; volatile unsigned * const ctrl_data; volatile unsigned * const output_dma_first; volatile unsigned char * const output_dma_cmd; volatile unsigned char * const output_dma_clr_irq; volatile unsigned * const input_dma_first; volatile unsigned char * const input_dma_cmd; + volatile unsigned * const input_dma_descr; + /* 8*4 */ volatile unsigned char * const input_dma_clr_irq; volatile unsigned * const data_out; - volatile unsigned * const data_in; - char data_avail_bit; /* In R_IRQ_MASK1_RD */ - char transmitter_ready_bit; /* In R_IRQ_MASK1_RD */ - char ready_irq_bit; /* In R_IRQ_MASK1_SET and R_IRQ_MASK1_CLR */ + const volatile unsigned * const data_in; + char data_avail_bit; /* In R_IRQ_MASK1_RD/SET/CLR */ + char transmitter_ready_bit; /* In R_IRQ_MASK1_RD/SET/CLR */ char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */ - char output_dma_bit; /* In R_IRQ_MASK2_RD */ - int enabled; /* 1 if port is enabled */ - int use_dma; /* 1 if port uses dma */ - int port_nbr; /* Port 0 or 1 */ - unsigned ctrl_data_shadow; /* Register shadow */ + char output_dma_bit; /* In R_IRQ_MASK2_RD */ + /* End of fields initialised in array */ + char started; /* 1 if port has been started */ + char port_nbr; /* Port 0 or 1 */ char busy; /* 1 if port is busy */ - wait_queue_head_t out_wait_q; - wait_queue_head_t in_wait_q; + + char enabled; /* 1 if port is enabled */ + char use_dma; /* 1 if port uses dma */ + char cur_in_descr; + char tr_running; + + unsigned int ctrl_data_shadow; /* Register shadow */ + volatile unsigned int out_count; /* Remaining bytes for current transfer */ + unsigned char* outp; /* Current position in out_buffer */ + /* 16*4 */ + volatile unsigned char* volatile readp; /* Next byte to be read by application */ + volatile unsigned char* volatile writep; /* Next byte to be written by etrax */ + unsigned int in_buffer_size; + unsigned int inbufchunk; struct etrax_dma_descr out_descr; - struct etrax_dma_descr in_descr1; - struct etrax_dma_descr in_descr2; - char out_buffer[OUT_BUFFER_SIZE]; - int out_count; /* Remaining bytes for current transfer */ - char* outp; /* Current position in out_buffer */ - char in_buffer[IN_BUFFER_SIZE]; - volatile char* readp; /* Next byte to be read by application */ - volatile char* writep; /* Next byte to be written by etrax */ - int started; /* 1 if port has been started */ + struct etrax_dma_descr in_descr[NUM_IN_DESCR]; + unsigned char out_buffer[OUT_BUFFER_SIZE]; + unsigned char in_buffer[IN_BUFFER_SIZE]; + + wait_queue_head_t out_wait_q; + wait_queue_head_t in_wait_q; } sync_port; static int etrax_sync_serial_init(void); static void initialize_port(int portnbr); +static inline int sync_data_avail(struct sync_port *port); + static int sync_serial_open(struct inode *, struct file*); static int sync_serial_release(struct inode*, struct file*); +static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); + static int sync_serial_ioctl(struct inode*, struct file*, unsigned int cmd, unsigned long arg); static ssize_t sync_serial_write(struct file * file, const char * buf, size_t count, loff_t *ppos); -static ssize_t sync_serial_manual_write(struct file * file, const char * buf, - size_t count, loff_t *ppos); static ssize_t sync_serial_read(struct file *file, char *buf, size_t count, loff_t *ppos); + +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \ + (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \ + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)) +#define SYNC_SER_DMA +#endif + static void send_word(sync_port* port); static void start_dma(struct sync_port *port, const char* data, int count); static void start_dma_in(sync_port* port); +#ifdef SYNC_SER_DMA static void tr_interrupt(int irq, void *dev_id, struct pt_regs * regs); static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs); +#endif +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ + !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \ + (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \ + !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)) +#define SYNC_SER_MANUAL +#endif +#ifdef SYNC_SER_MANUAL static void manual_interrupt(int irq, void *dev_id, struct pt_regs * regs); +#endif /* The ports */ static struct sync_port ports[]= { { - R_SYNC_SERIAL1_STATUS, /* status */ - R_SYNC_SERIAL1_CTRL, /* ctrl_data */ - R_DMA_CH8_FIRST, /* output_dma_first */ - R_DMA_CH8_CMD, /* output_dma_cmd */ - R_DMA_CH8_CLR_INTR, /* output_dma_clr_irq */ - R_DMA_CH9_FIRST, /* input_dma_first */ - R_DMA_CH9_CMD, /* input_dma_cmd */ - R_DMA_CH9_CLR_INTR, /* input_dma_clr_irq */ - R_SYNC_SERIAL1_TR_DATA, /* data_out */ - R_SYNC_SERIAL1_REC_DATA,/* data in */ - IO_BITNR(R_IRQ_MASK1_RD, ser1_data), /* data_avail_bit */ - IO_BITNR(R_IRQ_MASK1_RD, ser1_ready), /* transmitter_ready_bit */ - IO_BITNR(R_IRQ_MASK1_SET, ser1_ready), /* ready_irq_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma9_descr), /* input_dma_descr_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma8_eop), /* output_dma_bit */ + .status = R_SYNC_SERIAL1_STATUS, + .ctrl_data = R_SYNC_SERIAL1_CTRL, + .output_dma_first = R_DMA_CH8_FIRST, + .output_dma_cmd = R_DMA_CH8_CMD, + .output_dma_clr_irq = R_DMA_CH8_CLR_INTR, + .input_dma_first = R_DMA_CH9_FIRST, + .input_dma_cmd = R_DMA_CH9_CMD, + .input_dma_descr = R_DMA_CH9_DESCR, + .input_dma_clr_irq = R_DMA_CH9_CLR_INTR, + .data_out = R_SYNC_SERIAL1_TR_DATA, + .data_in = R_SYNC_SERIAL1_REC_DATA, + .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_data), + .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_ready), + .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma9_descr), + .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma8_eop), }, { - R_SYNC_SERIAL3_STATUS, /* status */ - R_SYNC_SERIAL3_CTRL, /* ctrl_data */ - R_DMA_CH4_FIRST, /* output_dma_first */ - R_DMA_CH4_CMD, /* output_dma_cmd */ - R_DMA_CH4_CLR_INTR, /* output_dma_clr_irq */ - R_DMA_CH5_FIRST, /* input_dma_first */ - R_DMA_CH5_CMD, /* input_dma_cmd */ - R_DMA_CH5_CLR_INTR, /* input_dma_clr_irq */ - R_SYNC_SERIAL3_TR_DATA, /* data_out */ - R_SYNC_SERIAL3_REC_DATA,/* data in */ - IO_BITNR(R_IRQ_MASK1_RD, ser3_data), /* data_avail_bit */ - IO_BITNR(R_IRQ_MASK1_RD, ser3_ready), /* transmitter_ready_bit */ - IO_BITNR(R_IRQ_MASK1_SET, ser3_ready), /* ready_irq_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma5_descr), /* input_dma_descr_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma4_eop), /* output_dma_bit */ + .status = R_SYNC_SERIAL3_STATUS, + .ctrl_data = R_SYNC_SERIAL3_CTRL, + .output_dma_first = R_DMA_CH4_FIRST, + .output_dma_cmd = R_DMA_CH4_CMD, + .output_dma_clr_irq = R_DMA_CH4_CLR_INTR, + .input_dma_first = R_DMA_CH5_FIRST, + .input_dma_cmd = R_DMA_CH5_CMD, + .input_dma_descr = R_DMA_CH5_DESCR, + .input_dma_clr_irq = R_DMA_CH5_CLR_INTR, + .data_out = R_SYNC_SERIAL3_TR_DATA, + .data_in = R_SYNC_SERIAL3_REC_DATA, + .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_data), + .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_ready), + .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma5_descr), + .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma4_eop), } }; @@ -176,12 +215,13 @@ #define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port)) static struct file_operations sync_serial_fops = { - owner: THIS_MODULE, - write: sync_serial_write, - read: sync_serial_read, - ioctl: sync_serial_ioctl, - open: sync_serial_open, - release: sync_serial_release + .owner = THIS_MODULE, + .write = sync_serial_write, + .read = sync_serial_read, + .poll = sync_serial_poll, + .ioctl = sync_serial_ioctl, + .open = sync_serial_open, + .release = sync_serial_release }; static int __init etrax_sync_serial_init(void) @@ -238,9 +278,9 @@ ports[1].use_dma = 1; initialize_port(1); if(request_irq(20, tr_interrupt, 0, "synchronous serial 3 dma tr", &ports[1])) - panic("Can't allocate sync serial port 1 IRQ"); + panic("Can't allocate sync serial port 3 IRQ"); if(request_irq(21, rx_interrupt, 0, "synchronous serial 3 dma rx", &ports[1])) - panic("Can't allocate sync serial port 1 IRQ"); + panic("Can't allocate sync serial port 3 IRQ"); RESET_DMA(4); WAIT_DMA(4); RESET_DMA(5); WAIT_DMA(5); *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | @@ -254,7 +294,7 @@ #else ports[1].use_dma = 0; initialize_port(1); - if (ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */ + if (!ports[0].enabled || ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */ { if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1])) panic("Can't allocate sync serial manual irq"); @@ -282,7 +322,7 @@ return 0; } -static void initialize_port(int portnbr) +static void __init initialize_port(int portnbr) { struct sync_port* port = &ports[portnbr]; @@ -290,13 +330,21 @@ port->started = 0; port->port_nbr = portnbr; - port->busy = 0; + port->busy = 0; + port->cur_in_descr = 0; + port->tr_running = 0; + + port->out_count = 0; + port->outp = port->out_buffer; + port->readp = port->in_buffer; port->writep = port->in_buffer; + port->in_buffer_size = IN_BUFFER_SIZE; + port->inbufchunk = port->in_buffer_size/NUM_IN_DESCR; init_waitqueue_head(&port->out_wait_q); init_waitqueue_head(&port->in_wait_q); - + port->ctrl_data_shadow = IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz) | IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) | @@ -329,9 +377,53 @@ *port->ctrl_data = port->ctrl_data_shadow; } +static inline int sync_data_avail(struct sync_port *port) +{ + int avail; + unsigned char *start; + unsigned char *end; + + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + /* 0123456789 0123456789 + * ----- - ----- + * ^rp ^wp ^wp ^rp + */ + + if (end >= start) + avail = end - start; + else + avail = port->in_buffer_size - (start - end); + return avail; +} + +static inline int sync_data_avail_to_end(struct sync_port *port) +{ + int avail; + unsigned char *start; + unsigned char *end; + + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + /* 0123456789 0123456789 + * ----- ----- + * ^rp ^wp ^wp ^rp + */ + + if (end >= start) + avail = end - start; + else + avail = port->in_buffer + port->in_buffer_size - start; + return avail; +} + + static int sync_serial_open(struct inode *inode, struct file *file) { int dev = MINOR(inode->i_rdev); + sync_port* port; + int mode; + DEBUG(printk("Open sync serial port %d\n", dev)); if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) @@ -339,33 +431,87 @@ DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } - if (ports[dev].busy) + port = &ports[dev]; + /* Allow open this device twice (assuming one reader and one writer) */ + if (port->busy == 2) { DEBUG(printk("Device is busy.. \n")); return -EBUSY; } - ports[dev].busy = 1; + port->busy++; + /* Start port if we use it as input */ + mode = IO_EXTRACT(R_SYNC_SERIAL1_CTRL, mode, port->ctrl_data_shadow); + if (mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_input) || + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_input) || + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_bidir) || + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_bidir)) { + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable); + port->started = 1; + *port->ctrl_data = port->ctrl_data_shadow; + if (!port->use_dma) + *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; + DEBUG(printk("sser%d rec started\n", dev)); + } return 0; } static int sync_serial_release(struct inode *inode, struct file *file) { int dev = MINOR(inode->i_rdev); + sync_port* port; + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } - ports[dev].busy = 0; + port = &ports[dev]; + if (port->busy) + port->busy--; + if (!port->busy) + *R_IRQ_MASK1_CLR = ((1 << port->data_avail_bit) | + (1 << port->transmitter_ready_bit)); + return 0; } + + +static unsigned int sync_serial_poll(struct file *file, poll_table *wait) +{ + int dev = MINOR(file->f_dentry->d_inode->i_rdev); + unsigned int mask = 0; + sync_port* port; + DEBUGPOLL( static unsigned int prev_mask = 0; ); + + port = &ports[dev]; + poll_wait(file, &port->out_wait_q, wait); + poll_wait(file, &port->in_wait_q, wait); + /* Some room to write */ + if (port->out_count < OUT_BUFFER_SIZE) + mask |= POLLOUT | POLLWRNORM; + /* At least an inbufchunk of data */ + if (sync_data_avail(port) >= port->inbufchunk) + mask |= POLLIN | POLLRDNORM; + + DEBUGPOLL(if (mask != prev_mask) + printk("sync_serial_poll: mask 0x%08X %s %s\n", mask, + mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":""); + prev_mask = mask; + ); + return mask; +} + static int sync_serial_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int return_val = 0; + unsigned long flags; + int dev = MINOR(file->f_dentry->d_inode->i_rdev); - sync_port* port; + sync_port* port; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { @@ -374,197 +520,199 @@ } port = &ports[dev]; + save_flags(flags); + cli(); /* Disable port while changing config */ if (dev) { - RESET_DMA(4); WAIT_DMA(4); - *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | - IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); + if (port->use_dma) { + RESET_DMA(4); WAIT_DMA(4); + *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | + IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); + } SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async); } else { - RESET_DMA(8); WAIT_DMA(8); - *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) | - IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); + if (port->use_dma) { + RESET_DMA(8); WAIT_DMA(8); + *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) | + IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); + } SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async); } *R_GEN_CONFIG_II = gen_config_ii_shadow; + restore_flags(flags); switch(cmd) { - case SSP_SPEED: - if (GET_SPEED(arg) == CODEC) - { - if (dev) - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec); - else - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec); - - SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg)); - SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg)); - SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg)); - } + case SSP_SPEED: + if (GET_SPEED(arg) == CODEC) + { + if (dev) + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec); else - { - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg)); - if (dev) - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate); - else - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate); - } - break; - case SSP_MODE: - if (arg > 5) - return -EINVAL; - if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT) - *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit; + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec); + + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg)); + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg)); + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg)); + } + else + { + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg)); + if (dev) + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate); else - *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg); - break; - case SSP_FRAME_SYNC: - if (arg & NORMAL_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); - else if (arg & EARLY_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early); - - if (arg & BIT_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit); - else if (arg & WORD_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); - else if (arg & EXTENDED_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended); - - if (arg & SYNC_ON) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); - else if (arg & SYNC_OFF) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off); - - if (arg & WORD_SIZE_8) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); - else if (arg & WORD_SIZE_12) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit); - else if (arg & WORD_SIZE_16) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit); - else if (arg & WORD_SIZE_24) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit); - else if (arg & WORD_SIZE_32) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit); - - if (arg & BIT_ORDER_MSB) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); - else if (arg & BIT_ORDER_LSB) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb); - - if (arg & FLOW_CONTROL_ENABLE) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled); - else if (arg & FLOW_CONTROL_DISABLE) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); - - if (arg & CLOCK_NOT_GATED) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal); - else if (arg & CLOCK_GATED) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated); - - break; - case SSP_IPOLARITY: - if (arg & CLOCK_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); - else if (arg & CLOCK_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos); - - if (arg & FRAME_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal); - else if (arg & FRAME_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); - - if (arg & STATUS_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal); - else if (arg & STATUS_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted); - break; - case SSP_OPOLARITY: - if (arg & CLOCK_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal); - else if (arg & CLOCK_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); - - if (arg & FRAME_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal); - else if (arg & FRAME_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); - - if (arg & STATUS_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal); - else if (arg & STATUS_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted); - break; - case SSP_SPI: - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate); + } + break; + case SSP_MODE: + if (arg > 5) + return -EINVAL; + if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT) + *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit; + else if (!port->use_dma) + *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg); + break; + case SSP_FRAME_SYNC: + if (arg & NORMAL_SYNC) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); - if (arg & SPI_SLAVE) - { - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT); - } - else - { - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT); + else if (arg & EARLY_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early); + + if (arg & BIT_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit); + else if (arg & WORD_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); + else if (arg & EXTENDED_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended); + + if (arg & SYNC_ON) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); + else if (arg & SYNC_OFF) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off); + + if (arg & WORD_SIZE_8) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); + else if (arg & WORD_SIZE_12) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit); + else if (arg & WORD_SIZE_16) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit); + else if (arg & WORD_SIZE_24) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit); + else if (arg & WORD_SIZE_32) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit); + + if (arg & BIT_ORDER_MSB) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); + else if (arg & BIT_ORDER_LSB) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb); + + if (arg & FLOW_CONTROL_ENABLE) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled); + else if (arg & FLOW_CONTROL_DISABLE) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); + + if (arg & CLOCK_NOT_GATED) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal); + else if (arg & CLOCK_GATED) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated); + + break; + case SSP_IPOLARITY: + /* NOTE!! negedge is considered NORMAL */ + if (arg & CLOCK_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); + else if (arg & CLOCK_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos); + + if (arg & FRAME_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal); + else if (arg & FRAME_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); + + if (arg & STATUS_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal); + else if (arg & STATUS_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted); + break; + case SSP_OPOLARITY: + if (arg & CLOCK_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal); + else if (arg & CLOCK_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); + + if (arg & FRAME_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal); + else if (arg & FRAME_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); + + if (arg & STATUS_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal); + else if (arg & STATUS_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted); + break; + case SSP_SPI: + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); + if (arg & SPI_SLAVE) + { + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT); + } + else + { + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT); + } + break; + case SSP_INBUFCHUNK: + if (arg > port->in_buffer_size/NUM_IN_DESCR) + return -EINVAL; + port->inbufchunk = arg; + /* Make sure in_buffer_size is a multiple of inbufchunk */ + port->in_buffer_size = (port->in_buffer_size/port->inbufchunk) * port->inbufchunk; + DEBUG(printk("inbufchunk %i in_buffer_size: %i\n", port->inbufchunk, port->in_buffer_size)); + if (port->use_dma) { + if (port->port_nbr == 0) { + RESET_DMA(9); + WAIT_DMA(9); + } else { + RESET_DMA(5); + WAIT_DMA(5); } - break; - default: - return_val = -1; + start_dma_in(port); + } + break; + default: + return_val = -1; } + /* Make sure we write the config without interruption */ + save_flags(flags); + cli(); /* Set config and enable port */ *port->ctrl_data = port->ctrl_data_shadow; + nop(); nop(); nop(); nop(); *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow; + nop(); nop(); nop(); nop(); if (dev) SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync); else SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync); *R_GEN_CONFIG_II = gen_config_ii_shadow; + restore_flags(flags); return return_val; } -static ssize_t sync_serial_manual_write(struct file * file, const char * buf, - size_t count, loff_t *ppos) -{ - int dev = MINOR(file->f_dentry->d_inode->i_rdev); - DECLARE_WAITQUEUE(wait, current); - sync_port* port; - - if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) - { - DEBUG(printk("Invalid minor %d\n", dev)); - return -ENODEV; - } - - port = &ports[dev]; - copy_from_user(port->out_buffer, buf, count); - port->outp = port->out_buffer; - port->out_count = count; - add_wait_queue(&port->out_wait_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - send_word(port); /* Start sender by sending first word */ - *R_IRQ_MASK1_SET = 1 << port->ready_irq_bit; /* transmitter ready IRQ on */ - schedule(); - set_current_state(TASK_RUNNING); - remove_wait_queue(&port->out_wait_q, &wait); - if (signal_pending(current)) - { - return -EINTR; - } - return count; -} static ssize_t sync_serial_write(struct file * file, const char * buf, size_t count, loff_t *ppos) @@ -572,6 +720,11 @@ int dev = MINOR(file->f_dentry->d_inode->i_rdev); DECLARE_WAITQUEUE(wait, current); sync_port *port; + unsigned long flags; + unsigned long c, c1; + unsigned long free_outp; + unsigned long outp; + unsigned long out_buffer; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { @@ -580,9 +733,52 @@ } port = &ports[dev]; - DEBUG(printk("Write dev %d count %d\n", port->port_nbr, count)); + DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE)); + /* Space to end of buffer */ + /* + * out_buffer 012345<- c ->OUT_BUFFER_SIZE + * outp^ +out_count + ^free_outp + * out_buffer 45<- c ->0123OUT_BUFFER_SIZE + * +out_count outp^ + * free_outp + * + */ - count = count > OUT_BUFFER_SIZE ? OUT_BUFFER_SIZE : count; + /* Read variables that may be updated by interrupts */ + save_flags(flags); + cli(); + count = count > OUT_BUFFER_SIZE - port->out_count ? OUT_BUFFER_SIZE - port->out_count : count; + outp = (unsigned long)port->outp; + free_outp = outp + port->out_count; + restore_flags(flags); + out_buffer = (unsigned long)port->out_buffer; + + /* Find out where and how much to write */ + if (free_outp >= out_buffer + OUT_BUFFER_SIZE) + free_outp -= OUT_BUFFER_SIZE; + if (free_outp >= outp) + c = out_buffer + OUT_BUFFER_SIZE - free_outp; + else + c = outp - free_outp; + if (c > count) + c = count; + +// DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c)); + if (copy_from_user((void*)free_outp, buf, c)) + return -EFAULT; + + if (c != count) { + buf += c; + c1 = count - c; + DEBUGWRITE(printk("w2 fi %lu c %lu c1 %lu\n", free_outp-out_buffer, c, c1)); + if (copy_from_user((void*)out_buffer, buf, c1)) + return -EFAULT; + } + save_flags(flags); + cli(); + port->out_count += count; + restore_flags(flags); /* Make sure transmitter/receiver is running */ if (!port->started) @@ -595,15 +791,42 @@ *port->ctrl_data = port->ctrl_data_shadow; - if (!port->use_dma) - { - return sync_serial_manual_write(file, buf, count, ppos); + if (file->f_flags & O_NONBLOCK) { + save_flags(flags); + cli(); + if (!port->tr_running) { + if (!port->use_dma) { + /* Start sender by writing data */ + send_word(port); + /* and enable transmitter ready IRQ */ + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit; + } else { + start_dma(port, (unsigned char* volatile )port->outp, c); + } + } + restore_flags(flags); + DEBUGWRITE(printk("w d%d c %lu NB\n", + port->port_nbr, count)); + return count; } - - copy_from_user(port->out_buffer, buf, count); + + /* Sleep until all sent */ + add_wait_queue(&port->out_wait_q, &wait); set_current_state(TASK_INTERRUPTIBLE); - start_dma(port, buf, count); + save_flags(flags); + cli(); + if (!port->tr_running) { + if (!port->use_dma) { + /* Start sender by writing data */ + send_word(port); + /* and enable transmitter ready IRQ */ + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit; + } else { + start_dma(port, port->outp, c); + } + } + restore_flags(flags); schedule(); set_current_state(TASK_RUNNING); remove_wait_queue(&port->out_wait_q, &wait); @@ -611,6 +834,7 @@ { return -EINTR; } + DEBUGWRITE(printk("w d%d c %lu\n", port->port_nbr, count)); return count; } @@ -620,8 +844,8 @@ int dev = MINOR(file->f_dentry->d_inode->i_rdev); int avail; sync_port *port; - char* start; - char* end; + unsigned char* start; + unsigned char* end; unsigned long flags; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) @@ -631,7 +855,7 @@ } port = &ports[dev]; - DEBUG(printk("Read dev %d count %d\n", dev, count)); + DEBUGREAD(printk("R%d c %d ri %lu wi %lu /%lu\n", dev, count, port->readp - port->in_buffer, port->writep - port->in_buffer, port->in_buffer_size)); if (!port->started) { @@ -640,11 +864,17 @@ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable); port->started = 1; } - *port->ctrl_data = port->ctrl_data_shadow; + /* Calculate number of available bytes */ - while (port->readp == port->writep) /* No data */ + /* Save pointers to avoid that they are modified by interrupt */ + save_flags(flags); + cli(); + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + restore_flags(flags); + while (start == end) /* No data */ { if (file->f_flags & O_NONBLOCK) return -EAGAIN; @@ -653,127 +883,137 @@ { return -EINTR; } + save_flags(flags); + cli(); + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + restore_flags(flags); } - - /* Save pointers to avoid that they are modified by interrupt */ - start = port->readp; - end = port->writep; /* Lazy read, never return wrapped data. */ if (end > start) avail = end - start; else - avail = port->in_buffer + IN_BUFFER_SIZE - start; + avail = port->in_buffer + port->in_buffer_size - start; count = count > avail ? avail : count; - copy_to_user(buf, start, count); + if (copy_to_user(buf, start, count)) + return -EFAULT; /* Disable interrupts while updating readp */ save_flags(flags); cli(); port->readp += count; - if (port->readp == port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */ + if (port->readp >= port->in_buffer + port->in_buffer_size) /* Wrap? */ port->readp = port->in_buffer; restore_flags(flags); - - DEBUG(printk("%d bytes read\n", count)); + DEBUGREAD(printk("r %d\n", count)); return count; } static void send_word(sync_port* port) { - switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize)) + switch(IO_EXTRACT(R_SYNC_SERIAL1_CTRL, wordsize, port->ctrl_data_shadow)) { - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): - port->out_count--; - *port->data_out = *port->outp++; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): - { - int data = (*port->outp++) << 8; - data |= *port->outp++; - port->out_count-=2; - *port->data_out = data; - } - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): - port->out_count-=2; - *port->data_out = *(unsigned short *)port->outp; - port->outp+=2; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): - port->out_count-=3; - *port->data_out = *(unsigned int *)port->outp; - port->outp+=3; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): - port->out_count-=4; - *port->data_out = *(unsigned int *)port->outp; - port->outp+=4; - break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): + port->out_count--; + *port->data_out = *port->outp++; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): + { + int data = (*port->outp++) << 8; + data |= *port->outp++; + port->out_count-=2; + *port->data_out = data; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + } + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): + port->out_count-=2; + *port->data_out = *(unsigned short *)port->outp; + port->outp+=2; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): + port->out_count-=3; + *port->data_out = *(unsigned int *)port->outp; + port->outp+=3; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): + port->out_count-=4; + *port->data_out = *(unsigned int *)port->outp; + port->outp+=4; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; } } + static void start_dma(struct sync_port* port, const char* data, int count) { + port->tr_running = 1; port->out_descr.hw_len = 0; port->out_descr.next = 0; - port->out_descr.ctrl = d_eol | d_eop | d_wait; + port->out_descr.ctrl = d_eol | d_eop; /* No d_wait to avoid glitches */ port->out_descr.sw_len = count; - port->out_descr.buf = virt_to_phys(port->out_buffer); + port->out_descr.buf = virt_to_phys((char*)data); port->out_descr.status = 0; *port->output_dma_first = virt_to_phys(&port->out_descr); *port->output_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start); + DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count)); } static void start_dma_in(sync_port* port) { - if (port->writep > port->in_buffer + IN_BUFFER_SIZE) + int i; + unsigned long buf; + port->cur_in_descr = 0; + port->writep = port->in_buffer; + + if (port->writep > port->in_buffer + port->in_buffer_size) { panic("Offset too large in sync serial driver\n"); return; } - port->in_descr1.hw_len = 0; - port->in_descr1.ctrl = d_int; - port->in_descr1.status = 0; - port->in_descr1.next = virt_to_phys(&port->in_descr2); - port->in_descr2.hw_len = 0; - port->in_descr2.next = virt_to_phys(&port->in_descr1); - port->in_descr2.ctrl = d_int; - port->in_descr2.status = 0; - - /* Find out which descriptor to start */ - if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2) - { - /* Start descriptor 2 */ - port->in_descr1.sw_len = IN_BUFFER_SIZE/2; /* All data available in 1 */ - port->in_descr1.buf = virt_to_phys(port->in_buffer); - port->in_descr2.sw_len = port->in_buffer + IN_BUFFER_SIZE - port->writep; - port->in_descr2.buf = virt_to_phys(port->writep); - *port->input_dma_first = virt_to_phys(&port->in_descr2); - } - else - { - /* Start descriptor 1 */ - port->in_descr1.sw_len = port->in_buffer + IN_BUFFER_SIZE/2 - port->writep; - port->in_descr1.buf = virt_to_phys(port->writep); - port->in_descr2.sw_len = IN_BUFFER_SIZE/2; - port->in_descr2.buf = virt_to_phys(port->in_buffer + IN_BUFFER_SIZE / 2); - *port->input_dma_first = virt_to_phys(&port->in_descr1); - } + buf = virt_to_phys(port->in_buffer); + for (i = 0; i < NUM_IN_DESCR; i++) { + port->in_descr[i].sw_len = port->inbufchunk; + port->in_descr[i].ctrl = d_int; + port->in_descr[i].next = virt_to_phys(&port->in_descr[i+1]); + port->in_descr[i].buf = buf; + port->in_descr[i].hw_len = 0; + port->in_descr[i].status = 0; + port->in_descr[i].fifo_len = 0; + buf += port->inbufchunk; + prepare_rx_descriptor(&port->in_descr[i]); + } + /* Link the last descriptor to the first */ + port->in_descr[i-1].next = virt_to_phys(&port->in_descr[0]); + *port->input_dma_first = virt_to_phys(&port->in_descr[(int)port->cur_in_descr]); *port->input_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start); } +#ifdef SYNC_SER_DMA static void tr_interrupt(int irq, void *dev_id, struct pt_regs * regs) { unsigned long ireg = *R_IRQ_MASK2_RD; int i; + struct etrax_dma_descr *descr; + unsigned int sentl; + for (i = 0; i < NUMBER_OF_PORTS; i++) { sync_port *port = &ports[i]; - if (!port->enabled) + if (!port->enabled || !port->use_dma ) continue; if (ireg & (1 << port->output_dma_bit)) /* IRQ active for the port? */ @@ -782,54 +1022,89 @@ *port->output_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) | IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do); + + descr = &port->out_descr; + if (!(descr->status & d_stop)) { + sentl = descr->sw_len; + } else + /* otherwise we find the amount of data sent here */ + sentl = descr->hw_len; + port->out_count -= sentl; + port->outp += sentl; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + if (port->out_count) { + int c; + c = port->out_buffer + OUT_BUFFER_SIZE - port->outp; + if (c > port->out_count) + c = port->out_count; + DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c)); + start_dma(port, port->outp, c); + } else { + DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl)); + port->tr_running = 0; + } wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */ } } -} +} /* tr_interrupt */ static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) { unsigned long ireg = *R_IRQ_MASK2_RD; - int i; + int i; for (i = 0; i < NUMBER_OF_PORTS; i++) { sync_port *port = &ports[i]; - if (!port->enabled) + if (!port->enabled || !port->use_dma ) continue; if (ireg & (1 << port->input_dma_descr_bit)) /* Descriptor interrupt */ { + struct etrax_dma_descr *descr; + unsigned recvl; + unsigned long oldbuf, buf; + /* DMA has reached end of descriptor */ *port->input_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do); - - /* Find out which descriptor that is ready */ - if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2) - { - /* Descr 2 was ready. Restart DMA at descriptor 1 */ - port->writep = port->in_buffer; - - /* Throw away data? */ - if (port->readp < port->in_buffer + IN_BUFFER_SIZE/2) - port->readp = port->in_buffer + IN_BUFFER_SIZE/2; - } - else - { - /* Descr 1 was ready. Restart DMA at descriptor 2 */ - port->writep = port->in_buffer + IN_BUFFER_SIZE/2; - - /* Throw away data? */ - if (port->readp >= port->in_buffer + IN_BUFFER_SIZE/2) - port->readp = port->in_buffer; + + descr = &port->in_descr[(int)port->cur_in_descr]; + if (descr == phys_to_virt(*port->input_dma_descr)) + printk("sser: desc = *input_dma_descr\n"); + + if (!(descr->status & d_eop)) { + recvl = descr->sw_len; + } else { + /* otherwise we find the amount of data received here */ + recvl = descr->hw_len; } - start_dma_in(port); + port->writep += recvl; + if (port->writep >= port->in_buffer+ port->in_buffer_size) + port->writep = port->in_buffer; + descr->sw_len = port->inbufchunk; + /* Reset the status information */ + descr->status = 0; + /* Change the buf pointer to new position */ + oldbuf = descr->buf; + + descr->buf += NUM_IN_DESCR * port->inbufchunk; + buf = virt_to_phys(port->in_buffer); + if (descr->buf >= buf + port->in_buffer_size) + descr->buf -= port->in_buffer_size; + DEBUGRXINT(printk("rx_int descr %i %X recvl: %i writep %lu obuf %lu %08lX buf 0x%08lX\n", port->cur_in_descr, (unsigned long) (*port->input_dma_descr), recvl, (unsigned long)(port->writep - port->in_buffer), oldbuf, oldbuf, (unsigned long)descr->buf)); + if (++port->cur_in_descr == NUM_IN_DESCR) + port->cur_in_descr = 0; + wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */ } } -} +} /* rx_interrupt */ +#endif /* SYNC_SER_DMA */ +#ifdef SYNC_SER_MANUAL static void manual_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int i; @@ -838,7 +1113,7 @@ { sync_port* port = &ports[i]; - if (!port->enabled) + if (!port->enabled || port->use_dma) { continue; } @@ -848,34 +1123,42 @@ /* Read data */ switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize)) { - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): - *port->writep++ = *(volatile char *)port->data_in; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): - { - int data = *(unsigned short *)port->data_in; - *port->writep = (data & 0x0ff0) >> 4; - *(port->writep + 1) = data & 0x0f; - port->writep+=2; - } + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): + *port->writep++ = *(volatile char *)port->data_in; + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): + { + int data = *(unsigned short *)port->data_in; + *port->writep = (data & 0x0ff0) >> 4; + *(port->writep + 1) = data & 0x0f; + port->writep+=2; + } + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): + *(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in; + port->writep+=2; + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): + *(unsigned int*)port->writep = *port->data_in; + port->writep+=3; + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): + *(unsigned int*)port->writep = *port->data_in; + port->writep+=4; break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): - *(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in; - port->writep+=2; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): - *(unsigned int*)port->writep = *port->data_in; - port->writep+=3; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): - *(unsigned int*)port->writep = *port->data_in; - port->writep+=4; - break; } - if (port->writep >= port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */ + if (port->writep >= port->in_buffer + port->in_buffer_size) /* Wrap? */ port->writep = port->in_buffer; - wake_up_interruptible(&port->in_wait_q); /* Wake up application */ + if (port->writep == port->readp) { + /* receive buffer overrun, discard oldest data + */ + port->readp++; + if (port->readp >= port->in_buffer + port->in_buffer_size) /* Wrap? */ + port->readp = port->in_buffer; + } + if (sync_data_avail(port) >= port->inbufchunk) + wake_up_interruptible(&port->in_wait_q); /* Wake up application */ } if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) /* Transmitter ready? */ @@ -884,11 +1167,12 @@ send_word(port); else /* transmission finished */ { - *R_IRQ_MASK1_CLR = 1 << port->ready_irq_bit; /* Turn off IRQ */ + *R_IRQ_MASK1_CLR = 1 << port->transmitter_ready_bit; /* Turn off IRQ */ wake_up_interruptible(&port->out_wait_q); /* Wake up application */ } } } } +#endif module_init(etrax_sync_serial_init); diff -urN linux-2.4.23-bk3/arch/cris/drivers/usb-host.c linux-2.4.23-bk4/arch/cris/drivers/usb-host.c --- linux-2.4.23-bk3/arch/cris/drivers/usb-host.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/drivers/usb-host.c 2003-12-06 02:49:48.000000000 -0800 @@ -41,7 +41,7 @@ #define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR #define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR -static const char *usb_hcd_version = "$Revision: 1.18 $"; +static const char *usb_hcd_version = "$Revision: 1.19 $"; #undef KERN_DEBUG #define KERN_DEBUG "" @@ -1540,9 +1540,18 @@ ctrl pipes are not. */ if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) { + __u32 r_usb_ept_data; + warn("error in rx desc->status, epid %d, first urb = 0x%lx", epid, (unsigned long)urb); __dump_in_desc(myNextRxDesc); + + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); + nop(); + r_usb_ept_data = *R_USB_EPT_DATA; + warn("R_USB_EPT_DATA for epid %d = 0x%x", epid, r_usb_ept_data); + warn("R_USB_STATUS = 0x%x", *R_USB_STATUS); + etrax_usb_complete_urb(urb, -EPROTO); goto skip_out; } diff -urN linux-2.4.23-bk3/arch/cris/kernel/debug.c linux-2.4.23-bk4/arch/cris/kernel/debug.c --- linux-2.4.23-bk3/arch/cris/kernel/debug.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/kernel/debug.c 2003-12-06 02:49:48.000000000 -0800 @@ -2,7 +2,7 @@ * arch/cris/kernel/debug.c * Various debug routines: * o Logging of interrupt enabling/disabling. /proc/debug_interrupt - * gives result and toggles if it is enabled or not. + * gives result and enables logging when read. * * Copyright (C) 2003 Axis Communications AB */ @@ -24,7 +24,7 @@ int log_int_trig0_pos = 0; int log_int_trig1_pos = 0; -int log_int_enable = 0; /* toggled every read of /proc/debug_interrupt */ +int log_int_enable = 0; /* Enabled every read of /proc/debug_interrupt */ struct log_int_struct { diff -urN linux-2.4.23-bk3/arch/cris/kernel/hexify.c linux-2.4.23-bk4/arch/cris/kernel/hexify.c --- linux-2.4.23-bk3/arch/cris/kernel/hexify.c 2001-02-08 16:32:44.000000000 -0800 +++ linux-2.4.23-bk4/arch/cris/kernel/hexify.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,31 +0,0 @@ -#include - - -void main() -{ - int c; - int comma=0; - int count=0; - while((c=getchar())!=EOF) - { - unsigned char x=c; - if(comma) - printf(","); - else - comma=1; - if(count==8) - { - count=0; - printf("\n"); - } - if(count==0) - printf("\t"); - printf("0x%02X",c); - count++; - } - if(count) - printf("\n"); - exit(0); -} - - diff -urN linux-2.4.23-bk3/arch/cris/kernel/ksyms.c linux-2.4.23-bk4/arch/cris/kernel/ksyms.c --- linux-2.4.23-bk3/arch/cris/kernel/ksyms.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/kernel/ksyms.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,90 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void dump_thread(struct pt_regs *, struct user *); -extern unsigned long get_cmos_time(void); -extern void __Udiv(void); -extern void __Umod(void); -extern void __ashrdi3(void); -extern void iounmap(void *addr); - -/* Platform dependent support */ -EXPORT_SYMBOL(dump_thread); -EXPORT_SYMBOL(enable_irq); -EXPORT_SYMBOL(disable_irq); -EXPORT_SYMBOL(kernel_thread); -EXPORT_SYMBOL(get_cmos_time); -EXPORT_SYMBOL(loops_per_usec); - -/* String functions */ -EXPORT_SYMBOL(memcmp); -EXPORT_SYMBOL(memmove); -EXPORT_SYMBOL(strtok); -EXPORT_SYMBOL(strpbrk); -EXPORT_SYMBOL(strstr); -EXPORT_SYMBOL(strcpy); -EXPORT_SYMBOL(strchr); -EXPORT_SYMBOL(strcmp); -EXPORT_SYMBOL(strlen); -EXPORT_SYMBOL(strncat); -EXPORT_SYMBOL(strncmp); -EXPORT_SYMBOL(strncpy); - -/* Math functions */ -EXPORT_SYMBOL(__Udiv); -EXPORT_SYMBOL(__Umod); -EXPORT_SYMBOL(__ashrdi3); - -/* Memory functions */ -EXPORT_SYMBOL(__ioremap); -EXPORT_SYMBOL(iounmap); - -/* Semaphore functions */ -EXPORT_SYMBOL(__up); -EXPORT_SYMBOL(__down); - -/* Export shadow registers for the CPU I/O pins */ -EXPORT_SYMBOL(genconfig_shadow); -EXPORT_SYMBOL(port_pa_data_shadow); -EXPORT_SYMBOL(port_pa_dir_shadow); -EXPORT_SYMBOL(port_pb_data_shadow); -EXPORT_SYMBOL(port_pb_dir_shadow); -EXPORT_SYMBOL(port_pb_config_shadow); -EXPORT_SYMBOL(port_g_data_shadow); - -/* Userspace access functions */ -EXPORT_SYMBOL(__copy_user_zeroing); -EXPORT_SYMBOL(__copy_user); - -/* Cache flush functions */ -EXPORT_SYMBOL(flush_etrax_cache); -EXPORT_SYMBOL(prepare_rx_descriptor); - -#undef memcpy -#undef memset -extern void * memset(void *, int, __kernel_size_t); -extern void * memcpy(void *, const void *, __kernel_size_t); -EXPORT_SYMBOL_NOVERS(memcpy); -EXPORT_SYMBOL_NOVERS(memset); - - diff -urN linux-2.4.23-bk3/arch/cris/kernel/ptrace.c linux-2.4.23-bk4/arch/cris/kernel/ptrace.c --- linux-2.4.23-bk3/arch/cris/kernel/ptrace.c 2002-02-25 11:37:52.000000000 -0800 +++ linux-2.4.23-bk4/arch/cris/kernel/ptrace.c 2003-12-06 02:49:48.000000000 -0800 @@ -8,6 +8,10 @@ * Authors: Bjorn Wesen * * $Log: ptrace.c,v $ + * Revision 1.9 2003/10/01 11:34:23 aurer + * * Allow PTRACE_PEEKUSR and PTRACE_POKEUSR to access USP. + * * Removed nonsensical comment about ptrace behavior. + * * Revision 1.8 2001/11/12 18:26:21 pkj * Fixed compiler warnings. * @@ -96,14 +100,6 @@ /* Todo - pending singlesteps? */ } -/* Note that this implementation of ptrace behaves differently from vanilla - * ptrace. Contrary to what the man page says, in the PTRACE_PEEKTEXT, - * PTRACE_PEEKDATA, and PTRACE_PEEKUSER requests the data variable is not - * ignored. Instead, the data variable is expected to point at a location - * (in user space) where the result of the ptrace call is written (instead of - * being returned). - */ - asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -163,17 +159,13 @@ /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: { unsigned long tmp; - + ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) break; - - tmp = 0; /* Default return condition */ - ret = -EIO; - if (addr < sizeof(struct pt_regs)) { - tmp = get_reg(child, addr >> 2); - ret = put_user(tmp, (unsigned long *)data); - } + + tmp = get_reg(child, addr >> 2); + ret = put_user(tmp, (unsigned long *)data); break; } @@ -188,23 +180,21 @@ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) break; - if (addr < sizeof(struct pt_regs)) { - addr >>= 2; + addr >>= 2; - if (addr == PT_DCCR) { + if (addr == PT_DCCR) { /* don't allow the tracing process to change stuff like * interrupt enable, kernel/user bit, dma enables etc. */ - data &= DCCR_MASK; - data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; - } - if (put_reg(child, addr, data)) - break; - ret = 0; + data &= DCCR_MASK; + data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; } + if (put_reg(child, addr, data)) + break; + ret = 0; break; case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ diff -urN linux-2.4.23-bk3/arch/cris/kernel/sys_cris.c linux-2.4.23-bk4/arch/cris/kernel/sys_cris.c --- linux-2.4.23-bk3/arch/cris/kernel/sys_cris.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/kernel/sys_cris.c 2003-12-06 02:49:48.000000000 -0800 @@ -109,7 +109,10 @@ switch (call) { case SEMOP: - return sys_semop (first, (struct sembuf *)ptr, second); + return sys_semtimedop (first, (struct sembuf *)ptr, second, NULL); + case SEMTIMEDOP: + return sys_semtimedop (first, (struct sembuf *)ptr, second, + (const struct timespec *)fifth); case SEMGET: return sys_semget (first, second, third); case SEMCTL: { @@ -163,7 +166,7 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } diff -urN linux-2.4.23-bk3/arch/cris/kernel/time.c linux-2.4.23-bk4/arch/cris/kernel/time.c --- linux-2.4.23-bk3/arch/cris/kernel/time.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/kernel/time.c 2003-12-06 02:49:48.000000000 -0800 @@ -328,7 +328,7 @@ int retval = 0; int real_seconds, real_minutes, cmos_minutes; - printk(KERN_INFO "set_rtc_mmss(%lu)\n", nowtime); + printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime); if(!have_rtc) return 0; @@ -514,7 +514,7 @@ mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); - printk(KERN_INFO + printk(KERN_DEBUG "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", sec, min, hour, day, mon, year); diff -urN linux-2.4.23-bk3/arch/cris/lib/dram_init.S linux-2.4.23-bk4/arch/cris/lib/dram_init.S --- linux-2.4.23-bk3/arch/cris/lib/dram_init.S 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/lib/dram_init.S 2003-12-06 02:49:48.000000000 -0800 @@ -1,4 +1,4 @@ -/* $Id: dram_init.S,v 1.14 2003/03/31 07:07:08 starvik Exp $ +/* $Id: dram_init.S,v 1.15 2003/09/22 09:22:22 starvik Exp $ * * DRAM/SDRAM initialization - alter with care * This file is intended to be included from other assembler files @@ -11,6 +11,10 @@ * Authors: Mikael Starvik (starvik@axis.com) * * $Log: dram_init.S,v $ + * Revision 1.15 2003/09/22 09:22:22 starvik + * Decompresser is linked to 0x407xxxxx and sdram commands are at 0x000xxxxx + * so we need to mask off 12 bits. + * * Revision 1.14 2003/03/31 07:07:08 starvik * Corrected calculation of end of sdram init commands * @@ -149,9 +153,9 @@ ; Issue initialization command sequence move.d _sdram_commands_start, $r2 - and.d 0x00ffffff, $r2 ; Make sure commands are read from flash + and.d 0x000fffff, $r2 ; Make sure commands are read from flash move.d _sdram_commands_end, $r3 - and.d 0x00ffffff, $r3 + and.d 0x000fffff, $r3 1: clear.d $r4 move.b [$r2+], $r4 lslq 9, $r4 ; Command starts at bit 9 diff -urN linux-2.4.23-bk3/arch/cris/mm/fault.c linux-2.4.23-bk4/arch/cris/mm/fault.c --- linux-2.4.23-bk3/arch/cris/mm/fault.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/cris/mm/fault.c 2003-12-06 02:49:48.000000000 -0800 @@ -6,6 +6,9 @@ * Authors: Bjorn Wesen * * $Log: fault.c,v $ + * Revision 1.23 2003/10/16 05:32:32 starvik + * Only read TLB_SELECT if DEBUG + * * Revision 1.22 2003/07/07 09:07:04 johana * Added special CONFIG_ETRAX_DEBUG_INTERRUPT handling here * to deal with a di in entry.S @@ -119,8 +122,9 @@ void handle_mmu_bus_fault(struct pt_regs *regs) { - int cause, select; + int cause; #ifdef DEBUG + int select; int index; int page_id; int acc, inv; @@ -135,11 +139,11 @@ log_int(rdpc(), regs->dccr, 0); #endif cause = *R_MMU_CAUSE; - select = *R_TLB_SELECT; address = cause & PAGE_MASK; /* get faulting address */ #ifdef DEBUG + select = *R_TLB_SELECT; page_id = IO_EXTRACT(R_MMU_CAUSE, page_id, cause); acc = IO_EXTRACT(R_MMU_CAUSE, acc_excp, cause); inv = IO_EXTRACT(R_MMU_CAUSE, inv_excp, cause); diff -urN linux-2.4.23-bk3/arch/ia64/config.in linux-2.4.23-bk4/arch/ia64/config.in --- linux-2.4.23-bk3/arch/ia64/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/config.in 2003-12-06 02:49:48.000000000 -0800 @@ -34,7 +34,7 @@ "generic CONFIG_IA64_GENERIC \ DIG-compliant CONFIG_IA64_DIG \ HP-simulator CONFIG_IA64_HP_SIM \ - HP-zx1 CONFIG_IA64_HP_ZX1 \ + HP CONFIG_IA64_HP_ZX1 \ SGI-SN2 CONFIG_IA64_SGI_SN2" generic if [ "$CONFIG_ITANIUM" = "y" ]; then @@ -90,7 +90,7 @@ int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 fi -tristate 'Support running of Linux/x86 binaries' CONFIG_IA32_SUPPORT +bool 'Support running of Linux/x86 binaries' CONFIG_IA32_SUPPORT bool 'Performance monitor support' CONFIG_PERFMON tristate '/proc/pal support' CONFIG_IA64_PALINFO tristate '/proc/efi/vars support' CONFIG_EFI_VARS diff -urN linux-2.4.23-bk3/arch/ia64/configs/dig linux-2.4.23-bk4/arch/ia64/configs/dig --- linux-2.4.23-bk3/arch/ia64/configs/dig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/configs/dig 2003-12-06 02:49:48.000000000 -0800 @@ -30,7 +30,6 @@ CONFIG_IA64_DIG=y # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -43,7 +42,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -52,6 +50,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set # CONFIG_IA64_PAL_IDLE is not set CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -113,6 +112,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -167,6 +172,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -339,6 +345,7 @@ # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -366,7 +373,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -438,7 +444,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -584,6 +589,7 @@ # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -601,12 +607,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -615,6 +626,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -690,6 +702,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -844,6 +857,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -914,6 +929,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -949,6 +965,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -971,3 +992,4 @@ CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set # CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.23-bk3/arch/ia64/configs/generic linux-2.4.23-bk4/arch/ia64/configs/generic --- linux-2.4.23-bk3/arch/ia64/configs/generic 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/configs/generic 2003-12-06 02:49:48.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -43,7 +42,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -52,6 +50,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set # CONFIG_IA64_PAL_IDLE is not set CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -113,6 +112,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -167,6 +172,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -275,6 +281,7 @@ # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SGIIOC4 is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set @@ -339,6 +346,7 @@ # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -371,7 +379,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -443,7 +450,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -588,7 +594,9 @@ # # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set +# CONFIG_FETCHOP is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -606,12 +614,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -620,6 +633,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -695,6 +709,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -849,6 +864,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -919,6 +936,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -954,6 +972,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -994,3 +1017,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.23-bk3/arch/ia64/configs/numa linux-2.4.23-bk4/arch/ia64/configs/numa --- linux-2.4.23-bk3/arch/ia64/configs/numa 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/configs/numa 2003-12-06 02:49:48.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -44,7 +43,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -53,6 +51,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_IA64_PAL_IDLE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -115,6 +114,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -169,6 +174,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -277,6 +283,7 @@ # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SGIIOC4 is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set @@ -341,6 +348,7 @@ # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -373,7 +381,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -445,7 +452,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -590,7 +596,9 @@ # # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set +# CONFIG_FETCHOP is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -608,12 +616,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -622,6 +635,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -697,6 +711,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -851,6 +866,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -921,6 +938,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -956,6 +974,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -996,3 +1019,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.23-bk3/arch/ia64/configs/ski linux-2.4.23-bk4/arch/ia64/configs/ski --- linux-2.4.23-bk3/arch/ia64/configs/ski 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/configs/ski 2003-12-06 02:49:48.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set CONFIG_IA64_HP_SIM=y # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -40,7 +39,6 @@ CONFIG_IA64_L1_CACHE_SHIFT=6 CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -49,6 +47,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_IA64_PAL_IDLE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -80,6 +79,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -161,6 +166,7 @@ # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -252,6 +258,7 @@ # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -265,6 +272,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -337,6 +348,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -478,3 +490,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.23-bk3/arch/ia64/configs/zx1 linux-2.4.23-bk4/arch/ia64/configs/zx1 --- linux-2.4.23-bk3/arch/ia64/configs/zx1 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/configs/zx1 2003-12-06 02:49:48.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set CONFIG_IA64_HP_ZX1=y -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -42,7 +41,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_4GB is not set # CONFIG_HUGETLB_PAGE_SIZE_1GB is not set # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set @@ -53,6 +51,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_IA64_PAL_IDLE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -114,6 +113,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -168,6 +173,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -340,6 +346,7 @@ # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -367,7 +374,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -439,7 +445,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -585,6 +590,7 @@ # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -602,12 +608,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -616,6 +627,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -691,6 +703,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -845,6 +858,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -915,6 +930,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -950,6 +966,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -983,3 +1004,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.23-bk3/arch/ia64/defconfig linux-2.4.23-bk4/arch/ia64/defconfig --- linux-2.4.23-bk3/arch/ia64/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/defconfig 2003-12-06 02:49:48.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -43,7 +42,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -114,6 +112,12 @@ # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -168,6 +172,7 @@ # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y @@ -276,6 +281,7 @@ # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SGIIOC4 is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set @@ -340,6 +346,7 @@ # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -372,7 +379,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -444,7 +450,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -589,7 +594,9 @@ # # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set +# CONFIG_FETCHOP is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -607,12 +614,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -621,6 +633,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -696,6 +709,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -850,6 +864,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -920,6 +936,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -955,6 +972,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -995,3 +1017,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.23-bk3/arch/ia64/hp/common/sba_iommu.c linux-2.4.23-bk4/arch/ia64/hp/common/sba_iommu.c --- linux-2.4.23-bk3/arch/ia64/hp/common/sba_iommu.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/hp/common/sba_iommu.c 2003-12-06 02:49:48.000000000 -0800 @@ -48,6 +48,11 @@ */ #define ALLOW_IOV_BYPASS +#ifdef CONFIG_PROC_FS + /* turn it off for now; without per-CPU counters, it's too much of a scalability bottleneck: */ +# define SBA_PROC_FS 0 +#endif + /* ** If a device prefetches beyond the end of a valid pdir entry, it will cause ** a hard failure, ie. MCA. Version 3.0 and later of the zx1 LBA should @@ -121,7 +126,7 @@ #endif /* -** The number of pdir entries to "free" before issueing +** The number of pdir entries to "free" before issuing ** a read to PCOM register to flush out PCOM writes. ** Interacts with allocation granularity (ie 4 or 8 entries ** allocated and free'd/purged at a time might make this @@ -186,7 +191,7 @@ } saved[DELAYED_RESOURCE_CNT]; #endif -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS #define SBA_SEARCH_SAMPLE 0x100 unsigned long avg_search[SBA_SEARCH_SAMPLE]; unsigned long avg_idx; /* current index into avg_search */ @@ -209,7 +214,7 @@ /* Stuff we don't need in performance path */ struct ioc *next; /* list of IOC's in system */ acpi_handle handle; /* for multiple IOC's */ - char *name; + const char *name; unsigned int func_id; unsigned int rev; /* HW revision of chip */ u32 iov_size; @@ -231,7 +236,11 @@ static u64 prefetch_spill_page; #endif -#define GET_IOC(dev) ((struct ioc *) PCI_CONTROLLER(dev)->iommu) +#ifdef CONFIG_PCI +# define GET_IOC(dev) ((struct ioc *) PCI_CONTROLLER(dev)->iommu) +#else +# define GET_IOC(dev) NULL +#endif /* ** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up @@ -510,7 +519,7 @@ sba_alloc_range(struct ioc *ioc, size_t size) { unsigned int pages_needed = size >> IOVP_SHIFT; -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS unsigned long itc_start = ia64_get_itc(); #endif unsigned long pide; @@ -544,7 +553,7 @@ (uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map), ioc->res_bitshift ); -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS { unsigned long itc_end = ia64_get_itc(); unsigned long tmp = itc_end - itc_start; @@ -586,7 +595,7 @@ __FUNCTION__, (uint) iova, size, bits_not_wanted, m, pide, res_ptr, *res_ptr); -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS ioc->used_pages -= bits_not_wanted; #endif @@ -749,12 +758,12 @@ * @dev: instance of PCI owned by the driver that's asking. * @addr: driver buffer to map. * @size: number of bytes to map in driver buffer. - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ dma_addr_t -sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction) +sba_map_single(struct pci_dev *dev, void *addr, size_t size, int dir) { struct ioc *ioc; unsigned long flags; @@ -778,7 +787,7 @@ ** Device is bit capable of DMA'ing to the buffer... ** just return the PCI address of ptr */ -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS spin_lock_irqsave(&ioc->res_lock, flags); ioc->msingle_bypass++; spin_unlock_irqrestore(&ioc->res_lock, flags); @@ -804,7 +813,7 @@ panic("Sanity check failed"); #endif -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS ioc->msingle_calls++; ioc->msingle_pages += size >> IOVP_SHIFT; #endif @@ -842,12 +851,11 @@ * @dev: instance of PCI owned by the driver that's asking. * @iova: IOVA of driver buffer previously mapped. * @size: number of bytes mapped in driver buffer. - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ -void sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, - int direction) +void sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int dir) { struct ioc *ioc; #if DELAYED_RESOURCE_CNT > 0 @@ -864,7 +872,7 @@ /* ** Address does not fall w/in IOVA, must be bypassing */ -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS spin_lock_irqsave(&ioc->res_lock, flags); ioc->usingle_bypass++; spin_unlock_irqrestore(&ioc->res_lock, flags); @@ -872,7 +880,7 @@ DBG_BYPASS("sba_unmap_single() bypass addr: 0x%lx\n", iova); #ifdef ENABLE_MARK_CLEAN - if (direction == PCI_DMA_FROMDEVICE) { + if (dir == PCI_DMA_FROMDEVICE) { mark_clean(phys_to_virt(iova), size); } #endif @@ -889,7 +897,7 @@ size = ROUNDUP(size, IOVP_SIZE); spin_lock_irqsave(&ioc->res_lock, flags); -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS ioc->usingle_calls++; ioc->usingle_pages += size >> IOVP_SHIFT; #endif @@ -914,7 +922,7 @@ READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */ #endif /* DELAYED_RESOURCE_CNT == 0 */ #ifdef ENABLE_MARK_CLEAN - if (direction == PCI_DMA_FROMDEVICE) { + if (dir == PCI_DMA_FROMDEVICE) { u32 iovp = (u32) SBA_IOVP(ioc,iova); int off = PDIR_INDEX(iovp); void *addr; @@ -951,55 +959,51 @@ /** - * sba_alloc_consistent - allocate/map shared mem for DMA - * @hwdev: instance of PCI owned by the driver that's asking. + * sba_alloc_coherent - allocate/map shared mem for DMA + * @dev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @dma_handle: IOVA of new buffer. * * See Documentation/DMA-mapping.txt */ void * -sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) +sba_alloc_coherent (struct pci_dev *dev, size_t size, dma_addr_t *dma_handle) { struct ioc *ioc; - void *ret; + void *addr; - if (!hwdev) { - /* only support PCI */ - *dma_handle = 0; - return 0; - } + if (!dev) + return NULL; /* only support PCI */ - ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size)); + addr = (void *) __get_free_pages(GFP_ATOMIC, get_order(size)); + if (!addr) + return NULL; - if (ret) { - memset(ret, 0, size); - /* - * REVISIT: if sba_map_single starts needing more - * than dma_mask from the device, this needs to be - * updated. - */ - ioc = GET_IOC(hwdev); - *dma_handle = sba_map_single(ioc->sac_only_dev, ret, size, 0); - } + /* + * REVISIT: if sba_map_single starts needing more than dma_mask from the + * device, this needs to be updated. + */ + ioc = GET_IOC(dev); + ASSERT(ioc); + *dma_handle = sba_map_single(ioc->sac_only_dev, addr, size, 0); - return ret; + memset(addr, 0, size); + return addr; } /** - * sba_free_consistent - free/unmap shared mem for DMA - * @hwdev: instance of PCI owned by the driver that's asking. + * sba_free_coherent - free/unmap shared mem for DMA + * @dev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @vaddr: virtual address IOVA of "consistent" buffer. * @dma_handler: IO virtual address of "consistent" buffer. * * See Documentation/DMA-mapping.txt */ -void sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, - dma_addr_t dma_handle) +void sba_free_coherent (struct pci_dev *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { - sba_unmap_single(hwdev, dma_handle, size, 0); + sba_unmap_single(dev, dma_handle, size, 0); free_pages((unsigned long) vaddr, get_order(size)); } @@ -1079,7 +1083,7 @@ cnt += dma_offset; dma_offset=0; /* only want offset on first chunk */ cnt = ROUNDUP(cnt, IOVP_SIZE); -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS ioc->msg_pages += cnt >> IOVP_SHIFT; #endif do { @@ -1121,7 +1125,7 @@ * in the DMA stream. Allocates PDIR entries but does not fill them. * Returns the number of DMA chunks. * - * Doing the fill seperate from the coalescing/allocation keeps the + * Doing the fill separate from the coalescing/allocation keeps the * code simpler. Future enhancement could make one pass through * the sglist do both. */ @@ -1246,11 +1250,11 @@ * @dev: instance of PCI owned by the driver that's asking. * @sglist: array of buffer/length pairs * @nents: number of entries in list - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ -int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction) +int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int dir) { struct ioc *ioc; int coalesced, filled = 0; @@ -1269,7 +1273,7 @@ sg->dma_length = sg->length; sg->dma_address = virt_to_phys(sba_sg_address(sg)); } -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS spin_lock_irqsave(&ioc->res_lock, flags); ioc->msg_bypass++; spin_unlock_irqrestore(&ioc->res_lock, flags); @@ -1280,10 +1284,9 @@ /* Fast path single entry scatterlists. */ if (nents == 1) { sglist->dma_length = sglist->length; - sglist->dma_address = sba_map_single(dev, - sba_sg_address(sglist), - sglist->length, direction); -#ifdef CONFIG_PROC_FS + sglist->dma_address = sba_map_single(dev, sba_sg_address(sglist), sglist->length, + dir); +#if SBA_PROC_FS /* ** Should probably do some stats counting, but trying to ** be precise quickly starts wasting CPU time. @@ -1302,7 +1305,7 @@ } #endif -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS ioc->msg_calls++; #endif @@ -1348,12 +1351,11 @@ * @dev: instance of PCI owned by the driver that's asking. * @sglist: array of buffer/length pairs * @nents: number of entries in list - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ -void sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, - int direction) +void sba_unmap_sg (struct pci_dev *dev, struct scatterlist *sglist, int nents, int dir) { struct ioc *ioc; #ifdef ASSERT_PDIR_SANITY @@ -1366,7 +1368,7 @@ ioc = GET_IOC(dev); ASSERT(ioc); -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS ioc->usg_calls++; #endif @@ -1378,9 +1380,8 @@ while (nents && sglist->dma_length) { - sba_unmap_single(dev, sglist->dma_address, - sglist->dma_length, direction); -#ifdef CONFIG_PROC_FS + sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir); +#if SBA_PROC_FS /* ** This leaves inconsistent data in the stats, but we can't ** tell which sg lists were mapped by map_single and which @@ -1416,7 +1417,7 @@ u32 iova_space_mask; int iov_order, tcnfg; int agp_found = 0; - struct pci_dev *device; + struct pci_dev *device = NULL; #ifdef FULL_VALID_PDIR unsigned long index; #endif @@ -1514,7 +1515,7 @@ ** We program the next pdir index after we stop w/ a key for ** the GART code to handshake on. */ - pci_for_each_dev(device) + while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP); if (agp_found && reserve_sba_gart) { @@ -1596,7 +1597,7 @@ struct pci_controller *controller = NULL; /* - * pci_alloc_consistent() must return a DMA address which is + * pci_alloc_coherent() must return a DMA address which is * SAC (single address cycle) addressable, so allocate a * pseudo-device to enforce that. */ @@ -1671,9 +1672,8 @@ if (!ioc->name) { ioc->name = kmalloc(24, GFP_KERNEL); if (ioc->name) - sprintf(ioc->name, "Unknown (%04x:%04x)", - ioc->func_id & 0xFFFF, - (ioc->func_id >> 16) & 0xFFFF); + sprintf((char *) ioc->name, "Unknown (%04x:%04x)", + ioc->func_id & 0xFFFF, (ioc->func_id >> 16) & 0xFFFF); else ioc->name = "Unknown"; } @@ -1701,7 +1701,7 @@ ** **************************************************************************/ -#ifdef CONFIG_PROC_FS +#if SBA_PROC_FS static void * ioc_start(struct seq_file *s, loff_t *pos) { @@ -1756,33 +1756,31 @@ if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; } avg /= SBA_SEARCH_SAMPLE; - seq_printf(s, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", - min, avg, max); + seq_printf(s, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", min, avg, max); seq_printf(s, "pci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", - ioc->msingle_calls, ioc->msingle_pages, - (int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls)); + ioc->msingle_calls, ioc->msingle_pages, + (int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls)); #ifdef ALLOW_IOV_BYPASS seq_printf(s, "pci_map_single(): %12ld bypasses\n", ioc->msingle_bypass); #endif seq_printf(s, "pci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", - ioc->usingle_calls, ioc->usingle_pages, - (int) ((ioc->usingle_pages * 1000)/ioc->usingle_calls)); + ioc->usingle_calls, ioc->usingle_pages, + (int) ((ioc->usingle_pages * 1000)/ioc->usingle_calls)); #ifdef ALLOW_IOV_BYPASS seq_printf(s, "pci_unmap_single: %12ld bypasses\n", ioc->usingle_bypass); #endif seq_printf(s, "pci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - ioc->msg_calls, ioc->msg_pages, - (int) ((ioc->msg_pages * 1000)/ioc->msg_calls)); + ioc->msg_calls, ioc->msg_pages, + (int) ((ioc->msg_pages * 1000)/ioc->msg_calls)); #ifdef ALLOW_IOV_BYPASS seq_printf(s, "pci_map_sg() : %12ld bypasses\n", ioc->msg_bypass); #endif seq_printf(s, "pci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - ioc->usg_calls, ioc->usg_pages, - (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); + ioc->usg_calls, ioc->usg_pages, (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); return 0; } @@ -1811,11 +1809,10 @@ ioc_map_show(struct seq_file *s, void *v) { struct ioc *ioc = v; - unsigned int *res_ptr = (unsigned int *)ioc->res_map; - int i; + unsigned int i, *res_ptr = (unsigned int *)ioc->res_map; - for (i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) - seq_printf(s, "%s%08x", (i & 7) ? " " : "\n ", *res_ptr); + for (i = 0; i < ioc->res_size / sizeof(unsigned int); ++i, ++res_ptr) + seq_printf(s, "%s%08x", (i & 7) ? " " : "\n ", *res_ptr); seq_printf(s, "\n"); return 0; @@ -1844,29 +1841,36 @@ static void __init ioc_proc_init(void) { - if (ioc_list) { - struct proc_dir_entry *dir, *entry; + struct proc_dir_entry *dir, *entry; - dir = proc_mkdir("bus/mckinley", 0); - entry = create_proc_entry(ioc_list->name, 0, dir); - if (entry) - entry->proc_fops = &ioc_fops; + dir = proc_mkdir("bus/mckinley", 0); + if (!dir) + return; - entry = create_proc_entry("bitmap", 0, dir); - if (entry) - entry->proc_fops = &ioc_map_fops; - } + entry = create_proc_entry(ioc_list->name, 0, dir); + if (entry) + entry->proc_fops = &ioc_fops; + + entry = create_proc_entry("bitmap", 0, dir); + if (entry) + entry->proc_fops = &ioc_map_fops; } #endif -void -sba_enable_device(struct pci_dev *dev) +static void +sba_connect_bus(struct pci_bus *bus) { acpi_handle handle, parent; acpi_status status; struct ioc *ioc; - handle = PCI_CONTROLLER(dev)->acpi_handle; + if (!PCI_CONTROLLER(bus)) + panic(PFX "no sysdata on bus %d!\n", bus->number); + + if (PCI_CONTROLLER(bus)->iommu) + return; + + handle = PCI_CONTROLLER(bus)->acpi_handle; if (!handle) return; @@ -1878,7 +1882,7 @@ do { for (ioc = ioc_list; ioc; ioc = ioc->next) if (ioc->handle == handle) { - PCI_CONTROLLER(dev)->iommu = ioc; + PCI_CONTROLLER(bus)->iommu = ioc; return; } @@ -1886,7 +1890,7 @@ handle = parent; } while (ACPI_SUCCESS(status)); - printk(KERN_WARNING "No IOC for %s in ACPI\n", dev->slot_name); + printk(KERN_WARNING "No IOC for PCI Bus %04x:%02x in ACPI\n", PCI_SEGMENT(bus), bus->number); } static int __init @@ -1924,19 +1928,29 @@ } static struct acpi_driver acpi_sba_ioc_driver = { - name: "IOC IOMMU Driver", - ids: "HWP0001,HWP0004", - ops: { - add: acpi_sba_ioc_add, - }, + .name = "IOC IOMMU Driver", + .ids = "HWP0001,HWP0004", + .ops = { + .add = acpi_sba_ioc_add, + }, }; void __init sba_init(void) { acpi_bus_register_driver(&acpi_sba_ioc_driver); + if (!ioc_list) + return 0; -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_PCI + { + struct pci_bus *b = NULL; + pci_for_each_bus(b) + sba_connect_bus(b); + } +#endif + +#if SBA_PROC_FS ioc_proc_init(); #endif } @@ -1963,5 +1977,5 @@ EXPORT_SYMBOL(sba_map_sg); EXPORT_SYMBOL(sba_unmap_sg); EXPORT_SYMBOL(sba_dma_supported); -EXPORT_SYMBOL(sba_alloc_consistent); -EXPORT_SYMBOL(sba_free_consistent); +EXPORT_SYMBOL(sba_alloc_coherent); +EXPORT_SYMBOL(sba_free_coherent); diff -urN linux-2.4.23-bk3/arch/ia64/hp/zx1/hpzx1_machvec.c linux-2.4.23-bk4/arch/ia64/hp/zx1/hpzx1_machvec.c --- linux-2.4.23-bk3/arch/ia64/hp/zx1/hpzx1_machvec.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/ia64/hp/zx1/hpzx1_machvec.c 2003-12-06 02:49:48.000000000 -0800 @@ -1,3 +1,3 @@ -#define MACHVEC_PLATFORM_NAME hpzx1 +#define MACHVEC_PLATFORM_NAME hp #define MACHVEC_PLATFORM_HEADER #include diff -urN linux-2.4.23-bk3/arch/ia64/hp/zx1/hpzx1_misc.c linux-2.4.23-bk4/arch/ia64/hp/zx1/hpzx1_misc.c --- linux-2.4.23-bk3/arch/ia64/hp/zx1/hpzx1_misc.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/hp/zx1/hpzx1_misc.c 2003-12-06 02:49:48.000000000 -0800 @@ -17,7 +17,7 @@ #include #include -#define PFX "hpzx1: " +#define PFX static int hpzx1_devices; @@ -50,7 +50,14 @@ fake_dev->sizing = 0; \ return PCIBIOS_SUCCESSFUL; \ } \ - *value = read##sz(fake_dev->mapped_csrs + where); \ + switch (where & ~0x7) { \ + case 0x48: /* initiates config cycles */ \ + case 0x78: /* elroy suspend mode register */ \ + *value = 0; \ + break; \ + default: \ + *value = read##sz(fake_dev->mapped_csrs + where); \ + } \ if (where == PCI_COMMAND) \ *value |= PCI_COMMAND_MEMORY; /* SBA omits this */ \ return PCIBIOS_SUCCESSFUL; \ @@ -68,8 +75,14 @@ if (value == (u##bits) ~0) \ fake_dev->sizing = 1; \ return PCIBIOS_SUCCESSFUL; \ - } else \ - write##sz(value, fake_dev->mapped_csrs + where); \ + } \ + switch (where & ~0x7) { \ + case 0x48: /* initiates config cycles */ \ + case 0x78: /* elroy suspend mode register */ \ + break; \ + default: \ + write##sz(value, fake_dev->mapped_csrs + where); \ + } \ return PCIBIOS_SUCCESSFUL; \ } diff -urN linux-2.4.23-bk3/arch/ia64/ia32/ia32_entry.S linux-2.4.23-bk4/arch/ia64/ia32/ia32_entry.S --- linux-2.4.23-bk3/arch/ia64/ia32/ia32_entry.S 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/ia64/ia32/ia32_entry.S 2003-12-06 02:49:48.000000000 -0800 @@ -138,6 +138,19 @@ ;; st8 [r2]=r3 // initialize return code to -ENOSYS br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args + // Need to reload arguments (they may be changed by the tracing process) + adds r2=IA64_PT_REGS_R9_OFFSET+16,sp // r2 = &pt_regs.r9 + adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13 + ;; + ld4 r33=[r2],8 // r9 == ecx + ld4 r37=[r3],16 // r13 == ebp + ;; + ld4 r34=[r2],8 // r10 == edx + ld4 r36=[r3],8 // r15 == edi + ;; + ld4 r32=[r2],8 // r11 == ebx + ld4 r35=[r3],8 // r14 == esi + ;; .ret2: br.call.sptk.few rp=b6 // do the syscall .ia32_strace_check_retval: cmp.lt p6,p0=r8,r0 // syscall failed? diff -urN linux-2.4.23-bk3/arch/ia64/ia32/sys_ia32.c linux-2.4.23-bk4/arch/ia64/ia32/sys_ia32.c --- linux-2.4.23-bk3/arch/ia64/ia32/sys_ia32.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/ia32/sys_ia32.c 2003-12-06 02:49:48.000000000 -0800 @@ -74,6 +74,7 @@ #define OFFSET4K(a) ((a) & 0xfff) #define PAGE_START(addr) ((addr) & PAGE_MASK) #define PAGE_OFF(addr) ((addr) & ~PAGE_MASK) +#define MINSIGSTKSZ_IA32 2048 extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *); extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long); @@ -201,13 +202,18 @@ asmlinkage long sys32_newstat (char *filename, struct stat32 *statbuf) { + char *name; int ret; struct stat s; mm_segment_t old_fs = get_fs(); + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newstat(filename, &s); + ret = sys_newstat(name, &s); set_fs(old_fs); + putname(name); if (putstat(statbuf, &s)) return -EFAULT; return ret; @@ -218,13 +224,18 @@ asmlinkage long sys32_newlstat (char *filename, struct stat32 *statbuf) { + char *name; mm_segment_t old_fs = get_fs(); struct stat s; int ret; + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newlstat(filename, &s); + ret = sys_newlstat(name, &s); set_fs(old_fs); + putname(name); if (putstat(statbuf, &s)) return -EFAULT; return ret; @@ -698,13 +709,18 @@ asmlinkage long sys32_statfs (const char *path, struct statfs32 *buf) { + const char *name; int ret; struct statfs s; mm_segment_t old_fs = get_fs(); + name = getname(path); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_statfs(path, &s); + ret = sys_statfs(name, &s); set_fs(old_fs); + putname(name); if (put_statfs(buf, &s)) return -EFAULT; return ret; @@ -3388,10 +3404,18 @@ return -EFAULT; uss.ss_sp = (void *) (long) buf32.ss_sp; uss.ss_flags = buf32.ss_flags; - uss.ss_size = buf32.ss_size; + /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the + check and set it to the user requested value later */ + if (buf32.ss_size < MINSIGSTKSZ_IA32) { + ret = -ENOMEM; + goto out; + } + uss.ss_size = MINSIGSTKSZ; set_fs(KERNEL_DS); ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12); + current->sas_ss_size = buf32.ss_size; set_fs(old_fs); +out: if (ret < 0) return(ret); if (uoss32) { @@ -3689,13 +3713,18 @@ asmlinkage long sys32_stat64 (char *filename, struct stat64 *statbuf) { + char *name; mm_segment_t old_fs = get_fs(); struct stat s; long ret; + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newstat(filename, &s); + ret = sys_newstat(name, &s); set_fs(old_fs); + putname(name); if (putstat64(statbuf, &s)) return -EFAULT; return ret; @@ -3704,13 +3733,18 @@ asmlinkage long sys32_lstat64 (char *filename, struct stat64 *statbuf) { + char *name; mm_segment_t old_fs = get_fs(); struct stat s; long ret; + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newlstat(filename, &s); + ret = sys_newlstat(name, &s); set_fs(old_fs); + putname(name); if (putstat64(statbuf, &s)) return -EFAULT; return ret; diff -urN linux-2.4.23-bk3/arch/ia64/kernel/acpi.c linux-2.4.23-bk4/arch/ia64/kernel/acpi.c --- linux-2.4.23-bk3/arch/ia64/kernel/acpi.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/kernel/acpi.c 2003-12-06 02:49:48.000000000 -0800 @@ -96,7 +96,7 @@ } if (!strcmp(hdr->oem_id, "HP")) { - return "hpzx1"; + return "hp"; } else if (!strcmp(hdr->oem_id, "SGI")) { return "sn2"; @@ -107,7 +107,7 @@ # if defined (CONFIG_IA64_HP_SIM) return "hpsim"; # elif defined (CONFIG_IA64_HP_ZX1) - return "hpzx1"; + return "hp"; # elif defined (CONFIG_IA64_SGI_SN2) return "sn2"; # elif defined (CONFIG_IA64_DIG) diff -urN linux-2.4.23-bk3/arch/ia64/kernel/efi.c linux-2.4.23-bk4/arch/ia64/kernel/efi.c --- linux-2.4.23-bk3/arch/ia64/kernel/efi.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/kernel/efi.c 2003-12-06 02:49:48.000000000 -0800 @@ -297,9 +297,9 @@ u64 start; u64 end; } prev, curr; - void *efi_map_start, *efi_map_end, *p, *q, *r; + void *efi_map_start, *efi_map_end, *p, *q; efi_memory_desc_t *md, *check_md; - u64 efi_desc_size, start, end, granule_addr, first_non_wb_addr = 0; + u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0; efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; @@ -312,41 +312,34 @@ if (!(md->attribute & EFI_MEMORY_WB)) continue; - if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > first_non_wb_addr) { - /* - * Search for the next run of contiguous WB memory. Start search - * at first granule boundary covered by md. - */ - granule_addr = ((md->phys_addr + IA64_GRANULE_SIZE - 1) - & -IA64_GRANULE_SIZE); - first_non_wb_addr = granule_addr; - for (q = p; q < efi_map_end; q += efi_desc_size) { - check_md = q; - - if (check_md->attribute & EFI_MEMORY_WB) - trim_bottom(check_md, granule_addr); - - if (check_md->phys_addr < granule_addr) - continue; + /* + * granule_addr is the base of md's first granule. + * [granule_addr - first_non_wb_addr) is guaranteed to + * be contiguous WB memory. + */ + granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1); + first_non_wb_addr = max(first_non_wb_addr, granule_addr); - if (!(check_md->attribute & EFI_MEMORY_WB)) - break; /* hit a non-WB region; stop search */ + if (first_non_wb_addr < md->phys_addr) { + trim_bottom(md, granule_addr + IA64_GRANULE_SIZE); + granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1); + first_non_wb_addr = max(first_non_wb_addr, granule_addr); + } - if (check_md->phys_addr != first_non_wb_addr) - break; /* hit a memory hole; stop search */ + for (q = p; q < efi_map_end; q += efi_desc_size) { + check_md = q; + if ((check_md->attribute & EFI_MEMORY_WB) && + (check_md->phys_addr == first_non_wb_addr)) first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT; - } - /* round it down to the previous granule-boundary: */ - first_non_wb_addr &= -IA64_GRANULE_SIZE; - - if (!(first_non_wb_addr > granule_addr)) - continue; /* couldn't find enough contiguous memory */ - - for (r = p; r < q; r += efi_desc_size) - trim_top(r, first_non_wb_addr); + else + break; /* non-WB or hole */ } + last_granule_addr = first_non_wb_addr & ~(IA64_GRANULE_SIZE - 1); + if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) + trim_top(md, last_granule_addr); + if (is_available_memory(md)) { if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) { if (md->phys_addr > mem_limit) @@ -446,10 +439,12 @@ panic("Woah! PAL code size bigger than a granule!"); mask = ~((1 << IA64_GRANULE_SHIFT) - 1); +#if EFI_DEBUG printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n", smp_processor_id(), md->phys_addr, md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE); +#endif /* * Cannot write to CRx with PSR.ic=1 @@ -688,8 +683,7 @@ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if ((md->phys_addr <= phys_addr) && (phys_addr <= - (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1))) + if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) return md->type; } return 0; @@ -709,8 +703,7 @@ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if ((md->phys_addr <= phys_addr) && (phys_addr <= - (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1))) + if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) return md->attribute; } return 0; diff -urN linux-2.4.23-bk3/arch/ia64/kernel/gate.S linux-2.4.23-bk4/arch/ia64/kernel/gate.S --- linux-2.4.23-bk3/arch/ia64/kernel/gate.S 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/ia64/kernel/gate.S 2003-12-06 02:49:48.000000000 -0800 @@ -88,10 +88,10 @@ ld8 r15=[base1] // get address of new RBS base (or NULL) cover // push args in interrupted frame onto backing store ;; - cmp.ne p8,p0=r15,r0 // do we need to switch the rbs? + cmp.ne p1,p0=r15,r0 // do we need to switch rbs? (note: pr is saved by kernel) mov.m r9=ar.bsp // fetch ar.bsp - .spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF -(p8) br.cond.spnt setup_rbs // yup -> (clobbers r14, r15, and r16) + .spillsp.p p1, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF +(p1) br.cond.spnt setup_rbs // yup -> (clobbers p8, r14-r16, and r18-r20) back_from_setup_rbs: alloc r8=ar.pfs,0,0,3,0 ld8 out0=[base0],16 // load arg0 (signum) @@ -130,8 +130,8 @@ ld8 r15=[base0],(CFM_OFF-BSP_OFF) // fetch sc_ar_bsp and advance to CFM_OFF mov r14=ar.bsp ;; - cmp.ne p8,p0=r14,r15 // do we need to restore the rbs? -(p8) br.cond.spnt restore_rbs // yup -> (clobbers r14-r18, f6 & f7) + cmp.ne p1,p0=r14,r15 // do we need to restore the rbs? +(p1) br.cond.spnt restore_rbs // yup -> (clobbers r14-r18, f6 & f7) ;; back_from_restore_rbs: adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp @@ -160,26 +160,30 @@ setup_rbs: mov ar.rsc=0 // put RSE into enforced lazy mode ;; - .save ar.rnat, r16 - mov r16=ar.rnat // save RNaT before switching backing store area + .save ar.rnat, r19 + mov r19=ar.rnat // save RNaT before switching backing store area adds r14=(RNAT_OFF+SIGCONTEXT_OFF),sp + mov r18=ar.bspstore mov ar.bspstore=r15 // switch over to new register backing store area ;; + .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF - st8 [r14]=r16 // save sc_ar_rnat + st8 [r14]=r19 // save sc_ar_rnat .body - adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp - mov.m r16=ar.bsp // sc_loadrs <- (new bsp - new bspstore) << 16 + adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp ;; invala sub r15=r16,r15 + extr.u r20=r18,3,6 ;; + mov ar.rsc=0xf // set RSE into eager mode, pl 3 + cmp.eq p8,p0=63,r20 shl r15=r15,16 ;; st8 [r14]=r15 // save sc_loadrs - mov ar.rsc=0xf // set RSE into eager mode, pl 3 +(p8) st8 [r18]=r19 // if bspstore points at RNaT slot, store RNaT there now .restore sp // pop .prologue br.cond.sptk back_from_setup_rbs diff -urN linux-2.4.23-bk3/arch/ia64/kernel/mca.c linux-2.4.23-bk4/arch/ia64/kernel/mca.c --- linux-2.4.23-bk3/arch/ia64/kernel/mca.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/kernel/mca.c 2003-12-06 02:49:48.000000000 -0800 @@ -91,6 +91,7 @@ static void ia64_log_init(int); extern void ia64_monarch_init_handler (void); extern void ia64_slave_init_handler (void); +static u64 ia64_log_get(int sal_info_type, u8 **buffer); extern struct hw_interrupt_type irq_type_iosapic_level; static struct irqaction cmci_irqaction = { @@ -151,7 +152,7 @@ */ static int cpe_poll_enabled = 1; -extern void salinfo_log_wakeup(int); +extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size); /* * ia64_mca_log_sal_error_record @@ -166,11 +167,13 @@ int ia64_mca_log_sal_error_record(int sal_info_type, int called_from_init) { - int platform_err = 0; + u8 *buffer; + u64 size; + int platform_err; - /* Get the MCA error record */ - if (!ia64_log_get(sal_info_type, (prfunc_t)printk)) - return platform_err; /* no record retrieved */ + size = ia64_log_get(sal_info_type, &buffer); + if (!size) + return 0; /* TODO: * 1. analyze error logs to determine recoverability @@ -178,8 +181,11 @@ * 3. set ia64_os_mca_recovery_successful flag, if applicable */ - salinfo_log_wakeup(sal_info_type); + salinfo_log_wakeup(sal_info_type, buffer, size); platform_err = ia64_log_print(sal_info_type, (prfunc_t)printk); + /* Clear logs from corrected errors in case there's no user-level logger */ + if (sal_info_type == SAL_INFO_TYPE_CPE || sal_info_type == SAL_INFO_TYPE_CMC) + ia64_sal_clear_state_info(sal_info_type); return platform_err; } @@ -834,7 +840,7 @@ irr = ia64_get_irr3(); break; } - } while (!(irr & (1 << irr_bit))) ; + } while (!(irr & (1UL << irr_bit))) ; } /* @@ -1416,12 +1422,12 @@ * Get the current MCA log from SAL and copy it into the OS log buffer. * * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE}) - * prfunc (fn ptr of log output function) * Outputs : size (total record length) + * *buffer (ptr to error record) * */ u64 -ia64_log_get(int sal_info_type, prfunc_t prfunc) +ia64_log_get(int sal_info_type, u8 **buffer) { sal_log_record_header_t *log_buffer; u64 total_len = 0; @@ -1439,6 +1445,7 @@ IA64_LOG_UNLOCK(sal_info_type); IA64_MCA_DEBUG("ia64_log_get: SAL error record type %d retrieved. " "Record length = %ld\n", sal_info_type, total_len); + *buffer = (u8 *) log_buffer; return total_len; } else { IA64_LOG_UNLOCK(sal_info_type); @@ -1483,7 +1490,7 @@ void ia64_log_rec_header_print (sal_log_record_header_t *lh, prfunc_t prfunc) { - prfunc("+Err Record ID: %d SAL Rev: %2x.%02x\n", lh->id, + prfunc("+Err Record ID: %ld SAL Rev: %2x.%02x\n", lh->id, lh->revision.major, lh->revision.minor); prfunc("+Time: %02x/%02x/%02x%02x %02x:%02x:%02x Severity %d\n", lh->timestamp.slh_month, lh->timestamp.slh_day, @@ -1606,13 +1613,13 @@ if (info->dl) prfunc(" Line: Data,"); prfunc(" Operation: %s,", pal_cache_op[info->op]); - if (info->wv) + if (info->wiv) prfunc(" Way: %d,", info->way); if (cache_check_info->valid.target_identifier) /* Hope target address is saved in target_identifier */ if (info->tv) prfunc(" Target Addr: 0x%lx,", target_addr); - if (info->mc) + if (info->mcc) prfunc(" MC: Corrected"); prfunc("\n"); } @@ -1648,13 +1655,13 @@ prfunc(" Failure: Data Translation Cache"); if (info->itr) { prfunc(" Failure: Instruction Translation Register"); - prfunc(" ,Slot: %d", info->tr_slot); + prfunc(" ,Slot: %ld", info->tr_slot); } if (info->dtr) { prfunc(" Failure: Data Translation Register"); - prfunc(" ,Slot: %d", info->tr_slot); + prfunc(" ,Slot: %ld", info->tr_slot); } - if (info->mc) + if (info->mcc) prfunc(" ,MC: Corrected"); prfunc("\n"); } @@ -1700,7 +1707,7 @@ prfunc(" ,Error: Internal"); if (info->eb) prfunc(" ,Error: External"); - if (info->mc) + if (info->mcc) prfunc(" ,MC: Corrected"); if (info->tv) prfunc(" ,Target Address: 0x%lx", targ_addr); @@ -2376,7 +2383,8 @@ ia64_log_rec_header_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc); break; case SAL_INFO_TYPE_INIT: - prfunc("+MCA INIT ERROR LOG (UNIMPLEMENTED)\n"); + prfunc("+CPU %d: SAL log contains INIT error record\n", smp_processor_id()); + ia64_log_rec_header_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc); break; case SAL_INFO_TYPE_CMC: prfunc("+BEGIN HARDWARE ERROR STATE AT CMC\n"); diff -urN linux-2.4.23-bk3/arch/ia64/kernel/mca_asm.S linux-2.4.23-bk4/arch/ia64/kernel/mca_asm.S --- linux-2.4.23-bk3/arch/ia64/kernel/mca_asm.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/kernel/mca_asm.S 2003-12-06 02:49:48.000000000 -0800 @@ -267,15 +267,15 @@ add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r4 - mov r3=cr0 // cr.dcr - mov r5=cr1 // cr.itm - mov r7=cr2;; // cr.iva + mov r3=cr.dcr + mov r5=cr.itm + mov r7=cr.iva;; st8 [r2]=r3,8*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; // 48 byte rements - mov r3=cr8;; // cr.pta + mov r3=cr.pta;; st8 [r2]=r3,8*8;; // 64 byte rements // if PSR.ic=0, reading interruption registers causes an illegal operation fault @@ -288,23 +288,23 @@ add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 - mov r3=cr16 // cr.ipsr - mov r5=cr17 // cr.isr - mov r7=r0;; // cr.ida => cr18 (reserved) + mov r3=cr.ipsr + mov r5=cr.isr + mov r7=r0;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=cr19 // cr.iip - mov r5=cr20 // cr.idtr - mov r7=cr21;; // cr.iitr + mov r3=cr.iip + mov r5=cr.ifa + mov r7=cr.itir;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=cr22 // cr.iipa - mov r5=cr23 // cr.ifs - mov r7=cr24;; // cr.iim + mov r3=cr.iipa + mov r5=cr.ifs + mov r7=cr.iim;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; @@ -313,104 +313,101 @@ st8 [r2]=r3,160;; // 160 byte rement SkipIntrRegs: - st8 [r2]=r0,168 // another 168 byte . + st8 [r2]=r0,152;; // another 152 byte . - mov r3=cr66;; // cr.lid - st8 [r2]=r3,40 // 40 byte rement + add r4=8,r2 // duplicate r2 in r4 + add r6=2*8,r2 // duplicate r2 in r6 - mov r3=cr71;; // cr.ivr - st8 [r2]=r3,8 - - mov r3=cr72;; // cr.tpr - st8 [r2]=r3,24 // 24 byte increment - - mov r3=r0;; // cr.eoi => cr75 - st8 [r2]=r3,168 // 168 byte inc. - - mov r3=r0;; // cr.irr0 => cr96 - st8 [r2]=r3,16 // 16 byte inc. - - mov r3=r0;; // cr.irr1 => cr98 - st8 [r2]=r3,16 // 16 byte inc. - - mov r3=r0;; // cr.irr2 => cr100 - st8 [r2]=r3,16 // 16 byte inc - - mov r3=r0;; // cr.irr3 => cr100 - st8 [r2]=r3,16 // 16b inc. - - mov r3=r0;; // cr.itv => cr114 - st8 [r2]=r3,16 // 16 byte inc. + mov r3=cr.lid +// mov r5=cr.ivr // cr.ivr, don't read it + mov r7=cr.tpr;; + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.pmv => cr116 - st8 [r2]=r3,8 + mov r3=r0 // cr.eoi => cr67 + mov r5=r0 // cr.irr0 => cr68 + mov r7=r0;; // cr.irr1 => cr69 + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.lrr0 => cr117 - st8 [r2]=r3,8 + mov r3=r0 // cr.irr2 => cr70 + mov r5=r0 // cr.irr3 => cr71 + mov r7=cr.itv;; + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.lrr1 => cr118 - st8 [r2]=r3,8 + mov r3=cr.pmv + mov r5=cr.cmcv;; + st8 [r2]=r3,7*8 + st8 [r4]=r5,7*8;; + + mov r3=r0 // cr.lrr0 => cr80 + mov r5=r0;; // cr.lrr1 => cr81 + st8 [r2]=r3,23*8 + st8 [r4]=r5,23*8;; - mov r3=r0;; // cr.cmcv => cr119 - st8 [r2]=r3,8*10;; + adds r2=25*8,r2;; cSaveARs: // save ARs add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 - mov r3=ar0 // ar.kro - mov r5=ar1 // ar.kr1 - mov r7=ar2;; // ar.kr2 + mov r3=ar.k0 + mov r5=ar.k1 + mov r7=ar.k2;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar3 // ar.kr3 - mov r5=ar4 // ar.kr4 - mov r7=ar5;; // ar.kr5 + mov r3=ar.k3 + mov r5=ar.k4 + mov r7=ar.k5;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar6 // ar.kr6 - mov r5=ar7 // ar.kr7 + mov r3=ar.k6 + mov r5=ar.k7 mov r7=r0;; // ar.kr8 st8 [r2]=r3,10*8 st8 [r4]=r5,10*8 st8 [r6]=r7,10*8;; // rement by 72 bytes - mov r3=ar16 // ar.rsc - mov ar16=r0 // put RSE in enforced lazy mode - mov r5=ar17 // ar.bsp + mov r3=ar.rsc + mov ar.rsc=r0 // put RSE in enforced lazy mode + mov r5=ar.bsp ;; - mov r7=ar18;; // ar.bspstore + mov r7=ar.bspstore;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar19;; // ar.rnat + mov r3=ar.rnat;; st8 [r2]=r3,8*13 // increment by 13x8 bytes - mov r3=ar32;; // ar.ccv + mov r3=ar.ccv;; st8 [r2]=r3,8*4 - mov r3=ar36;; // ar.unat + mov r3=ar.unat;; st8 [r2]=r3,8*4 - mov r3=ar40;; // ar.fpsr + mov r3=ar.fpsr;; st8 [r2]=r3,8*4 - mov r3=ar44;; // ar.itc + mov r3=ar.itc;; st8 [r2]=r3,160 // 160 - mov r3=ar64;; // ar.pfs + mov r3=ar.pfs;; st8 [r2]=r3,8 - mov r3=ar65;; // ar.lc + mov r3=ar.lc;; st8 [r2]=r3,8 - mov r3=ar66;; // ar.ec + mov r3=ar.ec;; st8 [r2]=r3 add r2=8*62,r2 //padding @@ -419,7 +416,8 @@ movl r4=0x00;; cStRR: - mov r3=rr[r4];; + dep.z r5=r4,61,3;; + mov r3=rr[r5];; st8 [r2]=r3,8 add r4=1,r4 br.cloop.sptk.few cStRR @@ -503,12 +501,12 @@ ld8 r3=[r2],8*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; // 48 byte increments - mov cr0=r3 // cr.dcr - mov cr1=r5 // cr.itm - mov cr2=r7;; // cr.iva + mov cr.dcr=r3 + mov cr.itm=r5 + mov cr.iva=r7;; ld8 r3=[r2],8*8;; // 64 byte increments -// mov cr8=r3 // cr.pta +// mov cr.pta=r3 // if PSR.ic=1, reading interruption registers causes an illegal operation fault @@ -525,64 +523,66 @@ ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr16=r3 // cr.ipsr - mov cr17=r5 // cr.isr is read only -// mov cr18=r7;; // cr.ida (reserved - don't restore) + mov cr.ipsr=r3 +// mov cr.isr=r5 // cr.isr is read only ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr19=r3 // cr.iip - mov cr20=r5 // cr.idtr - mov cr21=r7;; // cr.iitr + mov cr.iip=r3 + mov cr.ifa=r5 + mov cr.itir=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr22=r3 // cr.iipa - mov cr23=r5 // cr.ifs - mov cr24=r7 // cr.iim + mov cr.iipa=r3 + mov cr.ifs=r5 + mov cr.iim=r7 ld8 r3=[r2],160;; // 160 byte increment - mov cr25=r3 // cr.iha + mov cr.iha=r3 rSkipIntrRegs: - ld8 r3=[r2],168;; // another 168 byte inc. - - ld8 r3=[r2],40;; // 40 byte increment - mov cr66=r3 // cr.lid - - ld8 r3=[r2],8;; -// mov cr71=r3 // cr.ivr is read only - ld8 r3=[r2],24;; // 24 byte increment - mov cr72=r3 // cr.tpr - - ld8 r3=[r2],168;; // 168 byte inc. -// mov cr75=r3 // cr.eoi + ld8 r3=[r2],152;; // another 152 byte inc. - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr96=r3 // cr.irr0 is read only + add r4=8,r2 // duplicate r2 in r4 + add r6=2*8,r2;; // duplicate r2 in r6 - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr98=r3 // cr.irr1 is read only + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; + mov cr.lid=r3 +// mov cr.ivr=r5 // cr.ivr is read only + mov cr.tpr=r7;; + + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; +// mov cr.eoi=r3 +// mov cr.irr0=r5 // cr.irr0 is read only +// mov cr.irr1=r7;; // cr.irr1 is read only + + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; +// mov cr.irr2=r3 // cr.irr2 is read only +// mov cr.irr3=r5 // cr.irr3 is read only + mov cr.itv=r7;; + + ld8 r3=[r2],8*7 + ld8 r5=[r4],8*7;; + mov cr.pmv=r3 + mov cr.cmcv=r5;; + + ld8 r3=[r2],8*23 + ld8 r5=[r4],8*23;; + adds r2=8*23,r2 + adds r4=8*23,r4;; +// mov cr.lrr0=r3 +// mov cr.lrr1=r5 - ld8 r3=[r2],16;; // 16 byte inc -// mov cr100=r3 // cr.irr2 is read only - - ld8 r3=[r2],16;; // 16b inc. -// mov cr102=r3 // cr.irr3 is read only - - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr114=r3 // cr.itv - - ld8 r3=[r2],8;; -// mov cr116=r3 // cr.pmv - ld8 r3=[r2],8;; -// mov cr117=r3 // cr.lrr0 - ld8 r3=[r2],8;; -// mov cr118=r3 // cr.lrr1 - ld8 r3=[r2],8*10;; -// mov cr119=r3 // cr.cmcv + adds r2=8*2,r2;; restore_ARs: add r4=8,r2 // duplicate r2 in r4 @@ -591,67 +591,67 @@ ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov ar0=r3 // ar.kro - mov ar1=r5 // ar.kr1 - mov ar2=r7;; // ar.kr2 + mov ar.k0=r3 + mov ar.k1=r5 + mov ar.k2=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov ar3=r3 // ar.kr3 - mov ar4=r5 // ar.kr4 - mov ar5=r7;; // ar.kr5 + mov ar.k3=r3 + mov ar.k4=r5 + mov ar.k5=r7;; ld8 r3=[r2],10*8 ld8 r5=[r4],10*8 ld8 r7=[r6],10*8;; - mov ar6=r3 // ar.kr6 - mov ar7=r5 // ar.kr7 -// mov ar8=r6 // ar.kr8 + mov ar.k6=r3 + mov ar.k7=r5 ;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; -// mov ar16=r3 // ar.rsc -// mov ar17=r5 // ar.bsp is read only - mov ar16=r0 // make sure that RSE is in enforced lazy mode +// mov ar.rsc=r3 +// mov ar.bsp=r5 // ar.bsp is read only + mov ar.rsc=r0 // make sure that RSE is in enforced lazy mode ;; - mov ar18=r7;; // ar.bspstore + mov ar.bspstore=r7;; ld8 r9=[r2],8*13;; - mov ar19=r9 // ar.rnat + mov ar.rnat=r9 - mov ar16=r3 // ar.rsc + mov ar.rsc=r3 ld8 r3=[r2],8*4;; - mov ar32=r3 // ar.ccv + mov ar.ccv=r3 ld8 r3=[r2],8*4;; - mov ar36=r3 // ar.unat + mov ar.unat=r3 ld8 r3=[r2],8*4;; - mov ar40=r3 // ar.fpsr + mov ar.fpsr=r3 ld8 r3=[r2],160;; // 160 -// mov ar44=r3 // ar.itc +// mov ar.itc=r3 ld8 r3=[r2],8;; - mov ar64=r3 // ar.pfs + mov ar.pfs=r3 ld8 r3=[r2],8;; - mov ar65=r3 // ar.lc + mov ar.lc=r3 ld8 r3=[r2];; - mov ar66=r3 // ar.ec + mov ar.ec=r3 add r2=8*62,r2;; // padding restore_RRs: mov r5=ar.lc mov ar.lc=0x08-1 - movl r4=0x00 + movl r4=0x00;; cStRRr: + dep.z r7=r4,61,3 ld8 r3=[r2],8;; -// mov rr[r4]=r3 // what are its access previledges? + mov rr[r7]=r3 // what are its access previledges? add r4=1,r4 br.cloop.sptk.few cStRRr ;; diff -urN linux-2.4.23-bk3/arch/ia64/kernel/pci.c linux-2.4.23-bk4/arch/ia64/kernel/pci.c --- linux-2.4.23-bk3/arch/ia64/kernel/pci.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/kernel/pci.c 2003-12-06 02:49:48.000000000 -0800 @@ -523,8 +523,6 @@ if (ret < 0) return ret; - platform_pci_enable_device(dev); - printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name); return 0; diff -urN linux-2.4.23-bk3/arch/ia64/kernel/perfmon.c linux-2.4.23-bk4/arch/ia64/kernel/perfmon.c --- linux-2.4.23-bk3/arch/ia64/kernel/perfmon.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/kernel/perfmon.c 2003-12-06 02:49:48.000000000 -0800 @@ -4013,6 +4013,10 @@ if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_ONCE) { nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE; DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid)); + /* + * downgrade parent: once means only first child! + */ + ctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE; } /* * task is not yet visible in the tasklist, so we do diff -urN linux-2.4.23-bk3/arch/ia64/kernel/salinfo.c linux-2.4.23-bk4/arch/ia64/kernel/salinfo.c --- linux-2.4.23-bk3/arch/ia64/kernel/salinfo.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/kernel/salinfo.c 2003-12-06 02:49:48.000000000 -0800 @@ -3,19 +3,29 @@ * * Creates entries in /proc/sal for various system features. * - * Copyright (c) 2001 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. * Copyright (c) 2003 Hewlett-Packard Co * Bjorn Helgaas * * 10/30/2001 jbarnes@sgi.com copied much of Stephane's palinfo * code to create this file + * Oct 23 2003 kaos@sgi.com + * Replace IPI with set_cpus_allowed() to read a record from the required cpu. + * Redesign salinfo log processing to separate interrupt and user space + * contexts. + * Cache the record across multi-block reads from user space. + * Support > 64 cpus. + * Delete module_exit and MOD_INC/DEC_COUNT, salinfo cannot be a module. */ #include #include #include #include +#include +#include +#include #include #include @@ -57,48 +67,175 @@ (2 * ARRAY_SIZE(salinfo_log_name)) + /* /proc/sal/mca/{event,data} */ 1]; /* /proc/sal */ -struct salinfo_log_data { - int type; - u8 *log_buffer; - u64 log_size; -}; +/* Allow build with or without large SSI support */ +#ifdef CPU_MASK_NONE +#define SCA(x, y) set_cpus_allowed((x), &(y)) +#else +#define cpumask_t unsigned long +#define SCA(x, y) set_cpus_allowed((x), (y)) +#endif -struct salinfo_event { - int type; - int cpu; /* next CPU to check */ - volatile unsigned long cpu_mask; - wait_queue_head_t queue; +/* Some records we get ourselves, some are accessed as saved data in buffers + * that are owned by mca.c. + */ +struct salinfo_data_saved { + u8* buffer; + u64 size; + u64 id; + int cpu; }; -static struct salinfo_event *salinfo_event[ARRAY_SIZE(salinfo_log_name)]; +/* State transitions. Actions are :- + * Write "read " to the data file. + * Write "clear " to the data file. + * Write "oemdata to the data file. + * Read from the data file. + * Close the data file. + * + * Start state is NO_DATA. + * + * NO_DATA + * write "read " -> NO_DATA or LOG_RECORD. + * write "clear " -> NO_DATA or LOG_RECORD. + * write "oemdata -> return -EINVAL. + * read data -> return EOF. + * close -> unchanged. Free record areas. + * + * LOG_RECORD + * write "read " -> NO_DATA or LOG_RECORD. + * write "clear " -> NO_DATA or LOG_RECORD. + * write "oemdata -> format the oem data, goto OEMDATA. + * read data -> return the INIT/MCA/CMC/CPE record. + * close -> unchanged. Keep record areas. + * + * OEMDATA + * write "read " -> NO_DATA or LOG_RECORD. + * write "clear " -> NO_DATA or LOG_RECORD. + * write "oemdata -> format the oem data, goto OEMDATA. + * read data -> return the formatted oemdata. + * close -> unchanged. Keep record areas. + * + * Closing the data file does not change the state. This allows shell scripts + * to manipulate salinfo data, each shell redirection opens the file, does one + * action then closes it again. The record areas are only freed at close when + * the state is NO_DATA. + */ +enum salinfo_state { + STATE_NO_DATA, + STATE_LOG_RECORD, + STATE_OEMDATA, +}; struct salinfo_data { - int open; /* single-open to prevent races */ - int type; - int cpu; /* "current" cpu for reads */ + volatile cpumask_t cpu_event; /* which cpus have outstanding events */ + struct semaphore sem; /* count of cpus with outstanding events (bits set in cpu_event) */ + u8 *log_buffer; + u64 log_size; + u8 *oemdata; /* decoded oem data */ + u64 oemdata_size; + int open; /* single-open to prevent races */ + u8 type; + u8 saved_num; /* using a saved record? */ + enum salinfo_state state :8; /* processing state */ + u8 padding; + int cpu_check; /* next CPU to check */ + struct salinfo_data_saved data_saved[5];/* save last 5 records from mca.c, must be < 255 */ }; static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)]; -static spinlock_t data_lock; +static spinlock_t data_lock, data_saved_lock; + +/** salinfo_platform_oemdata - optional callback to decode oemdata from an error + * record. + * @sect_header: pointer to the start of the section to decode. + * @oemdata: returns vmalloc area containing the decded output. + * @oemdata_size: returns length of decoded output (strlen). + * + * Description: If user space asks for oem data to be decoded by the kernel + * and/or prom and the platform has set salinfo_platform_oemdata to the address + * of a platform specific routine then call that routine. salinfo_platform_oemdata + * vmalloc's and formats its output area, returning the address of the text + * and its strlen. Returns 0 for success, -ve for error. The callback is + * invoked on the cpu that generated the error record. + */ +int (*salinfo_platform_oemdata)(const u8 *sect_header, u8 **oemdata, u64 *oemdata_size); + +struct salinfo_platform_oemdata_parms { + const u8 *efi_guid; + u8 **oemdata; + u64 *oemdata_size; + int ret; +}; + +static void +salinfo_platform_oemdata_cpu(void *context) +{ + struct salinfo_platform_oemdata_parms *parms = context; + parms->ret = salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size); +} +static void +shift1_data_saved (struct salinfo_data *data, int shift) +{ + memcpy(data->data_saved+shift, data->data_saved+shift+1, + (ARRAY_SIZE(data->data_saved) - (shift+1)) * sizeof(data->data_saved[0])); + memset(data->data_saved + ARRAY_SIZE(data->data_saved) - 1, 0, + sizeof(data->data_saved[0])); +} + +/* This routine is invoked in interrupt context. Note: mca.c enables + * interrupts before calling this code for CMC/CPE. MCA and INIT events are + * not irq safe, do not call any routines that use spinlocks, they may deadlock. + * + * The buffer passed from mca.c points to the output from ia64_log_get. This is + * a persistent buffer but its contents can change between the interrupt and + * when user space processes the record. Save the record id to identify + * changes. + */ void -salinfo_log_wakeup(int type) +salinfo_log_wakeup(int type, u8 *buffer, u64 size) { - if (type < ARRAY_SIZE(salinfo_log_name)) { - struct salinfo_event *event = salinfo_event[type]; + struct salinfo_data *data = salinfo_data + type; + struct salinfo_data_saved *data_saved; + unsigned long flags = 0; + int i, irqsafe = type != SAL_INFO_TYPE_MCA && type != SAL_INFO_TYPE_INIT; + int saved_size = ARRAY_SIZE(data->data_saved); + + BUG_ON(type >= ARRAY_SIZE(salinfo_log_name)); + + if (irqsafe) + spin_lock_irqsave(&data_saved_lock, flags); + for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { + if (!data_saved->buffer) + break; + } + if (i == saved_size) { + if (!data->saved_num) { + shift1_data_saved(data, 0); + data_saved = data->data_saved + saved_size - 1; + } else + data_saved = NULL; + } + if (data_saved) { + data_saved->cpu = smp_processor_id(); + data_saved->id = ((sal_log_record_header_t *)buffer)->id; + data_saved->size = size; + data_saved->buffer = buffer; + } + if (irqsafe) + spin_unlock_irqrestore(&data_saved_lock, flags); - if (event) { - set_bit(smp_processor_id(), &event->cpu_mask); - wake_up_interruptible(&event->queue); - } + if (!test_and_set_bit(smp_processor_id(), &data->cpu_event)) { + if (irqsafe) + up(&data->sem); } } static int salinfo_event_open(struct inode *inode, struct file *file) { - if (!suser()) + if (!capable(CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -107,24 +244,23 @@ salinfo_event_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; - struct salinfo_event *event = entry->data; + struct proc_dir_entry *entry = PDE(inode); + struct salinfo_data *data = entry->data; char cmd[32]; size_t size; int i, n, cpu = -1; retry: - if (!event->cpu_mask) { + if (down_trylock(&data->sem)) { if (file->f_flags & O_NONBLOCK) return -EAGAIN; - interruptible_sleep_on(&event->queue); - if (signal_pending(current)) - return -EINTR; + if (down_interruptible(&data->sem)) + return -ERESTARTSYS; } - n = event->cpu; + n = data->cpu_check; for (i = 0; i < NR_CPUS; i++) { - if (event->cpu_mask & 1UL << n) { + if (test_bit(n, &data->cpu_event)) { cpu = n; break; } @@ -135,10 +271,13 @@ if (cpu == -1) goto retry; + /* events are sticky until the user says "clear" */ + up(&data->sem); + /* for next read, start checking at next CPU */ - event->cpu = cpu; - if (++event->cpu == NR_CPUS) - event->cpu = 0; + data->cpu_check = cpu; + if (++data->cpu_check == NR_CPUS) + data->cpu_check = 0; snprintf(cmd, sizeof(cmd), "read %d\n", cpu); @@ -159,10 +298,10 @@ static int salinfo_log_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; - if (!suser()) + if (!capable(CAP_SYS_ADMIN)) return -EPERM; spin_lock(&data_lock); @@ -173,15 +312,27 @@ data->open = 1; spin_unlock(&data_lock); + if (data->state == STATE_NO_DATA && + !(data->log_buffer = vmalloc(ia64_sal_get_state_info_size(data->type)))) { + data->open = 0; + return -ENOMEM; + } + return 0; } static int salinfo_log_release(struct inode *inode, struct file *file) { - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; + if (data->state == STATE_NO_DATA) { + vfree(data->log_buffer); + vfree(data->oemdata); + data->log_buffer = NULL; + data->oemdata = NULL; + } spin_lock(&data_lock); data->open = 0; spin_unlock(&data_lock); @@ -191,95 +342,131 @@ static void call_on_cpu(int cpu, void (*fn)(void *), void *arg) { - if (cpu == smp_processor_id()) - (*fn)(arg); -#ifdef CONFIG_SMP - else if (cpu_online(cpu)) /* cpu may not have been validated */ - smp_call_function_single(cpu, fn, arg, 0, 1); -#endif + cpumask_t save_cpus_allowed, new_cpus_allowed; + memcpy(&save_cpus_allowed, ¤t->cpus_allowed, sizeof(save_cpus_allowed)); + memset(&new_cpus_allowed, 0, sizeof(new_cpus_allowed)); + set_bit(cpu, &new_cpus_allowed); + SCA(current, new_cpus_allowed); + (*fn)(arg); + SCA(current, save_cpus_allowed); } static void salinfo_log_read_cpu(void *context) { - struct salinfo_log_data *info = context; - struct salinfo_event *event = salinfo_event[info->type]; - u64 size; - - size = ia64_sal_get_state_info_size(info->type); - info->log_buffer = kmalloc(size, GFP_ATOMIC); - if (!info->log_buffer) - return; - - clear_bit(smp_processor_id(), &event->cpu_mask); - info->log_size = ia64_sal_get_state_info(info->type, (u64 *) info->log_buffer); - if (info->log_size) - salinfo_log_wakeup(info->type); + struct salinfo_data *data = context; + data->log_size = ia64_sal_get_state_info(data->type, (u64 *) data->log_buffer); +} + +static void +salinfo_log_new_read(int cpu, struct salinfo_data *data) +{ + struct salinfo_data_saved *data_saved; + unsigned long flags; + int i; + int saved_size = ARRAY_SIZE(data->data_saved); + + data->saved_num = 0; + spin_lock_irqsave(&data_saved_lock, flags); +retry: + for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { + if (data_saved->buffer && data_saved->cpu == cpu) { + sal_log_record_header_t *rh = (sal_log_record_header_t *)(data_saved->buffer); + data->log_size = data_saved->size; + memcpy(data->log_buffer, rh, data->log_size); + barrier(); /* id check must not be moved */ + if (rh->id == data_saved->id) { + data->saved_num = i+1; + break; + } + /* saved record changed by mca.c since interrupt, discard it */ + shift1_data_saved(data, i); + goto retry; + } + } + spin_unlock_irqrestore(&data_saved_lock, flags); + + if (!data->saved_num) + call_on_cpu(cpu, salinfo_log_read_cpu, data); + data->state = data->log_size ? STATE_LOG_RECORD : STATE_NO_DATA; } static ssize_t salinfo_log_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; - struct salinfo_log_data info; - int ret; void *saldata; size_t size; + u8 *buf; + u64 bufsize; - info.type = data->type; - info.log_buffer = 0; - call_on_cpu(data->cpu, salinfo_log_read_cpu, &info); - if (!info.log_buffer || *ppos >= info.log_size) { - ret = 0; - goto out; + if (data->state == STATE_LOG_RECORD) { + buf = data->log_buffer; + bufsize = data->log_size; + } else if (data->state == STATE_OEMDATA) { + buf = data->oemdata; + bufsize = data->oemdata_size; + } else { + buf = NULL; + bufsize = 0; } + if (*ppos >= bufsize) + return 0; - saldata = info.log_buffer + file->f_pos; - size = info.log_size - file->f_pos; + saldata = buf + file->f_pos; + size = bufsize - file->f_pos; if (size > count) size = count; - if (copy_to_user(buffer, saldata, size)) { - ret = -EFAULT; - goto out; - } + if (copy_to_user(buffer, saldata, size)) + return -EFAULT; *ppos += size; - ret = size; - -out: - kfree(info.log_buffer); - return ret; + return size; } static void salinfo_log_clear_cpu(void *context) { struct salinfo_data *data = context; - struct salinfo_event *event = salinfo_event[data->type]; - struct salinfo_log_data info; - - clear_bit(smp_processor_id(), &event->cpu_mask); ia64_sal_clear_state_info(data->type); +} - /* clearing one record may make another visible */ - info.type = data->type; - salinfo_log_read_cpu(&info); - if (info.log_buffer && info.log_size) - salinfo_log_wakeup(data->type); +static int +salinfo_log_clear(struct salinfo_data *data, int cpu) +{ + data->state = STATE_NO_DATA; + if (!test_bit(cpu, &data->cpu_event)) + return 0; + down(&data->sem); + clear_bit(cpu, &data->cpu_event); + if (data->saved_num) { + unsigned long flags; + spin_lock_irqsave(&data_saved_lock, flags); + shift1_data_saved(data, data->saved_num - 1 ); + data->saved_num = 0; + spin_unlock_irqrestore(&data_saved_lock, flags); + } + call_on_cpu(cpu, salinfo_log_clear_cpu, data); - kfree(info.log_buffer); + /* clearing a record may make a new record visible */ + salinfo_log_new_read(cpu, data); + if (data->state == STATE_LOG_RECORD && + !test_and_set_bit(cpu, &data->cpu_event)) + up(&data->sem); + return 0; } static ssize_t salinfo_log_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; char cmd[32]; size_t size; + u32 offset; int cpu; size = sizeof(cmd); @@ -288,10 +475,31 @@ if (copy_from_user(cmd, buffer, size)) return -EFAULT; - if (sscanf(cmd, "read %d", &cpu) == 1) - data->cpu = cpu; - else if (sscanf(cmd, "clear %d", &cpu) == 1) - call_on_cpu(cpu, salinfo_log_clear_cpu, data); + if (sscanf(cmd, "read %d", &cpu) == 1) { + salinfo_log_new_read(cpu, data); + } else if (sscanf(cmd, "clear %d", &cpu) == 1) { + int ret; + if ((ret = salinfo_log_clear(data, cpu))) + count = ret; + } else if (sscanf(cmd, "oemdata %d %d", &cpu, &offset) == 2) { + if (data->state != STATE_LOG_RECORD && data->state != STATE_OEMDATA) + return -EINVAL; + if (offset > data->log_size - sizeof(efi_guid_t)) + return -EINVAL; + data->state = STATE_OEMDATA; + if (salinfo_platform_oemdata) { + struct salinfo_platform_oemdata_parms parms = { + .efi_guid = data->log_buffer + offset, + .oemdata = &data->oemdata, + .oemdata_size = &data->oemdata_size + }; + call_on_cpu(cpu, salinfo_platform_oemdata_cpu, &parms); + if (parms.ret) + count = parms.ret; + } else + data->oemdata_size = 0; + } else + return -EINVAL; return count; } @@ -309,9 +517,8 @@ struct proc_dir_entry *salinfo_dir; /* /proc/sal dir entry */ struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */ struct proc_dir_entry *dir, *entry; - struct salinfo_event *event; struct salinfo_data *data; - int i, j; + int i, j, online; salinfo_dir = proc_mkdir("sal", NULL); if (!salinfo_dir) @@ -324,6 +531,9 @@ } for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { + data = salinfo_data + i; + data->type = i; + sema_init(&data->sem, 0); dir = proc_mkdir(salinfo_log_name[i], salinfo_dir); if (!dir) continue; @@ -331,32 +541,26 @@ entry = create_proc_entry("event", S_IRUSR, dir); if (!entry) continue; - - event = kmalloc(sizeof(*event), GFP_KERNEL); - if (!event) - continue; - memset(event, 0, sizeof(*event)); - event->type = i; - init_waitqueue_head(&event->queue); - salinfo_event[i] = event; - /* we missed any events before now */ - for (j = 0; j < NR_CPUS; j++) - if (cpu_online(j)) - set_bit(j, &event->cpu_mask); - entry->data = event; + entry->data = data; entry->proc_fops = &salinfo_event_fops; *sdir++ = entry; entry = create_proc_entry("data", S_IRUSR | S_IWUSR, dir); if (!entry) continue; - - data = &salinfo_data[i]; - data->type = i; entry->data = data; entry->proc_fops = &salinfo_data_fops; *sdir++ = entry; + /* we missed any events before now */ + online = 0; + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) { + set_bit(j, &data->cpu_event); + ++online; + } + sema_init(&data->sem, online); + *sdir++ = dir; } @@ -365,17 +569,6 @@ return 0; } -static void __exit -salinfo_exit(void) -{ - int i = 0; - - for (i = 0; i < ARRAY_SIZE(salinfo_proc_entries); i++) { - if (salinfo_proc_entries[i]) - remove_proc_entry (salinfo_proc_entries[i]->name, NULL); - } -} - /* * 'data' contains an integer that corresponds to the feature we're * testing @@ -385,8 +578,6 @@ { int len = 0; - MOD_INC_USE_COUNT; - len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n"); if (len <= off+count) *eof = 1; @@ -397,10 +588,7 @@ if (len>count) len = count; if (len<0) len = 0; - MOD_DEC_USE_COUNT; - return len; } module_init(salinfo_init); -module_exit(salinfo_exit); diff -urN linux-2.4.23-bk3/arch/ia64/kernel/setup.c linux-2.4.23-bk4/arch/ia64/kernel/setup.c --- linux-2.4.23-bk3/arch/ia64/kernel/setup.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/kernel/setup.c 2003-12-06 02:49:48.000000000 -0800 @@ -376,7 +376,6 @@ saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; /* for safety */ efi_init(); - find_memory(); #ifdef CONFIG_ACPI_BOOT /* Initialize the ACPI boot-time table parser */ @@ -392,6 +391,7 @@ #endif /* CONFIG_APCI_BOOT */ iomem_resource.end = ~0UL; /* FIXME probably belongs elsewhere */ + find_memory(); #if 0 /* XXX fix me */ diff -urN linux-2.4.23-bk3/arch/ia64/kernel/time.c linux-2.4.23-bk4/arch/ia64/kernel/time.c --- linux-2.4.23-bk3/arch/ia64/kernel/time.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.23-bk4/arch/ia64/kernel/time.c 2003-12-06 02:49:48.000000000 -0800 @@ -93,7 +93,6 @@ * it! */ tv->tv_usec -= gettimeoffset(); - tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); while (tv->tv_usec < 0) { tv->tv_usec += 1000000; diff -urN linux-2.4.23-bk3/arch/ia64/kernel/traps.c linux-2.4.23-bk4/arch/ia64/kernel/traps.c --- linux-2.4.23-bk3/arch/ia64/kernel/traps.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/kernel/traps.c 2003-12-06 02:49:48.000000000 -0800 @@ -221,10 +221,6 @@ unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7, unsigned long stack) { - struct pt_regs *regs = (struct pt_regs *) &stack; - - printk(KERN_DEBUG "%s(%d): \n", current->comm, current->pid, - regs->r15, arg0, arg1, arg2, arg3); return -ENOSYS; } diff -urN linux-2.4.23-bk3/arch/ia64/lib/Makefile linux-2.4.23-bk4/arch/ia64/lib/Makefile --- linux-2.4.23-bk3/arch/ia64/lib/Makefile 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.23-bk4/arch/ia64/lib/Makefile 2003-12-06 02:49:48.000000000 -0800 @@ -18,6 +18,7 @@ obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o +obj-$(CONFIG_MD_RAID5) += xor.o IGNORE_FLAGS_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o diff -urN linux-2.4.23-bk3/arch/ia64/lib/xor.S linux-2.4.23-bk4/arch/ia64/lib/xor.S --- linux-2.4.23-bk3/arch/ia64/lib/xor.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/lib/xor.S 2003-12-06 02:49:48.000000000 -0800 @@ -0,0 +1,184 @@ +/* + * arch/ia64/lib/xor.S + * + * Optimized RAID-5 checksumming functions for IA-64. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * You should have received a copy of the GNU General Public License + * (for example /usr/src/linux/COPYING); if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +GLOBAL_ENTRY(xor_ia64_2) + .prologue + .fframe 0 + .save ar.pfs, r31 + alloc r31 = ar.pfs, 3, 0, 13, 16 + .save ar.lc, r30 + mov r30 = ar.lc + .save pr, r29 + mov r29 = pr + ;; + .body + mov r8 = in1 + mov ar.ec = 6 + 2 + shr in0 = in0, 3 + ;; + adds in0 = -1, in0 + mov r16 = in1 + mov r17 = in2 + ;; + mov ar.lc = in0 + mov pr.rot = 1 << 16 + ;; + .rotr s1[6+1], s2[6+1], d[2] + .rotp p[6+2] +0: +(p[0]) ld8.nta s1[0] = [r16], 8 +(p[0]) ld8.nta s2[0] = [r17], 8 +(p[6]) xor d[0] = s1[6], s2[6] +(p[6+1])st8.nta [r8] = d[1], 8 + nop.f 0 + br.ctop.dptk.few 0b + ;; + mov ar.lc = r30 + mov pr = r29, -1 + br.ret.sptk.few rp +END(xor_ia64_2) + +GLOBAL_ENTRY(xor_ia64_3) + .prologue + .fframe 0 + .save ar.pfs, r31 + alloc r31 = ar.pfs, 4, 0, 20, 24 + .save ar.lc, r30 + mov r30 = ar.lc + .save pr, r29 + mov r29 = pr + ;; + .body + mov r8 = in1 + mov ar.ec = 6 + 2 + shr in0 = in0, 3 + ;; + adds in0 = -1, in0 + mov r16 = in1 + mov r17 = in2 + ;; + mov r18 = in3 + mov ar.lc = in0 + mov pr.rot = 1 << 16 + ;; + .rotr s1[6+1], s2[6+1], s3[6+1], d[2] + .rotp p[6+2] +0: +(p[0]) ld8.nta s1[0] = [r16], 8 +(p[0]) ld8.nta s2[0] = [r17], 8 +(p[6]) xor d[0] = s1[6], s2[6] + ;; +(p[0]) ld8.nta s3[0] = [r18], 8 +(p[6+1])st8.nta [r8] = d[1], 8 +(p[6]) xor d[0] = d[0], s3[6] + br.ctop.dptk.few 0b + ;; + mov ar.lc = r30 + mov pr = r29, -1 + br.ret.sptk.few rp +END(xor_ia64_3) + +GLOBAL_ENTRY(xor_ia64_4) + .prologue + .fframe 0 + .save ar.pfs, r31 + alloc r31 = ar.pfs, 5, 0, 27, 32 + .save ar.lc, r30 + mov r30 = ar.lc + .save pr, r29 + mov r29 = pr + ;; + .body + mov r8 = in1 + mov ar.ec = 6 + 2 + shr in0 = in0, 3 + ;; + adds in0 = -1, in0 + mov r16 = in1 + mov r17 = in2 + ;; + mov r18 = in3 + mov ar.lc = in0 + mov pr.rot = 1 << 16 + mov r19 = in4 + ;; + .rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], d[2] + .rotp p[6+2] +0: +(p[0]) ld8.nta s1[0] = [r16], 8 +(p[0]) ld8.nta s2[0] = [r17], 8 +(p[6]) xor d[0] = s1[6], s2[6] +(p[0]) ld8.nta s3[0] = [r18], 8 +(p[0]) ld8.nta s4[0] = [r19], 8 +(p[6]) xor r20 = s3[6], s4[6] + ;; +(p[6+1])st8.nta [r8] = d[1], 8 +(p[6]) xor d[0] = d[0], r20 + br.ctop.dptk.few 0b + ;; + mov ar.lc = r30 + mov pr = r29, -1 + br.ret.sptk.few rp +END(xor_ia64_4) + +GLOBAL_ENTRY(xor_ia64_5) + .prologue + .fframe 0 + .save ar.pfs, r31 + alloc r31 = ar.pfs, 6, 0, 34, 40 + .save ar.lc, r30 + mov r30 = ar.lc + .save pr, r29 + mov r29 = pr + ;; + .body + mov r8 = in1 + mov ar.ec = 6 + 2 + shr in0 = in0, 3 + ;; + adds in0 = -1, in0 + mov r16 = in1 + mov r17 = in2 + ;; + mov r18 = in3 + mov ar.lc = in0 + mov pr.rot = 1 << 16 + mov r19 = in4 + mov r20 = in5 + ;; + .rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], s5[6+1], d[2] + .rotp p[6+2] +0: +(p[0]) ld8.nta s1[0] = [r16], 8 +(p[0]) ld8.nta s2[0] = [r17], 8 +(p[6]) xor d[0] = s1[6], s2[6] +(p[0]) ld8.nta s3[0] = [r18], 8 +(p[0]) ld8.nta s4[0] = [r19], 8 +(p[6]) xor r21 = s3[6], s4[6] + ;; +(p[0]) ld8.nta s5[0] = [r20], 8 +(p[6+1])st8.nta [r8] = d[1], 8 +(p[6]) xor d[0] = d[0], r21 + ;; +(p[6]) xor d[0] = d[0], s5[6] + nop.f 0 + br.ctop.dptk.few 0b + ;; + mov ar.lc = r30 + mov pr = r29, -1 + br.ret.sptk.few rp +END(xor_ia64_5) diff -urN linux-2.4.23-bk3/arch/ia64/mm/init.c linux-2.4.23-bk4/arch/ia64/mm/init.c --- linux-2.4.23-bk3/arch/ia64/mm/init.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/mm/init.c 2003-12-06 02:49:48.000000000 -0800 @@ -488,7 +488,8 @@ { char byte; - return __get_user(byte, (char *) page) == 0; + return (__get_user(byte, (char *) page) == 0) + && (__get_user(byte, (char *) (page + 1) - 1) == 0); } #define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1)) diff -urN linux-2.4.23-bk3/arch/ia64/mm/tlb.c linux-2.4.23-bk4/arch/ia64/mm/tlb.c --- linux-2.4.23-bk3/arch/ia64/mm/tlb.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/mm/tlb.c 2003-12-06 02:49:48.000000000 -0800 @@ -75,7 +75,7 @@ * and because interrupts are disabled during context switch. */ for (i = 0; i < NR_CPUS; ++i) - if (i != smp_processor_id()) + if (cpu_online(i) && (i != smp_processor_id())) cpu_data(i)->need_tlb_flush = 1; local_flush_tlb_all(); } diff -urN linux-2.4.23-bk3/arch/ia64/tools/Makefile linux-2.4.23-bk4/arch/ia64/tools/Makefile --- linux-2.4.23-bk3/arch/ia64/tools/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.23-bk4/arch/ia64/tools/Makefile 2003-12-06 02:49:48.000000000 -0800 @@ -33,7 +33,7 @@ comma := , -print_offsets: print_offsets.c FORCE_RECOMPILE +print_offsets: emptyoffsets print_offsets.c FORCE_RECOMPILE $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) print_offsets.c -o $@ FORCE_RECOMPILE: @@ -43,9 +43,20 @@ offsets.h: print_offsets.s $(AWK) -f print_offsets.awk $^ > $@ -print_offsets.s: print_offsets.c +print_offsets.s: emptyoffsets print_offsets.c $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -S print_offsets.c -o $@ endif +# +# The TARGET offsets.h is included by ptrace.h, which is included by +# print_offsets.c, so can't compile print_offsets.c to create offsets.h +# until we already have offsets.h. Break the chicken-and-egg cycle by +# creating a dummy offsets.h with sufficient define's to bootstrap +# the first compilation of print_offsets.c. +# + +emptyoffsets: + test -f ${TARGET} || echo '#define IA64_TASK_THREAD_OFFSET 0' > ${TARGET} + .PHONY: all modules modules_install diff -urN linux-2.4.23-bk3/drivers/char/drm/ffb_drv.c linux-2.4.23-bk4/drivers/char/drm/ffb_drv.c --- linux-2.4.23-bk3/drivers/char/drm/ffb_drv.c 2001-10-21 10:40:36.000000000 -0700 +++ linux-2.4.23-bk4/drivers/char/drm/ffb_drv.c 2003-12-06 02:49:48.000000000 -0800 @@ -372,25 +372,6 @@ return ret; } -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init ffb_options(char *str) -{ - DRM(parse_options)(str); - return 1; -} - -__setup(DRIVER_NAME "=", ffb_options); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff -urN linux-2.4.23-bk3/drivers/net/pcmcia/pcnet_cs.c linux-2.4.23-bk4/drivers/net/pcmcia/pcnet_cs.c --- linux-2.4.23-bk3/drivers/net/pcmcia/pcnet_cs.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk4/drivers/net/pcmcia/pcnet_cs.c 2003-12-06 02:49:49.000000000 -0800 @@ -11,7 +11,7 @@ Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net - pcnet_cs.c 1.149 2002/06/29 06:27:37 + pcnet_cs.c 1.153 2003/11/09 18:53:09 The network driver code is based on Donald Becker's NE2000 code: @@ -75,7 +75,7 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"pcnet_cs.c 1.149 2002/06/29 06:27:37 (David Hinds)"; +"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -303,7 +303,8 @@ memset(info, 0, sizeof(*info)); link = &info->link; dev = &info->dev; link->priv = info; - + + init_timer(&link->release); link->release.function = &pcnet_release; link->release.data = (u_long)link; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; @@ -895,13 +896,15 @@ MII interface support for DL10019 and DL10022 based cards - On the DL10019, the MII IO direction bit is 0x10; on the DL10022 + On the DL10019, the MII IO direction bit is 0x10; on the DL10022 it is 0x20. Setting both bits seems to work on both card types. ======================================================================*/ #define DLINK_GPIO 0x1c #define DLINK_DIAG 0x1d +#define DLINK_EEPROM 0x1e + #define MDIO_SHIFT_CLK 0x80 #define MDIO_DATA_OUT 0x40 #define MDIO_DIR_WRITE 0x30 @@ -964,6 +967,98 @@ outb_p(0x00, addr); } +/*====================================================================== + + EEPROM access routines for DL10019 and DL10022 based cards + +======================================================================*/ + +#define EE_EEP 0x40 +#define EE_ASIC 0x10 +#define EE_CS 0x08 +#define EE_CK 0x04 +#define EE_DO 0x02 +#define EE_DI 0x01 +#define EE_ADOT 0x01 /* DataOut for ASIC */ +#define EE_READ_CMD 0x06 + +#define DL19FDUPLX 0x0400 /* DL10019 Full duplex mode */ + +static int read_eeprom(ioaddr_t ioaddr, int location) +{ + int i, retval = 0; + ioaddr_t ee_addr = ioaddr + DLINK_EEPROM; + int read_cmd = location | (EE_READ_CMD << 8); + + outb(0, ee_addr); + outb(EE_EEP|EE_CS, ee_addr); + + /* Shift the read command bits out. */ + for (i = 10; i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_DO : 0; + outb_p(EE_EEP|EE_CS|dataval, ee_addr); + outb_p(EE_EEP|EE_CS|dataval|EE_CK, ee_addr); + } + outb(EE_EEP|EE_CS, ee_addr); + + for (i = 16; i > 0; i--) { + outb_p(EE_EEP|EE_CS | EE_CK, ee_addr); + retval = (retval << 1) | ((inb(ee_addr) & EE_DI) ? 1 : 0); + outb_p(EE_EEP|EE_CS, ee_addr); + } + + /* Terminate the EEPROM access. */ + outb(0, ee_addr); + return retval; +} + +/* + The internal ASIC registers can be changed by EEPROM READ access + with EE_ASIC bit set. + In ASIC mode, EE_ADOT is used to output the data to the ASIC. +*/ + +static void write_asic(ioaddr_t ioaddr, int location, short asic_data) +{ + int i; + ioaddr_t ee_addr = ioaddr + DLINK_EEPROM; + short dataval; + int read_cmd = location | (EE_READ_CMD << 8); + + asic_data |= read_eeprom(ioaddr, location); + + outb(0, ee_addr); + outb(EE_ASIC|EE_CS|EE_DI, ee_addr); + + read_cmd = read_cmd >> 1; + + /* Shift the read command bits out. */ + for (i = 9; i >= 0; i--) { + dataval = (read_cmd & (1 << i)) ? EE_DO : 0; + outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); + outb_p(EE_ASIC|EE_CS|EE_DI|dataval|EE_CK, ee_addr); + outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); + } + // sync + outb(EE_ASIC|EE_CS, ee_addr); + outb(EE_ASIC|EE_CS|EE_CK, ee_addr); + outb(EE_ASIC|EE_CS, ee_addr); + + for (i = 15; i >= 0; i--) { + dataval = (asic_data & (1 << i)) ? EE_ADOT : 0; + outb_p(EE_ASIC|EE_CS|dataval, ee_addr); + outb_p(EE_ASIC|EE_CS|dataval|EE_CK, ee_addr); + outb_p(EE_ASIC|EE_CS|dataval, ee_addr); + } + + /* Terminate the ASIC access. */ + outb(EE_ASIC|EE_DI, ee_addr); + outb(EE_ASIC|EE_DI| EE_CK, ee_addr); + outb(EE_ASIC|EE_DI, ee_addr); + + outb(0, ee_addr); +} + /*====================================================================*/ static void set_misc_reg(struct net_device *dev) @@ -1178,6 +1273,9 @@ if (link && (info->flags & IS_DL10022)) { /* Disable collision detection on full duplex links */ outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG); + } else if (link && (info->flags & IS_DL10019)) { + /* Disable collision detection on full duplex links */ + write_asic(dev->base_addr, 4, (p & 0x140) ? DL19FDUPLX : 0); } if (link) { if (info->phy_id == info->eth_phy) { diff -urN linux-2.4.23-bk3/drivers/sound/ac97_plugin_ad1980.c linux-2.4.23-bk4/drivers/sound/ac97_plugin_ad1980.c --- linux-2.4.23-bk3/drivers/sound/ac97_plugin_ad1980.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.23-bk4/drivers/sound/ac97_plugin_ad1980.c 2003-12-06 02:49:49.000000000 -0800 @@ -72,9 +72,11 @@ #define AC97_AD_MISC 0x76 - /* Switch the inputs/outputs over (from Dell code) */ + /* Switch the inputs/outputs over (from Dell code) + Set the ADI compatibility mode (AC97NC bit) */ + control = codec->codec_read(codec, AC97_AD_MISC); - codec->codec_write(codec, AC97_AD_MISC, control | 0x0420); + codec->codec_write(codec, AC97_AD_MISC, control | 0x4420); /* We could refuse the device since we dont need to hang around, but we will claim it */ @@ -120,5 +122,6 @@ return ac97_register_driver(&ad1980_driver); } +MODULE_LICENSE("GPL"); module_init(ad1980_init); module_exit(ad1980_exit); diff -urN linux-2.4.23-bk3/include/asm-cris/axisflashmap.h linux-2.4.23-bk4/include/asm-cris/axisflashmap.h --- linux-2.4.23-bk3/include/asm-cris/axisflashmap.h 2001-07-26 15:10:06.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-cris/axisflashmap.h 2003-12-06 02:49:49.000000000 -0800 @@ -59,4 +59,7 @@ #define PARTITION_TYPE_KERNEL 0x0002 #define PARTITION_TYPE_JFFS 0x0003 +/* The master mtd for the entire flash. */ +extern struct mtd_info* axisflash_mtd; + #endif diff -urN linux-2.4.23-bk3/include/asm-cris/bitops.h linux-2.4.23-bk4/include/asm-cris/bitops.h --- linux-2.4.23-bk3/include/asm-cris/bitops.h 2003-08-25 04:44:43.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-cris/bitops.h 2003-12-06 02:49:49.000000000 -0800 @@ -60,7 +60,7 @@ /* * change_bit - Toggle a bit in memory - * @nr: Bit to clear + * @nr: Bit to change * @addr: Address to start counting from * * change_bit() is atomic and may not be reordered. @@ -72,7 +72,7 @@ /* * __change_bit - Toggle a bit in memory - * @nr: the bit to set + * @nr: the bit to change * @addr: the address to start counting from * * Unlike change_bit(), this function is non-atomic and may be reordered. @@ -127,7 +127,7 @@ /** * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * * This operation is atomic and cannot be reordered. @@ -152,7 +152,7 @@ /** * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * * This operation is non-atomic and can be reordered. @@ -173,7 +173,7 @@ } /** * test_and_change_bit - Change a bit and return its new value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * * This operation is atomic and cannot be reordered. diff -urN linux-2.4.23-bk3/include/asm-cris/ioctls.h linux-2.4.23-bk4/include/asm-cris/ioctls.h --- linux-2.4.23-bk3/include/asm-cris/ioctls.h 2003-08-25 04:44:43.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-cris/ioctls.h 2003-12-06 02:49:49.000000000 -0800 @@ -69,12 +69,11 @@ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ #define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ -#define FIOQSIZE 0x5460 #define TIOCSERSETRS485 0x5460 /* enable rs-485 */ #define TIOCSERWRRS485 0x5461 /* write rs-485 */ - +#define FIOQSIZE _IOR('f', 128, loff_t) /* Get exact space used by quota */ /* Used for packet mode */ #define TIOCPKT_DATA 0 diff -urN linux-2.4.23-bk3/include/asm-cris/ipc.h linux-2.4.23-bk4/include/asm-cris/ipc.h --- linux-2.4.23-bk3/include/asm-cris/ipc.h 2001-02-08 16:32:44.000000000 -0800 +++ linux-2.4.23-bk4/include/asm-cris/ipc.h 2003-12-06 02:49:49.000000000 -0800 @@ -17,6 +17,7 @@ #define SEMOP 1 #define SEMGET 2 #define SEMCTL 3 +#define SEMTIMEDOP 4 #define MSGSND 11 #define MSGRCV 12 #define MSGGET 13 diff -urN linux-2.4.23-bk3/include/asm-cris/page.h linux-2.4.23-bk4/include/asm-cris/page.h --- linux-2.4.23-bk3/include/asm-cris/page.h 2002-08-02 17:39:45.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-cris/page.h 2003-12-06 02:49:49.000000000 -0800 @@ -80,6 +80,20 @@ BUG(); \ } while (0) +/* Pure 2^n version of get_order */ +static __inline__ int get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + #endif /* __ASSEMBLY__ */ /* macros to convert between really physical and virtual addresses diff -urN linux-2.4.23-bk3/include/asm-cris/sync_serial.h linux-2.4.23-bk4/include/asm-cris/sync_serial.h --- linux-2.4.23-bk3/include/asm-cris/sync_serial.h 2001-04-06 10:51:19.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-cris/sync_serial.h 2003-12-06 02:49:49.000000000 -0800 @@ -1,7 +1,7 @@ /* - * ioctl defines for synchrnous serial port driver + * ioctl defines for synchronous serial port driver * - * Copyright (c) 2001 Axis Communications AB + * Copyright (c) 2001-2003 Axis Communications AB * * Author: Mikael Starvik * @@ -18,6 +18,7 @@ #define SSP_IPOLARITY _IOR('S', 3, unsigned int) #define SSP_OPOLARITY _IOR('S', 4, unsigned int) #define SSP_SPI _IOR('S', 5, unsigned int) +#define SSP_INBUFCHUNK _IOR('S', 6, unsigned int) /* Values for SSP_SPEED */ #define SSP150 0 @@ -47,7 +48,7 @@ #define FREQ_32kHz 7 /* Used by application to set CODEC divider, word rate and frame rate */ -#define CODEC_VAL(freq, word, frame) (CODEC | (freq << 8) | (word << 16) | (frame << 28)) +#define CODEC_VAL(freq, clk_per_sync, sync_per_frame) (CODEC | (freq << 8) | (clk_per_sync << 16) | (sync_per_frame << 28)) /* Used by driver to extract speed */ #define GET_SPEED(x) (x & 0xff) @@ -66,15 +67,17 @@ /* Values for SSP_FRAME_SYNC */ #define NORMAL_SYNC 1 #define EARLY_SYNC 2 + #define BIT_SYNC 4 #define WORD_SYNC 8 #define EXTENDED_SYNC 0x10 + #define SYNC_OFF 0x20 #define SYNC_ON 0x40 #define WORD_SIZE_8 0x80 #define WORD_SIZE_12 0x100 #define WORD_SIZE_16 0x200 -#define WORD_SIZE_24 0x300 +#define WORD_SIZE_24 0x400 #define WORD_SIZE_32 0x800 #define BIT_ORDER_LSB 0x1000 #define BIT_ORDER_MSB 0x2000 @@ -86,6 +89,8 @@ /* Values for SSP_IPOLARITY and SSP_OPOLARITY */ #define CLOCK_NORMAL 1 #define CLOCK_INVERT 2 +#define CLOCK_INEGEDGE CLOCK_NORMAL +#define CLOCK_IPOSEDGE CLOCK_INVERT #define FRAME_NORMAL 4 #define FRAME_INVERT 8 #define STATUS_NORMAL 0x10 @@ -93,5 +98,9 @@ /* Values for SSP_SPI */ #define SPI_MASTER 0 -#define SPI_SLAVE 1 +#define SPI_SLAVE 1 + +/* Values for SSP_INBUFCHUNK */ +/* plain integer with the size of DMA chunks */ + #endif diff -urN linux-2.4.23-bk3/include/asm-ia64/kmap_types.h linux-2.4.23-bk4/include/asm-ia64/kmap_types.h --- linux-2.4.23-bk3/include/asm-ia64/kmap_types.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.23-bk4/include/asm-ia64/kmap_types.h 2003-12-06 02:49:49.000000000 -0800 @@ -0,0 +1,31 @@ +#ifndef _ASM_IA64_KMAP_TYPES_H +#define _ASM_IA64_KMAP_TYPES_H + +#include + +#ifdef CONFIG_DEBUG_HIGHMEM +# define D(n) __KM_FENCE_##n , +#else +# define D(n) +#endif + +enum km_type { +D(0) KM_BOUNCE_READ, +D(1) KM_SKB_SUNRPC_DATA, +D(2) KM_SKB_DATA_SOFTIRQ, +D(3) KM_USER0, +D(4) KM_USER1, +D(5) KM_BIO_SRC_IRQ, +D(6) KM_BIO_DST_IRQ, +D(7) KM_PTE0, +D(8) KM_PTE1, +D(9) KM_IRQ0, +D(10) KM_IRQ1, +D(11) KM_SOFTIRQ0, +D(12) KM_SOFTIRQ1, +D(13) KM_TYPE_NR +}; + +#undef D + +#endif /* _ASM_IA64_KMAP_TYPES_H */ diff -urN linux-2.4.23-bk3/include/asm-ia64/machvec.h linux-2.4.23-bk4/include/asm-ia64/machvec.h --- linux-2.4.23-bk3/include/asm-ia64/machvec.h 2003-06-13 07:51:38.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-ia64/machvec.h 2003-12-06 02:49:49.000000000 -0800 @@ -24,7 +24,6 @@ typedef void ia64_mv_cpu_init_t(void); typedef void ia64_mv_irq_init_t (void); typedef void ia64_mv_pci_fixup_t (int); -typedef void ia64_mv_pci_enable_device_t (struct pci_dev *); typedef unsigned long ia64_mv_map_nr_t (void *); typedef void ia64_mv_mca_init_t (void); typedef void ia64_mv_mca_handler_t (void); @@ -91,7 +90,6 @@ # define platform_cmci_handler ia64_mv.cmci_handler # define platform_log_print ia64_mv.log_print # define platform_pci_fixup ia64_mv.pci_fixup -# define platform_pci_enable_device ia64_mv.pci_enable_device # define platform_send_ipi ia64_mv.send_ipi # define platform_global_tlb_purge ia64_mv.global_tlb_purge # define platform_pci_dma_init ia64_mv.dma_init @@ -121,7 +119,6 @@ ia64_mv_cpu_init_t *cpu_init; ia64_mv_irq_init_t *irq_init; ia64_mv_pci_fixup_t *pci_fixup; - ia64_mv_pci_enable_device_t *pci_enable_device; ia64_mv_map_nr_t *map_nr; ia64_mv_mca_init_t *mca_init; ia64_mv_mca_handler_t *mca_handler; @@ -157,7 +154,6 @@ platform_cpu_init, \ platform_irq_init, \ platform_pci_fixup, \ - platform_pci_enable_device, \ platform_map_nr, \ platform_mca_init, \ platform_mca_handler, \ @@ -235,9 +231,6 @@ #ifndef platform_pci_fixup # define platform_pci_fixup ((ia64_mv_pci_fixup_t *) machvec_noop) #endif -#ifndef platform_pci_enable_device -# define platform_pci_enable_device ((ia64_mv_pci_enable_device_t *) machvec_noop) -#endif #ifndef platform_send_ipi # define platform_send_ipi ia64_send_ipi /* default to architected version */ #endif diff -urN linux-2.4.23-bk3/include/asm-ia64/machvec_hpzx1.h linux-2.4.23-bk4/include/asm-ia64/machvec_hpzx1.h --- linux-2.4.23-bk3/include/asm-ia64/machvec_hpzx1.h 2003-06-13 07:51:38.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-ia64/machvec_hpzx1.h 2003-12-06 02:49:49.000000000 -0800 @@ -3,10 +3,9 @@ extern ia64_mv_setup_t dig_setup; extern ia64_mv_pci_fixup_t hpzx1_pci_fixup; -extern ia64_mv_pci_enable_device_t sba_enable_device; extern ia64_mv_map_nr_t map_nr_dense; -extern ia64_mv_pci_alloc_consistent sba_alloc_consistent; -extern ia64_mv_pci_free_consistent sba_free_consistent; +extern ia64_mv_pci_alloc_consistent sba_alloc_coherent; +extern ia64_mv_pci_free_consistent sba_free_coherent; extern ia64_mv_pci_map_single sba_map_single; extern ia64_mv_pci_unmap_single sba_unmap_single; extern ia64_mv_pci_map_sg sba_map_sg; @@ -20,14 +19,13 @@ * platform's machvec structure. When compiling a non-generic kernel, * the macros are used directly. */ -#define platform_name "hpzx1" +#define platform_name "hp" #define platform_setup dig_setup #define platform_pci_fixup hpzx1_pci_fixup -#define platform_pci_enable_device sba_enable_device #define platform_map_nr map_nr_dense #define platform_pci_dma_init ((ia64_mv_pci_dma_init *) machvec_noop) -#define platform_pci_alloc_consistent sba_alloc_consistent -#define platform_pci_free_consistent sba_free_consistent +#define platform_pci_alloc_consistent sba_alloc_coherent +#define platform_pci_free_consistent sba_free_coherent #define platform_pci_map_single sba_map_single #define platform_pci_unmap_single sba_unmap_single #define platform_pci_map_sg sba_map_sg diff -urN linux-2.4.23-bk3/include/asm-ia64/mca.h linux-2.4.23-bk4/include/asm-ia64/mca.h --- linux-2.4.23-bk3/include/asm-ia64/mca.h 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/include/asm-ia64/mca.h 2003-12-06 02:49:49.000000000 -0800 @@ -140,7 +140,6 @@ extern int ia64_log_print(int,prfunc_t); extern void ia64_mca_cmc_vector_setup(void); extern int ia64_mca_check_errors(void); -extern u64 ia64_log_get(int, prfunc_t); #define PLATFORM_CALL(fn, args) printk("Platform call TBD\n") diff -urN linux-2.4.23-bk3/include/asm-ia64/mca_asm.h linux-2.4.23-bk4/include/asm-ia64/mca_asm.h --- linux-2.4.23-bk3/include/asm-ia64/mca_asm.h 2003-06-13 07:51:38.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-ia64/mca_asm.h 2003-12-06 02:49:49.000000000 -0800 @@ -212,7 +212,8 @@ * saved onto the new stack frame. * * +-----------------------+ - * |NDIRTY [BSP - BSPSTORE]| + * |NDIRTY_WORDS | + * | [BSP - BSPSTORE]| * +-----------------------+ * | RNAT | * +-----------------------+ @@ -230,7 +231,7 @@ #define rse_ifs_offset (rse_pfs_offset+0x08) #define rse_bspstore_offset (rse_ifs_offset+0x08) #define rse_rnat_offset (rse_bspstore_offset+0x08) -#define rse_ndirty_offset (rse_rnat_offset+0x08) +#define rse_ndirty_words_offset (rse_rnat_offset+0x08) /* * rse_switch_context @@ -243,7 +244,8 @@ * 6. Save the old RNAT on the new stack frame * 7. Write BSPSTORE with the new backing store pointer * 8. Read and save the new BSP to calculate the #dirty registers - * NOTE: Look at pages 11-10, 11-11 in PRM Vol 2 + * NOTE: Look at section 6.11 in Intel IA-64 Architecture Software Developer's + * Manual, Volume 2, System Architecture. */ #define rse_switch_context(temp,p_stackframe,p_bspstore) \ ;; \ @@ -280,12 +282,12 @@ #define rse_return_context(psr_mask_reg,temp,p_stackframe) \ ;; \ alloc temp=ar.pfs,0,0,0,0; \ - add p_stackframe=rse_ndirty_offset,p_stackframe;; \ + add p_stackframe=rse_ndirty_words_offset,p_stackframe;; \ ld8 temp=[p_stackframe];; \ shl temp=temp,16;; \ mov ar.rsc=temp;; \ loadrs;; \ - add p_stackframe=-rse_ndirty_offset+rse_bspstore_offset,p_stackframe;;\ + add p_stackframe=-rse_ndirty_words_offset+rse_bspstore_offset,p_stackframe;;\ ld8 temp=[p_stackframe];; \ mov ar.bspstore=temp;; \ add p_stackframe=-rse_bspstore_offset+rse_rnat_offset,p_stackframe;;\ diff -urN linux-2.4.23-bk3/include/asm-ia64/pal.h linux-2.4.23-bk4/include/asm-ia64/pal.h --- linux-2.4.23-bk3/include/asm-ia64/pal.h 2003-08-25 04:44:43.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-ia64/pal.h 2003-12-06 02:49:49.000000000 -0800 @@ -407,10 +407,11 @@ * generated. * (Trap Lost ) */ - op : 3, /* Operation that - * caused the machine - * check + mi : 1, /* More information available + * call PAL_MC_ERROR_INFO */ + pi : 1, /* Precise instruction pointer */ + pm : 1, /* Precise min-state save area */ dy : 1, /* Processor dynamic * state valid @@ -452,32 +453,23 @@ * by the processor */ - reserved2 : 12, + reserved2 : 11, cc : 1, /* Cache check */ tc : 1, /* TLB check */ bc : 1, /* Bus check */ - uc : 1; /* Unknown check */ + rc : 1, /* Register file check */ + uc : 1; /* Uarch check */ } pal_processor_state_info_t; typedef struct pal_cache_check_info_s { - u64 reserved1 : 16, - way : 5, /* Way in which the - * error occurred - */ - reserved2 : 1, - mc : 1, /* Machine check corrected */ - tv : 1, /* Target address - * structure is valid - */ - - wv : 1, /* Way field valid */ - op : 3, /* Type of cache + u64 op : 4, /* Type of cache * operation that * caused the machine * check. */ - + level : 2, /* Cache level */ + reserved1 : 2, dl : 1, /* Failure in data part * of cache line */ @@ -486,11 +478,34 @@ */ dc : 1, /* Failure in dcache */ ic : 1, /* Failure in icache */ - index : 24, /* Cache line index */ - mv : 1, /* mesi valid */ mesi : 3, /* Cache line state */ - level : 4; /* Cache level */ + mv : 1, /* mesi valid */ + way : 5, /* Way in which the + * error occurred + */ + wiv : 1, /* Way field valid */ + reserved2 : 10, + + index : 20, /* Cache line index */ + reserved3 : 2, + is : 1, /* instruction set (1 == ia32) */ + iv : 1, /* instruction set field valid */ + pl : 2, /* privilege level */ + pv : 1, /* privilege level field valid */ + mcc : 1, /* Machine check corrected */ + tv : 1, /* Target address + * structure is valid + */ + rq : 1, /* Requester identifier + * structure is valid + */ + rp : 1, /* Responder identifier + * structure is valid + */ + pi : 1; /* Precise instruction pointer + * structure is valid + */ } pal_cache_check_info_t; typedef struct pal_tlb_check_info_s { @@ -498,18 +513,38 @@ u64 tr_slot : 8, /* Slot# of TR where * error occurred */ - reserved2 : 8, + trv : 1, /* tr_slot field is valid */ + reserved1 : 1, + level : 2, /* TLB level where failure occurred */ + reserved2 : 4, dtr : 1, /* Fail in data TR */ itr : 1, /* Fail in inst TR */ dtc : 1, /* Fail in data TC */ itc : 1, /* Fail in inst. TC */ - mc : 1, /* Machine check corrected */ - reserved1 : 43; + op : 4, /* Cache operation */ + reserved3 : 30, + is : 1, /* instruction set (1 == ia32) */ + iv : 1, /* instruction set field valid */ + pl : 2, /* privilege level */ + pv : 1, /* privilege level field valid */ + mcc : 1, /* Machine check corrected */ + tv : 1, /* Target address + * structure is valid + */ + rq : 1, /* Requester identifier + * structure is valid + */ + rp : 1, /* Responder identifier + * structure is valid + */ + pi : 1; /* Precise instruction pointer + * structure is valid + */ } pal_tlb_check_info_t; typedef struct pal_bus_check_info_s { - u64 size : 5, /* Xaction size*/ + u64 size : 5, /* Xaction size */ ib : 1, /* Internal bus error */ eb : 1, /* External bus error */ cc : 1, /* Error occurred @@ -518,22 +553,99 @@ */ type : 8, /* Bus xaction type*/ sev : 5, /* Bus error severity*/ - tv : 1, /* Targ addr valid */ - rp : 1, /* Resp addr valid */ - rq : 1, /* Req addr valid */ + hier : 2, /* Bus hierarchy level */ + reserved1 : 1, bsi : 8, /* Bus error status * info */ - mc : 1, /* Machine check corrected */ - reserved1 : 31; + reserved2 : 22, + + is : 1, /* instruction set (1 == ia32) */ + iv : 1, /* instruction set field valid */ + pl : 2, /* privilege level */ + pv : 1, /* privilege level field valid */ + mcc : 1, /* Machine check corrected */ + tv : 1, /* Target address + * structure is valid + */ + rq : 1, /* Requester identifier + * structure is valid + */ + rp : 1, /* Responder identifier + * structure is valid + */ + pi : 1; /* Precise instruction pointer + * structure is valid + */ } pal_bus_check_info_t; +typedef struct pal_reg_file_check_info_s { + u64 id : 4, /* Register file identifier */ + op : 4, /* Type of register + * operation that + * caused the machine + * check. + */ + reg_num : 7, /* Register number */ + rnv : 1, /* reg_num valid */ + reserved2 : 38, + + is : 1, /* instruction set (1 == ia32) */ + iv : 1, /* instruction set field valid */ + pl : 2, /* privilege level */ + pv : 1, /* privilege level field valid */ + mcc : 1, /* Machine check corrected */ + reserved3 : 3, + pi : 1; /* Precise instruction pointer + * structure is valid + */ +} pal_reg_file_check_info_t; + +typedef struct pal_uarch_check_info_s { + u64 sid : 5, /* Structure identification */ + level : 3, /* Level of failure */ + array_id : 4, /* Array identification */ + op : 4, /* Type of + * operation that + * caused the machine + * check. + */ + way : 6, /* Way of structure */ + wv : 1, /* way valid */ + xv : 1, /* index valid */ + reserved1 : 8, + index : 8, /* Index or set of the uarch + * structure that failed. + */ + reserved2 : 24, + + is : 1, /* instruction set (1 == ia32) */ + iv : 1, /* instruction set field valid */ + pl : 2, /* privilege level */ + pv : 1, /* privilege level field valid */ + mcc : 1, /* Machine check corrected */ + tv : 1, /* Target address + * structure is valid + */ + rq : 1, /* Requester identifier + * structure is valid + */ + rp : 1, /* Responder identifier + * structure is valid + */ + pi : 1; /* Precise instruction pointer + * structure is valid + */ +} pal_uarch_check_info_t; + typedef union pal_mc_error_info_u { u64 pmei_data; pal_processor_state_info_t pme_processor; pal_cache_check_info_t pme_cache; pal_tlb_check_info_t pme_tlb; pal_bus_check_info_t pme_bus; + pal_reg_file_check_info_t pme_reg_file; + pal_uarch_check_info_t pme_uarch; } pal_mc_error_info_t; #define pmci_proc_unknown_check pme_processor.uc diff -urN linux-2.4.23-bk3/include/asm-ia64/param.h linux-2.4.23-bk4/include/asm-ia64/param.h --- linux-2.4.23-bk3/include/asm-ia64/param.h 2001-04-05 12:51:47.000000000 -0700 +++ linux-2.4.23-bk4/include/asm-ia64/param.h 2003-12-06 02:49:49.000000000 -0800 @@ -4,22 +4,10 @@ /* * Fundamental kernel parameters. * - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang + * Copyright (C) 1998, 1999, 2002-2003 Hewlett-Packard Co + * David Mosberger-Tang */ -#include - -#ifdef CONFIG_IA64_HP_SIM -/* - * Yeah, simulating stuff is slow, so let us catch some breath between - * timer interrupts... - */ -# define HZ 32 -#else -# define HZ 1024 -#endif - #define EXEC_PAGESIZE 65536 #ifndef NGROUPS @@ -33,7 +21,24 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ #ifdef __KERNEL__ +# include /* mustn't include outside of #ifdef __KERNEL__ */ +# ifdef CONFIG_IA64_HP_SIM + /* + * Yeah, simulating stuff is slow, so let us catch some breath between + * timer interrupts... + */ +# define HZ 32 +# else +# define HZ 1024 +# endif +# define USER_HZ HZ # define CLOCKS_PER_SEC HZ /* frequency at which times() counts */ +#else + /* + * Technically, this is wrong, but some old apps still refer to it. The proper way to + * get the HZ value is via sysconf(_SC_CLK_TCK). + */ +# define HZ 1024 #endif #endif /* _ASM_IA64_PARAM_H */ diff -urN linux-2.4.23-bk3/include/asm-ia64/sal.h linux-2.4.23-bk4/include/asm-ia64/sal.h --- linux-2.4.23-bk3/include/asm-ia64/sal.h 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/include/asm-ia64/sal.h 2003-12-06 02:49:49.000000000 -0800 @@ -806,6 +806,8 @@ extern unsigned long sal_platform_features; +extern int (*salinfo_platform_oemdata)(const u8 *, u8 **, u64 *); + #endif /* __ASSEMBLY__ */ -#endif /* _ASM_IA64_PAL_H */ +#endif /* _ASM_IA64_SAL_H */ diff -urN linux-2.4.23-bk3/include/asm-ia64/uaccess.h linux-2.4.23-bk4/include/asm-ia64/uaccess.h --- linux-2.4.23-bk3/include/asm-ia64/uaccess.h 2002-11-28 15:53:15.000000000 -0800 +++ linux-2.4.23-bk4/include/asm-ia64/uaccess.h 2003-12-06 02:49:49.000000000 -0800 @@ -8,7 +8,7 @@ * addresses. Thus, we need to be careful not to let the user to * trick us into accessing kernel memory that would normally be * inaccessible. This code is also fairly performance sensitive, - * so we want to spend as little time doing saftey checks as + * so we want to spend as little time doing safety checks as * possible. * * To make matters a bit more interesting, these macros sometimes also @@ -26,8 +26,8 @@ * associated and, if so, sets r8 to -EFAULT and clears r9 to 0 and * then resumes execution at the continuation point. * - * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co - * Copyright (C) 1998, 1999, 2001 David Mosberger-Tang + * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co + * David Mosberger-Tang */ #include @@ -56,8 +56,10 @@ * address TASK_SIZE is never valid. We also need to make sure that the address doesn't * point inside the virtually mapped linear page table. */ -#define __access_ok(addr,size,segment) (((unsigned long) (addr)) <= (segment).seg \ - && ((segment).seg == KERNEL_DS.seg || rgn_offset((unsigned long) (addr)) < RGN_MAP_LIMIT)) +#define __access_ok(addr,size,segment) \ + likely(((unsigned long) (addr)) <= (segment).seg \ + && ((segment).seg == KERNEL_DS.seg \ + || REGION_OFFSET((unsigned long) (addr)) < RGN_MAP_LIMIT)) #define access_ok(type,addr,size) __access_ok((addr),(size),get_fs()) static inline int diff -urN linux-2.4.23-bk3/include/asm-ia64/xor.h linux-2.4.23-bk4/include/asm-ia64/xor.h --- linux-2.4.23-bk3/include/asm-ia64/xor.h 2000-11-12 19:39:51.000000000 -0800 +++ linux-2.4.23-bk4/include/asm-ia64/xor.h 2003-12-06 02:49:49.000000000 -0800 @@ -22,256 +22,6 @@ extern void xor_ia64_5(unsigned long, unsigned long *, unsigned long *, unsigned long *, unsigned long *, unsigned long *); -asm (" - .text - - // Assume L2 memory latency of 6 cycles. - - .proc xor_ia64_2 -xor_ia64_2: - .prologue - .fframe 0 - { .mii - .save ar.pfs, r31 - alloc r31 = ar.pfs, 3, 0, 13, 16 - .save ar.lc, r30 - mov r30 = ar.lc - .save pr, r29 - mov r29 = pr - ;; - } - .body - { .mii - mov r8 = in1 - mov ar.ec = 6 + 2 - shr in0 = in0, 3 - ;; - } - { .mmi - adds in0 = -1, in0 - mov r16 = in1 - mov r17 = in2 - ;; - } - { .mii - mov ar.lc = in0 - mov pr.rot = 1 << 16 - ;; - } - .rotr s1[6+1], s2[6+1], d[2] - .rotp p[6+2] -0: { .mmi -(p[0]) ld8.nta s1[0] = [r16], 8 -(p[0]) ld8.nta s2[0] = [r17], 8 -(p[6]) xor d[0] = s1[6], s2[6] - } - { .mfb -(p[6+1]) st8.nta [r8] = d[1], 8 - nop.f 0 - br.ctop.dptk.few 0b - ;; - } - { .mii - mov ar.lc = r30 - mov pr = r29, -1 - } - { .bbb - br.ret.sptk.few rp - } - .endp xor_ia64_2 - - .proc xor_ia64_3 -xor_ia64_3: - .prologue - .fframe 0 - { .mii - .save ar.pfs, r31 - alloc r31 = ar.pfs, 4, 0, 20, 24 - .save ar.lc, r30 - mov r30 = ar.lc - .save pr, r29 - mov r29 = pr - ;; - } - .body - { .mii - mov r8 = in1 - mov ar.ec = 6 + 2 - shr in0 = in0, 3 - ;; - } - { .mmi - adds in0 = -1, in0 - mov r16 = in1 - mov r17 = in2 - ;; - } - { .mii - mov r18 = in3 - mov ar.lc = in0 - mov pr.rot = 1 << 16 - ;; - } - .rotr s1[6+1], s2[6+1], s3[6+1], d[2] - .rotp p[6+2] -0: { .mmi -(p[0]) ld8.nta s1[0] = [r16], 8 -(p[0]) ld8.nta s2[0] = [r17], 8 -(p[6]) xor d[0] = s1[6], s2[6] - ;; - } - { .mmi -(p[0]) ld8.nta s3[0] = [r18], 8 -(p[6+1]) st8.nta [r8] = d[1], 8 -(p[6]) xor d[0] = d[0], s3[6] - } - { .bbb - br.ctop.dptk.few 0b - ;; - } - { .mii - mov ar.lc = r30 - mov pr = r29, -1 - } - { .bbb - br.ret.sptk.few rp - } - .endp xor_ia64_3 - - .proc xor_ia64_4 -xor_ia64_4: - .prologue - .fframe 0 - { .mii - .save ar.pfs, r31 - alloc r31 = ar.pfs, 5, 0, 27, 32 - .save ar.lc, r30 - mov r30 = ar.lc - .save pr, r29 - mov r29 = pr - ;; - } - .body - { .mii - mov r8 = in1 - mov ar.ec = 6 + 2 - shr in0 = in0, 3 - ;; - } - { .mmi - adds in0 = -1, in0 - mov r16 = in1 - mov r17 = in2 - ;; - } - { .mii - mov r18 = in3 - mov ar.lc = in0 - mov pr.rot = 1 << 16 - } - { .mfb - mov r19 = in4 - ;; - } - .rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], d[2] - .rotp p[6+2] -0: { .mmi -(p[0]) ld8.nta s1[0] = [r16], 8 -(p[0]) ld8.nta s2[0] = [r17], 8 -(p[6]) xor d[0] = s1[6], s2[6] - } - { .mmi -(p[0]) ld8.nta s3[0] = [r18], 8 -(p[0]) ld8.nta s4[0] = [r19], 8 -(p[6]) xor r20 = s3[6], s4[6] - ;; - } - { .mib -(p[6+1]) st8.nta [r8] = d[1], 8 -(p[6]) xor d[0] = d[0], r20 - br.ctop.dptk.few 0b - ;; - } - { .mii - mov ar.lc = r30 - mov pr = r29, -1 - } - { .bbb - br.ret.sptk.few rp - } - .endp xor_ia64_4 - - .proc xor_ia64_5 -xor_ia64_5: - .prologue - .fframe 0 - { .mii - .save ar.pfs, r31 - alloc r31 = ar.pfs, 6, 0, 34, 40 - .save ar.lc, r30 - mov r30 = ar.lc - .save pr, r29 - mov r29 = pr - ;; - } - .body - { .mii - mov r8 = in1 - mov ar.ec = 6 + 2 - shr in0 = in0, 3 - ;; - } - { .mmi - adds in0 = -1, in0 - mov r16 = in1 - mov r17 = in2 - ;; - } - { .mii - mov r18 = in3 - mov ar.lc = in0 - mov pr.rot = 1 << 16 - } - { .mib - mov r19 = in4 - mov r20 = in5 - ;; - } - .rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], s5[6+1], d[2] - .rotp p[6+2] -0: { .mmi -(p[0]) ld8.nta s1[0] = [r16], 8 -(p[0]) ld8.nta s2[0] = [r17], 8 -(p[6]) xor d[0] = s1[6], s2[6] - } - { .mmi -(p[0]) ld8.nta s3[0] = [r18], 8 -(p[0]) ld8.nta s4[0] = [r19], 8 -(p[6]) xor r21 = s3[6], s4[6] - ;; - } - { .mmi -(p[0]) ld8.nta s5[0] = [r20], 8 -(p[6+1]) st8.nta [r8] = d[1], 8 -(p[6]) xor d[0] = d[0], r21 - ;; - } - { .mfb -(p[6]) xor d[0] = d[0], s5[6] - nop.f 0 - br.ctop.dptk.few 0b - ;; - } - { .mii - mov ar.lc = r30 - mov pr = r29, -1 - } - { .bbb - br.ret.sptk.few rp - } - .endp xor_ia64_5 -"); - static struct xor_block_template xor_block_ia64 = { name: "ia64", do_2: xor_ia64_2, diff -urN linux-2.4.23-bk3/include/linux/netfilter_ipv4/ip_conntrack_amanda.h linux-2.4.23-bk4/include/linux/netfilter_ipv4/ip_conntrack_amanda.h --- linux-2.4.23-bk3/include/linux/netfilter_ipv4/ip_conntrack_amanda.h 2003-06-13 07:51:38.000000000 -0700 +++ linux-2.4.23-bk4/include/linux/netfilter_ipv4/ip_conntrack_amanda.h 2003-12-06 02:49:50.000000000 -0800 @@ -2,28 +2,11 @@ #define _IP_CONNTRACK_AMANDA_H /* AMANDA tracking. */ -#ifdef __KERNEL__ - -#include - -/* Protects amanda part of conntracks */ -DECLARE_LOCK_EXTERN(ip_amanda_lock); - -#endif - -struct conn { - char* match; - int matchlen; -}; - -#define NUM_MSGS 3 - - struct ip_ct_amanda_expect { u_int16_t port; /* port number of this expectation */ - u_int16_t offset; /* offset of the port specification in ctrl packet */ - u_int16_t len; /* the length of the port number specification */ + u_int16_t offset; /* offset of port in ctrl packet */ + u_int16_t len; /* length of the port number string */ }; #endif /* _IP_CONNTRACK_AMANDA_H */ diff -urN linux-2.4.23-bk3/include/linux/netfilter_ipv4/listhelp.h linux-2.4.23-bk4/include/linux/netfilter_ipv4/listhelp.h --- linux-2.4.23-bk3/include/linux/netfilter_ipv4/listhelp.h 2003-08-25 04:44:44.000000000 -0700 +++ linux-2.4.23-bk4/include/linux/netfilter_ipv4/listhelp.h 2003-12-06 02:49:50.000000000 -0800 @@ -11,48 +11,42 @@ required to allow inlining of cmpfn. */ #define LIST_FIND(head, cmpfn, type, args...) \ ({ \ - const struct list_head *__i = (head); \ + const struct list_head *__i, *__j = NULL; \ \ ASSERT_READ_LOCK(head); \ - do { \ - __i = __i->next; \ - if (__i == (head)) { \ - __i = NULL; \ + list_for_each(__i, (head)) \ + if (cmpfn((const type)__i , ## args)) { \ + __j = __i; \ break; \ } \ - } while (!cmpfn((const type)__i , ## args)); \ - (type)__i; \ + (type)__j; \ }) -#define LIST_FIND_W(head, cmpfn, type, args...) \ -({ \ - const struct list_head *__i = (head); \ - \ - ASSERT_WRITE_LOCK(head); \ - do { \ - __i = __i->next; \ - if (__i == (head)) { \ - __i = NULL; \ - break; \ - } \ - } while (!cmpfn((type)__i , ## args)); \ - (type)__i; \ +#define LIST_FIND_W(head, cmpfn, type, args...) \ +({ \ + const struct list_head *__i, *__j = NULL; \ + \ + ASSERT_WRITE_LOCK(head); \ + list_for_each(__i, (head)) \ + if (cmpfn((const type)__i , ## args)) { \ + __j = __i; \ + break; \ + } \ + (type)__j; \ }) /* Just like LIST_FIND but we search backwards */ #define LIST_FIND_B(head, cmpfn, type, args...) \ ({ \ - const struct list_head *__i = (head); \ + const struct list_head *__i, *__j = NULL; \ \ ASSERT_READ_LOCK(head); \ - do { \ - __i = __i->prev; \ - if (__i == (head)) { \ - __i = NULL; \ + list_for_each_prev(__i, (head)) \ + if (cmpfn((const type)__i , ## args)) { \ + __j = __i; \ break; \ } \ - } while (!cmpfn((const type)__i , ## args)); \ - (type)__i; \ + (type)__j; \ }) static inline int @@ -100,9 +94,9 @@ do { \ struct list_head *__i; \ ASSERT_WRITE_LOCK(head); \ - for (__i = (head)->next; \ - !cmpfn((new), (typeof (new))__i) && __i != (head); \ - __i = __i->next); \ + list_for_each(__i, (head)) \ + if ((new), (typeof (new))__i) \ + break; \ list_add((struct list_head *)(new), __i->prev); \ } while(0) diff -urN linux-2.4.23-bk3/include/linux/rtnetlink.h linux-2.4.23-bk4/include/linux/rtnetlink.h --- linux-2.4.23-bk3/include/linux/rtnetlink.h 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/include/linux/rtnetlink.h 2003-12-06 02:49:50.000000000 -0800 @@ -140,6 +140,7 @@ #define RTPROT_ZEBRA 11 /* Zebra */ #define RTPROT_BIRD 12 /* BIRD */ #define RTPROT_DNROUTED 13 /* DECnet routing daemon */ +#define RTPROT_XORP 14 /* XORP */ /* rtm_scope diff -urN linux-2.4.23-bk3/include/linux/sysctl.h linux-2.4.23-bk4/include/linux/sysctl.h --- linux-2.4.23-bk3/include/linux/sysctl.h 2003-12-06 02:49:46.000000000 -0800 +++ linux-2.4.23-bk4/include/linux/sysctl.h 2003-12-06 02:49:50.000000000 -0800 @@ -377,6 +377,7 @@ NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11, NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12, NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13, + NET_IPV4_NF_CONNTRACK_BUCKETS=14, }; /* /proc/sys/net/ipv6 */ diff -urN linux-2.4.23-bk3/mm/filemap.c linux-2.4.23-bk4/mm/filemap.c --- linux-2.4.23-bk3/mm/filemap.c 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/mm/filemap.c 2003-12-06 02:49:50.000000000 -0800 @@ -1299,11 +1299,14 @@ */ ahead = 0; while (ahead < max_ahead) { - ahead ++; - if ((raend + ahead) >= end_index) + unsigned long ra_index = raend + ahead + 1; + + if (ra_index > end_index) break; - if (page_cache_read(filp, raend + ahead) < 0) + if (page_cache_read(filp, ra_index) < 0) break; + + ahead++; } /* * If we tried to read ahead some pages, diff -urN linux-2.4.23-bk3/net/atm/br2684.c linux-2.4.23-bk4/net/atm/br2684.c --- linux-2.4.23-bk3/net/atm/br2684.c 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/net/atm/br2684.c 2003-12-06 02:49:50.000000000 -0800 @@ -678,6 +678,7 @@ return -ENOIOCTLCMD; } +#ifdef CONFIG_PROC_FS /* Never put more than 256 bytes in at once */ static int br2684_proc_engine(loff_t pos, char *buf) { @@ -770,16 +771,19 @@ }; extern struct proc_dir_entry *atm_proc_root; /* from proc.c */ +#endif /* CONFIG_PROC_FS */ /* the following avoids some spurious warnings from the compiler */ #define UNUSED __attribute__((unused)) static int __init UNUSED br2684_init(void) { +#ifdef CONFIG_PROC_FS struct proc_dir_entry *p; if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL) return -ENOMEM; p->proc_fops = &br2684_proc_operations; +#endif /* CONFIG_PROC_FS */ br2684_ioctl_set(br2684_ioctl); return 0; } @@ -788,7 +792,9 @@ { struct br2684_dev *brdev; br2684_ioctl_set(NULL); +#ifdef CONFIG_PROC_FS remove_proc_entry("br2684", atm_proc_root); +#endif /* CONFIG_PROC_FS */ while (!list_empty(&br2684_devs)) { brdev = list_entry_brdev(br2684_devs.next); unregister_netdev(&brdev->net_dev); diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ip_conntrack_amanda.c linux-2.4.23-bk4/net/ipv4/netfilter/ip_conntrack_amanda.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ip_conntrack_amanda.c 2003-06-13 07:51:39.000000000 -0700 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ip_conntrack_amanda.c 2003-12-06 02:49:50.000000000 -0800 @@ -18,13 +18,13 @@ * */ +#include #include #include #include #include #include -#include #include #include @@ -36,176 +36,96 @@ MODULE_PARM(master_timeout, "i"); MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); -DECLARE_LOCK(ip_amanda_lock); -struct module *ip_conntrack_amanda = THIS_MODULE; - -#define MAXMATCHLEN 6 -struct conn conns[NUM_MSGS] = { - {"DATA ", 5}, - {"MESG ", 5}, - {"INDEX ", 6}, +static struct { char *match; int len; } conns[] = { + { "DATA ", 5}, + { "MESG ", 5}, + { "INDEX ", 6}, }; -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(format, args...) -#endif +#define NUM_MSGS 3 -/* FIXME: This should be in userspace. Later. */ static int help(const struct iphdr *iph, size_t len, - struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) + struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) { + struct ip_conntrack_expect exp; + struct ip_ct_amanda_expect *exp_amanda_info; struct udphdr *udph = (void *)iph + iph->ihl * 4; u_int32_t udplen = len - iph->ihl * 4; u_int32_t datalen = udplen - sizeof(struct udphdr); char *data = (char *)udph + sizeof(struct udphdr); - char *datap = data; - char *data_limit = (char *) data + datalen; - int dir = CTINFO2DIR(ctinfo); - struct ip_ct_amanda *info = - (struct ip_ct_amanda *)&ct->help.ct_ftp_info; - - /* Can't track connections formed before we registered */ - if (!info) - return NF_ACCEPT; - - /* increase the UDP timeout of the master connection as replies from - * Amanda clients to the server can be quite delayed */ - ip_ct_refresh(ct, master_timeout * HZ); + char *data_limit = data + datalen; + char *start = data, *tmp; + int i; - /* If packet is coming from Amanda server */ - if (dir == IP_CT_DIR_ORIGINAL) + /* Only look at packets from the Amanda server */ + if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) return NF_ACCEPT; - /* Not whole UDP header? */ if (udplen < sizeof(struct udphdr)) { - printk("ip_conntrack_amanda_help: udplen = %u\n", - (unsigned)udplen); + if (net_ratelimit()) + printk("amanda_help: udplen = %u\n", udplen); return NF_ACCEPT; } - /* Checksum invalid? Ignore. */ - if (csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, - csum_partial((char *)udph, udplen, 0))) { - DEBUGP("ip_ct_talk_help: bad csum: %p %u %u.%u.%u.%u " - "%u.%u.%u.%u\n", - udph, udplen, NIPQUAD(iph->saddr), - NIPQUAD(iph->daddr)); + if (udph->check && + csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, + csum_partial((char *)udph, udplen, 0))) return NF_ACCEPT; - } + + /* increase the UDP timeout of the master connection as replies from + * Amanda clients to the server can be quite delayed */ + ip_ct_refresh(ct, master_timeout * HZ); - /* Search for the CONNECT string */ - while (data < data_limit) { + /* Search for "CONNECT " string */ + do { + if (data + 8 >= data_limit) + return NF_ACCEPT; if (!memcmp(data, "CONNECT ", 8)) { + data += 8; break; } data++; - } - if (memcmp(data, "CONNECT ", 8)) - return NF_ACCEPT; + } while(1); - DEBUGP("ip_conntrack_amanda_help: CONNECT found in connection " - "%u.%u.%u.%u:%u %u.%u.%u.%u:%u\n", - NIPQUAD(iph->saddr), htons(udph->source), - NIPQUAD(iph->daddr), htons(udph->dest)); - data += 8; - while (*data != 0x0a && data < data_limit) { - - int i; - - for (i = 0; i < NUM_MSGS; i++) { - if (!memcmp(data, conns[i].match, - conns[i].matchlen)) { - - char *portchr; - struct ip_conntrack_expect expect; - struct ip_ct_amanda_expect - *exp_amanda_info = - &expect.help.exp_amanda_info; - - memset(&expect, 0, sizeof(expect)); - - data += conns[i].matchlen; - /* this is not really tcp, but let's steal an - * idea from a tcp stream helper :-) - */ - // XXX expect.seq = data - datap; - exp_amanda_info->offset = data - datap; -// XXX DEBUGP("expect.seq = %p - %p = %d\n", data, datap, expect.seq); -DEBUGP("exp_amanda_info->offset = %p - %p = %d\n", data, datap, exp_amanda_info->offset); - portchr = data; - exp_amanda_info->port = - simple_strtoul(data, &data, 10); - exp_amanda_info->len = data - portchr; - - /* eat whitespace */ - while (*data == ' ') - data++; - DEBUGP ("ip_conntrack_amanda_help: " - "CONNECT %s request with port " - "%u found\n", conns[i].match, - exp_amanda_info->port); - - LOCK_BH(&ip_amanda_lock); - - expect.tuple = ((struct ip_conntrack_tuple) - { { ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip, - { 0 } }, - { ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip, - { htons(exp_amanda_info->port) }, - IPPROTO_TCP }}); - expect.mask = ((struct ip_conntrack_tuple) - { { 0, { 0 } }, - { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); - - expect.expectfn = NULL; - - DEBUGP ("ip_conntrack_amanda_help: " - "expect_related: %u.%u.%u.%u:%u - " - "%u.%u.%u.%u:%u\n", - NIPQUAD(expect.tuple.src.ip), - ntohs(expect.tuple.src.u.tcp.port), - NIPQUAD(expect.tuple.dst.ip), - ntohs(expect.tuple.dst.u.tcp.port)); - if (ip_conntrack_expect_related(ct, &expect) == - -EEXIST) { - ; - /* this must be a packet being resent */ - /* XXX - how do I get the - * ip_conntrack_expect that - * already exists so that I can - * update the .seq so that the - * nat module rewrites the port - * numbers? - * Perhaps I should use the - * exp_amanda_info instead of - * .seq. - */ - } - UNLOCK_BH(&ip_amanda_lock); - } /* if memcmp(conns) */ - } /* for .. NUM_MSGS */ - data++; - } /* while (*data != 0x0a && data < data_limit) */ + memset(&exp, 0, sizeof(exp)); + exp.tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; + exp.tuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; + exp.tuple.dst.protonum = IPPROTO_TCP; + exp.mask.src.ip = 0xFFFFFFFF; + exp.mask.dst.ip = 0xFFFFFFFF; + exp.mask.dst.protonum = 0xFFFF; + exp.mask.dst.u.tcp.port = 0xFFFF; + + exp_amanda_info = &exp.help.exp_amanda_info; + for (i = 0; data + conns[i].len < data_limit && *data != '\n'; data++) { + if (memcmp(data, conns[i].match, conns[i].len)) + continue; + tmp = data += conns[i].len; + exp_amanda_info->offset = data - start; + exp_amanda_info->port = simple_strtoul(data, &data, 10); + exp_amanda_info->len = data - tmp; + if (exp_amanda_info->port == 0 || exp_amanda_info->len > 5) + break; + + exp.tuple.dst.u.tcp.port = htons(exp_amanda_info->port); + ip_conntrack_expect_related(ct, &exp); + if (++i == NUM_MSGS) + break; + } return NF_ACCEPT; } static struct ip_conntrack_helper amanda_helper; -static void fini(void) +static void __exit fini(void) { - DEBUGP("ip_ct_amanda: unregistering helper for port 10080\n"); ip_conntrack_helper_unregister(&amanda_helper); } static int __init init(void) { - int ret; - - memset(&amanda_helper, 0, sizeof(struct ip_conntrack_helper)); amanda_helper.tuple.src.u.udp.port = htons(10080); amanda_helper.tuple.dst.protonum = IPPROTO_UDP; amanda_helper.mask.src.u.udp.port = 0xFFFF; @@ -213,23 +133,12 @@ amanda_helper.max_expected = NUM_MSGS; amanda_helper.timeout = 180; amanda_helper.flags = IP_CT_HELPER_F_REUSE_EXPECT; - amanda_helper.me = ip_conntrack_amanda; + amanda_helper.me = THIS_MODULE; amanda_helper.help = help; amanda_helper.name = "amanda"; - DEBUGP("ip_ct_amanda: registering helper for port 10080\n"); - - ret = ip_conntrack_helper_register(&amanda_helper); - - if (ret) { - printk("ip_ct_amanda: ERROR registering helper\n"); - fini(); - return -EBUSY; - } - return 0; + return ip_conntrack_helper_register(&amanda_helper); } -EXPORT_SYMBOL(ip_amanda_lock); - module_init(init); module_exit(fini); diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.23-bk4/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ip_conntrack_core.c 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ip_conntrack_core.c 2003-12-06 02:49:50.000000000 -0800 @@ -975,7 +975,6 @@ } } else if (related_to->helper->max_expected && related_to->expecting >= related_to->helper->max_expected) { - struct list_head *cur_item; /* old == NULL */ if (!(related_to->helper->flags & IP_CT_HELPER_F_REUSE_EXPECT)) { @@ -1000,21 +999,14 @@ NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); /* choose the the oldest expectation to evict */ - list_for_each(cur_item, &related_to->sibling_list) { - struct ip_conntrack_expect *cur; - - cur = list_entry(cur_item, - struct ip_conntrack_expect, - expected_list); - if (cur->sibling == NULL) { - old = cur; + list_for_each_entry(old, &related_to->sibling_list, + expected_list) + if (old->sibling == NULL) break; - } - } - /* (!old) cannot happen, since related_to->expecting is the - * number of unconfirmed expects */ - IP_NF_ASSERT(old); + /* We cannot fail since related_to->expecting is the number + * of unconfirmed expectations */ + IP_NF_ASSERT(old && old->sibling == NULL); /* newnat14 does not reuse the real allocated memory * structures but rather unexpects the old and @@ -1046,7 +1038,7 @@ atomic_set(&new->use, 1); /* add to expected list for this connection */ - list_add(&new->expected_list, &related_to->sibling_list); + list_add_tail(&new->expected_list, &related_to->sibling_list); /* add to global list of expectations */ list_prepend(&ip_conntrack_expect_list, &new->list); /* add and start timer if required */ @@ -1266,14 +1258,13 @@ /* Bring out ya dead! */ static struct ip_conntrack_tuple_hash * get_next_corpse(int (*kill)(const struct ip_conntrack *i, void *data), - void *data) + void *data, unsigned int *bucket) { struct ip_conntrack_tuple_hash *h = NULL; - unsigned int i; READ_LOCK(&ip_conntrack_lock); - for (i = 0; !h && i < ip_conntrack_htable_size; i++) { - h = LIST_FIND(&ip_conntrack_hash[i], do_kill, + for (; !h && *bucket < ip_conntrack_htable_size; (*bucket)++) { + h = LIST_FIND(&ip_conntrack_hash[*bucket], do_kill, struct ip_conntrack_tuple_hash *, kill, data); } if (h) @@ -1288,9 +1279,9 @@ void *data) { struct ip_conntrack_tuple_hash *h; + unsigned int bucket = 0; - /* This is order n^2, by the way. */ - while ((h = get_next_corpse(kill, data)) != NULL) { + while ((h = get_next_corpse(kill, data, &bucket)) != NULL) { /* Time to push up daises... */ if (del_timer(&h->ctrack->timeout)) death_by_timeout((unsigned long)h->ctrack); diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.23-bk4/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-12-06 02:49:50.000000000 -0800 @@ -249,6 +249,7 @@ /* From ip_conntrack_core.c */ extern int ip_conntrack_max; +extern unsigned int ip_conntrack_htable_size; /* From ip_conntrack_proto_tcp.c */ extern unsigned long ip_ct_tcp_timeout_syn_sent; @@ -276,6 +277,9 @@ {NET_IPV4_NF_CONNTRACK_MAX, "ip_conntrack_max", &ip_conntrack_max, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_NF_CONNTRACK_BUCKETS, "ip_conntrack_buckets", + &ip_conntrack_htable_size, sizeof(unsigned int), 0444, NULL, + &proc_dointvec}, {NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "ip_conntrack_tcp_timeout_syn_sent", &ip_ct_tcp_timeout_syn_sent, sizeof(unsigned int), 0644, NULL, &proc_dointvec_jiffies}, diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ip_conntrack_tftp.c linux-2.4.23-bk4/net/ipv4/netfilter/ip_conntrack_tftp.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ip_conntrack_tftp.c 2003-06-13 07:51:39.000000000 -0700 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ip_conntrack_tftp.c 2003-12-06 02:49:50.000000000 -0800 @@ -94,8 +94,6 @@ for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { /* Create helper structure */ - memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper)); - tftp[i].tuple.dst.protonum = IPPROTO_UDP; tftp[i].tuple.src.u.udp.port = htons(ports[i]); tftp[i].mask.dst.protonum = 0xFFFF; diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ip_fw_compat_masq.c linux-2.4.23-bk4/net/ipv4/netfilter/ip_fw_compat_masq.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ip_fw_compat_masq.c 2002-11-28 15:53:15.000000000 -0800 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ip_fw_compat_masq.c 2003-12-06 02:49:50.000000000 -0800 @@ -91,9 +91,6 @@ WRITE_UNLOCK(&ip_nat_lock); return ret; } - - place_in_hashes(ct, info); - info->initialized = 1; } else DEBUGP("Masquerading already done on this conn.\n"); WRITE_UNLOCK(&ip_nat_lock); diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ip_nat_amanda.c linux-2.4.23-bk4/net/ipv4/netfilter/ip_nat_amanda.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ip_nat_amanda.c 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ip_nat_amanda.c 2003-12-06 02:49:50.000000000 -0800 @@ -11,69 +11,45 @@ * insmod ip_nat_amanda.o */ +#include #include -#include +#include +#include #include #include -#include #include #include +#include #include #include -#include #include #include -#if 0 -#define DEBUGP printk -#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos); -#else -#define DEBUGP(format, args...) -#define DUMP_OFFSET(x) -#endif - MODULE_AUTHOR("Brian J. Murrell "); -MODULE_DESCRIPTION("Amanda network address translation module"); +MODULE_DESCRIPTION("Amanda NAT helper"); MODULE_LICENSE("GPL"); -/* protects amanda part of conntracks */ -DECLARE_LOCK_EXTERN(ip_amanda_lock); - static unsigned int amanda_nat_expected(struct sk_buff **pskb, - unsigned int hooknum, - struct ip_conntrack *ct, - struct ip_nat_info *info) + unsigned int hooknum, + struct ip_conntrack *ct, + struct ip_nat_info *info) { - struct ip_nat_multi_range mr; - u_int32_t newdstip, newsrcip, newip; - u_int16_t port; - struct ip_ct_amanda_expect *exp_info; struct ip_conntrack *master = master_ct(ct); + struct ip_ct_amanda_expect *exp_amanda_info; + struct ip_nat_multi_range mr; + u_int32_t newip; IP_NF_ASSERT(info); IP_NF_ASSERT(master); - IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); - DEBUGP("nat_expected: We have a connection!\n"); - exp_info = &ct->master->help.exp_amanda_info; - - newdstip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; - newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; - DEBUGP("nat_expected: %u.%u.%u.%u->%u.%u.%u.%u\n", - NIPQUAD(newsrcip), NIPQUAD(newdstip)); - - port = exp_info->port; - if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) - newip = newsrcip; + newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; else - newip = newdstip; - - DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); + newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; mr.rangesize = 1; /* We don't want to manip the per-protocol, just the IPs. */ @@ -81,121 +57,79 @@ mr.range[0].min_ip = mr.range[0].max_ip = newip; if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { + exp_amanda_info = &ct->master->help.exp_amanda_info; mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; mr.range[0].min = mr.range[0].max = ((union ip_conntrack_manip_proto) - { .udp = { htons(port) } }); + { .udp = { htons(exp_amanda_info->port) } }); } return ip_nat_setup_info(ct, &mr, hooknum); } static int amanda_data_fixup(struct ip_conntrack *ct, - struct sk_buff **pskb, - enum ip_conntrack_info ctinfo, - struct ip_conntrack_expect *expect) + struct sk_buff **pskb, + enum ip_conntrack_info ctinfo, + struct ip_conntrack_expect *exp) { - u_int32_t newip; - /* DATA 99999 MESG 99999 INDEX 99999 */ - char buffer[6]; - struct ip_conntrack_expect *exp = expect; - struct ip_ct_amanda_expect *ct_amanda_info = &exp->help.exp_amanda_info; + struct ip_ct_amanda_expect *exp_amanda_info; struct ip_conntrack_tuple t = exp->tuple; + char buffer[sizeof("65535")]; u_int16_t port; - MUST_BE_LOCKED(&ip_amanda_lock); - - newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; - DEBUGP ("ip_nat_amanda_help: newip = %u.%u.%u.%u\n", NIPQUAD(newip)); - /* Alter conntrack's expectations. */ - - /* We can read expect here without conntrack lock, since it's - only set in ip_conntrack_amanda, with ip_amanda_lock held - writable */ - - t.dst.ip = newip; - for (port = ct_amanda_info->port; port != 0; port++) { + exp_amanda_info = &exp->help.exp_amanda_info; + t.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; + for (port = exp_amanda_info->port; port != 0; port++) { t.dst.u.tcp.port = htons(port); if (ip_conntrack_change_expect(exp, &t) == 0) break; } - if (port == 0) return 0; sprintf(buffer, "%u", port); - - return ip_nat_mangle_udp_packet(pskb, ct, ctinfo, /* XXX exp->seq */ ct_amanda_info->offset, - ct_amanda_info->len, buffer, strlen(buffer)); + return ip_nat_mangle_udp_packet(pskb, ct, ctinfo, + exp_amanda_info->offset, + exp_amanda_info->len, + buffer, strlen(buffer)); } static unsigned int help(struct ip_conntrack *ct, - struct ip_conntrack_expect *exp, - struct ip_nat_info *info, - enum ip_conntrack_info ctinfo, - unsigned int hooknum, - struct sk_buff **pskb) + struct ip_conntrack_expect *exp, + struct ip_nat_info *info, + enum ip_conntrack_info ctinfo, + unsigned int hooknum, + struct sk_buff **pskb) { - int dir; + int dir = CTINFO2DIR(ctinfo); + int ret = NF_ACCEPT; - if (!exp) - DEBUGP("ip_nat_amanda: no exp!!"); - /* Only mangle things once: original direction in POST_ROUTING and reply direction on PRE_ROUTING. */ - dir = CTINFO2DIR(ctinfo); if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) - || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { - DEBUGP("ip_nat_amanda_help: Not touching dir %s at hook %s\n", - dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", - hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" - : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" - : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" - : hooknum == NF_IP_LOCAL_IN ? "INPUT" : "???"); + || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) return NF_ACCEPT; - } - DEBUGP("ip_nat_amanda_help: got beyond not touching: dir %s at hook %s for expect: ", - dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", - hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" - : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" - : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" - : hooknum == NF_IP_LOCAL_IN ? "INPUT" : "???"); - DUMP_TUPLE(&exp->tuple); - LOCK_BH(&ip_amanda_lock); -// XXX if (exp->seq != 0) + /* if this exectation has a "offset" the packet needs to be mangled */ if (exp->help.exp_amanda_info.offset != 0) - /* if this packet has a "seq" it needs to have it's content mangled */ - if (!amanda_data_fixup(ct, pskb, ctinfo, exp)) { - UNLOCK_BH(&ip_amanda_lock); - DEBUGP("ip_nat_amanda: NF_DROP\n"); - return NF_DROP; - } + if (!amanda_data_fixup(ct, pskb, ctinfo, exp)) + ret = NF_DROP; exp->help.exp_amanda_info.offset = 0; - UNLOCK_BH(&ip_amanda_lock); - DEBUGP("ip_nat_amanda: NF_ACCEPT\n"); - return NF_ACCEPT; + return ret; } static struct ip_nat_helper ip_nat_amanda_helper; -/* This function is intentionally _NOT_ defined as __exit, because - * it is needed by init() */ -static void fini(void) +static void __exit fini(void) { - DEBUGP("ip_nat_amanda: unregistering nat helper\n"); ip_nat_helper_unregister(&ip_nat_amanda_helper); } static int __init init(void) { - int ret = 0; - struct ip_nat_helper *hlpr; - - hlpr = &ip_nat_amanda_helper; - memset(hlpr, 0, sizeof(struct ip_nat_helper)); + struct ip_nat_helper *hlpr = &ip_nat_amanda_helper; hlpr->tuple.dst.protonum = IPPROTO_UDP; hlpr->tuple.src.u.udp.port = htons(10080); @@ -205,22 +139,10 @@ hlpr->flags = 0; hlpr->me = THIS_MODULE; hlpr->expect = amanda_nat_expected; - hlpr->name = "amanda"; - DEBUGP - ("ip_nat_amanda: Trying to register nat helper\n"); - ret = ip_nat_helper_register(hlpr); - - if (ret) { - printk - ("ip_nat_amanda: error registering nat helper\n"); - fini(); - return 1; - } - return ret; + return ip_nat_helper_register(hlpr); } - module_init(init); module_exit(fini); diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ip_nat_core.c linux-2.4.23-bk4/net/ipv4/netfilter/ip_nat_core.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ip_nat_core.c 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ip_nat_core.c 2003-12-06 02:49:50.000000000 -0800 @@ -815,7 +815,7 @@ /* Have to grab read lock before sibling_list traversal */ READ_LOCK(&ip_conntrack_lock); - list_for_each(cur_item, &ct->sibling_list) { + list_for_each_prev(cur_item, &ct->sibling_list) { exp = list_entry(cur_item, struct ip_conntrack_expect, expected_list); diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ip_nat_tftp.c linux-2.4.23-bk4/net/ipv4/netfilter/ip_nat_tftp.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ip_nat_tftp.c 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ip_nat_tftp.c 2003-12-06 02:49:50.000000000 -0800 @@ -160,8 +160,6 @@ ports[0] = TFTP_PORT; for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { - memset(&tftp[i], 0, sizeof(struct ip_nat_helper)); - tftp[i].tuple.dst.protonum = IPPROTO_UDP; tftp[i].tuple.src.u.udp.port = htons(ports[i]); tftp[i].mask.dst.protonum = 0xFFFF; diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ipt_MASQUERADE.c linux-2.4.23-bk4/net/ipv4/netfilter/ipt_MASQUERADE.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ipt_MASQUERADE.c 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ipt_MASQUERADE.c 2003-12-06 02:49:50.000000000 -0800 @@ -124,63 +124,37 @@ } static inline int -device_cmp(const struct ip_conntrack *i, void *ifindex) +device_cmp(const struct ip_conntrack *i, void *_ina) { - int ret; + int ret = 0; + struct in_ifaddr *ina = _ina; READ_LOCK(&masq_lock); - ret = (i->nat.masq_index == (int)(long)ifindex); + /* If it's masquerading out this interface with a different address, + * or we don't know the new address of this interface. */ + if (i->nat.masq_index == ina->ifa_dev->dev->ifindex + && i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address) + ret = 1; READ_UNLOCK(&masq_lock); return ret; } -static int masq_device_event(struct notifier_block *this, - unsigned long event, - void *ptr) -{ - struct net_device *dev = ptr; - - if (event == NETDEV_DOWN) { - /* Device was downed. Search entire table for - conntracks which were associated with that device, - and forget them. */ - IP_NF_ASSERT(dev->ifindex != 0); - - ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex); - } - - return NOTIFY_DONE; -} - static int masq_inet_event(struct notifier_block *this, unsigned long event, void *ptr) { - struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev; - - if (event == NETDEV_DOWN) { - /* IP address was deleted. Search entire table for - conntracks which were associated with that device, - and forget them. */ - IP_NF_ASSERT(dev->ifindex != 0); - - ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex); - } + /* For some configurations, interfaces often come back with + * the same address. If not, clean up old conntrack + * entries. */ + if (event == NETDEV_UP) + ip_ct_selective_cleanup(device_cmp, ptr); return NOTIFY_DONE; } -static struct notifier_block masq_dev_notifier = { - masq_device_event, - NULL, - 0 -}; - static struct notifier_block masq_inet_notifier = { - masq_inet_event, - NULL, - 0 + .notifier_call = masq_inet_event }; static struct ipt_target masquerade @@ -193,12 +167,9 @@ ret = ipt_register_target(&masquerade); - if (ret == 0) { - /* Register for device down reports */ - register_netdevice_notifier(&masq_dev_notifier); + if (ret == 0) /* Register IP address change reports */ register_inetaddr_notifier(&masq_inet_notifier); - } return ret; } @@ -206,7 +177,6 @@ static void __exit fini(void) { ipt_unregister_target(&masquerade); - unregister_netdevice_notifier(&masq_dev_notifier); unregister_inetaddr_notifier(&masq_inet_notifier); } diff -urN linux-2.4.23-bk3/net/ipv4/netfilter/ipt_recent.c linux-2.4.23-bk4/net/ipv4/netfilter/ipt_recent.c --- linux-2.4.23-bk3/net/ipv4/netfilter/ipt_recent.c 2003-08-25 04:44:44.000000000 -0700 +++ linux-2.4.23-bk4/net/ipv4/netfilter/ipt_recent.c 2003-12-06 02:49:50.000000000 -0800 @@ -91,8 +91,10 @@ */ static spinlock_t recent_lock = SPIN_LOCK_UNLOCKED; +#ifdef CONFIG_PROC_FS /* Our /proc/net/ipt_recent entry */ static struct proc_dir_entry *proc_net_ipt_recent = NULL; +#endif /* Function declaration for later. */ static int @@ -963,8 +965,10 @@ int count; printk(version); +#ifdef CONFIG_PROC_FS proc_net_ipt_recent = proc_mkdir("ipt_recent",proc_net); if(!proc_net_ipt_recent) return -ENOMEM; +#endif if(ip_list_hash_size && ip_list_hash_size <= ip_list_tot) { printk(KERN_WARNING RECENT_NAME ": ip_list_hash_size too small, resetting to default.\n"); diff -urN linux-2.4.23-bk3/net/ipv6/mcast.c linux-2.4.23-bk4/net/ipv6/mcast.c --- linux-2.4.23-bk3/net/ipv6/mcast.c 2003-12-06 02:49:46.000000000 -0800 +++ linux-2.4.23-bk4/net/ipv6/mcast.c 2003-12-06 02:49:50.000000000 -0800 @@ -45,6 +45,9 @@ #include #include +#include +#include + #include #include @@ -1264,7 +1267,7 @@ { struct ipv6hdr *pip6 = skb->nh.ipv6h; struct mld2_report *pmr = (struct mld2_report *)skb->h.raw; - int payload_len, mldlen; + int payload_len, mldlen, err; payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h - sizeof(struct ipv6hdr); @@ -1273,8 +1276,10 @@ pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0)); - dev_queue_xmit(skb); - ICMP6_INC_STATS(Icmp6OutMsgs); + err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, + dev_queue_xmit); + if (!err) + ICMP6_INC_STATS(Icmp6OutMsgs); } static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel) @@ -1598,12 +1603,16 @@ IPPROTO_ICMPV6, csum_partial((__u8 *) hdr, len, 0)); - dev_queue_xmit(skb); - if (type == ICMPV6_MGM_REDUCTION) - ICMP6_INC_STATS(Icmp6OutGroupMembReductions); - else - ICMP6_INC_STATS(Icmp6OutGroupMembResponses); - ICMP6_INC_STATS(Icmp6OutMsgs); + err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, + dev_queue_xmit); + if (!err) { + if (type == ICMPV6_MGM_REDUCTION) + ICMP6_INC_STATS(Icmp6OutGroupMembReductions); + else + ICMP6_INC_STATS(Icmp6OutGroupMembResponses); + ICMP6_INC_STATS(Icmp6OutMsgs); + } + return; out: