diff --git a/.gitignore b/.gitignore
index 27fd376..b1f5b9d 100644
Index: linux-2.6.17/.gitignore
===================================================================
--- linux-2.6.17.orig/.gitignore 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/.gitignore 2006-09-14 17:27:14.000000000 +0100
@@ -30,6 +30,11 @@ include/config
include/linux/autoconf.h
include/linux/compile.h
include/linux/version.h
+include/linux/utsrelease.h
# stgit generated dirs
patches-*
+
+# quilt's files
+patches
+series
Index: linux-2.6.17/Documentation/DocBook/kernel-api.tmpl
===================================================================
--- linux-2.6.17.orig/Documentation/DocBook/kernel-api.tmpl 2006-09-14 16:26:30.000000000 +0100
+++ linux-2.6.17/Documentation/DocBook/kernel-api.tmpl 2006-09-14 17:27:14.000000000 +0100
@@ -59,6 +59,9 @@
!Iinclude/linux/hrtimer.h
!Ekernel/hrtimer.c
+ Workqueues and Kevents
+!Ekernel/workqueue.c
+
Internal Functions
!Ikernel/exit.c
!Ikernel/signal.c
@@ -300,7 +303,7 @@ X!Ekernel/module.c
Resources Management
-!Ekernel/resource.c
+!Ikernel/resource.c
MTRR Handling
@@ -312,9 +315,7 @@ X!Ekernel/module.c
!Edrivers/pci/pci-driver.c
!Edrivers/pci/remove.c
!Edrivers/pci/pci-acpi.c
-
+!Edrivers/pci/search.c
!Edrivers/pci/msi.c
!Edrivers/pci/bus.c
size-4096 slab */
@@ -3708,7 +3708,7 @@ e1000_clean_rx_irq(struct e1000_adapter
#define E1000_CB_LENGTH 256
if (length < E1000_CB_LENGTH) {
struct sk_buff *new_skb =
- dev_alloc_skb(length + NET_IP_ALIGN);
+ netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
if (new_skb) {
skb_reserve(new_skb, NET_IP_ALIGN);
new_skb->dev = netdev;
@@ -3979,7 +3979,7 @@ e1000_alloc_rx_buffers(struct e1000_adap
while (cleaned_count--) {
if (!(skb = buffer_info->skb))
- skb = dev_alloc_skb(bufsz);
+ skb = netdev_alloc_skb(netdev, bufsz);
else {
skb_trim(skb, 0);
goto map_skb;
@@ -3997,7 +3997,7 @@ e1000_alloc_rx_buffers(struct e1000_adap
DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
"at %p\n", bufsz, skb->data);
/* Try again, without freeing the previous */
- skb = dev_alloc_skb(bufsz);
+ skb = netdev_alloc_skb(netdev, bufsz);
/* Failed allocation, critical failure */
if (!skb) {
dev_kfree_skb(oldskb);
@@ -4121,7 +4121,8 @@ e1000_alloc_rx_buffers_ps(struct e1000_a
rx_desc->read.buffer_addr[j+1] = ~0;
}
- skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
+ skb = netdev_alloc_skb(netdev,
+ adapter->rx_ps_bsize0 + NET_IP_ALIGN);
if (unlikely(!skb)) {
adapter->alloc_rx_buff_failed++;
Index: linux-2.6.17/drivers/net/myri10ge/myri10ge.c
===================================================================
--- linux-2.6.17.orig/drivers/net/myri10ge/myri10ge.c 2006-09-14 17:25:55.000000000 +0100
+++ linux-2.6.17/drivers/net/myri10ge/myri10ge.c 2006-09-14 17:27:15.000000000 +0100
@@ -177,6 +177,7 @@ struct myri10ge_priv {
struct work_struct watchdog_work;
struct timer_list watchdog_timer;
int watchdog_tx_done;
+ int watchdog_tx_req;
int watchdog_resets;
int tx_linearized;
int pause;
@@ -448,6 +449,7 @@ static int myri10ge_load_hotplug_firmwar
struct mcp_gen_header *hdr;
size_t hdr_offset;
int status;
+ unsigned i;
if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) {
dev_err(dev, "Unable to load %s firmware image via hotplug\n",
@@ -479,18 +481,12 @@ static int myri10ge_load_hotplug_firmwar
goto abort_with_fw;
crc = crc32(~0, fw->data, fw->size);
- if (mgp->tx.boundary == 2048) {
- /* Avoid PCI burst on chipset with unaligned completions. */
- int i;
- __iomem u32 *ptr = (__iomem u32 *) (mgp->sram +
- MYRI10GE_FW_OFFSET);
- for (i = 0; i < fw->size / 4; i++) {
- __raw_writel(((u32 *) fw->data)[i], ptr + i);
- wmb();
- }
- } else {
- myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET, fw->data,
- fw->size);
+ for (i = 0; i < fw->size; i += 256) {
+ myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET + i,
+ fw->data + i,
+ min(256U, (unsigned)(fw->size - i)));
+ mb();
+ readb(mgp->sram);
}
/* corruption checking is good for parity recovery and buggy chipset */
memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size);
@@ -2547,7 +2543,8 @@ static void myri10ge_watchdog_timer(unsi
mgp = (struct myri10ge_priv *)arg;
if (mgp->tx.req != mgp->tx.done &&
- mgp->tx.done == mgp->watchdog_tx_done)
+ mgp->tx.done == mgp->watchdog_tx_done &&
+ mgp->watchdog_tx_req != mgp->watchdog_tx_done)
/* nic seems like it might be stuck.. */
schedule_work(&mgp->watchdog_work);
else
@@ -2556,6 +2553,7 @@ static void myri10ge_watchdog_timer(unsi
jiffies + myri10ge_watchdog_timeout * HZ);
mgp->watchdog_tx_done = mgp->tx.done;
+ mgp->watchdog_tx_req = mgp->tx.req;
}
static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
Index: linux-2.6.17/drivers/net/phy/phy.c
===================================================================
--- linux-2.6.17.orig/drivers/net/phy/phy.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/net/phy/phy.c 2006-09-14 17:27:15.000000000 +0100
@@ -419,9 +419,8 @@ void phy_start_machine(struct phy_device
/* phy_stop_machine
*
- * description: Stops the state machine timer, sets the state to
- * UP (unless it wasn't up yet), and then frees the interrupt,
- * if it is in use. This function must be called BEFORE
+ * description: Stops the state machine timer, sets the state to UP
+ * (unless it wasn't up yet). This function must be called BEFORE
* phy_detach.
*/
void phy_stop_machine(struct phy_device *phydev)
@@ -433,9 +432,6 @@ void phy_stop_machine(struct phy_device
phydev->state = PHY_UP;
spin_unlock(&phydev->lock);
- if (phydev->irq != PHY_POLL)
- phy_stop_interrupts(phydev);
-
phydev->adjust_state = NULL;
}
Index: linux-2.6.17/drivers/net/s2io.c
===================================================================
--- linux-2.6.17.orig/drivers/net/s2io.c 2006-09-14 17:21:43.000000000 +0100
+++ linux-2.6.17/drivers/net/s2io.c 2006-09-14 17:27:15.000000000 +0100
@@ -76,7 +76,7 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.14.2"
+#define DRV_VERSION "2.0.15.2"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
@@ -370,38 +370,50 @@ static const u64 fix_mac[] = {
END_SIGN
};
+MODULE_AUTHOR("Raghavendra Koushik ");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+
/* Module Loadable parameters. */
-static unsigned int tx_fifo_num = 1;
-static unsigned int tx_fifo_len[MAX_TX_FIFOS] =
- {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN};
-static unsigned int rx_ring_num = 1;
-static unsigned int rx_ring_sz[MAX_RX_RINGS] =
- {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT};
-static unsigned int rts_frm_len[MAX_RX_RINGS] =
- {[0 ...(MAX_RX_RINGS - 1)] = 0 };
-static unsigned int rx_ring_mode = 1;
-static unsigned int use_continuous_tx_intrs = 1;
-static unsigned int rmac_pause_time = 0x100;
-static unsigned int mc_pause_threshold_q0q3 = 187;
-static unsigned int mc_pause_threshold_q4q7 = 187;
-static unsigned int shared_splits;
-static unsigned int tmac_util_period = 5;
-static unsigned int rmac_util_period = 5;
-static unsigned int bimodal = 0;
-static unsigned int l3l4hdr_size = 128;
-#ifndef CONFIG_S2IO_NAPI
-static unsigned int indicate_max_pkts;
-#endif
+S2IO_PARM_INT(tx_fifo_num, 1);
+S2IO_PARM_INT(rx_ring_num, 1);
+
+
+S2IO_PARM_INT(rx_ring_mode, 1);
+S2IO_PARM_INT(use_continuous_tx_intrs, 1);
+S2IO_PARM_INT(rmac_pause_time, 0x100);
+S2IO_PARM_INT(mc_pause_threshold_q0q3, 187);
+S2IO_PARM_INT(mc_pause_threshold_q4q7, 187);
+S2IO_PARM_INT(shared_splits, 0);
+S2IO_PARM_INT(tmac_util_period, 5);
+S2IO_PARM_INT(rmac_util_period, 5);
+S2IO_PARM_INT(bimodal, 0);
+S2IO_PARM_INT(l3l4hdr_size, 128);
/* Frequency of Rx desc syncs expressed as power of 2 */
-static unsigned int rxsync_frequency = 3;
+S2IO_PARM_INT(rxsync_frequency, 3);
/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */
-static unsigned int intr_type = 0;
+S2IO_PARM_INT(intr_type, 0);
/* Large receive offload feature */
-static unsigned int lro = 0;
+S2IO_PARM_INT(lro, 0);
/* Max pkts to be aggregated by LRO at one time. If not specified,
* aggregation happens until we hit max IP pkt size(64K)
*/
-static unsigned int lro_max_pkts = 0xFFFF;
+S2IO_PARM_INT(lro_max_pkts, 0xFFFF);
+#ifndef CONFIG_S2IO_NAPI
+S2IO_PARM_INT(indicate_max_pkts, 0);
+#endif
+
+static unsigned int tx_fifo_len[MAX_TX_FIFOS] =
+ {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN};
+static unsigned int rx_ring_sz[MAX_RX_RINGS] =
+ {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT};
+static unsigned int rts_frm_len[MAX_RX_RINGS] =
+ {[0 ...(MAX_RX_RINGS - 1)] = 0 };
+
+module_param_array(tx_fifo_len, uint, NULL, 0);
+module_param_array(rx_ring_sz, uint, NULL, 0);
+module_param_array(rts_frm_len, uint, NULL, 0);
/*
* S2IO device table.
@@ -464,10 +476,9 @@ static int init_shared_mem(struct s2io_n
size += config->tx_cfg[i].fifo_len;
}
if (size > MAX_AVAILABLE_TXDS) {
- DBG_PRINT(ERR_DBG, "%s: Requested TxDs too high, ",
- __FUNCTION__);
+ DBG_PRINT(ERR_DBG, "s2io: Requested TxDs too high, ");
DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size);
- return FAILURE;
+ return -EINVAL;
}
lst_size = (sizeof(TxD_t) * config->max_txds);
@@ -547,6 +558,7 @@ static int init_shared_mem(struct s2io_n
nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL);
if (!nic->ufo_in_band_v)
return -ENOMEM;
+ memset(nic->ufo_in_band_v, 0, size);
/* Allocation and initialization of RXDs in Rings */
size = 0;
@@ -1213,7 +1225,7 @@ static int init_nic(struct s2io_nic *nic
break;
}
- /* Enable Tx FIFO partition 0. */
+ /* Enable all configured Tx FIFO partitions */
val64 = readq(&bar0->tx_fifo_partition_0);
val64 |= (TX_FIFO_PARTITION_EN);
writeq(val64, &bar0->tx_fifo_partition_0);
@@ -1650,7 +1662,7 @@ static void en_dis_able_nic_intrs(struct
writeq(temp64, &bar0->general_int_mask);
/*
* If Hercules adapter enable GPIO otherwise
- * disabled all PCIX, Flash, MDIO, IIC and GPIO
+ * disable all PCIX, Flash, MDIO, IIC and GPIO
* interrupts for now.
* TODO
*/
@@ -2119,7 +2131,7 @@ static struct sk_buff *s2io_txdl_getskb(
frag->size, PCI_DMA_TODEVICE);
}
}
- txdlp->Host_Control = 0;
+ memset(txdlp,0, (sizeof(TxD_t) * fifo_data->max_txds));
return(skb);
}
@@ -2371,9 +2383,14 @@ static int fill_rx_buffers(struct s2io_n
skb->data = (void *) (unsigned long)tmp;
skb->tail = (void *) (unsigned long)tmp;
- ((RxD3_t*)rxdp)->Buffer0_ptr =
- pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
+ if (!(((RxD3_t*)rxdp)->Buffer0_ptr))
+ ((RxD3_t*)rxdp)->Buffer0_ptr =
+ pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
PCI_DMA_FROMDEVICE);
+ else
+ pci_dma_sync_single_for_device(nic->pdev,
+ (dma_addr_t) ((RxD3_t*)rxdp)->Buffer0_ptr,
+ BUF0_LEN, PCI_DMA_FROMDEVICE);
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
if (nic->rxd_mode == RXD_MODE_3B) {
/* Two buffer mode */
@@ -2386,10 +2403,13 @@ static int fill_rx_buffers(struct s2io_n
(nic->pdev, skb->data, dev->mtu + 4,
PCI_DMA_FROMDEVICE);
- /* Buffer-1 will be dummy buffer not used */
- ((RxD3_t*)rxdp)->Buffer1_ptr =
- pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN,
- PCI_DMA_FROMDEVICE);
+ /* Buffer-1 will be dummy buffer. Not used */
+ if (!(((RxD3_t*)rxdp)->Buffer1_ptr)) {
+ ((RxD3_t*)rxdp)->Buffer1_ptr =
+ pci_map_single(nic->pdev,
+ ba->ba_1, BUF1_LEN,
+ PCI_DMA_FROMDEVICE);
+ }
rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
rxdp->Control_2 |= SET_BUFFER2_SIZE_3
(dev->mtu + 4);
@@ -2614,23 +2634,23 @@ no_rx:
}
#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
/**
- * s2io_netpoll - Rx interrupt service handler for netpoll support
+ * s2io_netpoll - netpoll event handler entry point
* @dev : pointer to the device structure.
* Description:
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
+ * This function will be called by upper layer to check for events on the
+ * interface in situations where interrupts are disabled. It is used for
+ * specific in-kernel networking tasks, such as remote consoles and kernel
+ * debugging over the network (example netdump in RedHat).
*/
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
static void s2io_netpoll(struct net_device *dev)
{
nic_t *nic = dev->priv;
mac_info_t *mac_control;
struct config_param *config;
XENA_dev_config_t __iomem *bar0 = nic->bar0;
- u64 val64;
+ u64 val64 = 0xFFFFFFFFFFFFFFFFULL;
int i;
disable_irq(dev->irq);
@@ -2639,9 +2659,17 @@ static void s2io_netpoll(struct net_devi
mac_control = &nic->mac_control;
config = &nic->config;
- val64 = readq(&bar0->rx_traffic_int);
writeq(val64, &bar0->rx_traffic_int);
+ writeq(val64, &bar0->tx_traffic_int);
+
+ /* we need to free up the transmitted skbufs or else netpoll will
+ * run out of skbs and will fail and eventually netpoll application such
+ * as netdump will fail.
+ */
+ for (i = 0; i < config->tx_fifo_num; i++)
+ tx_intr_handler(&mac_control->fifos[i]);
+ /* check for received packet and indicate up to network */
for (i = 0; i < config->rx_ring_num; i++)
rx_intr_handler(&mac_control->rings[i]);
@@ -2708,7 +2736,7 @@ static void rx_intr_handler(ring_info_t
/* If your are next to put index then it's FIFO full condition */
if ((get_block == put_block) &&
(get_info.offset + 1) == put_info.offset) {
- DBG_PRINT(ERR_DBG, "%s: Ring Full\n",dev->name);
+ DBG_PRINT(INTR_DBG, "%s: Ring Full\n",dev->name);
break;
}
skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control);
@@ -2728,18 +2756,15 @@ static void rx_intr_handler(ring_info_t
HEADER_SNAP_SIZE,
PCI_DMA_FROMDEVICE);
} else if (nic->rxd_mode == RXD_MODE_3B) {
- pci_unmap_single(nic->pdev, (dma_addr_t)
+ pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t)
((RxD3_t*)rxdp)->Buffer0_ptr,
BUF0_LEN, PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
- ((RxD3_t*)rxdp)->Buffer1_ptr,
- BUF1_LEN, PCI_DMA_FROMDEVICE);
- pci_unmap_single(nic->pdev, (dma_addr_t)
((RxD3_t*)rxdp)->Buffer2_ptr,
dev->mtu + 4,
PCI_DMA_FROMDEVICE);
} else {
- pci_unmap_single(nic->pdev, (dma_addr_t)
+ pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t)
((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN,
PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
@@ -3327,7 +3352,7 @@ static void s2io_reset(nic_t * sp)
/* Clear certain PCI/PCI-X fields after reset */
if (sp->device_type == XFRAME_II_DEVICE) {
- /* Clear parity err detect bit */
+ /* Clear "detected parity error" bit */
pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000);
/* Clearing PCIX Ecc status register */
@@ -3528,7 +3553,7 @@ static void restore_xmsi_data(nic_t *nic
u64 val64;
int i;
- for (i=0; i< nic->avail_msix_vectors; i++) {
+ for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
writeq(nic->msix_info[i].data, &bar0->xmsi_data);
val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
@@ -3547,7 +3572,7 @@ static void store_xmsi_data(nic_t *nic)
int i;
/* Store and display */
- for (i=0; i< nic->avail_msix_vectors; i++) {
+ for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
val64 = (BIT(15) | vBIT(i, 26, 6));
writeq(val64, &bar0->xmsi_access);
if (wait_for_msix_trans(nic, i)) {
@@ -3808,13 +3833,11 @@ static int s2io_xmit(struct sk_buff *skb
TxD_t *txdp;
TxFIFO_element_t __iomem *tx_fifo;
unsigned long flags;
-#ifdef NETIF_F_TSO
- int mss;
-#endif
u16 vlan_tag = 0;
int vlan_priority = 0;
mac_info_t *mac_control;
struct config_param *config;
+ int offload_type;
mac_control = &sp->mac_control;
config = &sp->config;
@@ -3862,13 +3885,11 @@ static int s2io_xmit(struct sk_buff *skb
return 0;
}
- txdp->Control_1 = 0;
- txdp->Control_2 = 0;
+ offload_type = s2io_offload_type(skb);
#ifdef NETIF_F_TSO
- mss = skb_shinfo(skb)->gso_size;
- if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
+ if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
txdp->Control_1 |= TXD_TCP_LSO_EN;
- txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
+ txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb));
}
#endif
if (skb->ip_summed == CHECKSUM_HW) {
@@ -3886,10 +3907,10 @@ static int s2io_xmit(struct sk_buff *skb
}
frg_len = skb->len - skb->data_len;
- if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) {
+ if (offload_type == SKB_GSO_UDP) {
int ufo_size;
- ufo_size = skb_shinfo(skb)->gso_size;
+ ufo_size = s2io_udp_mss(skb);
ufo_size &= ~7;
txdp->Control_1 |= TXD_UFO_EN;
txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
@@ -3906,16 +3927,13 @@ static int s2io_xmit(struct sk_buff *skb
sp->ufo_in_band_v,
sizeof(u64), PCI_DMA_TODEVICE);
txdp++;
- txdp->Control_1 = 0;
- txdp->Control_2 = 0;
}
txdp->Buffer_Pointer = pci_map_single
(sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
txdp->Host_Control = (unsigned long) skb;
txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
-
- if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP)
+ if (offload_type == SKB_GSO_UDP)
txdp->Control_1 |= TXD_UFO_EN;
frg_cnt = skb_shinfo(skb)->nr_frags;
@@ -3930,12 +3948,12 @@ static int s2io_xmit(struct sk_buff *skb
(sp->pdev, frag->page, frag->page_offset,
frag->size, PCI_DMA_TODEVICE);
txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
- if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP)
+ if (offload_type == SKB_GSO_UDP)
txdp->Control_1 |= TXD_UFO_EN;
}
txdp->Control_1 |= TXD_GATHER_CODE_LAST;
- if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP)
+ if (offload_type == SKB_GSO_UDP)
frg_cnt++; /* as Txd0 was used for inband header */
tx_fifo = mac_control->tx_FIFO_start[queue];
@@ -3944,13 +3962,9 @@ static int s2io_xmit(struct sk_buff *skb
val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST |
TX_FIFO_LAST_LIST);
-
-#ifdef NETIF_F_TSO
- if (mss)
- val64 |= TX_FIFO_SPECIAL_FUNC;
-#endif
- if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP)
+ if (offload_type)
val64 |= TX_FIFO_SPECIAL_FUNC;
+
writeq(val64, &tx_fifo->List_Control);
mmiowb();
@@ -3984,13 +3998,41 @@ s2io_alarm_handle(unsigned long data)
mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
}
+static int s2io_chk_rx_buffers(nic_t *sp, int rng_n)
+{
+ int rxb_size, level;
+
+ if (!sp->lro) {
+ rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]);
+ level = rx_buffer_level(sp, rxb_size, rng_n);
+
+ if ((level == PANIC) && (!TASKLET_IN_USE)) {
+ int ret;
+ DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__);
+ DBG_PRINT(INTR_DBG, "PANIC levels\n");
+ if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) {
+ DBG_PRINT(ERR_DBG, "Out of memory in %s",
+ __FUNCTION__);
+ clear_bit(0, (&sp->tasklet_status));
+ return -1;
+ }
+ clear_bit(0, (&sp->tasklet_status));
+ } else if (level == LOW)
+ tasklet_schedule(&sp->task);
+
+ } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) {
+ DBG_PRINT(ERR_DBG, "%s:Out of memory", sp->dev->name);
+ DBG_PRINT(ERR_DBG, " in Rx Intr!!\n");
+ }
+ return 0;
+}
+
static irqreturn_t
s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_id;
nic_t *sp = dev->priv;
int i;
- int ret;
mac_info_t *mac_control;
struct config_param *config;
@@ -4012,35 +4054,8 @@ s2io_msi_handle(int irq, void *dev_id, s
* reallocate the buffers from the interrupt handler itself,
* else schedule a tasklet to reallocate the buffers.
*/
- for (i = 0; i < config->rx_ring_num; i++) {
- if (!sp->lro) {
- int rxb_size = atomic_read(&sp->rx_bufs_left[i]);
- int level = rx_buffer_level(sp, rxb_size, i);
-
- if ((level == PANIC) && (!TASKLET_IN_USE)) {
- DBG_PRINT(INTR_DBG, "%s: Rx BD hit ",
- dev->name);
- DBG_PRINT(INTR_DBG, "PANIC levels\n");
- if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) {
- DBG_PRINT(ERR_DBG, "%s:Out of memory",
- dev->name);
- DBG_PRINT(ERR_DBG, " in ISR!!\n");
- clear_bit(0, (&sp->tasklet_status));
- atomic_dec(&sp->isr_cnt);
- return IRQ_HANDLED;
- }
- clear_bit(0, (&sp->tasklet_status));
- } else if (level == LOW) {
- tasklet_schedule(&sp->task);
- }
- }
- else if (fill_rx_buffers(sp, i) == -ENOMEM) {
- DBG_PRINT(ERR_DBG, "%s:Out of memory",
- dev->name);
- DBG_PRINT(ERR_DBG, " in Rx Intr!!\n");
- break;
- }
- }
+ for (i = 0; i < config->rx_ring_num; i++)
+ s2io_chk_rx_buffers(sp, i);
atomic_dec(&sp->isr_cnt);
return IRQ_HANDLED;
@@ -4051,39 +4066,13 @@ s2io_msix_ring_handle(int irq, void *dev
{
ring_info_t *ring = (ring_info_t *)dev_id;
nic_t *sp = ring->nic;
- struct net_device *dev = (struct net_device *) dev_id;
- int rxb_size, level, rng_n;
atomic_inc(&sp->isr_cnt);
- rx_intr_handler(ring);
- rng_n = ring->ring_no;
- if (!sp->lro) {
- rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]);
- level = rx_buffer_level(sp, rxb_size, rng_n);
-
- if ((level == PANIC) && (!TASKLET_IN_USE)) {
- int ret;
- DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__);
- DBG_PRINT(INTR_DBG, "PANIC levels\n");
- if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) {
- DBG_PRINT(ERR_DBG, "Out of memory in %s",
- __FUNCTION__);
- clear_bit(0, (&sp->tasklet_status));
- return IRQ_HANDLED;
- }
- clear_bit(0, (&sp->tasklet_status));
- } else if (level == LOW) {
- tasklet_schedule(&sp->task);
- }
- }
- else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) {
- DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name);
- DBG_PRINT(ERR_DBG, " in Rx Intr!!\n");
- }
+ rx_intr_handler(ring);
+ s2io_chk_rx_buffers(sp, ring->ring_no);
atomic_dec(&sp->isr_cnt);
-
return IRQ_HANDLED;
}
@@ -4248,37 +4237,8 @@ static irqreturn_t s2io_isr(int irq, voi
* else schedule a tasklet to reallocate the buffers.
*/
#ifndef CONFIG_S2IO_NAPI
- for (i = 0; i < config->rx_ring_num; i++) {
- if (!sp->lro) {
- int ret;
- int rxb_size = atomic_read(&sp->rx_bufs_left[i]);
- int level = rx_buffer_level(sp, rxb_size, i);
-
- if ((level == PANIC) && (!TASKLET_IN_USE)) {
- DBG_PRINT(INTR_DBG, "%s: Rx BD hit ",
- dev->name);
- DBG_PRINT(INTR_DBG, "PANIC levels\n");
- if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) {
- DBG_PRINT(ERR_DBG, "%s:Out of memory",
- dev->name);
- DBG_PRINT(ERR_DBG, " in ISR!!\n");
- clear_bit(0, (&sp->tasklet_status));
- atomic_dec(&sp->isr_cnt);
- writeq(org_mask, &bar0->general_int_mask);
- return IRQ_HANDLED;
- }
- clear_bit(0, (&sp->tasklet_status));
- } else if (level == LOW) {
- tasklet_schedule(&sp->task);
- }
- }
- else if (fill_rx_buffers(sp, i) == -ENOMEM) {
- DBG_PRINT(ERR_DBG, "%s:Out of memory",
- dev->name);
- DBG_PRINT(ERR_DBG, " in Rx intr!!\n");
- break;
- }
- }
+ for (i = 0; i < config->rx_ring_num; i++)
+ s2io_chk_rx_buffers(sp, i);
#endif
writeq(org_mask, &bar0->general_int_mask);
atomic_dec(&sp->isr_cnt);
@@ -4308,6 +4268,8 @@ static void s2io_updt_stats(nic_t *sp)
if (cnt == 5)
break; /* Updt failed */
} while(1);
+ } else {
+ memset(sp->mac_control.stats_info, 0, sizeof(StatInfo_t));
}
}
@@ -4942,7 +4904,8 @@ static int write_eeprom(nic_t * sp, int
}
static void s2io_vpd_read(nic_t *nic)
{
- u8 vpd_data[256],data;
+ u8 *vpd_data;
+ u8 data;
int i=0, cnt, fail = 0;
int vpd_addr = 0x80;
@@ -4955,6 +4918,10 @@ static void s2io_vpd_read(nic_t *nic)
vpd_addr = 0x50;
}
+ vpd_data = kmalloc(256, GFP_KERNEL);
+ if (!vpd_data)
+ return;
+
for (i = 0; i < 256; i +=4 ) {
pci_write_config_byte(nic->pdev, (vpd_addr + 2), i);
pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data);
@@ -4977,6 +4944,7 @@ static void s2io_vpd_read(nic_t *nic)
memset(nic->product_name, 0, vpd_data[1]);
memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
}
+ kfree(vpd_data);
}
/**
@@ -5295,7 +5263,7 @@ static int s2io_link_test(nic_t * sp, ui
else
*data = 0;
- return 0;
+ return *data;
}
/**
@@ -5753,6 +5721,19 @@ static int s2io_ethtool_op_set_tx_csum(s
return 0;
}
+static u32 s2io_ethtool_op_get_tso(struct net_device *dev)
+{
+ return (dev->features & NETIF_F_TSO) != 0;
+}
+static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
+{
+ if (data)
+ dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
+ else
+ dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+ return 0;
+}
static struct ethtool_ops netdev_ethtool_ops = {
.get_settings = s2io_ethtool_gset,
@@ -5773,8 +5754,8 @@ static struct ethtool_ops netdev_ethtool
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
#ifdef NETIF_F_TSO
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
+ .get_tso = s2io_ethtool_op_get_tso,
+ .set_tso = s2io_ethtool_op_set_tso,
#endif
.get_ufo = ethtool_op_get_ufo,
.set_ufo = ethtool_op_set_ufo,
@@ -6337,7 +6318,7 @@ static int s2io_card_up(nic_t * sp)
s2io_set_multicast(dev);
if (sp->lro) {
- /* Initialize max aggregatable pkts based on MTU */
+ /* Initialize max aggregatable pkts per session based on MTU */
sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu;
/* Check if we can use(if specified) user provided value */
if (lro_max_pkts < sp->lro_max_aggr_per_sess)
@@ -6438,7 +6419,7 @@ static void s2io_tx_watchdog(struct net_
* @cksum : FCS checksum of the frame.
* @ring_no : the ring from which this RxD was extracted.
* Description:
- * This function is called by the Tx interrupt serivce routine to perform
+ * This function is called by the Rx interrupt serivce routine to perform
* some OS related operations on the SKB before passing it to the upper
* layers. It mainly checks if the checksum is OK, if so adds it to the
* SKBs cksum variable, increments the Rx packet count and passes the SKB
@@ -6698,33 +6679,6 @@ static void s2io_init_pci(nic_t * sp)
pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd);
}
-MODULE_AUTHOR("Raghavendra Koushik ");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
-
-module_param(tx_fifo_num, int, 0);
-module_param(rx_ring_num, int, 0);
-module_param(rx_ring_mode, int, 0);
-module_param_array(tx_fifo_len, uint, NULL, 0);
-module_param_array(rx_ring_sz, uint, NULL, 0);
-module_param_array(rts_frm_len, uint, NULL, 0);
-module_param(use_continuous_tx_intrs, int, 1);
-module_param(rmac_pause_time, int, 0);
-module_param(mc_pause_threshold_q0q3, int, 0);
-module_param(mc_pause_threshold_q4q7, int, 0);
-module_param(shared_splits, int, 0);
-module_param(tmac_util_period, int, 0);
-module_param(rmac_util_period, int, 0);
-module_param(bimodal, bool, 0);
-module_param(l3l4hdr_size, int , 0);
-#ifndef CONFIG_S2IO_NAPI
-module_param(indicate_max_pkts, int, 0);
-#endif
-module_param(rxsync_frequency, int, 0);
-module_param(intr_type, int, 0);
-module_param(lro, int, 0);
-module_param(lro_max_pkts, int, 0);
-
static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
{
if ( tx_fifo_num > 8) {
@@ -6832,8 +6786,8 @@ s2io_init_nic(struct pci_dev *pdev, cons
}
if (dev_intr_type != MSI_X) {
if (pci_request_regions(pdev, s2io_driver_name)) {
- DBG_PRINT(ERR_DBG, "Request Regions failed\n"),
- pci_disable_device(pdev);
+ DBG_PRINT(ERR_DBG, "Request Regions failed\n");
+ pci_disable_device(pdev);
return -ENODEV;
}
}
@@ -6957,7 +6911,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
/* initialize the shared memory used by the NIC and the host */
if (init_shared_mem(sp)) {
DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n",
- __FUNCTION__);
+ dev->name);
ret = -ENOMEM;
goto mem_alloc_failed;
}
@@ -7094,6 +7048,9 @@ s2io_init_nic(struct pci_dev *pdev, cons
dev->addr_len = ETH_ALEN;
memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN);
+ /* reset Nic and bring it to known state */
+ s2io_reset(sp);
+
/*
* Initialize the tasklet status and link state flags
* and the card state parameter
@@ -7131,11 +7088,11 @@ s2io_init_nic(struct pci_dev *pdev, cons
goto register_failed;
}
s2io_vpd_read(sp);
- DBG_PRINT(ERR_DBG, "%s: Neterion %s",dev->name, sp->product_name);
- DBG_PRINT(ERR_DBG, "(rev %d), Driver version %s\n",
- get_xena_rev_id(sp->pdev),
- s2io_driver_version);
DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n");
+ DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name,
+ sp->product_name, get_xena_rev_id(sp->pdev));
+ DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,
+ s2io_driver_version);
DBG_PRINT(ERR_DBG, "%s: MAC ADDR: "
"%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
sp->def_mac_addr[0].mac_addr[0],
@@ -7436,8 +7393,13 @@ static int verify_l3_l4_lro_capable(lro_
if (ip->ihl != 5) /* IP has options */
return -1;
+ /* If we see CE codepoint in IP header, packet is not mergeable */
+ if (INET_ECN_is_ce(ipv4_get_dsfield(ip)))
+ return -1;
+
+ /* If we see ECE or CWR flags in TCP header, packet is not mergeable */
if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin ||
- !tcp->ack) {
+ tcp->ece || tcp->cwr || !tcp->ack) {
/*
* Currently recognize only the ack control word and
* any other control field being set would result in
@@ -7591,18 +7553,16 @@ static void queue_rx_frame(struct sk_buf
static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb,
u32 tcp_len)
{
- struct sk_buff *tmp, *first = lro->parent;
+ struct sk_buff *first = lro->parent;
first->len += tcp_len;
first->data_len = lro->frags_len;
skb_pull(skb, (skb->len - tcp_len));
- if ((tmp = skb_shinfo(first)->frag_list)) {
- while (tmp->next)
- tmp = tmp->next;
- tmp->next = skb;
- }
+ if (skb_shinfo(first)->frag_list)
+ lro->last_frag->next = skb;
else
skb_shinfo(first)->frag_list = skb;
+ lro->last_frag = skb;
sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++;
return;
}
Index: linux-2.6.17/drivers/net/s2io.h
===================================================================
--- linux-2.6.17.orig/drivers/net/s2io.h 2006-09-14 17:21:43.000000000 +0100
+++ linux-2.6.17/drivers/net/s2io.h 2006-09-14 17:27:15.000000000 +0100
@@ -719,6 +719,7 @@ struct msix_info_st {
/* Data structure to represent a LRO session */
typedef struct lro {
struct sk_buff *parent;
+ struct sk_buff *last_frag;
u8 *l2h;
struct iphdr *iph;
struct tcphdr *tcph;
@@ -1011,4 +1012,13 @@ static void clear_lro_session(lro_t *lro
static void queue_rx_frame(struct sk_buff *skb);
static void update_L3L4_header(nic_t *sp, lro_t *lro);
static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, u32 tcp_len);
+
+#define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size
+#define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size
+#define s2io_offload_type(skb) skb_shinfo(skb)->gso_type
+
+#define S2IO_PARM_INT(X, def_val) \
+ static unsigned int X = def_val;\
+ module_param(X , uint, 0);
+
#endif /* _S2IO_H */
Index: linux-2.6.17/drivers/net/tg3.c
===================================================================
--- linux-2.6.17.orig/drivers/net/tg3.c 2006-09-14 17:25:55.000000000 +0100
+++ linux-2.6.17/drivers/net/tg3.c 2006-09-14 17:27:15.000000000 +0100
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.63"
-#define DRV_MODULE_RELDATE "July 25, 2006"
+#define DRV_MODULE_VERSION "3.64"
+#define DRV_MODULE_RELDATE "July 31, 2006"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -3097,7 +3097,7 @@ static int tg3_alloc_rx_skb(struct tg3 *
* Callers depend upon this behavior and assume that
* we leave everything unchanged if we fail.
*/
- skb = dev_alloc_skb(skb_size);
+ skb = netdev_alloc_skb(tp->dev, skb_size);
if (skb == NULL)
return -ENOMEM;
@@ -3270,7 +3270,7 @@ static int tg3_rx(struct tg3 *tp, int bu
tg3_recycle_rx(tp, opaque_key,
desc_idx, *post_ptr);
- copy_skb = dev_alloc_skb(len + 2);
+ copy_skb = netdev_alloc_skb(tp->dev, len + 2);
if (copy_skb == NULL)
goto drop_it_no_recycle;
@@ -8618,7 +8618,7 @@ static int tg3_run_loopback(struct tg3 *
err = -EIO;
tx_len = 1514;
- skb = dev_alloc_skb(tx_len);
+ skb = netdev_alloc_skb(tp->dev, tx_len);
if (!skb)
return -ENOMEM;
Index: linux-2.6.17/drivers/net/wireless/zd1211rw/zd_chip.c
===================================================================
--- linux-2.6.17.orig/drivers/net/wireless/zd1211rw/zd_chip.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/net/wireless/zd1211rw/zd_chip.c 2006-09-14 17:27:15.000000000 +0100
@@ -797,7 +797,7 @@ static int zd1211_hw_init_hmac(struct zd
{ CR_ADDA_MBIAS_WARMTIME, 0x30000808 },
{ CR_ZD1211_RETRY_MAX, 0x2 },
{ CR_SNIFFER_ON, 0 },
- { CR_RX_FILTER, AP_RX_FILTER },
+ { CR_RX_FILTER, STA_RX_FILTER },
{ CR_GROUP_HASH_P1, 0x00 },
{ CR_GROUP_HASH_P2, 0x80000000 },
{ CR_REG1, 0xa4 },
@@ -844,7 +844,7 @@ static int zd1211b_hw_init_hmac(struct z
{ CR_ZD1211B_AIFS_CTL2, 0x008C003C },
{ CR_ZD1211B_TXOP, 0x01800824 },
{ CR_SNIFFER_ON, 0 },
- { CR_RX_FILTER, AP_RX_FILTER },
+ { CR_RX_FILTER, STA_RX_FILTER },
{ CR_GROUP_HASH_P1, 0x00 },
{ CR_GROUP_HASH_P2, 0x80000000 },
{ CR_REG1, 0xa4 },
Index: linux-2.6.17/drivers/net/wireless/zd1211rw/zd_chip.h
===================================================================
--- linux-2.6.17.orig/drivers/net/wireless/zd1211rw/zd_chip.h 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/net/wireless/zd1211rw/zd_chip.h 2006-09-14 17:27:15.000000000 +0100
@@ -461,10 +461,15 @@
#define CR_RX_FILTER CTL_REG(0x068c)
#define RX_FILTER_ASSOC_RESPONSE 0x0002
+#define RX_FILTER_REASSOC_RESPONSE 0x0008
#define RX_FILTER_PROBE_RESPONSE 0x0020
#define RX_FILTER_BEACON 0x0100
+#define RX_FILTER_DISASSOC 0x0400
#define RX_FILTER_AUTH 0x0800
-/* Sniff modus sets filter to 0xfffff */
+#define AP_RX_FILTER 0x0400feff
+#define STA_RX_FILTER 0x0000ffff
+
+/* Monitor mode sets filter to 0xfffff */
#define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690)
#define CR_BCN_FIFO_SEMAPHORE CTL_REG(0x0694)
@@ -546,9 +551,6 @@
#define CR_ZD1211B_TXOP CTL_REG(0x0b20)
#define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28)
-#define AP_RX_FILTER 0x0400feff
-#define STA_RX_FILTER 0x0000ffff
-
#define CWIN_SIZE 0x007f043f
Index: linux-2.6.17/drivers/net/wireless/zd1211rw/zd_mac.c
===================================================================
--- linux-2.6.17.orig/drivers/net/wireless/zd1211rw/zd_mac.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/net/wireless/zd1211rw/zd_mac.c 2006-09-14 17:27:15.000000000 +0100
@@ -108,7 +108,9 @@ int zd_mac_init_hw(struct zd_mac *mac, u
if (r)
goto disable_int;
- r = zd_set_encryption_type(chip, NO_WEP);
+ /* We must inform the device that we are doing encryption/decryption in
+ * software at the moment. */
+ r = zd_set_encryption_type(chip, ENC_SNIFFER);
if (r)
goto disable_int;
@@ -136,10 +138,8 @@ static int reset_mode(struct zd_mac *mac
{
struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
struct zd_ioreq32 ioreqs[3] = {
- { CR_RX_FILTER, RX_FILTER_BEACON|RX_FILTER_PROBE_RESPONSE|
- RX_FILTER_AUTH|RX_FILTER_ASSOC_RESPONSE },
+ { CR_RX_FILTER, STA_RX_FILTER },
{ CR_SNIFFER_ON, 0U },
- { CR_ENCRYPTION_TYPE, NO_WEP },
};
if (ieee->iw_mode == IW_MODE_MONITOR) {
@@ -713,10 +713,10 @@ static int zd_mac_tx(struct zd_mac *mac,
struct zd_rt_hdr {
struct ieee80211_radiotap_header rt_hdr;
u8 rt_flags;
+ u8 rt_rate;
u16 rt_channel;
u16 rt_chbitmask;
- u16 rt_rate;
-};
+} __attribute__((packed));
static void fill_rt_header(void *buffer, struct zd_mac *mac,
const struct ieee80211_rx_stats *stats,
@@ -735,14 +735,14 @@ static void fill_rt_header(void *buffer,
if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256))
hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP;
+ hdr->rt_rate = stats->rate / 5;
+
/* FIXME: 802.11a */
hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz(
_zd_chip_get_channel(&mac->chip)));
hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ |
((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) ==
ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK));
-
- hdr->rt_rate = stats->rate / 5;
}
/* Returns 1 if the data packet is for us and 0 otherwise. */
Index: linux-2.6.17/drivers/net/wireless/zd1211rw/zd_usb.c
===================================================================
--- linux-2.6.17.orig/drivers/net/wireless/zd1211rw/zd_usb.c 2006-09-14 17:21:44.000000000 +0100
+++ linux-2.6.17/drivers/net/wireless/zd1211rw/zd_usb.c 2006-09-14 17:27:15.000000000 +0100
@@ -323,7 +323,6 @@ static void disable_read_regs_int(struct
{
struct zd_usb_interrupt *intr = &usb->intr;
- ZD_ASSERT(in_interrupt());
spin_lock(&intr->lock);
intr->read_regs_enabled = 0;
spin_unlock(&intr->lock);
@@ -545,11 +544,11 @@ static void handle_rx_packet(struct zd_u
* be padded. Unaligned access might also happen if the length_info
* structure is not present.
*/
- if (get_unaligned(&length_info->tag) == RX_LENGTH_INFO_TAG) {
+ if (get_unaligned(&length_info->tag) == cpu_to_le16(RX_LENGTH_INFO_TAG))
+ {
unsigned int l, k, n;
for (i = 0, l = 0;; i++) {
- k = le16_to_cpu(get_unaligned(
- &length_info->length[i]));
+ k = le16_to_cpu(get_unaligned(&length_info->length[i]));
n = l+k;
if (n > length)
return;
Index: linux-2.6.17/drivers/pci/hotplug/acpiphp_core.c
===================================================================
--- linux-2.6.17.orig/drivers/pci/hotplug/acpiphp_core.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/pci/hotplug/acpiphp_core.c 2006-09-14 17:27:15.000000000 +0100
@@ -27,8 +27,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * Send feedback to ,
- *
+ * Send feedback to
*
*/
Index: linux-2.6.17/drivers/pci/hotplug/acpiphp_glue.c
===================================================================
--- linux-2.6.17.orig/drivers/pci/hotplug/acpiphp_glue.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/pci/hotplug/acpiphp_glue.c 2006-09-14 17:27:15.000000000 +0100
@@ -26,7 +26,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * Send feedback to
+ * Send feedback to
*
*/
Index: linux-2.6.17/drivers/pci/pcie/portdrv_pci.c
===================================================================
--- linux-2.6.17.orig/drivers/pci/pcie/portdrv_pci.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/drivers/pci/pcie/portdrv_pci.c 2006-09-14 17:27:15.000000000 +0100
@@ -30,23 +30,6 @@ MODULE_LICENSE("GPL");
/* global data */
static const char device_name[] = "pcieport-driver";
-static int pcie_portdrv_save_config(struct pci_dev *dev)
-{
- return pci_save_state(dev);
-}
-
-static int pcie_portdrv_restore_config(struct pci_dev *dev)
-{
- int retval;
-
- pci_restore_state(dev);
- retval = pci_enable_device(dev);
- if (retval)
- return retval;
- pci_set_master(dev);
- return 0;
-}
-
/*
* pcie_portdrv_probe - Probe PCI-Express port devices
* @dev: PCI-Express port device being probed
@@ -73,8 +56,10 @@ static int __devinit pcie_portdrv_probe
"%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n",
__FUNCTION__, dev->device, dev->vendor);
}
- if (pcie_port_device_register(dev))
+ if (pcie_port_device_register(dev)) {
+ pci_disable_device(dev);
return -ENOMEM;
+ }
return 0;
}
@@ -86,6 +71,23 @@ static void pcie_portdrv_remove (struct
}
#ifdef CONFIG_PM
+static int pcie_portdrv_save_config(struct pci_dev *dev)
+{
+ return pci_save_state(dev);
+}
+
+static int pcie_portdrv_restore_config(struct pci_dev *dev)
+{
+ int retval;
+
+ pci_restore_state(dev);
+ retval = pci_enable_device(dev);
+ if (retval)
+ return retval;
+ pci_set_master(dev);
+ return 0;
+}
+
static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state)
{
int ret = pcie_port_device_suspend(dev, state);
Index: linux-2.6.17/drivers/pci/quirks.c
===================================================================
--- linux-2.6.17.orig/drivers/pci/quirks.c 2006-09-14 17:21:44.000000000 +0100
+++ linux-2.6.17/drivers/pci/quirks.c 2006-09-14 17:27:15.000000000 +0100
@@ -990,6 +990,11 @@ static void __init asus_hides_smbus_host
case 0x8070: /* P4G8X Deluxe */
asus_hides_smbus = 1;
}
+ if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH)
+ switch (dev->subsystem_device) {
+ case 0x80c9: /* PU-DLS */
+ asus_hides_smbus = 1;
+ }
if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
switch (dev->subsystem_device) {
case 0x1751: /* M2N notebook */
@@ -1058,6 +1063,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7501_MCH, asus_hides_smbus_hostbridge );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge );
@@ -1081,6 +1087,7 @@ static void __init asus_hides_smbus_lpc(
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc );
Index: linux-2.6.17/drivers/pci/search.c
===================================================================
--- linux-2.6.17.orig/drivers/pci/search.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/pci/search.c 2006-09-14 17:27:15.000000000 +0100
@@ -41,7 +41,7 @@ pci_do_find_bus(struct pci_bus* bus, uns
* in the global list of PCI buses. If the bus is found, a pointer to its
* data structure is returned. If no bus is found, %NULL is returned.
*/
-struct pci_bus * __devinit pci_find_bus(int domain, int busnr)
+struct pci_bus * pci_find_bus(int domain, int busnr)
{
struct pci_bus *bus = NULL;
struct pci_bus *tmp_bus;
@@ -61,7 +61,7 @@ struct pci_bus * __devinit pci_find_bus(
* @from: Previous PCI bus found, or %NULL for new search.
*
* Iterates through the list of known PCI busses. A new search is
- * initiated by passing %NULL to the @from argument. Otherwise if
+ * initiated by passing %NULL as the @from argument. Otherwise if
* @from is not %NULL, searches continue from next device on the
* global list.
*/
@@ -148,13 +148,14 @@ struct pci_dev * pci_get_slot(struct pci
* @from: Previous PCI device found in search, or %NULL for new search.
*
* Iterates through the list of known PCI devices. If a PCI device is
- * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its
- * device structure is returned. Otherwise, %NULL is returned.
- * A new search is initiated by passing %NULL to the @from argument.
- * Otherwise if @from is not %NULL, searches continue from next device on the global list.
+ * found with a matching @vendor, @device, @ss_vendor and @ss_device, a
+ * pointer to its device structure is returned. Otherwise, %NULL is returned.
+ * A new search is initiated by passing %NULL as the @from argument.
+ * Otherwise if @from is not %NULL, searches continue from next device
+ * on the global list.
*
- * NOTE: Do not use this function anymore, use pci_get_subsys() instead, as
- * the pci device returned by this function can disappear at any moment in
+ * NOTE: Do not use this function any more; use pci_get_subsys() instead, as
+ * the PCI device returned by this function can disappear at any moment in
* time.
*/
static struct pci_dev * pci_find_subsys(unsigned int vendor,
@@ -191,14 +192,15 @@ exit:
* @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
* @from: Previous PCI device found in search, or %NULL for new search.
*
- * Iterates through the list of known PCI devices. If a PCI device is
- * found with a matching @vendor and @device, a pointer to its device structure is
+ * Iterates through the list of known PCI devices. If a PCI device is found
+ * with a matching @vendor and @device, a pointer to its device structure is
* returned. Otherwise, %NULL is returned.
- * A new search is initiated by passing %NULL to the @from argument.
- * Otherwise if @from is not %NULL, searches continue from next device on the global list.
+ * A new search is initiated by passing %NULL as the @from argument.
+ * Otherwise if @from is not %NULL, searches continue from next device
+ * on the global list.
*
- * NOTE: Do not use this function anymore, use pci_get_device() instead, as
- * the pci device returned by this function can disappear at any moment in
+ * NOTE: Do not use this function any more; use pci_get_device() instead, as
+ * the PCI device returned by this function can disappear at any moment in
* time.
*/
struct pci_dev *
@@ -215,11 +217,11 @@ pci_find_device(unsigned int vendor, uns
* @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids
* @from: Previous PCI device found in search, or %NULL for new search.
*
- * Iterates through the list of known PCI devices. If a PCI device is
- * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its
+ * Iterates through the list of known PCI devices. If a PCI device is found
+ * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its
* device structure is returned, and the reference count to the device is
* incremented. Otherwise, %NULL is returned. A new search is initiated by
- * passing %NULL to the @from argument. Otherwise if @from is not %NULL,
+ * passing %NULL as the @from argument. Otherwise if @from is not %NULL,
* searches continue from next device on the global list.
* The reference count for @from is always decremented if it is not %NULL.
*/
@@ -262,7 +264,7 @@ exit:
* found with a matching @vendor and @device, the reference count to the
* device is incremented and a pointer to its device structure is returned.
* Otherwise, %NULL is returned. A new search is initiated by passing %NULL
- * to the @from argument. Otherwise if @from is not %NULL, searches continue
+ * as the @from argument. Otherwise if @from is not %NULL, searches continue
* from next device on the global list. The reference count for @from is
* always decremented if it is not %NULL.
*/
@@ -279,11 +281,13 @@ pci_get_device(unsigned int vendor, unsi
* @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
* @from: Previous PCI device found in search, or %NULL for new search.
*
- * Iterates through the list of known PCI devices in the reverse order of pci_find_device().
+ * Iterates through the list of known PCI devices in the reverse order of
+ * pci_find_device().
* If a PCI device is found with a matching @vendor and @device, a pointer to
* its device structure is returned. Otherwise, %NULL is returned.
- * A new search is initiated by passing %NULL to the @from argument.
- * Otherwise if @from is not %NULL, searches continue from previous device on the global list.
+ * A new search is initiated by passing %NULL as the @from argument.
+ * Otherwise if @from is not %NULL, searches continue from previous device
+ * on the global list.
*/
struct pci_dev *
pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from)
@@ -317,7 +321,7 @@ exit:
* found with a matching @class, the reference count to the device is
* incremented and a pointer to its device structure is returned.
* Otherwise, %NULL is returned.
- * A new search is initiated by passing %NULL to the @from argument.
+ * A new search is initiated by passing %NULL as the @from argument.
* Otherwise if @from is not %NULL, searches continue from next device
* on the global list. The reference count for @from is always decremented
* if it is not %NULL.
Index: linux-2.6.17/drivers/pcmcia/pcmcia_ioctl.c
===================================================================
--- linux-2.6.17.orig/drivers/pcmcia/pcmcia_ioctl.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/drivers/pcmcia/pcmcia_ioctl.c 2006-09-14 17:27:15.000000000 +0100
@@ -601,12 +601,8 @@ static int ds_ioctl(struct inode * inode
ret = CS_BAD_ARGS;
else {
struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
- if (p_dev == NULL)
- ret = CS_BAD_ARGS;
- else {
- ret = pccard_get_configuration_info(s, p_dev, &buf->config);
- pcmcia_put_dev(p_dev);
- }
+ ret = pccard_get_configuration_info(s, p_dev, &buf->config);
+ pcmcia_put_dev(p_dev);
}
break;
case DS_GET_FIRST_TUPLE:
@@ -636,12 +632,8 @@ static int ds_ioctl(struct inode * inode
ret = CS_BAD_ARGS;
else {
struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
- if (p_dev == NULL)
- ret = CS_BAD_ARGS;
- else {
- ret = pccard_get_status(s, p_dev, &buf->status);
- pcmcia_put_dev(p_dev);
- }
+ ret = pccard_get_status(s, p_dev, &buf->status);
+ pcmcia_put_dev(p_dev);
}
break;
case DS_VALIDATE_CIS:
Index: linux-2.6.17/drivers/pcmcia/pcmcia_resource.c
===================================================================
--- linux-2.6.17.orig/drivers/pcmcia/pcmcia_resource.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/pcmcia/pcmcia_resource.c 2006-09-14 17:27:15.000000000 +0100
@@ -245,10 +245,17 @@ int pccard_get_configuration_info(struct
return CS_SUCCESS;
}
- /* !!! This is a hack !!! */
- memcpy(&config->Attributes, &c->Attributes, sizeof(config_t));
- config->Attributes |= CONF_VALID_CLIENT;
- config->CardValues = c->CardValues;
+ config->Attributes = c->Attributes | CONF_VALID_CLIENT;
+ config->Vcc = s->socket.Vcc;
+ config->Vpp1 = config->Vpp2 = s->socket.Vpp;
+ config->IntType = c->IntType;
+ config->ConfigBase = c->ConfigBase;
+ config->Status = c->Status;
+ config->Pin = c->Pin;
+ config->Copy = c->Copy;
+ config->Option = c->Option;
+ config->ExtStatus = c->ExtStatus;
+ config->Present = config->CardValues = c->CardValues;
config->IRQAttributes = c->irq.Attributes;
config->AssignedIRQ = s->irq.AssignedIRQ;
config->BasePort1 = c->io.BasePort1;
Index: linux-2.6.17/drivers/pnp/interface.c
===================================================================
--- linux-2.6.17.orig/drivers/pnp/interface.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/pnp/interface.c 2006-09-14 17:27:15.000000000 +0100
@@ -265,8 +265,8 @@ static ssize_t pnp_show_current_resource
pnp_printf(buffer," disabled\n");
else
pnp_printf(buffer," 0x%llx-0x%llx\n",
- pnp_port_start(dev, i),
- pnp_port_end(dev, i));
+ (unsigned long long)pnp_port_start(dev, i),
+ (unsigned long long)pnp_port_end(dev, i));
}
}
for (i = 0; i < PNP_MAX_MEM; i++) {
@@ -276,8 +276,8 @@ static ssize_t pnp_show_current_resource
pnp_printf(buffer," disabled\n");
else
pnp_printf(buffer," 0x%llx-0x%llx\n",
- pnp_mem_start(dev, i),
- pnp_mem_end(dev, i));
+ (unsigned long long)pnp_mem_start(dev, i),
+ (unsigned long long)pnp_mem_end(dev, i));
}
}
for (i = 0; i < PNP_MAX_IRQ; i++) {
@@ -287,7 +287,7 @@ static ssize_t pnp_show_current_resource
pnp_printf(buffer," disabled\n");
else
pnp_printf(buffer," %lld\n",
- pnp_irq(dev, i));
+ (unsigned long long)pnp_irq(dev, i));
}
}
for (i = 0; i < PNP_MAX_DMA; i++) {
@@ -297,7 +297,7 @@ static ssize_t pnp_show_current_resource
pnp_printf(buffer," disabled\n");
else
pnp_printf(buffer," %lld\n",
- pnp_dma(dev, i));
+ (unsigned long long)pnp_dma(dev, i));
}
}
ret = (buffer->curr - buf);
Index: linux-2.6.17/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- linux-2.6.17.orig/drivers/pnp/pnpacpi/rsparser.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/pnp/pnpacpi/rsparser.c 2006-09-14 17:27:15.000000000 +0100
@@ -173,6 +173,9 @@ pnpacpi_parse_allocated_address_space(st
return;
}
+ if (p->producer_consumer == ACPI_PRODUCER)
+ return;
+
if (p->resource_type == ACPI_MEMORY_RANGE)
pnpacpi_parse_allocated_memresource(res_table,
p->minimum, p->address_length);
@@ -252,9 +255,14 @@ static acpi_status pnpacpi_allocated_res
break;
case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
+ if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
+ return AE_OK;
break;
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+ if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER)
+ return AE_OK;
+
for (i = 0; i < res->data.extended_irq.interrupt_count; i++) {
pnpacpi_parse_allocated_irqresource(res_table,
res->data.extended_irq.interrupts[i],
Index: linux-2.6.17/drivers/pnp/pnpbios/core.c
===================================================================
--- linux-2.6.17.orig/drivers/pnp/pnpbios/core.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/drivers/pnp/pnpbios/core.c 2006-09-14 17:27:15.000000000 +0100
@@ -346,7 +346,7 @@ static int insert_device(struct pnp_dev
dev->flags = node->flags;
if (!(dev->flags & PNPBIOS_NO_CONFIG))
dev->capabilities |= PNP_CONFIGURABLE;
- if (!(dev->flags & PNPBIOS_NO_DISABLE))
+ if (!(dev->flags & PNPBIOS_NO_DISABLE) && pnpbios_is_dynamic(dev))
dev->capabilities |= PNP_DISABLE;
dev->capabilities |= PNP_READ;
if (pnpbios_is_dynamic(dev))
Index: linux-2.6.17/drivers/scsi/ahci.c
===================================================================
--- linux-2.6.17.orig/drivers/scsi/ahci.c 2006-09-14 16:26:38.000000000 +0100
+++ linux-2.6.17/drivers/scsi/ahci.c 2006-09-14 17:27:15.000000000 +0100
@@ -940,14 +940,8 @@ static void ahci_host_intr(struct ata_po
return;
/* ignore interim PIO setup fis interrupts */
- if (ata_tag_valid(ap->active_tag)) {
- struct ata_queued_cmd *qc =
- ata_qc_from_tag(ap, ap->active_tag);
-
- if (qc && qc->tf.protocol == ATA_PROT_PIO &&
- (status & PORT_IRQ_PIOS_FIS))
- return;
- }
+ if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS))
+ return;
if (ata_ratelimit())
ata_port_printk(ap, KERN_INFO, "spurious interrupt "
Index: linux-2.6.17/drivers/scsi/aic7xxx/aicasm/Makefile
===================================================================
--- linux-2.6.17.orig/drivers/scsi/aic7xxx/aicasm/Makefile 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/drivers/scsi/aic7xxx/aicasm/Makefile 2006-09-14 17:27:15.000000000 +0100
@@ -14,6 +14,8 @@ LIBS= -ldb
clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG)
# Override default kernel CFLAGS. This is a userland app.
AICASM_CFLAGS:= -I/usr/include -I.
+LEX= flex
+YACC= bison
YFLAGS= -d
NOMAN= noman
Index: linux-2.6.17/drivers/usb/Kconfig
===================================================================
--- linux-2.6.17.orig/drivers/usb/Kconfig 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/Kconfig 2006-09-14 17:27:15.000000000 +0100
@@ -24,7 +24,7 @@ config USB_ARCH_HAS_OHCI
default y if ARCH_S3C2410
default y if PXA27x
default y if ARCH_EP93XX
- default y if ARCH_AT91RM9200
+ default y if (ARCH_AT91RM9200 || ARCH_AT91SAM9261)
# PPC:
default y if STB03xxx
default y if PPC_MPC52xx
Index: linux-2.6.17/drivers/usb/core/devio.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/core/devio.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/usb/core/devio.c 2006-09-14 17:27:15.000000000 +0100
@@ -517,19 +517,19 @@ static int check_ctrlrecip(struct dev_st
static struct usb_device *usbdev_lookup_minor(int minor)
{
- struct device *device;
- struct usb_device *udev = NULL;
+ struct class_device *class_dev;
+ struct usb_device *dev = NULL;
down(&usb_device_class->sem);
- list_for_each_entry(device, &usb_device_class->devices, node) {
- if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
- udev = device->platform_data;
+ list_for_each_entry(class_dev, &usb_device_class->children, node) {
+ if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
+ dev = class_dev->class_data;
break;
}
}
up(&usb_device_class->sem);
- return udev;
+ return dev;
};
/*
@@ -1580,16 +1580,16 @@ static void usbdev_add(struct usb_device
{
int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
- dev->usbfs_dev = device_create(usb_device_class, &dev->dev,
- MKDEV(USB_DEVICE_MAJOR, minor),
+ dev->class_dev = class_device_create(usb_device_class, NULL,
+ MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
"usbdev%d.%d", dev->bus->busnum, dev->devnum);
- dev->usbfs_dev->platform_data = dev;
+ dev->class_dev->class_data = dev;
}
static void usbdev_remove(struct usb_device *dev)
{
- device_unregister(dev->usbfs_dev);
+ class_device_unregister(dev->class_dev);
}
static int usbdev_notify(struct notifier_block *self, unsigned long action,
Index: linux-2.6.17/drivers/usb/core/file.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/core/file.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/usb/core/file.c 2006-09-14 17:27:15.000000000 +0100
@@ -194,13 +194,14 @@ int usb_register_dev(struct usb_interfac
++temp;
else
temp = name;
- intf->usb_dev = device_create(usb_class->class, &intf->dev,
- MKDEV(USB_MAJOR, minor), "%s", temp);
- if (IS_ERR(intf->usb_dev)) {
+ intf->class_dev = class_device_create(usb_class->class, NULL,
+ MKDEV(USB_MAJOR, minor),
+ &intf->dev, "%s", temp);
+ if (IS_ERR(intf->class_dev)) {
spin_lock (&minor_lock);
usb_minors[intf->minor] = NULL;
spin_unlock (&minor_lock);
- retval = PTR_ERR(intf->usb_dev);
+ retval = PTR_ERR(intf->class_dev);
}
exit:
return retval;
@@ -241,8 +242,8 @@ void usb_deregister_dev(struct usb_inter
spin_unlock (&minor_lock);
snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
- device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
- intf->usb_dev = NULL;
+ class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
+ intf->class_dev = NULL;
intf->minor = -1;
destroy_usb_class();
}
Index: linux-2.6.17/drivers/usb/gadget/Kconfig
===================================================================
--- linux-2.6.17.orig/drivers/usb/gadget/Kconfig 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/drivers/usb/gadget/Kconfig 2006-09-14 17:27:15.000000000 +0100
@@ -207,7 +207,7 @@ config USB_AT91
config USB_GADGET_DUMMY_HCD
boolean "Dummy HCD (DEVELOPMENT)"
- depends on USB && EXPERIMENTAL
+ depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL
select USB_GADGET_DUALSPEED
help
This host controller driver emulates USB, looping all data transfer
Index: linux-2.6.17/drivers/usb/gadget/at91_udc.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/gadget/at91_udc.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/usb/gadget/at91_udc.c 2006-09-14 17:27:15.000000000 +0100
@@ -57,19 +57,23 @@
/*
* This controller is simple and PIO-only. It's used in many AT91-series
- * ARMv4T controllers, including the at91rm9200 (arm920T, with MMU),
- * at91sam9261 (arm926ejs, with MMU), and several no-mmu versions.
+ * full speed USB controllers, including the at91rm9200 (arm920T, with MMU),
+ * at91sam926x (arm926ejs, with MMU), and several no-mmu versions.
*
* This driver expects the board has been wired with two GPIOs suppporting
* a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the
- * testing hasn't covered such cases.) The pullup is most important; it
+ * testing hasn't covered such cases.)
+ *
+ * The pullup is most important (so it's integrated on sam926x parts). It
* provides software control over whether the host enumerates the device.
+ *
* The VBUS sensing helps during enumeration, and allows both USB clocks
* (and the transceiver) to stay gated off until they're necessary, saving
- * power. During USB suspend, the 48 MHz clock is gated off.
+ * power. During USB suspend, the 48 MHz clock is gated off in hardware;
+ * it may also be gated off by software during some Linux sleep states.
*/
-#define DRIVER_VERSION "8 March 2005"
+#define DRIVER_VERSION "3 May 2006"
static const char driver_name [] = "at91_udc";
static const char ep0name[] = "ep0";
@@ -316,9 +320,15 @@ static void done(struct at91_ep *ep, str
*
* There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE
* that shouldn't normally be changed.
+ *
+ * NOTE at91sam9260 docs mention synch between UDPCK and MCK clock domains,
+ * implying a need to wait for one write to complete (test relevant bits)
+ * before starting the next write. This shouldn't be an issue given how
+ * infrequently we write, except maybe for write-then-read idioms.
*/
#define SET_FX (AT91_UDP_TXPKTRDY)
-#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
+#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP \
+ | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
/* pull OUT packet data from the endpoint's fifo */
static int read_fifo (struct at91_ep *ep, struct at91_request *req)
@@ -472,7 +482,8 @@ static void nuke(struct at91_ep *ep, int
/*-------------------------------------------------------------------------*/
-static int at91_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
+static int at91_ep_enable(struct usb_ep *_ep,
+ const struct usb_endpoint_descriptor *desc)
{
struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
struct at91_udc *dev = ep->udc;
@@ -582,11 +593,12 @@ static int at91_ep_disable (struct usb_e
* interesting for request or buffer allocation.
*/
-static struct usb_request *at91_ep_alloc_request (struct usb_ep *_ep, unsigned int gfp_flags)
+static struct usb_request *
+at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags)
{
struct at91_request *req;
- req = kcalloc(1, sizeof (struct at91_request), SLAB_KERNEL);
+ req = kcalloc(1, sizeof (struct at91_request), gfp_flags);
if (!req)
return NULL;
@@ -862,6 +874,7 @@ static void stop_activity(struct at91_ud
if (udc->gadget.speed == USB_SPEED_UNKNOWN)
driver = NULL;
udc->gadget.speed = USB_SPEED_UNKNOWN;
+ udc->suspended = 0;
for (i = 0; i < NUM_ENDPOINTS; i++) {
struct at91_ep *ep = &udc->ep[i];
@@ -889,8 +902,8 @@ static void clk_off(struct at91_udc *udc
return;
udc->clocked = 0;
udc->gadget.speed = USB_SPEED_UNKNOWN;
- clk_disable(udc->iclk);
clk_disable(udc->fclk);
+ clk_disable(udc->iclk);
}
/*
@@ -911,9 +924,6 @@ static void pullup(struct at91_udc *udc,
at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
at91_set_gpio_value(udc->board.pullup_pin, 0);
clk_off(udc);
-
- // REVISIT: with transceiver disabled, will D- float
- // so that a host would falsely detect a device?
}
}
@@ -1290,7 +1300,8 @@ static void handle_ep0(struct at91_udc *
if (udc->wait_for_addr_ack) {
u32 tmp;
- at91_udp_write(AT91_UDP_FADDR, AT91_UDP_FEN | udc->addr);
+ at91_udp_write(AT91_UDP_FADDR,
+ AT91_UDP_FEN | udc->addr);
tmp = at91_udp_read(AT91_UDP_GLB_STAT);
tmp &= ~AT91_UDP_FADDEN;
if (udc->addr)
@@ -1361,9 +1372,10 @@ static irqreturn_t at91_udc_irq (int irq
u32 rescans = 5;
while (rescans--) {
- u32 status = at91_udp_read(AT91_UDP_ISR);
+ u32 status;
- status &= at91_udp_read(AT91_UDP_IMR);
+ status = at91_udp_read(AT91_UDP_ISR)
+ & at91_udp_read(AT91_UDP_IMR);
if (!status)
break;
@@ -1379,18 +1391,17 @@ static irqreturn_t at91_udc_irq (int irq
stop_activity(udc);
/* enable ep0 */
- at91_udp_write(AT91_UDP_CSR(0), AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
+ at91_udp_write(AT91_UDP_CSR(0),
+ AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
udc->gadget.speed = USB_SPEED_FULL;
udc->suspended = 0;
at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0));
/*
* NOTE: this driver keeps clocks off unless the
- * USB host is present. That saves power, and also
- * eliminates IRQs (reset, resume, suspend) that can
- * otherwise flood from the controller. If your
- * board doesn't support VBUS detection, suspend and
- * resume irq logic may need more attention...
+ * USB host is present. That saves power, but for
+ * boards that don't support VBUS detection, both
+ * clocks need to be active most of the time.
*/
/* host initiated suspend (3+ms bus idle) */
@@ -1452,13 +1463,19 @@ static irqreturn_t at91_udc_irq (int irq
/*-------------------------------------------------------------------------*/
+static void nop_release(struct device *dev)
+{
+ /* nothing to free */
+}
+
static struct at91_udc controller = {
.gadget = {
- .ops = &at91_udc_ops,
- .ep0 = &controller.ep[0].ep,
- .name = driver_name,
- .dev = {
- .bus_id = "gadget"
+ .ops = &at91_udc_ops,
+ .ep0 = &controller.ep[0].ep,
+ .name = driver_name,
+ .dev = {
+ .bus_id = "gadget",
+ .release = nop_release,
}
},
.ep[0] = {
@@ -1468,7 +1485,8 @@ static struct at91_udc controller = {
},
.udc = &controller,
.maxpacket = 8,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(0)),
+ .creg = (void __iomem *)(AT91_VA_BASE_UDP
+ + AT91_UDP_CSR(0)),
.int_mask = 1 << 0,
},
.ep[1] = {
@@ -1479,7 +1497,8 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 64,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(1)),
+ .creg = (void __iomem *)(AT91_VA_BASE_UDP
+ + AT91_UDP_CSR(1)),
.int_mask = 1 << 1,
},
.ep[2] = {
@@ -1490,7 +1509,8 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 64,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(2)),
+ .creg = (void __iomem *)(AT91_VA_BASE_UDP
+ + AT91_UDP_CSR(2)),
.int_mask = 1 << 2,
},
.ep[3] = {
@@ -1501,7 +1521,8 @@ static struct at91_udc controller = {
},
.udc = &controller,
.maxpacket = 8,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(3)),
+ .creg = (void __iomem *)(AT91_VA_BASE_UDP
+ + AT91_UDP_CSR(3)),
.int_mask = 1 << 3,
},
.ep[4] = {
@@ -1512,7 +1533,8 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 256,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(4)),
+ .creg = (void __iomem *)(AT91_VA_BASE_UDP
+ + AT91_UDP_CSR(4)),
.int_mask = 1 << 4,
},
.ep[5] = {
@@ -1523,10 +1545,11 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 256,
- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(5)),
+ .creg = (void __iomem *)(AT91_VA_BASE_UDP
+ + AT91_UDP_CSR(5)),
.int_mask = 1 << 5,
},
- /* ep6 and ep7 are also reserved */
+ /* ep6 and ep7 are also reserved (custom silicon might use them) */
};
static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r)
@@ -1593,6 +1616,7 @@ int usb_gadget_unregister_driver (struct
local_irq_disable();
udc->enabled = 0;
+ at91_udp_write(AT91_UDP_IDR, ~0);
pullup(udc, 0);
local_irq_enable();
@@ -1624,6 +1648,16 @@ static int __devinit at91udc_probe(struc
return -ENODEV;
}
+ if (pdev->num_resources != 2) {
+ DBG("invalid num_resources");
+ return -ENODEV;
+ }
+ if ((pdev->resource[0].flags != IORESOURCE_MEM)
+ || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
+ DBG("invalid resource type");
+ return -ENODEV;
+ }
+
if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) {
DBG("someone's using UDC memory\n");
return -EBUSY;
@@ -1649,19 +1683,26 @@ static int __devinit at91udc_probe(struc
if (retval < 0)
goto fail0;
- /* disable everything until there's a gadget driver and vbus */
- pullup(udc, 0);
+ /* don't do anything until we have both gadget driver and VBUS */
+ clk_enable(udc->iclk);
+ at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
+ at91_udp_write(AT91_UDP_IDR, 0xffffffff);
+ clk_disable(udc->iclk);
/* request UDC and maybe VBUS irqs */
- if (request_irq(AT91_ID_UDP, at91_udc_irq, IRQF_DISABLED, driver_name, udc)) {
- DBG("request irq %d failed\n", AT91_ID_UDP);
+ udc->udp_irq = platform_get_irq(pdev, 0);
+ if (request_irq(udc->udp_irq, at91_udc_irq,
+ IRQF_DISABLED, driver_name, udc)) {
+ DBG("request irq %d failed\n", udc->udp_irq);
retval = -EBUSY;
goto fail1;
}
if (udc->board.vbus_pin > 0) {
- if (request_irq(udc->board.vbus_pin, at91_vbus_irq, IRQF_DISABLED, driver_name, udc)) {
- DBG("request vbus irq %d failed\n", udc->board.vbus_pin);
- free_irq(AT91_ID_UDP, udc);
+ if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
+ IRQF_DISABLED, driver_name, udc)) {
+ DBG("request vbus irq %d failed\n",
+ udc->board.vbus_pin);
+ free_irq(udc->udp_irq, udc);
retval = -EBUSY;
goto fail1;
}
@@ -1670,6 +1711,7 @@ static int __devinit at91udc_probe(struc
udc->vbus = 1;
}
dev_set_drvdata(dev, udc);
+ device_init_wakeup(dev, 1);
create_debug_file(udc);
INFO("%s version %s\n", driver_name, DRIVER_VERSION);
@@ -1678,14 +1720,14 @@ static int __devinit at91udc_probe(struc
fail1:
device_unregister(&udc->gadget.dev);
fail0:
- release_mem_region(AT91_VA_BASE_UDP, SZ_16K);
+ release_mem_region(AT91_BASE_UDP, SZ_16K);
DBG("%s probe failed, %d\n", driver_name, retval);
return retval;
}
-static int __devexit at91udc_remove(struct platform_device *dev)
+static int __devexit at91udc_remove(struct platform_device *pdev)
{
- struct at91_udc *udc = platform_get_drvdata(dev);
+ struct at91_udc *udc = platform_get_drvdata(pdev);
DBG("remove\n");
@@ -1694,10 +1736,11 @@ static int __devexit at91udc_remove(stru
if (udc->driver != 0)
usb_gadget_unregister_driver(udc->driver);
+ device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
if (udc->board.vbus_pin > 0)
free_irq(udc->board.vbus_pin, udc);
- free_irq(AT91_ID_UDP, udc);
+ free_irq(udc->udp_irq, udc);
device_unregister(&udc->gadget.dev);
release_mem_region(AT91_BASE_UDP, SZ_16K);
@@ -1708,31 +1751,36 @@ static int __devexit at91udc_remove(stru
}
#ifdef CONFIG_PM
-static int at91udc_suspend(struct platform_device *dev, pm_message_t mesg)
+static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
{
- struct at91_udc *udc = platform_get_drvdata(dev);
+ struct at91_udc *udc = platform_get_drvdata(pdev);
+ int wake = udc->driver && device_may_wakeup(&pdev->dev);
- /*
- * The "safe" suspend transitions are opportunistic ... e.g. when
- * the USB link is suspended (48MHz clock autogated off), or when
- * it's disconnected (programmatically gated off, elsewhere).
- * Then we can suspend, and the chip can enter slow clock mode.
- *
- * The problem case is some component (user mode?) suspending this
- * device while it's active, with the 48 MHz clock in use. There
- * are two basic approaches: (a) veto suspend levels involving slow
- * clock mode, (b) disconnect, so 48 MHz will no longer be in use
- * and we can enter slow clock mode. This uses (b) for now, since
- * it's simplest until AT91 PM exists and supports the other option.
+ /* Unless we can act normally to the host (letting it wake us up
+ * whenever it has work for us) force disconnect. Wakeup requires
+ * PLLB for USB events (signaling for reset, wakeup, or incoming
+ * tokens) and VBUS irqs (on systems which support them).
*/
- if (udc->vbus && !udc->suspended)
+ if ((!udc->suspended && udc->addr)
+ || !wake
+ || at91_suspend_entering_slow_clock()) {
pullup(udc, 0);
+ disable_irq_wake(udc->udp_irq);
+ } else
+ enable_irq_wake(udc->udp_irq);
+
+ if (udc->board.vbus_pin > 0) {
+ if (wake)
+ enable_irq_wake(udc->board.vbus_pin);
+ else
+ disable_irq_wake(udc->board.vbus_pin);
+ }
return 0;
}
-static int at91udc_resume(struct platform_device *dev)
+static int at91udc_resume(struct platform_device *pdev)
{
- struct at91_udc *udc = platform_get_drvdata(dev);
+ struct at91_udc *udc = platform_get_drvdata(pdev);
/* maybe reconnect to host; if so, clocks on */
pullup(udc, 1);
@@ -1748,7 +1796,7 @@ static struct platform_driver at91_udc =
.remove = __devexit_p(at91udc_remove),
.shutdown = at91udc_shutdown,
.suspend = at91udc_suspend,
- .resume = at91udc_resume,
+ .resume = at91udc_resume,
.driver = {
.name = (char *) driver_name,
.owner = THIS_MODULE,
@@ -1767,6 +1815,6 @@ static void __devexit udc_exit_module(vo
}
module_exit(udc_exit_module);
-MODULE_DESCRIPTION("AT91RM9200 udc driver");
+MODULE_DESCRIPTION("AT91 udc driver");
MODULE_AUTHOR("Thomas Rathbone, David Brownell");
MODULE_LICENSE("GPL");
Index: linux-2.6.17/drivers/usb/gadget/at91_udc.h
===================================================================
--- linux-2.6.17.orig/drivers/usb/gadget/at91_udc.h 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/drivers/usb/gadget/at91_udc.h 2006-09-14 17:27:15.000000000 +0100
@@ -141,6 +141,7 @@ struct at91_udc {
struct clk *iclk, *fclk;
struct platform_device *pdev;
struct proc_dir_entry *pde;
+ int udp_irq;
};
static inline struct at91_udc *to_udc(struct usb_gadget *g)
Index: linux-2.6.17/drivers/usb/gadget/dummy_hcd.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/gadget/dummy_hcd.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/usb/gadget/dummy_hcd.c 2006-09-14 17:27:15.000000000 +0100
@@ -609,7 +609,8 @@ static int dummy_dequeue (struct usb_ep
if (!dum->driver)
return -ESHUTDOWN;
- spin_lock_irqsave (&dum->lock, flags);
+ local_irq_save (flags);
+ spin_lock (&dum->lock);
list_for_each_entry (req, &ep->queue, queue) {
if (&req->req == _req) {
list_del_init (&req->queue);
@@ -618,7 +619,7 @@ static int dummy_dequeue (struct usb_ep
break;
}
}
- spin_unlock_irqrestore (&dum->lock, flags);
+ spin_unlock (&dum->lock);
if (retval == 0) {
dev_dbg (udc_dev(dum),
@@ -626,6 +627,7 @@ static int dummy_dequeue (struct usb_ep
req, _ep->name, _req->length, _req->buf);
_req->complete (_ep, _req);
}
+ local_irq_restore (flags);
return retval;
}
Index: linux-2.6.17/drivers/usb/host/ehci-hcd.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/host/ehci-hcd.c 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/host/ehci-hcd.c 2006-09-14 17:27:15.000000000 +0100
@@ -892,7 +892,7 @@ MODULE_LICENSE ("GPL");
#define PCI_DRIVER ehci_pci_driver
#endif
-#ifdef CONFIG_PPC_83xx
+#ifdef CONFIG_MPC834x
#include "ehci-fsl.c"
#define PLATFORM_DRIVER ehci_fsl_driver
#endif
Index: linux-2.6.17/drivers/usb/host/ohci-at91.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/host/ohci-at91.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/usb/host/ohci-at91.c 2006-09-14 17:27:15.000000000 +0100
@@ -4,7 +4,7 @@
* Copyright (C) 2004 SAN People (Pty) Ltd.
* Copyright (C) 2005 Thibaut VARENE
*
- * AT91RM9200 Bus Glue
+ * AT91 Bus Glue
*
* Based on fragments of 2.4 driver by Rick Bronson.
* Based on ohci-omap.c
@@ -19,12 +19,13 @@
#include
#include
-#ifndef CONFIG_ARCH_AT91RM9200
-#error "CONFIG_ARCH_AT91RM9200 must be defined."
+#ifndef CONFIG_ARCH_AT91
+#error "CONFIG_ARCH_AT91 must be defined."
#endif
/* interface and function clocks */
static struct clk *iclk, *fclk;
+static int clocked;
extern int usb_disabled(void);
@@ -35,13 +36,14 @@ static void at91_start_hc(struct platfor
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd->regs;
- dev_dbg(&pdev->dev, "starting AT91RM9200 OHCI USB Controller\n");
+ dev_dbg(&pdev->dev, "start\n");
/*
* Start the USB clocks.
*/
clk_enable(iclk);
clk_enable(fclk);
+ clocked = 1;
/*
* The USB host controller must remain in reset.
@@ -54,7 +56,7 @@ static void at91_stop_hc(struct platform
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd->regs;
- dev_dbg(&pdev->dev, "stopping AT91RM9200 OHCI USB Controller\n");
+ dev_dbg(&pdev->dev, "stop\n");
/*
* Put the USB host controller into reset.
@@ -66,6 +68,7 @@ static void at91_stop_hc(struct platform
*/
clk_disable(fclk);
clk_disable(iclk);
+ clocked = 0;
}
@@ -78,14 +81,15 @@ static int usb_hcd_at91_remove (struct u
/**
- * usb_hcd_at91_probe - initialize AT91RM9200-based HCDs
+ * usb_hcd_at91_probe - initialize AT91-based HCDs
* Context: !in_interrupt()
*
* Allocates basic resources for this USB host controller, and
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*/
-int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev)
+static int usb_hcd_at91_probe(const struct hc_driver *driver,
+ struct platform_device *pdev)
{
int retval;
struct usb_hcd *hcd = NULL;
@@ -95,12 +99,13 @@ int usb_hcd_at91_probe (const struct hc_
return -ENODEV;
}
- if ((pdev->resource[0].flags != IORESOURCE_MEM) || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
+ if ((pdev->resource[0].flags != IORESOURCE_MEM)
+ || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
pr_debug("hcd probe: invalid resource type\n");
return -ENODEV;
}
- hcd = usb_create_hcd(driver, &pdev->dev, "at91rm9200");
+ hcd = usb_create_hcd(driver, &pdev->dev, "at91");
if (!hcd)
return -ENOMEM;
hcd->rsrc_start = pdev->resource[0].start;
@@ -149,21 +154,23 @@ int usb_hcd_at91_probe (const struct hc_
/* may be called with controller, bus, and devices active */
/**
- * usb_hcd_at91_remove - shutdown processing for AT91RM9200-based HCDs
+ * usb_hcd_at91_remove - shutdown processing for AT91-based HCDs
* @dev: USB Host Controller being removed
* Context: !in_interrupt()
*
* Reverses the effect of usb_hcd_at91_probe(), first invoking
* the HCD's stop() method. It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
+ * context, "rmmod" or something similar.
*
*/
-static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pdev)
+static int usb_hcd_at91_remove(struct usb_hcd *hcd,
+ struct platform_device *pdev)
{
usb_remove_hcd(hcd);
at91_stop_hc(pdev);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ disable_irq_wake(hcd->irq);
clk_put(fclk);
clk_put(iclk);
@@ -178,19 +185,21 @@ static int usb_hcd_at91_remove (struct u
static int __devinit
ohci_at91_start (struct usb_hcd *hcd)
{
-// struct at91_ohci_data *board = hcd->self.controller->platform_data;
+ struct at91_usbh_data *board = hcd->self.controller->platform_data;
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ struct usb_device *root = hcd->self.root_hub;
int ret;
if ((ret = ohci_init(ohci)) < 0)
return ret;
+ root->maxchild = board->ports;
+
if ((ret = ohci_run(ohci)) < 0) {
err("can't start %s", hcd->self.bus_name);
ohci_stop(hcd);
return ret;
}
-// hcd->self.root_hub->maxchild = board->ports;
return 0;
}
@@ -198,7 +207,7 @@ ohci_at91_start (struct usb_hcd *hcd)
static const struct hc_driver ohci_at91_hc_driver = {
.description = hcd_name,
- .product_desc = "AT91RM9200 OHCI",
+ .product_desc = "AT91 OHCI",
.hcd_priv_size = sizeof(struct ohci_hcd),
/*
@@ -240,33 +249,54 @@ static const struct hc_driver ohci_at91_
/*-------------------------------------------------------------------------*/
-static int ohci_hcd_at91_drv_probe(struct platform_device *dev)
+static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
{
- return usb_hcd_at91_probe(&ohci_at91_hc_driver, dev);
+ device_init_wakeup(&pdev->dev, 1);
+ return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
}
-static int ohci_hcd_at91_drv_remove(struct platform_device *dev)
+static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
{
- return usb_hcd_at91_remove(platform_get_drvdata(dev), dev);
+ device_init_wakeup(&pdev->dev, 0);
+ return usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev);
}
#ifdef CONFIG_PM
-/* REVISIT suspend/resume look "too" simple here */
-
static int
-ohci_hcd_at91_drv_suspend(struct platform_device *dev, pm_message_t mesg)
+ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
{
- clk_disable(fclk);
- clk_disable(iclk);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+ if (device_may_wakeup(&pdev->dev))
+ enable_irq_wake(hcd->irq);
+ else
+ disable_irq_wake(hcd->irq);
+
+ /*
+ * The integrated transceivers seem unable to notice disconnect,
+ * reconnect, or wakeup without the 48 MHz clock active. so for
+ * correctness, always discard connection state (using reset).
+ *
+ * REVISIT: some boards will be able to turn VBUS off...
+ */
+ if (at91_suspend_entering_slow_clock()) {
+ ohci_usb_reset (ohci);
+ clk_disable(fclk);
+ clk_disable(iclk);
+ clocked = 0;
+ }
return 0;
}
-static int ohci_hcd_at91_drv_resume(struct platform_device *dev)
+static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
{
- clk_enable(iclk);
- clk_enable(fclk);
+ if (!clocked) {
+ clk_enable(iclk);
+ clk_enable(fclk);
+ }
return 0;
}
@@ -275,7 +305,7 @@ static int ohci_hcd_at91_drv_resume(stru
#define ohci_hcd_at91_drv_resume NULL
#endif
-MODULE_ALIAS("at91rm9200-ohci");
+MODULE_ALIAS("at91_ohci");
static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe,
@@ -283,7 +313,7 @@ static struct platform_driver ohci_hcd_a
.suspend = ohci_hcd_at91_drv_suspend,
.resume = ohci_hcd_at91_drv_resume,
.driver = {
- .name = "at91rm9200-ohci",
+ .name = "at91_ohci",
.owner = THIS_MODULE,
},
};
Index: linux-2.6.17/drivers/usb/host/ohci-hcd.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/host/ohci-hcd.c 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/host/ohci-hcd.c 2006-09-14 17:27:15.000000000 +0100
@@ -913,7 +913,7 @@ MODULE_LICENSE ("GPL");
#include "ohci-ppc-soc.c"
#endif
-#ifdef CONFIG_ARCH_AT91RM9200
+#if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261)
#include "ohci-at91.c"
#endif
@@ -927,6 +927,7 @@ MODULE_LICENSE ("GPL");
|| defined (CONFIG_SOC_AU1X00) \
|| defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
|| defined (CONFIG_ARCH_AT91RM9200) \
+ || defined (CONFIG_ARCH_AT91SAM9261) \
)
#error "missing bus glue for ohci-hcd"
#endif
Index: linux-2.6.17/drivers/usb/host/uhci-q.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/host/uhci-q.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/usb/host/uhci-q.c 2006-09-14 17:27:15.000000000 +0100
@@ -943,7 +943,9 @@ static int uhci_result_common(struct uhc
/* We received a short packet */
if (urb->transfer_flags & URB_SHORT_NOT_OK)
ret = -EREMOTEIO;
- else if (ctrlstat & TD_CTRL_SPD)
+
+ /* Fixup needed only if this isn't the URB's last TD */
+ else if (&td->list != urbp->td_list.prev)
ret = 1;
}
Index: linux-2.6.17/drivers/usb/input/ati_remote.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/input/ati_remote.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/usb/input/ati_remote.c 2006-09-14 17:27:15.000000000 +0100
@@ -111,14 +111,28 @@
#define NAME_BUFSIZE 80 /* size of product name, path buffers */
#define DATA_BUFSIZE 63 /* size of URB data buffers */
+/*
+ * Duplicate event filtering time.
+ * Sequential, identical KIND_FILTERED inputs with less than
+ * FILTER_TIME milliseconds between them are considered as repeat
+ * events. The hardware generates 5 events for the first keypress
+ * and we have to take this into account for an accurate repeat
+ * behaviour.
+ */
+#define FILTER_TIME 60 /* msec */
+
static unsigned long channel_mask;
-module_param(channel_mask, ulong, 0444);
+module_param(channel_mask, ulong, 0644);
MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore");
static int debug;
-module_param(debug, int, 0444);
+module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
+static int repeat_filter = FILTER_TIME;
+module_param(repeat_filter, int, 0644);
+MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec");
+
#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
#undef err
#define err(format, arg...) printk(KERN_ERR format , ## arg)
@@ -143,19 +157,6 @@ MODULE_DEVICE_TABLE(usb, ati_remote_tabl
static char init1[] = { 0x01, 0x00, 0x20, 0x14 };
static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
-/* Acceleration curve for directional control pad */
-static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
-
-/* Duplicate event filtering time.
- * Sequential, identical KIND_FILTERED inputs with less than
- * FILTER_TIME jiffies between them are considered as repeat
- * events. The hardware generates 5 events for the first keypress
- * and we have to take this into account for an accurate repeat
- * behaviour.
- * (HZ / 20) == 50 ms and works well for me.
- */
-#define FILTER_TIME (HZ / 20)
-
struct ati_remote {
struct input_dev *idev;
struct usb_device *udev;
@@ -413,6 +414,43 @@ static int ati_remote_event_lookup(int r
}
/*
+ * ati_remote_compute_accel
+ *
+ * Implements acceleration curve for directional control pad
+ * If elapsed time since last event is > 1/4 second, user "stopped",
+ * so reset acceleration. Otherwise, user is probably holding the control
+ * pad down, so we increase acceleration, ramping up over two seconds to
+ * a maximum speed.
+ */
+static int ati_remote_compute_accel(struct ati_remote *ati_remote)
+{
+ static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
+ unsigned long now = jiffies;
+ int acc;
+
+ if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) {
+ acc = 1;
+ ati_remote->acc_jiffies = now;
+ }
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125)))
+ acc = accel[0];
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250)))
+ acc = accel[1];
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500)))
+ acc = accel[2];
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000)))
+ acc = accel[3];
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500)))
+ acc = accel[4];
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000)))
+ acc = accel[5];
+ else
+ acc = accel[6];
+
+ return acc;
+}
+
+/*
* ati_remote_report_input
*/
static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
@@ -465,9 +503,9 @@ static void ati_remote_input_report(stru
if (ati_remote_tbl[index].kind == KIND_FILTERED) {
/* Filter duplicate events which happen "too close" together. */
- if ((ati_remote->old_data[0] == data[1]) &&
- (ati_remote->old_data[1] == data[2]) &&
- time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) {
+ if (ati_remote->old_data[0] == data[1] &&
+ ati_remote->old_data[1] == data[2] &&
+ time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(repeat_filter))) {
ati_remote->repeat_count++;
} else {
ati_remote->repeat_count = 0;
@@ -477,75 +515,61 @@ static void ati_remote_input_report(stru
ati_remote->old_data[1] = data[2];
ati_remote->old_jiffies = jiffies;
- if ((ati_remote->repeat_count > 0)
- && (ati_remote->repeat_count < 5))
+ if (ati_remote->repeat_count > 0 &&
+ ati_remote->repeat_count < 5)
return;
input_regs(dev, regs);
input_event(dev, ati_remote_tbl[index].type,
ati_remote_tbl[index].code, 1);
+ input_sync(dev);
input_event(dev, ati_remote_tbl[index].type,
ati_remote_tbl[index].code, 0);
input_sync(dev);
- return;
- }
+ } else {
- /*
- * Other event kinds are from the directional control pad, and have an
- * acceleration factor applied to them. Without this acceleration, the
- * control pad is mostly unusable.
- *
- * If elapsed time since last event is > 1/4 second, user "stopped",
- * so reset acceleration. Otherwise, user is probably holding the control
- * pad down, so we increase acceleration, ramping up over two seconds to
- * a maximum speed. The acceleration curve is #defined above.
- */
- if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) {
- acc = 1;
- ati_remote->acc_jiffies = jiffies;
+ /*
+ * Other event kinds are from the directional control pad, and have an
+ * acceleration factor applied to them. Without this acceleration, the
+ * control pad is mostly unusable.
+ */
+ acc = ati_remote_compute_accel(ati_remote);
+
+ input_regs(dev, regs);
+ switch (ati_remote_tbl[index].kind) {
+ case KIND_ACCEL:
+ input_event(dev, ati_remote_tbl[index].type,
+ ati_remote_tbl[index].code,
+ ati_remote_tbl[index].value * acc);
+ break;
+ case KIND_LU:
+ input_report_rel(dev, REL_X, -acc);
+ input_report_rel(dev, REL_Y, -acc);
+ break;
+ case KIND_RU:
+ input_report_rel(dev, REL_X, acc);
+ input_report_rel(dev, REL_Y, -acc);
+ break;
+ case KIND_LD:
+ input_report_rel(dev, REL_X, -acc);
+ input_report_rel(dev, REL_Y, acc);
+ break;
+ case KIND_RD:
+ input_report_rel(dev, REL_X, acc);
+ input_report_rel(dev, REL_Y, acc);
+ break;
+ default:
+ dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
+ ati_remote_tbl[index].kind);
+ }
+ input_sync(dev);
+
+ ati_remote->old_jiffies = jiffies;
+ ati_remote->old_data[0] = data[1];
+ ati_remote->old_data[1] = data[2];
}
- else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3))) acc = accel[0];
- else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2))) acc = accel[1];
- else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1))) acc = accel[2];
- else if (time_before(jiffies, ati_remote->acc_jiffies + HZ)) acc = accel[3];
- else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4];
- else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1))) acc = accel[5];
- else acc = accel[6];
-
- input_regs(dev, regs);
- switch (ati_remote_tbl[index].kind) {
- case KIND_ACCEL:
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code,
- ati_remote_tbl[index].value * acc);
- break;
- case KIND_LU:
- input_report_rel(dev, REL_X, -acc);
- input_report_rel(dev, REL_Y, -acc);
- break;
- case KIND_RU:
- input_report_rel(dev, REL_X, acc);
- input_report_rel(dev, REL_Y, -acc);
- break;
- case KIND_LD:
- input_report_rel(dev, REL_X, -acc);
- input_report_rel(dev, REL_Y, acc);
- break;
- case KIND_RD:
- input_report_rel(dev, REL_X, acc);
- input_report_rel(dev, REL_Y, acc);
- break;
- default:
- dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
- ati_remote_tbl[index].kind);
- }
- input_sync(dev);
-
- ati_remote->old_jiffies = jiffies;
- ati_remote->old_data[0] = data[1];
- ati_remote->old_data[1] = data[2];
}
/*
Index: linux-2.6.17/drivers/usb/input/hid-input.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/input/hid-input.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/usb/input/hid-input.c 2006-09-14 17:27:15.000000000 +0100
@@ -607,7 +607,8 @@ static void hidinput_configure_usage(str
}
- if (usage->hat_min < usage->hat_max || usage->hat_dir) {
+ if (usage->type == EV_ABS &&
+ (usage->hat_min < usage->hat_max || usage->hat_dir)) {
int i;
for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
input_set_abs_params(input, i, -1, 1, 0, 0);
Index: linux-2.6.17/drivers/usb/input/hiddev.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/input/hiddev.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/usb/input/hiddev.c 2006-09-14 17:27:15.000000000 +0100
@@ -49,7 +49,7 @@ struct hiddev {
int open;
wait_queue_head_t wait;
struct hid_device *hid;
- struct hiddev_list *list;
+ struct list_head list;
};
struct hiddev_list {
@@ -59,7 +59,7 @@ struct hiddev_list {
unsigned flags;
struct fasync_struct *fasync;
struct hiddev *hiddev;
- struct hiddev_list *next;
+ struct list_head node;
};
static struct hiddev *hiddev_table[HIDDEV_MINORS];
@@ -73,12 +73,15 @@ static struct hiddev *hiddev_table[HIDDE
static struct hid_report *
hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
{
- unsigned flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
+ unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
+ unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK;
struct hid_report_enum *report_enum;
+ struct hid_report *report;
struct list_head *list;
if (rinfo->report_type < HID_REPORT_TYPE_MIN ||
- rinfo->report_type > HID_REPORT_TYPE_MAX) return NULL;
+ rinfo->report_type > HID_REPORT_TYPE_MAX)
+ return NULL;
report_enum = hid->report_enum +
(rinfo->report_type - HID_REPORT_TYPE_MIN);
@@ -88,21 +91,25 @@ hiddev_lookup_report(struct hid_device *
break;
case HID_REPORT_ID_FIRST:
- list = report_enum->report_list.next;
- if (list == &report_enum->report_list)
+ if (list_empty(&report_enum->report_list))
return NULL;
- rinfo->report_id = ((struct hid_report *) list)->id;
+
+ list = report_enum->report_list.next;
+ report = list_entry(list, struct hid_report, list);
+ rinfo->report_id = report->id;
break;
case HID_REPORT_ID_NEXT:
- list = (struct list_head *)
- report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK];
- if (list == NULL)
+ report = report_enum->report_id_hash[rid];
+ if (!report)
return NULL;
- list = list->next;
+
+ list = report->list.next;
if (list == &report_enum->report_list)
return NULL;
- rinfo->report_id = ((struct hid_report *) list)->id;
+
+ report = list_entry(list, struct hid_report, list);
+ rinfo->report_id = report->id;
break;
default:
@@ -125,12 +132,13 @@ hiddev_lookup_usage(struct hid_device *h
struct hid_field *field;
if (uref->report_type < HID_REPORT_TYPE_MIN ||
- uref->report_type > HID_REPORT_TYPE_MAX) return NULL;
+ uref->report_type > HID_REPORT_TYPE_MAX)
+ return NULL;
report_enum = hid->report_enum +
(uref->report_type - HID_REPORT_TYPE_MIN);
- list_for_each_entry(report, &report_enum->report_list, list)
+ list_for_each_entry(report, &report_enum->report_list, list) {
for (i = 0; i < report->maxfield; i++) {
field = report->field[i];
for (j = 0; j < field->maxusage; j++) {
@@ -142,6 +150,7 @@ hiddev_lookup_usage(struct hid_device *h
}
}
}
+ }
return NULL;
}
@@ -150,9 +159,9 @@ static void hiddev_send_event(struct hid
struct hiddev_usage_ref *uref)
{
struct hiddev *hiddev = hid->hiddev;
- struct hiddev_list *list = hiddev->list;
+ struct hiddev_list *list;
- while (list) {
+ list_for_each_entry(list, &hiddev->list, node) {
if (uref->field_index != HID_FIELD_INDEX_NONE ||
(list->flags & HIDDEV_FLAG_REPORT) != 0) {
list->buffer[list->head] = *uref;
@@ -160,8 +169,6 @@ static void hiddev_send_event(struct hid
(HIDDEV_BUFFER_SIZE - 1);
kill_fasync(&list->fasync, SIGIO, POLL_IN);
}
-
- list = list->next;
}
wake_up_interruptible(&hiddev->wait);
@@ -180,7 +187,7 @@ void hiddev_hid_event(struct hid_device
uref.report_type =
(type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
- ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
+ ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
uref.report_id = field->report->id;
uref.field_index = field->index;
uref.usage_index = (usage - field->usage);
@@ -200,7 +207,7 @@ void hiddev_report_event(struct hid_devi
uref.report_type =
(type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
- ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
+ ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
uref.report_id = report->id;
uref.field_index = HID_FIELD_INDEX_NONE;
@@ -213,7 +220,9 @@ static int hiddev_fasync(int fd, struct
{
int retval;
struct hiddev_list *list = file->private_data;
+
retval = fasync_helper(fd, file, on, &list->fasync);
+
return retval < 0 ? retval : 0;
}
@@ -224,14 +233,9 @@ static int hiddev_fasync(int fd, struct
static int hiddev_release(struct inode * inode, struct file * file)
{
struct hiddev_list *list = file->private_data;
- struct hiddev_list **listptr;
- listptr = &list->hiddev->list;
hiddev_fasync(-1, file, 0);
-
- while (*listptr && (*listptr != list))
- listptr = &((*listptr)->next);
- *listptr = (*listptr)->next;
+ list_del(&list->node);
if (!--list->hiddev->open) {
if (list->hiddev->exist)
@@ -248,7 +252,8 @@ static int hiddev_release(struct inode *
/*
* open file op
*/
-static int hiddev_open(struct inode * inode, struct file * file) {
+static int hiddev_open(struct inode *inode, struct file *file)
+{
struct hiddev_list *list;
int i = iminor(inode) - HIDDEV_MINOR_BASE;
@@ -260,9 +265,7 @@ static int hiddev_open(struct inode * in
return -ENOMEM;
list->hiddev = hiddev_table[i];
- list->next = hiddev_table[i]->list;
- hiddev_table[i]->list = list;
-
+ list_add_tail(&list->node, &hiddev_table[i]->list);
file->private_data = list;
if (!list->hiddev->open++)
@@ -362,6 +365,7 @@ static ssize_t hiddev_read(struct file *
static unsigned int hiddev_poll(struct file *file, poll_table *wait)
{
struct hiddev_list *list = file->private_data;
+
poll_wait(file, &list->hiddev->wait, wait);
if (list->head != list->tail)
return POLLIN | POLLRDNORM;
@@ -382,7 +386,7 @@ static int hiddev_ioctl(struct inode *in
struct hiddev_collection_info cinfo;
struct hiddev_report_info rinfo;
struct hiddev_field_info finfo;
- struct hiddev_usage_ref_multi *uref_multi=NULL;
+ struct hiddev_usage_ref_multi *uref_multi = NULL;
struct hiddev_usage_ref *uref;
struct hiddev_devinfo dinfo;
struct hid_report *report;
@@ -764,15 +768,15 @@ int hiddev_connect(struct hid_device *hi
}
init_waitqueue_head(&hiddev->wait);
-
- hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
-
+ INIT_LIST_HEAD(&hiddev->list);
hiddev->hid = hid;
hiddev->exist = 1;
hid->minor = hid->intf->minor;
hid->hiddev = hiddev;
+ hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
+
return 0;
}
Index: linux-2.6.17/drivers/usb/misc/cypress_cy7c63.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/misc/cypress_cy7c63.c 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/misc/cypress_cy7c63.c 2006-09-14 17:27:15.000000000 +0100
@@ -12,8 +12,13 @@
* the single I/O ports of the device.
*
* Supported vendors: AK Modul-Bus Computer GmbH
-* Supported devices: CY7C63001A-PC (to be continued...)
-* Supported functions: Read/Write Ports (to be continued...)
+* (Firmware "Port-Chip")
+*
+* Supported devices: CY7C63001A-PC
+* CY7C63001C-PXC
+* CY7C63001C-SXC
+*
+* Supported functions: Read/Write Ports
*
*
* This program is free software; you can redistribute it and/or
Index: linux-2.6.17/drivers/usb/net/rtl8150.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/net/rtl8150.c 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/net/rtl8150.c 2006-09-14 17:27:15.000000000 +0100
@@ -175,6 +175,8 @@ static inline struct sk_buff *pull_skb(r
static void rtl8150_disconnect(struct usb_interface *intf);
static int rtl8150_probe(struct usb_interface *intf,
const struct usb_device_id *id);
+static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message);
+static int rtl8150_resume(struct usb_interface *intf);
static const char driver_name [] = "rtl8150";
@@ -183,6 +185,8 @@ static struct usb_driver rtl8150_driver
.probe = rtl8150_probe,
.disconnect = rtl8150_disconnect,
.id_table = rtl8150_table,
+ .suspend = rtl8150_suspend,
+ .resume = rtl8150_resume
};
/*
@@ -238,9 +242,11 @@ static int async_set_registers(rtl8150_t
usb_fill_control_urb(dev->ctrl_urb, dev->udev,
usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
&dev->rx_creg, size, ctrl_callback, dev);
- if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC)))
+ if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) {
+ if (ret == -ENODEV)
+ netif_device_detach(dev->netdev);
err("control request submission failed: %d", ret);
- else
+ } else
set_bit(RX_REG_SET, &dev->flags);
return ret;
@@ -416,6 +422,7 @@ static void read_bulk_callback(struct ur
struct sk_buff *skb;
struct net_device *netdev;
u16 rx_stat;
+ int status;
dev = urb->context;
if (!dev)
@@ -465,7 +472,10 @@ static void read_bulk_callback(struct ur
goon:
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
- if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) {
+ status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
+ if (status == -ENODEV)
+ netif_device_detach(dev->netdev);
+ else if (status) {
set_bit(RX_URB_FAIL, &dev->flags);
goto resched;
} else {
@@ -481,6 +491,7 @@ static void rx_fixup(unsigned long data)
{
rtl8150_t *dev;
struct sk_buff *skb;
+ int status;
dev = (rtl8150_t *)data;
@@ -499,10 +510,13 @@ static void rx_fixup(unsigned long data)
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
try_again:
- if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) {
+ status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
+ if (status == -ENODEV) {
+ netif_device_detach(dev->netdev);
+ } else if (status) {
set_bit(RX_URB_FAIL, &dev->flags);
goto tlsched;
- } else {
+ } else {
clear_bit(RX_URB_FAIL, &dev->flags);
}
@@ -574,12 +588,43 @@ static void intr_callback(struct urb *ur
resubmit:
status = usb_submit_urb (urb, SLAB_ATOMIC);
- if (status)
+ if (status == -ENODEV)
+ netif_device_detach(dev->netdev);
+ else if (status)
err ("can't resubmit intr, %s-%s/input0, status %d",
dev->udev->bus->bus_name,
dev->udev->devpath, status);
}
+static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ rtl8150_t *dev = usb_get_intfdata(intf);
+
+ netif_device_detach(dev->netdev);
+
+ if (netif_running(dev->netdev)) {
+ usb_kill_urb(dev->rx_urb);
+ usb_kill_urb(dev->intr_urb);
+ }
+ return 0;
+}
+
+static int rtl8150_resume(struct usb_interface *intf)
+{
+ rtl8150_t *dev = usb_get_intfdata(intf);
+
+ netif_device_attach(dev->netdev);
+ if (netif_running(dev->netdev)) {
+ dev->rx_urb->status = 0;
+ dev->rx_urb->actual_length = 0;
+ read_bulk_callback(dev->rx_urb, NULL);
+
+ dev->intr_urb->status = 0;
+ dev->intr_urb->actual_length = 0;
+ intr_callback(dev->intr_urb, NULL);
+ }
+ return 0;
+}
/*
**
@@ -690,9 +735,14 @@ static int rtl8150_start_xmit(struct sk_
usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
skb->data, count, write_bulk_callback, dev);
if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) {
- warn("failed tx_urb %d\n", res);
- dev->stats.tx_errors++;
- netif_start_queue(netdev);
+ /* Can we get/handle EPIPE here? */
+ if (res == -ENODEV)
+ netif_device_detach(dev->netdev);
+ else {
+ warn("failed tx_urb %d\n", res);
+ dev->stats.tx_errors++;
+ netif_start_queue(netdev);
+ }
} else {
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
@@ -729,16 +779,25 @@ static int rtl8150_open(struct net_devic
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
- if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL)))
+ if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
+ if (res == -ENODEV)
+ netif_device_detach(dev->netdev);
warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
+ return res;
+ }
usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
dev->intr_buff, INTBUFSIZE, intr_callback,
dev, dev->intr_interval);
- if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL)))
+ if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) {
+ if (res == -ENODEV)
+ netif_device_detach(dev->netdev);
warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
- netif_start_queue(netdev);
+ usb_kill_urb(dev->rx_urb);
+ return res;
+ }
enable_net_traffic(dev);
set_carrier(netdev);
+ netif_start_queue(netdev);
return res;
}
Index: linux-2.6.17/drivers/usb/serial/Kconfig
===================================================================
--- linux-2.6.17.orig/drivers/usb/serial/Kconfig 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/serial/Kconfig 2006-09-14 17:27:15.000000000 +0100
@@ -62,15 +62,6 @@ config USB_SERIAL_AIRPRIME
To compile this driver as a module, choose M here: the
module will be called airprime.
-config USB_SERIAL_ANYDATA
- tristate "USB AnyData CDMA Wireless Driver"
- depends on USB_SERIAL
- help
- Say Y here if you want to use a AnyData CDMA device.
-
- To compile this driver as a module, choose M here: the
- module will be called anydata.
-
config USB_SERIAL_ARK3116
tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)"
depends on USB_SERIAL && EXPERIMENTAL
@@ -502,15 +493,18 @@ config USB_SERIAL_XIRCOM
module will be called keyspan_pda.
config USB_SERIAL_OPTION
- tristate "USB driver for GSM modems"
+ tristate "USB driver for GSM and CDMA modems"
depends on USB_SERIAL
help
- Say Y here if you have an "Option" GSM PCMCIA card
- (or an OEM version: branded Huawei, Audiovox, or Novatel).
+ Say Y here if you have a GSM or CDMA modem that's connected to USB.
+
+ This driver also supports several PCMCIA cards which have a
+ built-in OHCI-USB adapter and an internally-connected GSM modem.
+ The USB bus on these cards is not accessible externally.
- These cards feature a built-in OHCI-USB adapter and an
- internally-connected GSM modem. The USB bus is not
- accessible externally.
+ Supported devices include (some of?) those made by:
+ Option, Huawei, Audiovox, Sierra Wireless, Novatel Wireless, or
+ Anydata.
To compile this driver as a module, choose M here: the
module will be called option.
Index: linux-2.6.17/drivers/usb/serial/Makefile
===================================================================
--- linux-2.6.17.orig/drivers/usb/serial/Makefile 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/serial/Makefile 2006-09-14 17:27:15.000000000 +0100
@@ -12,7 +12,6 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ez
usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y)
obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o
-obj-$(CONFIG_USB_SERIAL_ANYDATA) += anydata.o
obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o
obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o
obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o
Index: linux-2.6.17/drivers/usb/serial/anydata.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/serial/anydata.c 2006-09-14 17:21:45.000000000 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,123 +0,0 @@
-/*
- * AnyData CDMA Serial USB driver
- *
- * Copyright (C) 2005 Greg Kroah-Hartman
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-static struct usb_device_id id_table [] = {
- { USB_DEVICE(0x16d5, 0x6501) }, /* AirData CDMA device */
- { },
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-/* if overridden by the user, then use their value for the size of the
- * read and write urbs */
-static int buffer_size;
-static int debug;
-
-static struct usb_driver anydata_driver = {
- .name = "anydata",
- .probe = usb_serial_probe,
- .disconnect = usb_serial_disconnect,
- .id_table = id_table,
- .no_dynamic_id = 1,
-};
-
-static int anydata_open(struct usb_serial_port *port, struct file *filp)
-{
- char *buffer;
- int result = 0;
-
- dbg("%s - port %d", __FUNCTION__, port->number);
-
- if (buffer_size) {
- /* override the default buffer sizes */
- buffer = kmalloc(buffer_size, GFP_KERNEL);
- if (!buffer) {
- dev_err(&port->dev, "%s - out of memory.\n",
- __FUNCTION__);
- return -ENOMEM;
- }
- kfree (port->read_urb->transfer_buffer);
- port->read_urb->transfer_buffer = buffer;
- port->read_urb->transfer_buffer_length = buffer_size;
-
- buffer = kmalloc(buffer_size, GFP_KERNEL);
- if (!buffer) {
- dev_err(&port->dev, "%s - out of memory.\n",
- __FUNCTION__);
- return -ENOMEM;
- }
- kfree (port->write_urb->transfer_buffer);
- port->write_urb->transfer_buffer = buffer;
- port->write_urb->transfer_buffer_length = buffer_size;
- port->bulk_out_size = buffer_size;
- }
-
- /* Start reading from the device */
- usb_fill_bulk_urb(port->read_urb, port->serial->dev,
- usb_rcvbulkpipe(port->serial->dev,
- port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer,
- port->read_urb->transfer_buffer_length,
- usb_serial_generic_read_bulk_callback, port);
- result = usb_submit_urb(port->read_urb, GFP_KERNEL);
- if (result)
- dev_err(&port->dev,
- "%s - failed submitting read urb, error %d\n",
- __FUNCTION__, result);
-
- return result;
-}
-
-static struct usb_serial_driver anydata_device = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "anydata",
- },
- .id_table = id_table,
- .num_interrupt_in = NUM_DONT_CARE,
- .num_bulk_in = NUM_DONT_CARE,
- .num_bulk_out = NUM_DONT_CARE,
- .num_ports = 1,
- .open = anydata_open,
-};
-
-static int __init anydata_init(void)
-{
- int retval;
-
- retval = usb_serial_register(&anydata_device);
- if (retval)
- return retval;
- retval = usb_register(&anydata_driver);
- if (retval)
- usb_serial_deregister(&anydata_device);
- return retval;
-}
-
-static void __exit anydata_exit(void)
-{
- usb_deregister(&anydata_driver);
- usb_serial_deregister(&anydata_device);
-}
-
-module_init(anydata_init);
-module_exit(anydata_exit);
-MODULE_LICENSE("GPL");
-
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
-module_param(buffer_size, int, 0);
-MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers");
Index: linux-2.6.17/drivers/usb/serial/ftdi_sio.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/serial/ftdi_sio.c 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/serial/ftdi_sio.c 2006-09-14 17:27:15.000000000 +0100
@@ -337,6 +337,7 @@ static struct usb_device_id id_table_com
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) },
Index: linux-2.6.17/drivers/usb/serial/ftdi_sio.h
===================================================================
--- linux-2.6.17.orig/drivers/usb/serial/ftdi_sio.h 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/serial/ftdi_sio.h 2006-09-14 17:27:15.000000000 +0100
@@ -182,6 +182,10 @@
/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */
+/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */
+
+#define FTDI_TNC_X_PID 0xEBE0
+
/*
* ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
* All of these devices use FTDI's vendor ID (0x0403).
Index: linux-2.6.17/drivers/usb/serial/ipaq.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/serial/ipaq.c 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/serial/ipaq.c 2006-09-14 17:27:15.000000000 +0100
@@ -250,6 +250,7 @@ static struct usb_device_id ipaq_id_tabl
{ USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
{ USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
{ USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
+ { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */
{ USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */
{ USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */
{ USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
Index: linux-2.6.17/drivers/usb/serial/option.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/serial/option.c 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/serial/option.c 2006-09-14 17:27:15.000000000 +0100
@@ -9,40 +9,14 @@
Portions copied from the Keyspan driver by Hugh Blemings
- History:
-
- 2005-05-19 v0.1 Initial version, based on incomplete docs
- and analysis of misbehavior with the standard driver
- 2005-05-20 v0.2 Extended the input buffer to avoid losing
- random 64-byte chunks of data
- 2005-05-21 v0.3 implemented chars_in_buffer()
- turned on low_latency
- simplified the code somewhat
- 2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load
- removed some dead code
- added sponsor notice
- coding style clean-up
- 2005-06-20 v0.4.1 add missing braces :-/
- killed end-of-line whitespace
- 2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2
- 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard
- 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes
- wants to send >2000 bytes.
- 2006-04-10 v0.5 fixed two array overrun errors :-/
- 2006-04-21 v0.5.1 added support for Sierra Wireless MC8755
- 2006-05-15 v0.6 re-enable multi-port support
- 2006-06-01 v0.6.1 add COBRA
- 2006-06-01 v0.6.2 add backwards-compatibility stuff
- 2006-06-01 v0.6.3 add Novatel Wireless
- 2006-06-01 v0.7 Option => GSM
- 2006-06-01 v0.7.1 add COBRA2
+ History: see the git log.
Work sponsored by: Sigos GmbH, Germany
This driver exists because the "normal" serial driver doesn't work too well
with GSM modems. Issues:
- data loss -- one single Receive URB is not nearly enough
- - nonstandard flow (Option devices) and multiplex (Sierra) control
+ - nonstandard flow (Option devices) control
- controlling the baud rate doesn't make sense
This driver is named "option" because the most common device it's
@@ -96,8 +70,8 @@ static int option_send_setup(struct usb
#define OPTION_VENDOR_ID 0x0AF0
#define HUAWEI_VENDOR_ID 0x12D1
#define AUDIOVOX_VENDOR_ID 0x0F3D
-#define SIERRAWIRELESS_VENDOR_ID 0x1199
#define NOVATELWIRELESS_VENDOR_ID 0x1410
+#define ANYDATA_VENDOR_ID 0x16d5
#define OPTION_PRODUCT_OLD 0x5000
#define OPTION_PRODUCT_FUSION 0x6000
@@ -106,8 +80,8 @@ static int option_send_setup(struct usb
#define OPTION_PRODUCT_COBRA2 0x6600
#define HUAWEI_PRODUCT_E600 0x1001
#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
-#define SIERRAWIRELESS_PRODUCT_MC8755 0x6802
#define NOVATELWIRELESS_PRODUCT_U740 0x1400
+#define ANYDATA_PRODUCT_ID 0x6501
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
@@ -117,8 +91,8 @@ static struct usb_device_id option_ids[]
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
- { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
+ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */
};
@@ -131,10 +105,7 @@ static struct usb_device_id option_ids1[
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
- { } /* Terminating entry */
-};
-static struct usb_device_id option_ids3[] = {
- { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
+ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */
};
@@ -151,37 +122,11 @@ static struct usb_driver option_driver =
/* The card has three separate interfaces, which the serial driver
* recognizes separately, thus num_port=1.
*/
-static struct usb_serial_driver option_3port_device = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "option",
- },
- .description = "GSM modem (3-port)",
- .id_table = option_ids3,
- .num_interrupt_in = NUM_DONT_CARE,
- .num_bulk_in = NUM_DONT_CARE,
- .num_bulk_out = NUM_DONT_CARE,
- .num_ports = 3,
- .open = option_open,
- .close = option_close,
- .write = option_write,
- .write_room = option_write_room,
- .chars_in_buffer = option_chars_in_buffer,
- .throttle = option_rx_throttle,
- .unthrottle = option_rx_unthrottle,
- .set_termios = option_set_termios,
- .break_ctl = option_break_ctl,
- .tiocmget = option_tiocmget,
- .tiocmset = option_tiocmset,
- .attach = option_startup,
- .shutdown = option_shutdown,
- .read_int_callback = option_instat_callback,
-};
static struct usb_serial_driver option_1port_device = {
.driver = {
.owner = THIS_MODULE,
- .name = "option",
+ .name = "option1",
},
.description = "GSM modem (1-port)",
.id_table = option_ids1,
@@ -245,9 +190,6 @@ static int __init option_init(void)
retval = usb_serial_register(&option_1port_device);
if (retval)
goto failed_1port_device_register;
- retval = usb_serial_register(&option_3port_device);
- if (retval)
- goto failed_3port_device_register;
retval = usb_register(&option_driver);
if (retval)
goto failed_driver_register;
@@ -257,8 +199,6 @@ static int __init option_init(void)
return 0;
failed_driver_register:
- usb_serial_deregister (&option_3port_device);
-failed_3port_device_register:
usb_serial_deregister (&option_1port_device);
failed_1port_device_register:
return retval;
@@ -267,7 +207,6 @@ failed_1port_device_register:
static void __exit option_exit(void)
{
usb_deregister (&option_driver);
- usb_serial_deregister (&option_3port_device);
usb_serial_deregister (&option_1port_device);
}
@@ -656,7 +595,6 @@ static void option_setup_urbs(struct usb
dbg("%s", __FUNCTION__);
-
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
portdata = usb_get_serial_port_data(port);
Index: linux-2.6.17/drivers/usb/serial/pl2303.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/serial/pl2303.c 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/serial/pl2303.c 2006-09-14 17:27:15.000000000 +0100
@@ -81,6 +81,7 @@ static struct usb_device_id id_table []
{ USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },
{ USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) },
{ USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
+ { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
{ } /* Terminating entry */
};
Index: linux-2.6.17/drivers/usb/serial/pl2303.h
===================================================================
--- linux-2.6.17.orig/drivers/usb/serial/pl2303.h 2006-09-14 17:21:45.000000000 +0100
+++ linux-2.6.17/drivers/usb/serial/pl2303.h 2006-09-14 17:27:15.000000000 +0100
@@ -89,3 +89,7 @@
/* DATAPILOT Universal-2 Phone Cable */
#define DATAPILOT_U2_VENDOR_ID 0x0731
#define DATAPILOT_U2_PRODUCT_ID 0x2003
+
+/* Belkin "F5U257" Serial Adapter */
+#define BELKIN_VENDOR_ID 0x050d
+#define BELKIN_PRODUCT_ID 0x0257
Index: linux-2.6.17/drivers/usb/storage/unusual_devs.h
===================================================================
--- linux-2.6.17.orig/drivers/usb/storage/unusual_devs.h 2006-09-14 17:21:46.000000000 +0100
+++ linux-2.6.17/drivers/usb/storage/unusual_devs.h 2006-09-14 17:27:15.000000000 +0100
@@ -145,6 +145,13 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
+/* Reported by Mario Rettig */
+UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100,
+ "Nokia",
+ "Nokia 3250",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
+
/* Reported by Sumedha Swamy and
* Einar Th. Einarsson */
UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100,
@@ -627,18 +634,6 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x
"Digital Camera EX-20 DSC",
US_SC_8070, US_PR_DEVICE, NULL, 0 ),
-/* The entry was here before I took over, and had US_SC_RBC. It turns
- * out that isn't needed. Additionally, Torsten Eriksson
- * is able to use his device fine
- * without this entry at all - but I don't suspect that will be true
- * for all users (the protocol is likely needed), so is staying at
- * this time. - Phil Dibowitz
- */
-UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200,
- "LaCie",
- "USB Hard Disk",
- US_SC_DEVICE, US_PR_CB, NULL, 0 ),
-
/* Submitted by Joel Bourquard
* Some versions of this device need the SubClass and Protocol overrides
* while others don't.
@@ -1106,7 +1101,15 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xff
"Optio S/S4",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
-
+
+/* This is a virtual windows driver CD, which the zd1211rw driver automatically
+ * converts into a WLAN device. */
+UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
+ "ZyXEL",
+ "G-220F USB-WLAN Install",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_DEVICE ),
+
#ifdef CONFIG_USB_STORAGE_ISD200
UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
"ATI",
Index: linux-2.6.17/drivers/usb/storage/usb.c
===================================================================
--- linux-2.6.17.orig/drivers/usb/storage/usb.c 2006-09-14 17:21:46.000000000 +0100
+++ linux-2.6.17/drivers/usb/storage/usb.c 2006-09-14 17:27:15.000000000 +0100
@@ -483,7 +483,7 @@ static struct us_unusual_dev *find_unusu
}
/* Get the unusual_devs entries and the string descriptors */
-static void get_device_info(struct us_data *us, const struct usb_device_id *id)
+static int get_device_info(struct us_data *us, const struct usb_device_id *id)
{
struct usb_device *dev = us->pusb_dev;
struct usb_interface_descriptor *idesc =
@@ -500,6 +500,11 @@ static void get_device_info(struct us_da
unusual_dev->useTransport;
us->flags = USB_US_ORIG_FLAGS(id->driver_info);
+ if (us->flags & US_FL_IGNORE_DEVICE) {
+ printk(KERN_INFO USB_STORAGE "device ignored\n");
+ return -ENODEV;
+ }
+
/*
* This flag is only needed when we're in high-speed, so let's
* disable it if we're in full-speed
@@ -541,6 +546,8 @@ static void get_device_info(struct us_da
msgs[msg],
UTS_RELEASE);
}
+
+ return 0;
}
/* Get the transport settings */
@@ -969,7 +976,9 @@ static int storage_probe(struct usb_inte
* of the match from the usb_device_id table, so we can find the
* corresponding entry in the private table.
*/
- get_device_info(us, id);
+ result = get_device_info(us, id);
+ if (result)
+ goto BadDevice;
/* Get the transport, protocol, and pipe settings */
result = get_transport(us);
Index: linux-2.6.17/drivers/video/Kconfig
===================================================================
--- linux-2.6.17.orig/drivers/video/Kconfig 2006-09-14 17:21:46.000000000 +0100
+++ linux-2.6.17/drivers/video/Kconfig 2006-09-14 17:27:15.000000000 +0100
@@ -86,9 +86,11 @@ config FB_MACMODES
default n
config FB_BACKLIGHT
- bool
- depends on FB
- default n
+ bool
+ depends on FB
+ select BACKLIGHT_LCD_SUPPORT
+ select BACKLIGHT_CLASS_DEVICE
+ default n
config FB_MODE_HELPERS
bool "Enable Video Mode Handling Helpers"
@@ -420,7 +422,7 @@ config FB_OF
config FB_CONTROL
bool "Apple \"control\" display support"
- depends on (FB = y) && PPC_PMAC
+ depends on (FB = y) && PPC_PMAC && PPC32
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -431,7 +433,7 @@ config FB_CONTROL
config FB_PLATINUM
bool "Apple \"platinum\" display support"
- depends on (FB = y) && PPC_PMAC
+ depends on (FB = y) && PPC_PMAC && PPC32
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -442,7 +444,7 @@ config FB_PLATINUM
config FB_VALKYRIE
bool "Apple \"valkyrie\" display support"
- depends on (FB = y) && (MAC || PPC_PMAC)
+ depends on (FB = y) && (MAC || (PPC_PMAC && PPC32))
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -453,7 +455,7 @@ config FB_VALKYRIE
config FB_CT65550
bool "Chips 65550 display support"
- depends on (FB = y) && PPC
+ depends on (FB = y) && PPC32
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -721,10 +723,8 @@ config FB_NVIDIA_I2C
config FB_NVIDIA_BACKLIGHT
bool "Support for backlight control"
- depends on FB_NVIDIA && PPC_PMAC
+ depends on FB_NVIDIA && PMAC_BACKLIGHT
select FB_BACKLIGHT
- select BACKLIGHT_LCD_SUPPORT
- select BACKLIGHT_CLASS_DEVICE
default y
help
Say Y here if you want to control the backlight of your display.
@@ -769,10 +769,8 @@ config FB_RIVA_DEBUG
config FB_RIVA_BACKLIGHT
bool "Support for backlight control"
- depends on FB_RIVA && PPC_PMAC
+ depends on FB_RIVA && PMAC_BACKLIGHT
select FB_BACKLIGHT
- select BACKLIGHT_LCD_SUPPORT
- select BACKLIGHT_CLASS_DEVICE
default y
help
Say Y here if you want to control the backlight of your display.
@@ -1025,10 +1023,8 @@ config FB_RADEON_I2C
config FB_RADEON_BACKLIGHT
bool "Support for backlight control"
- depends on FB_RADEON && PPC_PMAC
+ depends on FB_RADEON && PMAC_BACKLIGHT
select FB_BACKLIGHT
- select BACKLIGHT_LCD_SUPPORT
- select BACKLIGHT_CLASS_DEVICE
default y
help
Say Y here if you want to control the backlight of your display.
@@ -1059,10 +1055,8 @@ config FB_ATY128
config FB_ATY128_BACKLIGHT
bool "Support for backlight control"
- depends on FB_ATY128 && PPC_PMAC
+ depends on FB_ATY128 && PMAC_BACKLIGHT
select FB_BACKLIGHT
- select BACKLIGHT_LCD_SUPPORT
- select BACKLIGHT_CLASS_DEVICE
default y
help
Say Y here if you want to control the backlight of your display.
@@ -1111,10 +1105,8 @@ config FB_ATY_GX
config FB_ATY_BACKLIGHT
bool "Support for backlight control"
- depends on FB_ATY && PPC_PMAC
+ depends on FB_ATY && PMAC_BACKLIGHT
select FB_BACKLIGHT
- select BACKLIGHT_LCD_SUPPORT
- select BACKLIGHT_CLASS_DEVICE
default y
help
Say Y here if you want to control the backlight of your display.
@@ -1620,7 +1612,7 @@ if FB || SGI_NEWPORT_CONSOLE
source "drivers/video/logo/Kconfig"
endif
-if FB && SYSFS
+if SYSFS
source "drivers/video/backlight/Kconfig"
endif
Index: linux-2.6.17/drivers/video/Makefile
===================================================================
--- linux-2.6.17.orig/drivers/video/Makefile 2006-09-14 17:21:46.000000000 +0100
+++ linux-2.6.17/drivers/video/Makefile 2006-09-14 17:27:15.000000000 +0100
@@ -4,6 +4,7 @@
# Each configuration option enables a list of files.
+obj-y += fb_notify.o
obj-$(CONFIG_FB) += fb.o
fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
modedb.o fbcvt.o
Index: linux-2.6.17/drivers/video/aty/aty128fb.c
===================================================================
--- linux-2.6.17.orig/drivers/video/aty/aty128fb.c 2006-09-14 17:21:46.000000000 +0100
+++ linux-2.6.17/drivers/video/aty/aty128fb.c 2006-09-14 17:27:15.000000000 +0100
@@ -455,7 +455,10 @@ static void do_wait_for_fifo(u16 entries
static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
static void wait_for_idle(struct aty128fb_par *par);
static u32 depth_to_dst(u32 depth);
+
+#ifdef CONFIG_FB_ATY128_BACKLIGHT
static void aty128_bl_set_power(struct fb_info *info, int power);
+#endif
#define BIOS_IN8(v) (readb(bios + (v)))
#define BIOS_IN16(v) (readb(bios + (v)) | \
@@ -1910,9 +1913,6 @@ static int __devinit aty128_init(struct
u8 chip_rev;
u32 dac;
- if (!par->vram_size) /* may have already been probed */
- par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
-
/* Get the chip revision */
chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
@@ -2025,9 +2025,6 @@ static int __devinit aty128_init(struct
aty128_init_engine(par);
- if (register_framebuffer(info) < 0)
- return 0;
-
par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
par->pdev = pdev;
par->asleep = 0;
@@ -2037,6 +2034,9 @@ static int __devinit aty128_init(struct
aty128_bl_init(par);
#endif
+ if (register_framebuffer(info) < 0)
+ return 0;
+
printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
info->node, info->fix.id, video_card);
@@ -2086,7 +2086,6 @@ static int __devinit aty128_probe(struct
par = info->par;
info->pseudo_palette = par->pseudo_palette;
- info->fix = aty128fb_fix;
/* Virtualize mmio region */
info->fix.mmio_start = reg_addr;
Index: linux-2.6.17/drivers/video/aty/atyfb_base.c
===================================================================
--- linux-2.6.17.orig/drivers/video/aty/atyfb_base.c 2006-09-14 17:21:46.000000000 +0100
+++ linux-2.6.17/drivers/video/aty/atyfb_base.c 2006-09-14 17:27:15.000000000 +0100
@@ -2812,7 +2812,7 @@ static int atyfb_blank(int blank, struct
if (par->lock_blank || par->asleep)
return 0;
-#ifdef CONFIG_PMAC_BACKLIGHT
+#ifdef CONFIG_FB_ATY_BACKLIGHT
if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
aty_bl_set_power(info, FB_BLANK_POWERDOWN);
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
@@ -2844,7 +2844,7 @@ static int atyfb_blank(int blank, struct
}
aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
-#ifdef CONFIG_PMAC_BACKLIGHT
+#ifdef CONFIG_FB_ATY_BACKLIGHT
if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
aty_bl_set_power(info, FB_BLANK_UNBLANK);
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
Index: linux-2.6.17/drivers/video/aty/radeon_base.c
===================================================================
--- linux-2.6.17.orig/drivers/video/aty/radeon_base.c 2006-09-14 17:21:46.000000000 +0100
+++ linux-2.6.17/drivers/video/aty/radeon_base.c 2006-09-14 17:27:15.000000000 +0100
@@ -266,6 +266,8 @@ static int force_measure_pll = 0;
#ifdef CONFIG_MTRR
static int nomtrr = 0;
#endif
+static int force_sleep;
+static int ignore_devlist;
/*
* prototypes
@@ -2327,9 +2329,9 @@ static int __devinit radeonfb_pci_regist
/* -2 is special: means ON on mobility chips and do not
* change on others
*/
- radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1);
+ radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1, ignore_devlist, force_sleep);
} else
- radeonfb_pm_init(rinfo, default_dynclk);
+ radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep);
pci_set_drvdata(pdev, info);
@@ -2477,6 +2479,12 @@ static int __init radeonfb_setup (char *
force_measure_pll = 1;
} else if (!strncmp(this_opt, "ignore_edid", 11)) {
ignore_edid = 1;
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+ } else if (!strncmp(this_opt, "force_sleep", 11)) {
+ force_sleep = 1;
+ } else if (!strncmp(this_opt, "ignore_devlist", 14)) {
+ ignore_devlist = 1;
+#endif
} else
mode_option = this_opt;
}
@@ -2532,3 +2540,9 @@ module_param(panel_yres, int, 0);
MODULE_PARM_DESC(panel_yres, "int: set panel yres");
module_param(mode_option, charp, 0);
MODULE_PARM_DESC(mode_option, "Specify resolution as \"x[-][@]\" ");
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+module_param(force_sleep, bool, 0);
+MODULE_PARM_DESC(force_sleep, "bool: force D2 sleep mode on all hardware");
+module_param(ignore_devlist, bool, 0);
+MODULE_PARM_DESC(ignore_devlist, "bool: ignore workarounds for bugs in specific laptops");
+#endif
Index: linux-2.6.17/drivers/video/aty/radeon_pm.c
===================================================================
--- linux-2.6.17.orig/drivers/video/aty/radeon_pm.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/drivers/video/aty/radeon_pm.c 2006-09-14 17:27:15.000000000 +0100
@@ -27,6 +27,99 @@
#include "ati_ids.h"
+static void radeon_reinitialize_M10(struct radeonfb_info *rinfo);
+
+/*
+ * Workarounds for bugs in PC laptops:
+ * - enable D2 sleep in some IBM Thinkpads
+ * - special case for Samsung P35
+ *
+ * Whitelist by subsystem vendor/device because
+ * its the subsystem vendor's fault!
+ */
+
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+struct radeon_device_id {
+ const char *ident; /* (arbitrary) Name */
+ const unsigned short subsystem_vendor; /* Subsystem Vendor ID */
+ const unsigned short subsystem_device; /* Subsystem Device ID */
+ const enum radeon_pm_mode pm_mode_modifier; /* modify pm_mode */
+ const reinit_function_ptr new_reinit_func; /* changed reinit_func */
+};
+
+#define BUGFIX(model, sv, sd, pm, fn) { \
+ .ident = model, \
+ .subsystem_vendor = sv, \
+ .subsystem_device = sd, \
+ .pm_mode_modifier = pm, \
+ .new_reinit_func = fn \
+}
+
+static struct radeon_device_id radeon_workaround_list[] = {
+ BUGFIX("IBM Thinkpad R32",
+ PCI_VENDOR_ID_IBM, 0x1905,
+ radeon_pm_d2, NULL),
+ BUGFIX("IBM Thinkpad R40",
+ PCI_VENDOR_ID_IBM, 0x0526,
+ radeon_pm_d2, NULL),
+ BUGFIX("IBM Thinkpad R40",
+ PCI_VENDOR_ID_IBM, 0x0527,
+ radeon_pm_d2, NULL),
+ BUGFIX("IBM Thinkpad R50/R51/T40/T41",
+ PCI_VENDOR_ID_IBM, 0x0531,
+ radeon_pm_d2, NULL),
+ BUGFIX("IBM Thinkpad R51/T40/T41/T42",
+ PCI_VENDOR_ID_IBM, 0x0530,
+ radeon_pm_d2, NULL),
+ BUGFIX("IBM Thinkpad T30",
+ PCI_VENDOR_ID_IBM, 0x0517,
+ radeon_pm_d2, NULL),
+ BUGFIX("IBM Thinkpad T40p",
+ PCI_VENDOR_ID_IBM, 0x054d,
+ radeon_pm_d2, NULL),
+ BUGFIX("IBM Thinkpad T42",
+ PCI_VENDOR_ID_IBM, 0x0550,
+ radeon_pm_d2, NULL),
+ BUGFIX("IBM Thinkpad X31/X32",
+ PCI_VENDOR_ID_IBM, 0x052f,
+ radeon_pm_d2, NULL),
+ BUGFIX("Samsung P35",
+ PCI_VENDOR_ID_SAMSUNG, 0xc00c,
+ radeon_pm_off, radeon_reinitialize_M10),
+ { .ident = NULL }
+};
+
+static int radeon_apply_workarounds(struct radeonfb_info *rinfo)
+{
+ struct radeon_device_id *id;
+
+ for (id = radeon_workaround_list; id->ident != NULL; id++ )
+ if ((id->subsystem_vendor == rinfo->pdev->subsystem_vendor ) &&
+ (id->subsystem_device == rinfo->pdev->subsystem_device )) {
+
+ /* we found a device that requires workaround */
+ printk(KERN_DEBUG "radeonfb: %s detected"
+ ", enabling workaround\n", id->ident);
+
+ rinfo->pm_mode |= id->pm_mode_modifier;
+
+ if (id->new_reinit_func != NULL)
+ rinfo->reinit_func = id->new_reinit_func;
+
+ return 1;
+ }
+ return 0; /* not found */
+}
+
+#else /* defined(CONFIG_PM) && defined(CONFIG_X86) */
+static inline int radeon_apply_workarounds(struct radeonfb_info *rinfo)
+{
+ return 0;
+}
+#endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */
+
+
+
static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
{
u32 tmp;
@@ -852,18 +945,26 @@ static void radeon_pm_setup_for_suspend(
/* because both INPLL and OUTPLL take the same lock, that's why. */
tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND;
OUTPLL( pllMCLK_MISC, tmp);
-
- /* AGP PLL control */
- if (rinfo->family <= CHIP_FAMILY_RV280) {
- OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID);
- OUTREG(BUS_CNTL1,
- (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
- | (2<family <= CHIP_FAMILY_RV280) {
+ OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID);
+ OUTREG(BUS_CNTL1,
+ (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
+ | (2<pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM);
@@ -2729,22 +2830,13 @@ void radeonfb_pm_init(struct radeonfb_in
}
#if defined(CONFIG_PM)
+#if defined(CONFIG_PPC_PMAC)
/* Check if we can power manage on suspend/resume. We can do
* D2 on M6, M7 and M9, and we can resume from D3 cold a few other
* "Mac" cards, but that's all. We need more infos about what the
* BIOS does tho. Right now, all this PM stuff is pmac-only for that
* reason. --BenH
*/
- /* Special case for Samsung P35 laptops
- */
- if ((rinfo->pdev->vendor == PCI_VENDOR_ID_ATI) &&
- (rinfo->pdev->device == PCI_CHIP_RV350_NP) &&
- (rinfo->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) &&
- (rinfo->pdev->subsystem_device == 0xc00c)) {
- rinfo->reinit_func = radeon_reinitialize_M10;
- rinfo->pm_mode |= radeon_pm_off;
- }
-#if defined(CONFIG_PPC_PMAC)
if (machine_is(powermac) && rinfo->of_node) {
if (rinfo->is_mobility && rinfo->pm_reg &&
rinfo->family <= CHIP_FAMILY_RV250)
@@ -2790,6 +2882,18 @@ void radeonfb_pm_init(struct radeonfb_in
}
#endif /* defined(CONFIG_PPC_PMAC) */
#endif /* defined(CONFIG_PM) */
+
+ if (ignore_devlist)
+ printk(KERN_DEBUG
+ "radeonfb: skipping test for device workarounds\n");
+ else
+ radeon_apply_workarounds(rinfo);
+
+ if (force_sleep) {
+ printk(KERN_DEBUG
+ "radeonfb: forcefully enabling D2 sleep mode\n");
+ rinfo->pm_mode |= radeon_pm_d2;
+ }
}
void radeonfb_pm_exit(struct radeonfb_info *rinfo)
Index: linux-2.6.17/drivers/video/aty/radeonfb.h
===================================================================
--- linux-2.6.17.orig/drivers/video/aty/radeonfb.h 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/video/aty/radeonfb.h 2006-09-14 17:27:15.000000000 +0100
@@ -273,6 +273,8 @@ enum radeon_pm_mode {
radeon_pm_off = 0x00000002, /* Can resume from D3 cold */
};
+typedef void (*reinit_function_ptr)(struct radeonfb_info *rinfo);
+
struct radeonfb_info {
struct fb_info *info;
@@ -338,7 +340,7 @@ struct radeonfb_info {
int dynclk;
int no_schedule;
enum radeon_pm_mode pm_mode;
- void (*reinit_func)(struct radeonfb_info *rinfo);
+ reinit_function_ptr reinit_func;
/* Lock on register access */
spinlock_t reg_lock;
@@ -600,7 +602,7 @@ extern int radeon_probe_i2c_connector(st
/* PM Functions */
extern int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state);
extern int radeonfb_pci_resume(struct pci_dev *pdev);
-extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk);
+extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep);
extern void radeonfb_pm_exit(struct radeonfb_info *rinfo);
/* Monitor probe functions */
Index: linux-2.6.17/drivers/video/au1100fb.c
===================================================================
--- linux-2.6.17.orig/drivers/video/au1100fb.c 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/video/au1100fb.c 2006-09-14 17:27:15.000000000 +0100
@@ -156,7 +156,7 @@ int au1100fb_setmode(struct au1100fb_dev
info->fix.visual = FB_VISUAL_TRUECOLOR;
info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */
- }
+ }
} else {
/* mono */
info->fix.visual = FB_VISUAL_MONO10;
@@ -164,20 +164,16 @@ int au1100fb_setmode(struct au1100fb_dev
}
info->screen_size = info->fix.line_length * info->var.yres_virtual;
+ info->var.rotate = ((fbdev->panel->control_base&LCD_CONTROL_SM_MASK) \
+ >> LCD_CONTROL_SM_BIT) * 90;
/* Determine BPP mode and format */
- fbdev->regs->lcd_control = fbdev->panel->control_base |
- ((info->var.rotate/90) << LCD_CONTROL_SM_BIT);
-
- fbdev->regs->lcd_intenable = 0;
- fbdev->regs->lcd_intstatus = 0;
-
+ fbdev->regs->lcd_control = fbdev->panel->control_base;
fbdev->regs->lcd_horztiming = fbdev->panel->horztiming;
-
fbdev->regs->lcd_verttiming = fbdev->panel->verttiming;
-
fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base;
-
+ fbdev->regs->lcd_intenable = 0;
+ fbdev->regs->lcd_intstatus = 0;
fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys);
if (panel_is_dual(fbdev->panel)) {
@@ -206,6 +202,8 @@ int au1100fb_setmode(struct au1100fb_dev
/* Resume controller */
fbdev->regs->lcd_control |= LCD_CONTROL_GO;
+ mdelay(10);
+ au1100fb_fb_blank(VESA_NO_BLANKING, info);
return 0;
}
Index: linux-2.6.17/drivers/video/backlight/Kconfig
===================================================================
--- linux-2.6.17.orig/drivers/video/backlight/Kconfig 2006-09-14 16:26:39.000000000 +0100
+++ linux-2.6.17/drivers/video/backlight/Kconfig 2006-09-14 17:27:15.000000000 +0100
@@ -10,7 +10,7 @@ menuconfig BACKLIGHT_LCD_SUPPORT
config BACKLIGHT_CLASS_DEVICE
tristate "Lowlevel Backlight controls"
- depends on BACKLIGHT_LCD_SUPPORT && FB
+ depends on BACKLIGHT_LCD_SUPPORT
default m
help
This framework adds support for low-level control of the LCD
@@ -26,7 +26,7 @@ config BACKLIGHT_DEVICE
config LCD_CLASS_DEVICE
tristate "Lowlevel LCD controls"
- depends on BACKLIGHT_LCD_SUPPORT && FB
+ depends on BACKLIGHT_LCD_SUPPORT
default m
help
This framework adds support for low-level control of LCD.
Index: linux-2.6.17/drivers/video/console/mdacon.c
===================================================================
--- linux-2.6.17.orig/drivers/video/console/mdacon.c 2006-09-14 17:21:46.000000000 +0100
+++ linux-2.6.17/drivers/video/console/mdacon.c 2006-09-14 17:27:15.000000000 +0100
@@ -197,7 +197,7 @@ static int __init mdacon_setup(char *str
__setup("mdacon=", mdacon_setup);
#endif
-static int __init mda_detect(void)
+static int mda_detect(void)
{
int count=0;
u16 *p, p_save;
@@ -282,7 +282,7 @@ static int __init mda_detect(void)
return 1;
}
-static void __init mda_initialize(void)
+static void mda_initialize(void)
{
write_mda_b(97, 0x00); /* horizontal total */
write_mda_b(80, 0x01); /* horizontal displayed */
Index: linux-2.6.17/drivers/video/fb_notify.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.17/drivers/video/fb_notify.c 2006-09-14 17:27:15.000000000 +0100
@@ -0,0 +1,46 @@
+/*
+ * linux/drivers/video/fb_notify.c
+ *
+ * Copyright (C) 2006 Antonino Daplas
+ *
+ * 2001 - Documented with DocBook
+ * - Brad Douglas
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+#include
+#include
+
+static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);
+
+/**
+ * fb_register_client - register a client notifier
+ * @nb: notifier block to callback on events
+ */
+int fb_register_client(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&fb_notifier_list, nb);
+}
+EXPORT_SYMBOL(fb_register_client);
+
+/**
+ * fb_unregister_client - unregister a client notifier
+ * @nb: notifier block to callback on events
+ */
+int fb_unregister_client(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
+}
+EXPORT_SYMBOL(fb_unregister_client);
+
+/**
+ * fb_notifier_call_chain - notify clients of fb_events
+ *
+ */
+int fb_notifier_call_chain(unsigned long val, void *v)
+{
+ return blocking_notifier_call_chain(&fb_notifier_list, val, v);
+}
+EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
Index: linux-2.6.17/drivers/video/fbmem.c
===================================================================
--- linux-2.6.17.orig/drivers/video/fbmem.c 2006-09-14 17:21:46.000000000 +0100
+++ linux-2.6.17/drivers/video/fbmem.c 2006-09-14 17:27:15.000000000 +0100
@@ -52,7 +52,6 @@
#define FBPIXMAPSIZE (1024 * 8)
-static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
@@ -791,8 +790,7 @@ fb_set_var(struct fb_info *info, struct
event.info = info;
event.data = &mode1;
- ret = blocking_notifier_call_chain(&fb_notifier_list,
- FB_EVENT_MODE_DELETE, &event);
+ ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event);
}
if (!ret)
@@ -837,8 +835,7 @@ fb_set_var(struct fb_info *info, struct
info->flags &= ~FBINFO_MISC_USEREVENT;
event.info = info;
- blocking_notifier_call_chain(&fb_notifier_list,
- evnt, &event);
+ fb_notifier_call_chain(evnt, &event);
}
}
}
@@ -861,8 +858,7 @@ fb_blank(struct fb_info *info, int blank
event.info = info;
event.data = ␣
- blocking_notifier_call_chain(&fb_notifier_list,
- FB_EVENT_BLANK, &event);
+ fb_notifier_call_chain(FB_EVENT_BLANK, &event);
}
return ret;
@@ -933,8 +929,7 @@ fb_ioctl(struct inode *inode, struct fil
con2fb.framebuffer = -1;
event.info = info;
event.data = &con2fb;
- blocking_notifier_call_chain(&fb_notifier_list,
- FB_EVENT_GET_CONSOLE_MAP, &event);
+ fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
return copy_to_user(argp, &con2fb,
sizeof(con2fb)) ? -EFAULT : 0;
case FBIOPUT_CON2FBMAP:
@@ -952,9 +947,8 @@ fb_ioctl(struct inode *inode, struct fil
return -EINVAL;
event.info = info;
event.data = &con2fb;
- return blocking_notifier_call_chain(&fb_notifier_list,
- FB_EVENT_SET_CONSOLE_MAP,
- &event);
+ return fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
+ &event);
case FBIOBLANK:
acquire_console_sem();
info->flags |= FBINFO_MISC_USEREVENT;
@@ -1330,8 +1324,7 @@ register_framebuffer(struct fb_info *fb_
registered_fb[i] = fb_info;
event.info = fb_info;
- blocking_notifier_call_chain(&fb_notifier_list,
- FB_EVENT_FB_REGISTERED, &event);
+ fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
return 0;
}
@@ -1365,30 +1358,11 @@ unregister_framebuffer(struct fb_info *f
fb_cleanup_class_device(fb_info);
class_device_destroy(fb_class, MKDEV(FB_MAJOR, i));
event.info = fb_info;
- blocking_notifier_call_chain(&fb_notifier_list,
- FB_EVENT_FB_UNREGISTERED, &event);
+ fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
return 0;
}
/**
- * fb_register_client - register a client notifier
- * @nb: notifier block to callback on events
- */
-int fb_register_client(struct notifier_block *nb)
-{
- return blocking_notifier_chain_register(&fb_notifier_list, nb);
-}
-
-/**
- * fb_unregister_client - unregister a client notifier
- * @nb: notifier block to callback on events
- */
-int fb_unregister_client(struct notifier_block *nb)
-{
- return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
-}
-
-/**
* fb_set_suspend - low level driver signals suspend
* @info: framebuffer affected
* @state: 0 = resuming, !=0 = suspending
@@ -1403,13 +1377,11 @@ void fb_set_suspend(struct fb_info *info
event.info = info;
if (state) {
- blocking_notifier_call_chain(&fb_notifier_list,
- FB_EVENT_SUSPEND, &event);
+ fb_notifier_call_chain(FB_EVENT_SUSPEND, &event);
info->state = FBINFO_STATE_SUSPENDED;
} else {
info->state = FBINFO_STATE_RUNNING;
- blocking_notifier_call_chain(&fb_notifier_list,
- FB_EVENT_RESUME, &event);
+ fb_notifier_call_chain(FB_EVENT_RESUME, &event);
}
}
@@ -1480,9 +1452,7 @@ int fb_new_modelist(struct fb_info *info
if (!list_empty(&info->modelist)) {
event.info = info;
- err = blocking_notifier_call_chain(&fb_notifier_list,
- FB_EVENT_NEW_MODELIST,
- &event);
+ err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
}
return err;
@@ -1594,8 +1564,6 @@ EXPORT_SYMBOL(fb_blank);
EXPORT_SYMBOL(fb_pan_display);
EXPORT_SYMBOL(fb_get_buffer_offset);
EXPORT_SYMBOL(fb_set_suspend);
-EXPORT_SYMBOL(fb_register_client);
-EXPORT_SYMBOL(fb_unregister_client);
EXPORT_SYMBOL(fb_get_options);
MODULE_LICENSE("GPL");
Index: linux-2.6.17/drivers/video/nvidia/nvidia.c
===================================================================
--- linux-2.6.17.orig/drivers/video/nvidia/nvidia.c 2006-09-14 17:21:47.000000000 +0100
+++ linux-2.6.17/drivers/video/nvidia/nvidia.c 2006-09-14 17:27:15.000000000 +0100
@@ -34,10 +34,6 @@
#include "nv_proto.h"
#include "nv_dma.h"
-#ifndef CONFIG_PCI /* sanity check */
-#error This driver requires PCI support.
-#endif
-
#undef CONFIG_FB_NVIDIA_DEBUG
#ifdef CONFIG_FB_NVIDIA_DEBUG
#define NVTRACE printk
@@ -1303,20 +1299,19 @@ static int __devinit nvidiafb_probe(stru
nvidia_save_vga(par, &par->SavedReg);
+ pci_set_drvdata(pd, info);
+ nvidia_bl_init(par);
if (register_framebuffer(info) < 0) {
printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
goto err_out_iounmap_fb;
}
- pci_set_drvdata(pd, info);
printk(KERN_INFO PFX
"PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
info->fix.id,
par->FbMapSize / (1024 * 1024), info->fix.smem_start);
- nvidia_bl_init(par);
-
NVTRACE_LEAVE();
return 0;
Index: linux-2.6.17/drivers/video/offb.c
===================================================================
--- linux-2.6.17.orig/drivers/video/offb.c 2006-09-14 17:21:47.000000000 +0100
+++ linux-2.6.17/drivers/video/offb.c 2006-09-14 17:27:15.000000000 +0100
@@ -62,8 +62,6 @@ struct offb_par default_par;
* Interface used by the world
*/
-int offb_init(void);
-
static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
static int offb_blank(int blank, struct fb_info *info);
@@ -72,11 +70,6 @@ static int offb_blank(int blank, struct
extern boot_infos_t *boot_infos;
#endif
-static void offb_init_nodriver(struct device_node *);
-static void offb_init_fb(const char *name, const char *full_name,
- int width, int height, int depth, int pitch,
- unsigned long address, struct device_node *dp);
-
static struct fb_ops offb_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = offb_setcolreg,
@@ -229,123 +222,17 @@ static int offb_blank(int blank, struct
return 0;
}
- /*
- * Initialisation
- */
-int __init offb_init(void)
+static void __iomem *offb_map_reg(struct device_node *np, int index,
+ unsigned long offset, unsigned long size)
{
- struct device_node *dp = NULL, *boot_disp = NULL;
-
- if (fb_get_options("offb", NULL))
- return -ENODEV;
+ struct resource r;
- for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
- if (get_property(dp, "linux,opened", NULL) &&
- get_property(dp, "linux,boot-display", NULL)) {
- boot_disp = dp;
- offb_init_nodriver(dp);
- }
- }
- for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
- if (get_property(dp, "linux,opened", NULL) &&
- dp != boot_disp)
- offb_init_nodriver(dp);
- }
-
- return 0;
-}
-
-
-static void __init offb_init_nodriver(struct device_node *dp)
-{
- unsigned int len;
- int i, width = 640, height = 480, depth = 8, pitch = 640;
- unsigned int flags, rsize, addr_prop = 0;
- unsigned long max_size = 0;
- u64 rstart, address = OF_BAD_ADDR;
- u32 *pp, *addrp, *up;
- u64 asize;
-
- pp = (u32 *)get_property(dp, "linux,bootx-depth", &len);
- if (pp == NULL)
- pp = (u32 *)get_property(dp, "depth", &len);
- if (pp && len == sizeof(u32))
- depth = *pp;
-
- pp = (u32 *)get_property(dp, "linux,bootx-width", &len);
- if (pp == NULL)
- pp = (u32 *)get_property(dp, "width", &len);
- if (pp && len == sizeof(u32))
- width = *pp;
-
- pp = (u32 *)get_property(dp, "linux,bootx-height", &len);
- if (pp == NULL)
- pp = (u32 *)get_property(dp, "height", &len);
- if (pp && len == sizeof(u32))
- height = *pp;
-
- pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len);
- if (pp == NULL)
- pp = (u32 *)get_property(dp, "linebytes", &len);
- if (pp && len == sizeof(u32))
- pitch = *pp;
- else
- pitch = width * ((depth + 7) / 8);
-
- rsize = (unsigned long)pitch * (unsigned long)height;
-
- /* Ok, now we try to figure out the address of the framebuffer.
- *
- * Unfortunately, Open Firmware doesn't provide a standard way to do
- * so. All we can do is a dodgy heuristic that happens to work in
- * practice. On most machines, the "address" property contains what
- * we need, though not on Matrox cards found in IBM machines. What I've
- * found that appears to give good results is to go through the PCI
- * ranges and pick one that is both big enough and if possible encloses
- * the "address" property. If none match, we pick the biggest
- */
- up = (u32 *)get_property(dp, "linux,bootx-addr", &len);
- if (up == NULL)
- up = (u32 *)get_property(dp, "address", &len);
- if (up && len == sizeof(u32))
- addr_prop = *up;
-
- for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
- != NULL; i++) {
- int match_addrp = 0;
-
- if (!(flags & IORESOURCE_MEM))
- continue;
- if (asize < rsize)
- continue;
- rstart = of_translate_address(dp, addrp);
- if (rstart == OF_BAD_ADDR)
- continue;
- if (addr_prop && (rstart <= addr_prop) &&
- ((rstart + asize) >= (addr_prop + rsize)))
- match_addrp = 1;
- if (match_addrp) {
- address = addr_prop;
- break;
- }
- if (rsize > max_size) {
- max_size = rsize;
- address = OF_BAD_ADDR;
- }
-
- if (address == OF_BAD_ADDR)
- address = rstart;
- }
- if (address == OF_BAD_ADDR && addr_prop)
- address = (u64)addr_prop;
- if (address != OF_BAD_ADDR) {
- /* kludge for valkyrie */
- if (strcmp(dp->name, "valkyrie") == 0)
- address += 0x1000;
- offb_init_fb(dp->name, dp->full_name, width, height, depth,
- pitch, address, dp);
- }
+ if (of_address_to_resource(np, index, &r))
+ return 0;
+ if ((r.start + offset + size) > r.end)
+ return 0;
+ return ioremap(r.start + offset, size);
}
static void __init offb_init_fb(const char *name, const char *full_name,
@@ -402,45 +289,39 @@ static void __init offb_init_fb(const ch
par->cmap_type = cmap_unknown;
if (depth == 8) {
-
/* Palette hacks disabled for now */
-#if 0
if (dp && !strncmp(name, "ATY,Rage128", 11)) {
- unsigned long regbase = dp->addrs[2].address;
- par->cmap_adr = ioremap(regbase, 0x1FFF);
- par->cmap_type = cmap_r128;
+ par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
+ if (par->cmap_adr)
+ par->cmap_type = cmap_r128;
} else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
|| !strncmp(name, "ATY,RageM3p12A", 14))) {
- unsigned long regbase =
- dp->parent->addrs[2].address;
- par->cmap_adr = ioremap(regbase, 0x1FFF);
- par->cmap_type = cmap_M3A;
+ par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
+ if (par->cmap_adr)
+ par->cmap_type = cmap_M3A;
} else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
- unsigned long regbase =
- dp->parent->addrs[2].address;
- par->cmap_adr = ioremap(regbase, 0x1FFF);
- par->cmap_type = cmap_M3B;
+ par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
+ if (par->cmap_adr)
+ par->cmap_type = cmap_M3B;
} else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
- unsigned long regbase = dp->addrs[1].address;
- par->cmap_adr = ioremap(regbase, 0x1FFF);
- par->cmap_type = cmap_radeon;
+ par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
+ if (par->cmap_adr)
+ par->cmap_type = cmap_radeon;
} else if (!strncmp(name, "ATY,", 4)) {
unsigned long base = address & 0xff000000UL;
par->cmap_adr =
ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
par->cmap_data = par->cmap_adr + 1;
par->cmap_type = cmap_m64;
- } else if (device_is_compatible(dp, "pci1014,b7")) {
- unsigned long regbase = dp->addrs[0].address;
- par->cmap_adr = ioremap(regbase + 0x6000, 0x1000);
- par->cmap_type = cmap_gxt2000;
+ } else if (dp && device_is_compatible(dp, "pci1014,b7")) {
+ par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
+ if (par->cmap_adr)
+ par->cmap_type = cmap_gxt2000;
}
-#endif
- fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
- : FB_VISUAL_STATIC_PSEUDOCOLOR;
+ fix->visual = (par->cmap_type != cmap_unknown) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR;
} else
- fix->visual = /* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR
- : */ FB_VISUAL_TRUECOLOR;
+ fix->visual = FB_VISUAL_TRUECOLOR;
var->xoffset = var->yoffset = 0;
switch (depth) {
@@ -520,5 +401,139 @@ static void __init offb_init_fb(const ch
info->node, full_name);
}
+
+static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
+{
+ unsigned int len;
+ int i, width = 640, height = 480, depth = 8, pitch = 640;
+ unsigned int flags, rsize, addr_prop = 0;
+ unsigned long max_size = 0;
+ u64 rstart, address = OF_BAD_ADDR;
+ u32 *pp, *addrp, *up;
+ u64 asize;
+
+ pp = (u32 *)get_property(dp, "linux,bootx-depth", &len);
+ if (pp == NULL)
+ pp = (u32 *)get_property(dp, "depth", &len);
+ if (pp && len == sizeof(u32))
+ depth = *pp;
+
+ pp = (u32 *)get_property(dp, "linux,bootx-width", &len);
+ if (pp == NULL)
+ pp = (u32 *)get_property(dp, "width", &len);
+ if (pp && len == sizeof(u32))
+ width = *pp;
+
+ pp = (u32 *)get_property(dp, "linux,bootx-height", &len);
+ if (pp == NULL)
+ pp = (u32 *)get_property(dp, "height", &len);
+ if (pp && len == sizeof(u32))
+ height = *pp;
+
+ pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len);
+ if (pp == NULL)
+ pp = (u32 *)get_property(dp, "linebytes", &len);
+ if (pp && len == sizeof(u32))
+ pitch = *pp;
+ else
+ pitch = width * ((depth + 7) / 8);
+
+ rsize = (unsigned long)pitch * (unsigned long)height;
+
+ /* Ok, now we try to figure out the address of the framebuffer.
+ *
+ * Unfortunately, Open Firmware doesn't provide a standard way to do
+ * so. All we can do is a dodgy heuristic that happens to work in
+ * practice. On most machines, the "address" property contains what
+ * we need, though not on Matrox cards found in IBM machines. What I've
+ * found that appears to give good results is to go through the PCI
+ * ranges and pick one that is both big enough and if possible encloses
+ * the "address" property. If none match, we pick the biggest
+ */
+ up = (u32 *)get_property(dp, "linux,bootx-addr", &len);
+ if (up == NULL)
+ up = (u32 *)get_property(dp, "address", &len);
+ if (up && len == sizeof(u32))
+ addr_prop = *up;
+
+ /* Hack for when BootX is passing us */
+ if (no_real_node)
+ goto skip_addr;
+
+ for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
+ != NULL; i++) {
+ int match_addrp = 0;
+
+ if (!(flags & IORESOURCE_MEM))
+ continue;
+ if (asize < rsize)
+ continue;
+ rstart = of_translate_address(dp, addrp);
+ if (rstart == OF_BAD_ADDR)
+ continue;
+ if (addr_prop && (rstart <= addr_prop) &&
+ ((rstart + asize) >= (addr_prop + rsize)))
+ match_addrp = 1;
+ if (match_addrp) {
+ address = addr_prop;
+ break;
+ }
+ if (rsize > max_size) {
+ max_size = rsize;
+ address = OF_BAD_ADDR;
+ }
+
+ if (address == OF_BAD_ADDR)
+ address = rstart;
+ }
+ skip_addr:
+ if (address == OF_BAD_ADDR && addr_prop)
+ address = (u64)addr_prop;
+ if (address != OF_BAD_ADDR) {
+ /* kludge for valkyrie */
+ if (strcmp(dp->name, "valkyrie") == 0)
+ address += 0x1000;
+ offb_init_fb(no_real_node ? "bootx" : dp->name,
+ no_real_node ? "display" : dp->full_name,
+ width, height, depth, pitch, address,
+ no_real_node ? dp : NULL);
+ }
+}
+
+static int __init offb_init(void)
+{
+ struct device_node *dp = NULL, *boot_disp = NULL;
+
+ if (fb_get_options("offb", NULL))
+ return -ENODEV;
+
+ /* Check if we have a MacOS display without a node spec */
+ if (get_property(of_chosen, "linux,bootx-noscreen", NULL) != NULL) {
+ /* The old code tried to work out which node was the MacOS
+ * display based on the address. I'm dropping that since the
+ * lack of a node spec only happens with old BootX versions
+ * (users can update) and with this code, they'll still get
+ * a display (just not the palette hacks).
+ */
+ offb_init_nodriver(of_chosen, 1);
+ }
+
+ for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
+ if (get_property(dp, "linux,opened", NULL) &&
+ get_property(dp, "linux,boot-display", NULL)) {
+ boot_disp = dp;
+ offb_init_nodriver(dp, 0);
+ }
+ }
+ for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
+ if (get_property(dp, "linux,opened", NULL) &&
+ dp != boot_disp)
+ offb_init_nodriver(dp, 0);
+ }
+
+ return 0;
+}
+
+
module_init(offb_init);
MODULE_LICENSE("GPL");
Index: linux-2.6.17/drivers/video/riva/fbdev.c
===================================================================
--- linux-2.6.17.orig/drivers/video/riva/fbdev.c 2006-09-14 17:21:47.000000000 +0100
+++ linux-2.6.17/drivers/video/riva/fbdev.c 2006-09-14 17:27:15.000000000 +0100
@@ -2132,6 +2132,9 @@ static int __devinit rivafb_probe(struct
fb_destroy_modedb(info->monspecs.modedb);
info->monspecs.modedb = NULL;
+
+ pci_set_drvdata(pd, info);
+ riva_bl_init(info->par);
ret = register_framebuffer(info);
if (ret < 0) {
printk(KERN_ERR PFX
@@ -2139,8 +2142,6 @@ static int __devinit rivafb_probe(struct
goto err_iounmap_screen_base;
}
- pci_set_drvdata(pd, info);
-
printk(KERN_INFO PFX
"PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n",
info->fix.id,
@@ -2148,8 +2149,6 @@ static int __devinit rivafb_probe(struct
info->fix.smem_len / (1024 * 1024),
info->fix.smem_start);
- riva_bl_init(info->par);
-
NVTRACE_LEAVE();
return 0;
Index: linux-2.6.17/fs/9p/conv.c
===================================================================
--- linux-2.6.17.orig/fs/9p/conv.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/9p/conv.c 2006-09-14 17:27:15.000000000 +0100
@@ -673,8 +673,10 @@ struct v9fs_fcall *v9fs_create_tcreate(u
struct cbuf *bufp = &buffer;
size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */
- if (extended && extension!=NULL)
- size += 2 + strlen(extension); /* extension[s] */
+ if (extended) {
+ size += 2 + /* extension[s] */
+ (extension == NULL ? 0 : strlen(extension));
+ }
fc = v9fs_create_common(bufp, size, TCREATE);
if (IS_ERR(fc))
Index: linux-2.6.17/fs/9p/vfs_inode.c
===================================================================
--- linux-2.6.17.orig/fs/9p/vfs_inode.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/9p/vfs_inode.c 2006-09-14 17:27:15.000000000 +0100
@@ -434,11 +434,11 @@ static int v9fs_remove(struct inode *dir
result = v9fs_t_remove(v9ses, fid, &fcall);
if (result < 0) {
PRINT_FCALL_ERROR("remove fails", fcall);
- } else {
- v9fs_put_idpool(fid, &v9ses->fidpool);
- v9fs_fid_destroy(v9fid);
}
+ v9fs_put_idpool(fid, &v9ses->fidpool);
+ v9fs_fid_destroy(v9fid);
+
kfree(fcall);
return result;
}
Index: linux-2.6.17/fs/befs/linuxvfs.c
===================================================================
--- linux-2.6.17.orig/fs/befs/linuxvfs.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/befs/linuxvfs.c 2006-09-14 17:27:16.000000000 +0100
@@ -512,7 +512,11 @@ befs_utf2nls(struct super_block *sb, con
wchar_t uni;
int unilen, utflen;
char *result;
- int maxlen = in_len; /* The utf8->nls conversion can't make more chars */
+ /* The utf8->nls conversion won't make the final nls string bigger
+ * than the utf one, but if the string is pure ascii they'll have the
+ * same width and an extra char is needed to save the additional \0
+ */
+ int maxlen = in_len + 1;
befs_debug(sb, "---> utf2nls()");
@@ -588,7 +592,10 @@ befs_nls2utf(struct super_block *sb, con
wchar_t uni;
int unilen, utflen;
char *result;
- int maxlen = 3 * in_len;
+ /* There're nls characters that will translate to 3-chars-wide UTF-8
+ * characters, a additional byte is needed to save the final \0
+ * in special cases */
+ int maxlen = (3 * in_len) + 1;
befs_debug(sb, "---> nls2utf()\n");
Index: linux-2.6.17/fs/buffer.c
===================================================================
--- linux-2.6.17.orig/fs/buffer.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/buffer.c 2006-09-14 17:27:16.000000000 +0100
@@ -470,13 +470,18 @@ out:
pass does the actual I/O. */
void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers)
{
+ struct address_space *mapping = bdev->bd_inode->i_mapping;
+
+ if (mapping->nrpages == 0)
+ return;
+
invalidate_bh_lrus();
/*
* FIXME: what about destroy_dirty_buffers?
* We really want to use invalidate_inode_pages2() for
* that, but not until that's cleaned up.
*/
- invalidate_inode_pages(bdev->bd_inode->i_mapping);
+ invalidate_inode_pages(mapping);
}
/*
Index: linux-2.6.17/fs/coda/file.c
===================================================================
--- linux-2.6.17.orig/fs/coda/file.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/coda/file.c 2006-09-14 17:27:16.000000000 +0100
@@ -136,10 +136,8 @@ int coda_open(struct inode *coda_inode,
coda_vfs_stat.open++;
cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL);
- if (!cfi) {
- unlock_kernel();
+ if (!cfi)
return -ENOMEM;
- }
lock_kernel();
Index: linux-2.6.17/fs/efs/symlink.c
===================================================================
--- linux-2.6.17.orig/fs/efs/symlink.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/efs/symlink.c 2006-09-14 17:27:16.000000000 +0100
@@ -22,7 +22,7 @@ static int efs_symlink_readpage(struct f
err = -ENAMETOOLONG;
if (size > 2 * EFS_BLOCKSIZE)
- goto fail;
+ goto fail_notlocked;
lock_kernel();
/* read first 512 bytes of link target */
@@ -47,6 +47,7 @@ static int efs_symlink_readpage(struct f
return 0;
fail:
unlock_kernel();
+fail_notlocked:
SetPageError(page);
kunmap(page);
unlock_page(page);
Index: linux-2.6.17/fs/ext3/inode.c
===================================================================
--- linux-2.6.17.orig/fs/ext3/inode.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/ext3/inode.c 2006-09-14 17:27:16.000000000 +0100
@@ -1158,7 +1158,7 @@ retry:
ret = PTR_ERR(handle);
goto out;
}
- if (test_opt(inode->i_sb, NOBH))
+ if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode))
ret = nobh_prepare_write(page, from, to, ext3_get_block);
else
ret = block_prepare_write(page, from, to, ext3_get_block);
@@ -1244,7 +1244,7 @@ static int ext3_writeback_commit_write(s
if (new_i_size > EXT3_I(inode)->i_disksize)
EXT3_I(inode)->i_disksize = new_i_size;
- if (test_opt(inode->i_sb, NOBH))
+ if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode))
ret = nobh_commit_write(file, page, from, to);
else
ret = generic_commit_write(file, page, from, to);
@@ -1494,7 +1494,7 @@ static int ext3_writeback_writepage(stru
goto out_fail;
}
- if (test_opt(inode->i_sb, NOBH))
+ if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode))
ret = nobh_writepage(page, ext3_get_block, wbc);
else
ret = block_write_full_page(page, ext3_get_block, wbc);
@@ -2402,14 +2402,15 @@ static ext3_fsblk_t ext3_get_inode_block
struct buffer_head *bh;
struct ext3_group_desc * gdp;
-
- if ((ino != EXT3_ROOT_INO && ino != EXT3_JOURNAL_INO &&
- ino != EXT3_RESIZE_INO && ino < EXT3_FIRST_INO(sb)) ||
- ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) {
- ext3_error(sb, "ext3_get_inode_block",
- "bad inode number: %lu", ino);
+ if (!ext3_valid_inum(sb, ino)) {
+ /*
+ * This error is already checked for in namei.c unless we are
+ * looking at an NFS filehandle, in which case no error
+ * report is needed
+ */
return 0;
}
+
block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb);
if (block_group >= EXT3_SB(sb)->s_groups_count) {
ext3_error(sb,"ext3_get_inode_block","group >= groups count");
Index: linux-2.6.17/fs/ext3/namei.c
===================================================================
--- linux-2.6.17.orig/fs/ext3/namei.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/ext3/namei.c 2006-09-14 17:27:16.000000000 +0100
@@ -1000,7 +1000,12 @@ static struct dentry *ext3_lookup(struct
if (bh) {
unsigned long ino = le32_to_cpu(de->inode);
brelse (bh);
- inode = iget(dir->i_sb, ino);
+ if (!ext3_valid_inum(dir->i_sb, ino)) {
+ ext3_error(dir->i_sb, "ext3_lookup",
+ "bad inode number: %lu", ino);
+ inode = NULL;
+ } else
+ inode = iget(dir->i_sb, ino);
if (!inode)
return ERR_PTR(-EACCES);
@@ -1028,7 +1033,13 @@ struct dentry *ext3_get_parent(struct de
return ERR_PTR(-ENOENT);
ino = le32_to_cpu(de->inode);
brelse(bh);
- inode = iget(child->d_inode->i_sb, ino);
+
+ if (!ext3_valid_inum(child->d_inode->i_sb, ino)) {
+ ext3_error(child->d_inode->i_sb, "ext3_get_parent",
+ "bad inode number: %lu", ino);
+ inode = NULL;
+ } else
+ inode = iget(child->d_inode->i_sb, ino);
if (!inode)
return ERR_PTR(-EACCES);
Index: linux-2.6.17/fs/freevxfs/vxfs_lookup.c
===================================================================
--- linux-2.6.17.orig/fs/freevxfs/vxfs_lookup.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/fs/freevxfs/vxfs_lookup.c 2006-09-14 17:27:16.000000000 +0100
@@ -246,6 +246,8 @@ vxfs_readdir(struct file *fp, void *retp
u_long page, npages, block, pblocks, nblocks, offset;
loff_t pos;
+ lock_kernel();
+
switch ((long)fp->f_pos) {
case 0:
if (filler(retp, ".", 1, fp->f_pos, ip->i_ino, DT_DIR) < 0)
Index: linux-2.6.17/fs/fuse/control.c
===================================================================
--- linux-2.6.17.orig/fs/fuse/control.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/fuse/control.c 2006-09-14 17:27:16.000000000 +0100
@@ -105,7 +105,7 @@ static struct dentry *fuse_ctl_add_dentr
/*
* Add a connection to the control filesystem (if it exists). Caller
- * must host fuse_mutex
+ * must hold fuse_mutex
*/
int fuse_ctl_add_conn(struct fuse_conn *fc)
{
@@ -139,7 +139,7 @@ int fuse_ctl_add_conn(struct fuse_conn *
/*
* Remove a connection from the control filesystem (if it exists).
- * Caller must host fuse_mutex
+ * Caller must hold fuse_mutex
*/
void fuse_ctl_remove_conn(struct fuse_conn *fc)
{
Index: linux-2.6.17/fs/fuse/dir.c
===================================================================
--- linux-2.6.17.orig/fs/fuse/dir.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/fuse/dir.c 2006-09-14 17:27:16.000000000 +0100
@@ -14,6 +14,33 @@
#include
#include
+#if BITS_PER_LONG >= 64
+static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
+{
+ entry->d_time = time;
+}
+
+static inline u64 fuse_dentry_time(struct dentry *entry)
+{
+ return entry->d_time;
+}
+#else
+/*
+ * On 32 bit archs store the high 32 bits of time in d_fsdata
+ */
+static void fuse_dentry_settime(struct dentry *entry, u64 time)
+{
+ entry->d_time = time;
+ entry->d_fsdata = (void *) (unsigned long) (time >> 32);
+}
+
+static u64 fuse_dentry_time(struct dentry *entry)
+{
+ return (u64) entry->d_time +
+ ((u64) (unsigned long) entry->d_fsdata << 32);
+}
+#endif
+
/*
* FUSE caches dentries and attributes with separate timeout. The
* time in jiffies until the dentry/attributes are valid is stored in
@@ -23,10 +50,13 @@
/*
* Calculate the time in jiffies until a dentry/attributes are valid
*/
-static unsigned long time_to_jiffies(unsigned long sec, unsigned long nsec)
+static u64 time_to_jiffies(unsigned long sec, unsigned long nsec)
{
- struct timespec ts = {sec, nsec};
- return jiffies + timespec_to_jiffies(&ts);
+ if (sec || nsec) {
+ struct timespec ts = {sec, nsec};
+ return get_jiffies_64() + timespec_to_jiffies(&ts);
+ } else
+ return 0;
}
/*
@@ -35,7 +65,8 @@ static unsigned long time_to_jiffies(uns
*/
static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
{
- entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec);
+ fuse_dentry_settime(entry,
+ time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
if (entry->d_inode)
get_fuse_inode(entry->d_inode)->i_time =
time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
@@ -47,7 +78,7 @@ static void fuse_change_timeout(struct d
*/
void fuse_invalidate_attr(struct inode *inode)
{
- get_fuse_inode(inode)->i_time = jiffies - 1;
+ get_fuse_inode(inode)->i_time = 0;
}
/*
@@ -60,7 +91,7 @@ void fuse_invalidate_attr(struct inode *
*/
static void fuse_invalidate_entry_cache(struct dentry *entry)
{
- entry->d_time = jiffies - 1;
+ fuse_dentry_settime(entry, 0);
}
/*
@@ -102,7 +133,7 @@ static int fuse_dentry_revalidate(struct
if (inode && is_bad_inode(inode))
return 0;
- else if (time_after(jiffies, entry->d_time)) {
+ else if (fuse_dentry_time(entry) < get_jiffies_64()) {
int err;
struct fuse_entry_out outarg;
struct fuse_conn *fc;
@@ -666,7 +697,7 @@ static int fuse_revalidate(struct dentry
if (!fuse_allow_task(fc, current))
return -EACCES;
if (get_node_id(inode) != FUSE_ROOT_ID &&
- time_before_eq(jiffies, fi->i_time))
+ fi->i_time >= get_jiffies_64())
return 0;
return fuse_do_getattr(inode);
Index: linux-2.6.17/fs/fuse/fuse_i.h
===================================================================
--- linux-2.6.17.orig/fs/fuse/fuse_i.h 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/fuse/fuse_i.h 2006-09-14 17:27:16.000000000 +0100
@@ -59,7 +59,7 @@ struct fuse_inode {
struct fuse_req *forget_req;
/** Time in jiffies until the file attributes are valid */
- unsigned long i_time;
+ u64 i_time;
};
/** FUSE specific file data */
Index: linux-2.6.17/fs/fuse/inode.c
===================================================================
--- linux-2.6.17.orig/fs/fuse/inode.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/fuse/inode.c 2006-09-14 17:27:16.000000000 +0100
@@ -51,7 +51,7 @@ static struct inode *fuse_alloc_inode(st
return NULL;
fi = get_fuse_inode(inode);
- fi->i_time = jiffies - 1;
+ fi->i_time = 0;
fi->nodeid = 0;
fi->nlookup = 0;
fi->forget_req = fuse_request_alloc();
Index: linux-2.6.17/fs/inotify_user.c
===================================================================
--- linux-2.6.17.orig/fs/inotify_user.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/inotify_user.c 2006-09-14 17:27:16.000000000 +0100
@@ -187,7 +187,7 @@ static struct inotify_kernel_event * ker
{
struct inotify_kernel_event *kevent;
- kevent = kmem_cache_alloc(event_cachep, GFP_KERNEL);
+ kevent = kmem_cache_alloc(event_cachep, GFP_NOFS);
if (unlikely(!kevent))
return NULL;
Index: linux-2.6.17/fs/lockd/svclock.c
===================================================================
--- linux-2.6.17.orig/fs/lockd/svclock.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/lockd/svclock.c 2006-09-14 17:27:16.000000000 +0100
@@ -638,9 +638,6 @@ static void nlmsvc_grant_callback(struct
if (task->tk_status < 0) {
/* RPC error: Re-insert for retransmission */
timeout = 10 * HZ;
- } else if (block->b_done) {
- /* Block already removed, kill it for real */
- timeout = 0;
} else {
/* Call was successful, now wait for client callback */
timeout = 60 * HZ;
@@ -709,13 +706,10 @@ nlmsvc_retry_blocked(void)
break;
if (time_after(block->b_when,jiffies))
break;
- dprintk("nlmsvc_retry_blocked(%p, when=%ld, done=%d)\n",
- block, block->b_when, block->b_done);
+ dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
+ block, block->b_when);
kref_get(&block->b_count);
- if (block->b_done)
- nlmsvc_unlink_block(block);
- else
- nlmsvc_grant_blocked(block);
+ nlmsvc_grant_blocked(block);
nlmsvc_release_block(block);
}
Index: linux-2.6.17/fs/namei.c
===================================================================
--- linux-2.6.17.orig/fs/namei.c 2006-09-14 17:21:47.000000000 +0100
+++ linux-2.6.17/fs/namei.c 2006-09-14 17:27:16.000000000 +0100
@@ -159,7 +159,7 @@ char * getname(const char __user * filen
#ifdef CONFIG_AUDITSYSCALL
void putname(const char *name)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
audit_putname(name);
else
__putname(name);
@@ -1125,7 +1125,7 @@ static int fastcall do_path_lookup(int d
retval = link_path_walk(name, nd);
out:
if (likely(retval == 0)) {
- if (unlikely(current->audit_context && nd && nd->dentry &&
+ if (unlikely(!audit_dummy_context() && nd && nd->dentry &&
nd->dentry->d_inode))
audit_inode(name, nd->dentry->d_inode);
}
@@ -1357,7 +1357,7 @@ static int may_delete(struct inode *dir,
return -ENOENT;
BUG_ON(victim->d_parent->d_inode != dir);
- audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino);
+ audit_inode_child(victim->d_name.name, victim->d_inode, dir);
error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
if (error)
@@ -1659,6 +1659,7 @@ do_last:
* It already exists.
*/
mutex_unlock(&dir->d_inode->i_mutex);
+ audit_inode_update(path.dentry->d_inode);
error = -EEXIST;
if (flag & O_EXCL)
@@ -1669,6 +1670,7 @@ do_last:
if (flag & O_NOFOLLOW)
goto exit_dput;
}
+
error = -ENOENT;
if (!path.dentry->d_inode)
goto exit_dput;
Index: linux-2.6.17/fs/nfs/namespace.c
===================================================================
--- linux-2.6.17.orig/fs/nfs/namespace.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/nfs/namespace.c 2006-09-14 17:27:16.000000000 +0100
@@ -51,7 +51,7 @@ char *nfs_path(const char *base, const s
namelen = dentry->d_name.len;
buflen -= namelen + 1;
if (buflen < 0)
- goto Elong;
+ goto Elong_unlock;
end -= namelen;
memcpy(end, dentry->d_name.name, namelen);
*--end = '/';
@@ -68,6 +68,8 @@ char *nfs_path(const char *base, const s
end -= namelen;
memcpy(end, base, namelen);
return end;
+Elong_unlock:
+ spin_unlock(&dcache_lock);
Elong:
return ERR_PTR(-ENAMETOOLONG);
}
Index: linux-2.6.17/fs/nfs/read.c
===================================================================
--- linux-2.6.17.orig/fs/nfs/read.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/nfs/read.c 2006-09-14 17:27:16.000000000 +0100
@@ -63,7 +63,7 @@ struct nfs_read_data *nfs_readdata_alloc
return p;
}
-void nfs_readdata_free(struct nfs_read_data *p)
+static void nfs_readdata_free(struct nfs_read_data *p)
{
if (p && (p->pagevec != &p->page_array[0]))
kfree(p->pagevec);
Index: linux-2.6.17/fs/nfs/write.c
===================================================================
--- linux-2.6.17.orig/fs/nfs/write.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/nfs/write.c 2006-09-14 17:27:16.000000000 +0100
@@ -137,7 +137,7 @@ struct nfs_write_data *nfs_writedata_all
return p;
}
-void nfs_writedata_free(struct nfs_write_data *p)
+static void nfs_writedata_free(struct nfs_write_data *p)
{
if (p && (p->pagevec != &p->page_array[0]))
kfree(p->pagevec);
Index: linux-2.6.17/fs/nfsd/nfsfh.c
===================================================================
--- linux-2.6.17.orig/fs/nfsd/nfsfh.c 2006-09-14 16:26:41.000000000 +0100
+++ linux-2.6.17/fs/nfsd/nfsfh.c 2006-09-14 17:27:16.000000000 +0100
@@ -187,6 +187,11 @@ fh_verify(struct svc_rqst *rqstp, struct
goto out;
}
+ /* Set user creds for this exportpoint */
+ error = nfserrno(nfsd_setuser(rqstp, exp));
+ if (error)
+ goto out;
+
/*
* Look up the dentry using the NFS file handle.
*/
@@ -241,16 +246,17 @@ fh_verify(struct svc_rqst *rqstp, struct
dprintk("nfsd: fh_verify - just checking\n");
dentry = fhp->fh_dentry;
exp = fhp->fh_export;
+ /* Set user creds for this exportpoint; necessary even
+ * in the "just checking" case because this may be a
+ * filehandle that was created by fh_compose, and that
+ * is about to be used in another nfsv4 compound
+ * operation */
+ error = nfserrno(nfsd_setuser(rqstp, exp));
+ if (error)
+ goto out;
}
cache_get(&exp->h);
- /* Set user creds for this exportpoint; necessary even in the "just
- * checking" case because this may be a filehandle that was created by
- * fh_compose, and that is about to be used in another nfsv4 compound
- * operation */
- error = nfserrno(nfsd_setuser(rqstp, exp));
- if (error)
- goto out;
error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type);
if (error)
Index: linux-2.6.17/fs/partitions/Kconfig
===================================================================
--- linux-2.6.17.orig/fs/partitions/Kconfig 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/fs/partitions/Kconfig 2006-09-14 17:27:16.000000000 +0100
@@ -99,7 +99,7 @@ config IBM_PARTITION
config MAC_PARTITION
bool "Macintosh partition map support" if PARTITION_ADVANCED
- default y if MAC
+ default y if (MAC || PPC_PMAC)
help
Say Y here if you would like to use hard disks under Linux which
were partitioned on a Macintosh.
Index: linux-2.6.17/fs/reiserfs/file.c
===================================================================
--- linux-2.6.17.orig/fs/reiserfs/file.c 2006-09-14 17:21:47.000000000 +0100
+++ linux-2.6.17/fs/reiserfs/file.c 2006-09-14 17:27:16.000000000 +0100
@@ -48,8 +48,8 @@ static int reiserfs_file_release(struct
return 0;
}
- reiserfs_write_lock(inode->i_sb);
mutex_lock(&inode->i_mutex);
+ reiserfs_write_lock(inode->i_sb);
/* freeing preallocation only involves relogging blocks that
* are already in the current transaction. preallocation gets
* freed at the end of each transaction, so it is impossible for
Index: linux-2.6.17/fs/reiserfs/inode.c
===================================================================
--- linux-2.6.17.orig/fs/reiserfs/inode.c 2006-09-14 16:26:42.000000000 +0100
+++ linux-2.6.17/fs/reiserfs/inode.c 2006-09-14 17:27:16.000000000 +0100
@@ -39,14 +39,10 @@ void reiserfs_delete_inode(struct inode
/* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
- mutex_lock(&inode->i_mutex);
-
reiserfs_delete_xattrs(inode);
- if (journal_begin(&th, inode->i_sb, jbegin_count)) {
- mutex_unlock(&inode->i_mutex);
+ if (journal_begin(&th, inode->i_sb, jbegin_count))
goto out;
- }
reiserfs_update_inode_transaction(inode);
err = reiserfs_delete_object(&th, inode);
@@ -57,12 +53,8 @@ void reiserfs_delete_inode(struct inode
if (!err)
DQUOT_FREE_INODE(inode);
- if (journal_end(&th, inode->i_sb, jbegin_count)) {
- mutex_unlock(&inode->i_mutex);
+ if (journal_end(&th, inode->i_sb, jbegin_count))
goto out;
- }
-
- mutex_unlock(&inode->i_mutex);
/* check return value from reiserfs_delete_object after
* ending the transaction
@@ -2348,6 +2340,7 @@ static int reiserfs_write_full_page(stru
unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
int error = 0;
unsigned long block;
+ sector_t last_block;
struct buffer_head *head, *bh;
int partial = 0;
int nr = 0;
@@ -2395,10 +2388,19 @@ static int reiserfs_write_full_page(stru
}
bh = head;
block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits);
+ last_block = (i_size_read(inode) - 1) >> inode->i_blkbits;
/* first map all the buffers, logging any direct items we find */
do {
- if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
- (buffer_mapped(bh)
+ if (block > last_block) {
+ /*
+ * This can happen when the block size is less than
+ * the page size. The corresponding bytes in the page
+ * were zero filled above
+ */
+ clear_buffer_dirty(bh);
+ set_buffer_uptodate(bh);
+ } else if ((checked || buffer_dirty(bh)) &&
+ (!buffer_mapped(bh) || (buffer_mapped(bh)
&& bh->b_blocknr ==
0))) {
/* not mapped yet, or it points to a direct item, search
Index: linux-2.6.17/fs/reiserfs/ioctl.c
===================================================================
--- linux-2.6.17.orig/fs/reiserfs/ioctl.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/fs/reiserfs/ioctl.c 2006-09-14 17:27:16.000000000 +0100
@@ -116,12 +116,12 @@ static int reiserfs_unpack(struct inode
if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
return 0;
}
- reiserfs_write_lock(inode->i_sb);
/* we need to make sure nobody is changing the file size beneath
** us
*/
mutex_lock(&inode->i_mutex);
+ reiserfs_write_lock(inode->i_sb);
write_from = inode->i_size & (blocksize - 1);
/* if we are on a block boundary, we are already unpacked. */
Index: linux-2.6.17/fs/udf/ialloc.c
===================================================================
--- linux-2.6.17.orig/fs/udf/ialloc.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/fs/udf/ialloc.c 2006-09-14 17:27:16.000000000 +0100
@@ -75,6 +75,12 @@ struct inode * udf_new_inode (struct ino
}
*err = -ENOSPC;
+ UDF_I_UNIQUE(inode) = 0;
+ UDF_I_LENEXTENTS(inode) = 0;
+ UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
+ UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
+ UDF_I_STRAT4096(inode) = 0;
+
block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
start, err);
if (*err)
@@ -84,11 +90,6 @@ struct inode * udf_new_inode (struct ino
}
mutex_lock(&sbi->s_alloc_mutex);
- UDF_I_UNIQUE(inode) = 0;
- UDF_I_LENEXTENTS(inode) = 0;
- UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
- UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
- UDF_I_STRAT4096(inode) = 0;
if (UDF_SB_LVIDBH(sb))
{
struct logicalVolHeaderDesc *lvhd;
Index: linux-2.6.17/fs/ufs/balloc.c
===================================================================
--- linux-2.6.17.orig/fs/ufs/balloc.c 2006-09-14 16:26:42.000000000 +0100
+++ linux-2.6.17/fs/ufs/balloc.c 2006-09-14 17:27:16.000000000 +0100
@@ -248,7 +248,7 @@ static void ufs_change_blocknr(struct in
if (likely(cur_index != index)) {
page = ufs_get_locked_page(mapping, index);
- if (IS_ERR(page))
+ if (!page || IS_ERR(page)) /* it was truncated or EIO */
continue;
} else
page = locked_page;
Index: linux-2.6.17/fs/ufs/namei.c
===================================================================
--- linux-2.6.17.orig/fs/ufs/namei.c 2006-09-14 16:26:42.000000000 +0100
+++ linux-2.6.17/fs/ufs/namei.c 2006-09-14 17:27:16.000000000 +0100
@@ -129,7 +129,7 @@ static int ufs_symlink (struct inode * d
struct inode * inode;
if (l > sb->s_blocksize)
- goto out;
+ goto out_notlocked;
lock_kernel();
inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO);
@@ -155,6 +155,7 @@ static int ufs_symlink (struct inode * d
err = ufs_add_nondir(dentry, inode);
out:
unlock_kernel();
+out_notlocked:
return err;
out_fail:
Index: linux-2.6.17/fs/ufs/util.c
===================================================================
--- linux-2.6.17.orig/fs/ufs/util.c 2006-09-14 16:26:42.000000000 +0100
+++ linux-2.6.17/fs/ufs/util.c 2006-09-14 17:27:16.000000000 +0100
@@ -251,12 +251,12 @@ struct page *ufs_get_locked_page(struct
{
struct page *page;
-try_again:
page = find_lock_page(mapping, index);
if (!page) {
page = read_cache_page(mapping, index,
(filler_t*)mapping->a_ops->readpage,
NULL);
+
if (IS_ERR(page)) {
printk(KERN_ERR "ufs_change_blocknr: "
"read_cache_page error: ino %lu, index: %lu\n",
@@ -266,6 +266,14 @@ try_again:
lock_page(page);
+ if (unlikely(page->mapping == NULL)) {
+ /* Truncate got there first */
+ unlock_page(page);
+ page_cache_release(page);
+ page = NULL;
+ goto out;
+ }
+
if (!PageUptodate(page) || PageError(page)) {
unlock_page(page);
page_cache_release(page);
@@ -275,15 +283,8 @@ try_again:
mapping->host->i_ino, index);
page = ERR_PTR(-EIO);
- goto out;
}
}
-
- if (unlikely(!page->mapping || !page_has_buffers(page))) {
- unlock_page(page);
- page_cache_release(page);
- goto try_again;/*we really need these buffers*/
- }
out:
return page;
}
Index: linux-2.6.17/include/asm-arm/arch-omap/clock.h
===================================================================
--- linux-2.6.17.orig/include/asm-arm/arch-omap/clock.h 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/include/asm-arm/arch-omap/clock.h 2006-09-14 17:27:16.000000000 +0100
@@ -48,8 +48,6 @@ struct clk_functions {
};
extern unsigned int mpurate;
-extern struct list_head clocks;
-extern spinlock_t clockfw_lock;
extern int clk_init(struct clk_functions * custom_clocks);
extern int clk_register(struct clk *clk);
Index: linux-2.6.17/include/asm-i386/kprobes.h
===================================================================
--- linux-2.6.17.orig/include/asm-i386/kprobes.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/asm-i386/kprobes.h 2006-09-14 17:27:16.000000000 +0100
@@ -45,6 +45,7 @@ typedef u8 kprobe_opcode_t;
#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry
#define ARCH_SUPPORTS_KRETPROBES
#define ARCH_INACTIVE_KPROBE_COUNT 0
+#define flush_insn_slot(p) do { } while (0)
void arch_remove_kprobe(struct kprobe *p);
void kretprobe_trampoline(void);
Index: linux-2.6.17/include/asm-ia64/kprobes.h
===================================================================
--- linux-2.6.17.orig/include/asm-ia64/kprobes.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/asm-ia64/kprobes.h 2006-09-14 17:27:16.000000000 +0100
@@ -125,5 +125,6 @@ static inline void jprobe_return(void)
}
extern void invalidate_stacked_regs(void);
extern void flush_register_stack(void);
+extern void flush_insn_slot(struct kprobe *p);
#endif /* _ASM_KPROBES_H */
Index: linux-2.6.17/include/asm-ia64/meminit.h
===================================================================
--- linux-2.6.17.orig/include/asm-ia64/meminit.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/asm-ia64/meminit.h 2006-09-14 17:27:16.000000000 +0100
@@ -56,6 +56,11 @@ extern void efi_memmap_init(unsigned lon
extern struct page *vmem_map;
extern int find_largest_hole (u64 start, u64 end, void *arg);
extern int create_mem_map_page_table (u64 start, u64 end, void *arg);
+ extern int vmemmap_find_next_valid_pfn(int, int);
+#else
+static inline int vmemmap_find_next_valid_pfn(int node, int i)
+{
+ return i + 1;
+}
#endif
-
#endif /* meminit_h */
Index: linux-2.6.17/include/asm-ia64/pal.h
===================================================================
--- linux-2.6.17.orig/include/asm-ia64/pal.h 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/include/asm-ia64/pal.h 2006-09-14 17:27:16.000000000 +0100
@@ -1433,7 +1433,12 @@ typedef union pal_version_u {
} pal_version_u_t;
-/* Return PAL version information */
+/*
+ * Return PAL version information. While the documentation states that
+ * PAL_VERSION can be called in either physical or virtual mode, some
+ * implementations only allow physical calls. We don't call it very often,
+ * so the overhead isn't worth eliminating.
+ */
static inline s64
ia64_pal_version (pal_version_u_t *pal_min_version, pal_version_u_t *pal_cur_version)
{
Index: linux-2.6.17/include/asm-ia64/sn/xpc.h
===================================================================
--- linux-2.6.17.orig/include/asm-ia64/sn/xpc.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/asm-ia64/sn/xpc.h 2006-09-14 17:27:16.000000000 +0100
@@ -1124,8 +1124,8 @@ xpc_notify_IRQ_send_local(struct xpc_cha
#define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff))
#define XPC_SET_IPI_FLAGS(_amo, _c, _f) (_amo) |= ((u64) (_f) << ((_c) * 8))
-#define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f)
-#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & 0x1010101010101010)
+#define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & __IA64_UL_CONST(0x0f0f0f0f0f0f0f0f))
+#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & __IA64_UL_CONST(0x1010101010101010))
static inline void
Index: linux-2.6.17/include/asm-ia64/system.h
===================================================================
--- linux-2.6.17.orig/include/asm-ia64/system.h 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/include/asm-ia64/system.h 2006-09-14 17:27:16.000000000 +0100
@@ -24,7 +24,7 @@
* 0xa000000000000000+2*PERCPU_PAGE_SIZE
* - 0xa000000000000000+3*PERCPU_PAGE_SIZE remain unmapped (guard page)
*/
-#define KERNEL_START (GATE_ADDR+0x100000000)
+#define KERNEL_START (GATE_ADDR+__IA64_UL_CONST(0x100000000))
#define PERCPU_ADDR (-PERCPU_PAGE_SIZE)
#ifndef __ASSEMBLY__
Index: linux-2.6.17/include/asm-powerpc/backlight.h
===================================================================
--- linux-2.6.17.orig/include/asm-powerpc/backlight.h 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/include/asm-powerpc/backlight.h 2006-09-14 17:27:16.000000000 +0100
@@ -30,8 +30,12 @@ static inline void pmac_backlight_key_do
pmac_backlight_key(1);
}
+extern void pmac_backlight_set_legacy_brightness_pmu(int brightness);
extern int pmac_backlight_set_legacy_brightness(int brightness);
extern int pmac_backlight_get_legacy_brightness(void);
+extern void pmac_backlight_enable(void);
+extern void pmac_backlight_disable(void);
+
#endif /* __KERNEL__ */
#endif
Index: linux-2.6.17/include/asm-powerpc/kprobes.h
===================================================================
--- linux-2.6.17.orig/include/asm-powerpc/kprobes.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/asm-powerpc/kprobes.h 2006-09-14 17:27:16.000000000 +0100
@@ -51,6 +51,7 @@ typedef unsigned int kprobe_opcode_t;
#define ARCH_SUPPORTS_KRETPROBES
#define ARCH_INACTIVE_KPROBE_COUNT 1
+#define flush_insn_slot(p) do { } while (0)
void kretprobe_trampoline(void);
extern void arch_remove_kprobe(struct kprobe *p);
Index: linux-2.6.17/include/asm-sparc64/kprobes.h
===================================================================
--- linux-2.6.17.orig/include/asm-sparc64/kprobes.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/asm-sparc64/kprobes.h 2006-09-14 17:27:16.000000000 +0100
@@ -13,6 +13,7 @@ typedef u32 kprobe_opcode_t;
#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry
#define arch_remove_kprobe(p) do {} while (0)
#define ARCH_INACTIVE_KPROBE_COUNT 0
+#define flush_insn_slot(p) do { } while (0)
/* Architecture specific copy of original instruction*/
struct arch_specific_insn {
Index: linux-2.6.17/include/asm-x86_64/kprobes.h
===================================================================
--- linux-2.6.17.orig/include/asm-x86_64/kprobes.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/asm-x86_64/kprobes.h 2006-09-14 17:27:16.000000000 +0100
@@ -47,6 +47,7 @@ typedef u8 kprobe_opcode_t;
void kretprobe_trampoline(void);
extern void arch_remove_kprobe(struct kprobe *p);
+#define flush_insn_slot(p) do { } while (0)
/* Architecture specific copy of original instruction*/
struct arch_specific_insn {
Index: linux-2.6.17/include/linux/audit.h
===================================================================
--- linux-2.6.17.orig/include/linux/audit.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/audit.h 2006-09-14 17:27:16.000000000 +0100
@@ -327,21 +327,31 @@ extern void __audit_getname(const char *
extern void audit_putname(const char *name);
extern void __audit_inode(const char *name, const struct inode *inode);
extern void __audit_inode_child(const char *dname, const struct inode *inode,
- unsigned long pino);
+ const struct inode *parent);
+extern void __audit_inode_update(const struct inode *inode);
+static inline int audit_dummy_context(void)
+{
+ void *p = current->audit_context;
+ return !p || *(int *)p;
+}
static inline void audit_getname(const char *name)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
__audit_getname(name);
}
static inline void audit_inode(const char *name, const struct inode *inode) {
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
__audit_inode(name, inode);
}
static inline void audit_inode_child(const char *dname,
- const struct inode *inode,
- unsigned long pino) {
- if (unlikely(current->audit_context))
- __audit_inode_child(dname, inode, pino);
+ const struct inode *inode,
+ const struct inode *parent) {
+ if (unlikely(!audit_dummy_context()))
+ __audit_inode_child(dname, inode, parent);
+}
+static inline void audit_inode_update(const struct inode *inode) {
+ if (unlikely(!audit_dummy_context()))
+ __audit_inode_update(inode);
}
/* Private API (for audit.c only) */
@@ -365,57 +375,61 @@ extern int __audit_mq_getsetattr(mqd_t m
static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
return __audit_ipc_obj(ipcp);
return 0;
}
static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
return __audit_ipc_set_perm(qbytes, uid, gid, mode);
return 0;
}
static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
return __audit_mq_open(oflag, mode, u_attr);
return 0;
}
static inline int audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
return __audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout);
return 0;
}
static inline int audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
return __audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
return 0;
}
static inline int audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
return __audit_mq_notify(mqdes, u_notification);
return 0;
}
static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
{
- if (unlikely(current->audit_context))
+ if (unlikely(!audit_dummy_context()))
return __audit_mq_getsetattr(mqdes, mqstat);
return 0;
}
+extern int audit_n_rules;
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
#define audit_syscall_entry(ta,a,b,c,d,e) do { ; } while (0)
#define audit_syscall_exit(f,r) do { ; } while (0)
+#define audit_dummy_context() 1
#define audit_getname(n) do { ; } while (0)
#define audit_putname(n) do { ; } while (0)
#define __audit_inode(n,i) do { ; } while (0)
#define __audit_inode_child(d,i,p) do { ; } while (0)
+#define __audit_inode_update(i) do { ; } while (0)
#define audit_inode(n,i) do { ; } while (0)
#define audit_inode_child(d,i,p) do { ; } while (0)
+#define audit_inode_update(i) do { ; } while (0)
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
#define audit_get_loginuid(c) ({ -1; })
#define audit_ipc_obj(i) ({ 0; })
@@ -430,6 +444,7 @@ static inline int audit_mq_getsetattr(mq
#define audit_mq_timedreceive(d,l,p,t) ({ 0; })
#define audit_mq_notify(d,n) ({ 0; })
#define audit_mq_getsetattr(d,s) ({ 0; })
+#define audit_n_rules 0
#endif
#ifdef CONFIG_AUDIT
Index: linux-2.6.17/include/linux/cn_proc.h
===================================================================
--- linux-2.6.17.orig/include/linux/cn_proc.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/cn_proc.h 2006-09-14 17:27:16.000000000 +0100
@@ -57,7 +57,8 @@ struct proc_event {
PROC_EVENT_EXIT = 0x80000000
} what;
__u32 cpu;
- struct timespec timestamp;
+ __u64 __attribute__((aligned(8))) timestamp_ns;
+ /* Number of nano seconds since system boot */
union { /* must be last field of proc_event struct */
struct {
__u32 err;
Index: linux-2.6.17/include/linux/debug_locks.h
===================================================================
--- linux-2.6.17.orig/include/linux/debug_locks.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/debug_locks.h 2006-09-14 17:27:16.000000000 +0100
@@ -1,6 +1,8 @@
#ifndef __LINUX_DEBUG_LOCKING_H
#define __LINUX_DEBUG_LOCKING_H
+struct task_struct;
+
extern int debug_locks;
extern int debug_locks_silent;
Index: linux-2.6.17/include/linux/delayacct.h
===================================================================
--- linux-2.6.17.orig/include/linux/delayacct.h 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/include/linux/delayacct.h 2006-09-14 17:27:16.000000000 +0100
@@ -55,7 +55,7 @@ static inline void delayacct_tsk_init(st
{
/* reinitialize in case parent's non-null pointer was dup'ed*/
tsk->delays = NULL;
- if (unlikely(delayacct_on))
+ if (delayacct_on)
__delayacct_tsk_init(tsk);
}
@@ -80,9 +80,7 @@ static inline void delayacct_blkio_end(v
static inline int delayacct_add_tsk(struct taskstats *d,
struct task_struct *tsk)
{
- if (likely(!delayacct_on))
- return -EINVAL;
- if (!tsk->delays)
+ if (!delayacct_on || !tsk->delays)
return 0;
return __delayacct_add_tsk(d, tsk);
}
Index: linux-2.6.17/include/linux/ext3_fs.h
===================================================================
--- linux-2.6.17.orig/include/linux/ext3_fs.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/ext3_fs.h 2006-09-14 17:27:16.000000000 +0100
@@ -492,6 +492,15 @@ static inline struct ext3_inode_info *EX
{
return container_of(inode, struct ext3_inode_info, vfs_inode);
}
+
+static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino)
+{
+ return ino == EXT3_ROOT_INO ||
+ ino == EXT3_JOURNAL_INO ||
+ ino == EXT3_RESIZE_INO ||
+ (ino >= EXT3_FIRST_INO(sb) &&
+ ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count));
+}
#else
/* Assume that user mode programs are passing in an ext3fs superblock, not
* a kernel struct super_block. This will allow us to call the feature-test
Index: linux-2.6.17/include/linux/fb.h
===================================================================
--- linux-2.6.17.orig/include/linux/fb.h 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/include/linux/fb.h 2006-09-14 17:27:16.000000000 +0100
@@ -524,7 +524,7 @@ struct fb_event {
extern int fb_register_client(struct notifier_block *nb);
extern int fb_unregister_client(struct notifier_block *nb);
-
+extern int fb_notifier_call_chain(unsigned long val, void *v);
/*
* Pixmap structure definition
*
Index: linux-2.6.17/include/linux/fsnotify.h
===================================================================
--- linux-2.6.17.orig/include/linux/fsnotify.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/fsnotify.h 2006-09-14 17:27:16.000000000 +0100
@@ -67,7 +67,7 @@ static inline void fsnotify_move(struct
if (source) {
inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL);
}
- audit_inode_child(new_name, source, new_dir->i_ino);
+ audit_inode_child(new_name, source, new_dir);
}
/*
@@ -98,7 +98,7 @@ static inline void fsnotify_create(struc
inode_dir_notify(inode, DN_CREATE);
inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name,
dentry->d_inode);
- audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
+ audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
}
/*
@@ -109,7 +109,7 @@ static inline void fsnotify_mkdir(struct
inode_dir_notify(inode, DN_CREATE);
inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0,
dentry->d_name.name, dentry->d_inode);
- audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
+ audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
}
/*
Index: linux-2.6.17/include/linux/input.h
===================================================================
--- linux-2.6.17.orig/include/linux/input.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/input.h 2006-09-14 17:27:16.000000000 +0100
@@ -893,7 +893,6 @@ struct input_dev {
int (*open)(struct input_dev *dev);
void (*close)(struct input_dev *dev);
- int (*accept)(struct input_dev *dev, struct file *file);
int (*flush)(struct input_dev *dev, struct file *file);
int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect);
@@ -961,6 +960,26 @@ struct input_dev {
struct input_handle;
+/**
+ * struct input_handler - implements one of interfaces for input devices
+ * @private: driver-specific data
+ * @event: event handler
+ * @connect: called when attaching a handler to an input device
+ * @disconnect: disconnects a handler from input device
+ * @start: starts handler for given handle. This function is called by
+ * input core right after connect() method and also when a process
+ * that "grabbed" a device releases it
+ * @fops: file operations this driver implements
+ * @minor: beginning of range of 32 minors for devices this driver
+ * can provide
+ * @name: name of the handler, to be shown in /proc/bus/input/handlers
+ * @id_table: pointer to a table of input_device_ids this driver can
+ * handle
+ * @blacklist: prointer to a table of input_device_ids this driver should
+ * ignore even if they match @id_table
+ * @h_list: list of input handles associated with the handler
+ * @node: for placing the driver onto input_handler_list
+ */
struct input_handler {
void *private;
@@ -968,6 +987,7 @@ struct input_handler {
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
+ void (*start)(struct input_handle *handle);
const struct file_operations *fops;
int minor;
@@ -1030,10 +1050,10 @@ void input_release_device(struct input_h
int input_open_device(struct input_handle *);
void input_close_device(struct input_handle *);
-int input_accept_process(struct input_handle *handle, struct file *file);
int input_flush_device(struct input_handle* handle, struct file* file);
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
+void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value);
static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
{
Index: linux-2.6.17/include/linux/irq.h
===================================================================
--- linux-2.6.17.orig/include/linux/irq.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/irq.h 2006-09-14 17:27:16.000000000 +0100
@@ -47,8 +47,8 @@
#define IRQ_WAITING 0x00200000 /* IRQ not yet seen - for autodetection */
#define IRQ_LEVEL 0x00400000 /* IRQ level triggered */
#define IRQ_MASKED 0x00800000 /* IRQ masked - shouldn't be seen again */
+#define IRQ_PER_CPU 0x01000000 /* IRQ is per CPU */
#ifdef CONFIG_IRQ_PER_CPU
-# define IRQ_PER_CPU 0x01000000 /* IRQ is per CPU */
# define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
#else
# define CHECK_IRQ_PER_CPU(var) 0
@@ -58,6 +58,7 @@
#define IRQ_NOREQUEST 0x04000000 /* IRQ cannot be requested */
#define IRQ_NOAUTOEN 0x08000000 /* IRQ will not be enabled on request irq */
#define IRQ_DELAYED_DISABLE 0x10000000 /* IRQ disable (masking) happens delayed. */
+#define IRQ_WAKEUP 0x20000000 /* IRQ triggers system wakeup */
struct proc_dir_entry;
@@ -124,6 +125,7 @@ struct irq_chip {
* @action: the irq action chain
* @status: status information
* @depth: disable-depth, for nested irq_disable() calls
+ * @wake_depth: enable depth, for multiple set_irq_wake() callers
* @irq_count: stats field to detect stalled irqs
* @irqs_unhandled: stats field for spurious unhandled interrupts
* @lock: locking for SMP
@@ -147,6 +149,7 @@ struct irq_desc {
unsigned int status; /* IRQ status */
unsigned int depth; /* nested irq disables */
+ unsigned int wake_depth; /* nested wake enables */
unsigned int irq_count; /* For detecting broken IRQs */
unsigned int irqs_unhandled;
spinlock_t lock;
Index: linux-2.6.17/include/linux/jiffies.h
===================================================================
--- linux-2.6.17.orig/include/linux/jiffies.h 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/include/linux/jiffies.h 2006-09-14 17:27:16.000000000 +0100
@@ -47,8 +47,8 @@
* - (NOM / DEN) fits in (32 - LSH) bits.
* - (NOM % DEN) fits in (32 - LSH) bits.
*/
-#define SH_DIV(NOM,DEN,LSH) ( ((NOM / DEN) << LSH) \
- + (((NOM % DEN) << LSH) + DEN / 2) / DEN)
+#define SH_DIV(NOM,DEN,LSH) ( (((NOM) / (DEN)) << (LSH)) \
+ + ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN))
/* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */
#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8))
Index: linux-2.6.17/include/linux/kobject.h
===================================================================
--- linux-2.6.17.orig/include/linux/kobject.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/kobject.h 2006-09-14 17:27:16.000000000 +0100
@@ -46,8 +46,6 @@ enum kobject_action {
KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices (broken) */
KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* device offline */
KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* device online */
- KOBJ_UNDOCK = (__force kobject_action_t) 0x08, /* undocking */
- KOBJ_DOCK = (__force kobject_action_t) 0x09, /* dock */
};
struct kobject {
Index: linux-2.6.17/include/linux/lockd/lockd.h
===================================================================
--- linux-2.6.17.orig/include/linux/lockd/lockd.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/lockd/lockd.h 2006-09-14 17:27:16.000000000 +0100
@@ -123,7 +123,6 @@ struct nlm_block {
unsigned int b_id; /* block id */
unsigned char b_queued; /* re-queued */
unsigned char b_granted; /* VFS granted lock */
- unsigned char b_done; /* callback complete */
struct nlm_file * b_file; /* file in question */
};
Index: linux-2.6.17/include/linux/netfilter_bridge.h
===================================================================
--- linux-2.6.17.orig/include/linux/netfilter_bridge.h 2006-09-14 17:25:56.000000000 +0100
+++ linux-2.6.17/include/linux/netfilter_bridge.h 2006-09-14 17:27:16.000000000 +0100
@@ -6,7 +6,6 @@
#include
#if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER)
-#include
#include
#endif
Index: linux-2.6.17/include/linux/nfs_fs.h
===================================================================
--- linux-2.6.17.orig/include/linux/nfs_fs.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/nfs_fs.h 2006-09-14 17:27:17.000000000 +0100
@@ -476,10 +476,9 @@ static inline int nfs_wb_page(struct ino
}
/*
- * Allocate and free nfs_write_data structures
+ * Allocate nfs_write_data structures
*/
extern struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount);
-extern void nfs_writedata_free(struct nfs_write_data *p);
/*
* linux/fs/nfs/read.c
@@ -491,10 +490,9 @@ extern int nfs_readpage_result(struct r
extern void nfs_readdata_release(void *data);
/*
- * Allocate and free nfs_read_data structures
+ * Allocate nfs_read_data structures
*/
extern struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount);
-extern void nfs_readdata_free(struct nfs_read_data *p);
/*
* linux/fs/nfs3proc.c
Index: linux-2.6.17/include/linux/pci_ids.h
===================================================================
--- linux-2.6.17.orig/include/linux/pci_ids.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/pci_ids.h 2006-09-14 17:27:17.000000000 +0100
@@ -2142,6 +2142,7 @@
#define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501
#define PCI_DEVICE_ID_INTEL_82850_HB 0x2530
#define PCI_DEVICE_ID_INTEL_82860_HB 0x2531
+#define PCI_DEVICE_ID_INTEL_E7501_MCH 0x254c
#define PCI_DEVICE_ID_INTEL_82845G_HB 0x2560
#define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562
#define PCI_DEVICE_ID_INTEL_82865_HB 0x2570
Index: linux-2.6.17/include/linux/pmu.h
===================================================================
--- linux-2.6.17.orig/include/linux/pmu.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/pmu.h 2006-09-14 17:27:17.000000000 +0100
@@ -231,7 +231,6 @@ extern struct pmu_battery_info pmu_batte
extern unsigned int pmu_power_flags;
/* Backlight */
-extern int disable_kernel_backlight;
-extern void pmu_backlight_init(struct device_node*);
+extern void pmu_backlight_init(void);
#endif /* __KERNEL__ */
Index: linux-2.6.17/include/linux/sched.h
===================================================================
--- linux-2.6.17.orig/include/linux/sched.h 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/include/linux/sched.h 2006-09-14 17:27:17.000000000 +0100
@@ -1558,6 +1558,14 @@ static inline void freeze(struct task_st
}
/*
+ * Sometimes we may need to cancel the previous 'freeze' request
+ */
+static inline void do_not_freeze(struct task_struct *p)
+{
+ p->flags &= ~PF_FREEZE;
+}
+
+/*
* Wake up a frozen process
*/
static inline int thaw_process(struct task_struct *p)
Index: linux-2.6.17/include/linux/security.h
===================================================================
--- linux-2.6.17.orig/include/linux/security.h 2006-09-14 16:26:43.000000000 +0100
+++ linux-2.6.17/include/linux/security.h 2006-09-14 17:27:17.000000000 +0100
@@ -1109,6 +1109,16 @@ struct swap_info_struct;
* @name contains the name of the security module being unstacked.
* @ops contains a pointer to the struct security_operations of the module to unstack.
*
+ * @secid_to_secctx:
+ * Convert secid to security context.
+ * @secid contains the security ID.
+ * @secdata contains the pointer that stores the converted security context.
+ *
+ * @release_secctx:
+ * Release the security context.
+ * @secdata contains the security context.
+ * @seclen contains the length of the security context.
+ *
* This is the main security structure.
*/
struct security_operations {
@@ -1289,6 +1299,8 @@ struct security_operations {
int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size);
int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size);
+ int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen);
+ void (*release_secctx)(char *secdata, u32 seclen);
#ifdef CONFIG_SECURITY_NETWORK
int (*unix_stream_connect) (struct socket * sock,
@@ -1317,7 +1329,7 @@ struct security_operations {
int (*socket_shutdown) (struct socket * sock, int how);
int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);
int (*socket_getpeersec_stream) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
- int (*socket_getpeersec_dgram) (struct sk_buff *skb, char **secdata, u32 *seclen);
+ int (*socket_getpeersec_dgram) (struct socket *sock, struct sk_buff *skb, u32 *secid);
int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
void (*sk_free_security) (struct sock *sk);
unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir);
@@ -2059,6 +2071,16 @@ static inline int security_netlink_recv(
return security_ops->netlink_recv(skb, cap);
}
+static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+{
+ return security_ops->secid_to_secctx(secid, secdata, seclen);
+}
+
+static inline void security_release_secctx(char *secdata, u32 seclen)
+{
+ return security_ops->release_secctx(secdata, seclen);
+}
+
/* prototypes */
extern int security_init (void);
extern int register_security (struct security_operations *ops);
@@ -2725,6 +2747,14 @@ static inline void securityfs_remove(str
{
}
+static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void security_release_secctx(char *secdata, u32 seclen)
+{
+}
#endif /* CONFIG_SECURITY */
#ifdef CONFIG_SECURITY_NETWORK
@@ -2840,10 +2870,9 @@ static inline int security_socket_getpee
return security_ops->socket_getpeersec_stream(sock, optval, optlen, len);
}
-static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata,
- u32 *seclen)
+static inline int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
{
- return security_ops->socket_getpeersec_dgram(skb, secdata, seclen);
+ return security_ops->socket_getpeersec_dgram(sock, skb, secid);
}
static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
@@ -2968,8 +2997,7 @@ static inline int security_socket_getpee
return -ENOPROTOOPT;
}
-static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata,
- u32 *seclen)
+static inline int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
{
return -ENOPROTOOPT;
}
Index: linux-2.6.17/include/linux/skbuff.h
===================================================================
--- linux-2.6.17.orig/include/linux/skbuff.h 2006-09-14 17:25:56.000000000 +0100
+++ linux-2.6.17/include/linux/skbuff.h 2006-09-14 17:27:17.000000000 +0100
@@ -604,12 +604,17 @@ static inline __u32 skb_queue_len(const
return list_->qlen;
}
-extern struct lock_class_key skb_queue_lock_key;
-
+/*
+ * This function creates a split out lock class for each invocation;
+ * this is needed for now since a whole lot of users of the skb-queue
+ * infrastructure in drivers have different locking usage (in hardirq)
+ * than the networking core (in softirq only). In the long run either the
+ * network layer or drivers should need annotation to consolidate the
+ * main types of usage into 3 classes.
+ */
static inline void skb_queue_head_init(struct sk_buff_head *list)
{
spin_lock_init(&list->lock);
- lockdep_set_class(&list->lock, &skb_queue_lock_key);
list->prev = list->next = (struct sk_buff *)list;
list->qlen = 0;
}
@@ -1104,6 +1109,28 @@ static inline struct sk_buff *dev_alloc_
return __dev_alloc_skb(length, GFP_ATOMIC);
}
+extern struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
+ unsigned int length, gfp_t gfp_mask);
+
+/**
+ * netdev_alloc_skb - allocate an skbuff for rx on a specific device
+ * @dev: network device to receive on
+ * @length: length to allocate
+ *
+ * Allocate a new &sk_buff and assign it a usage count of one. The
+ * buffer has unspecified headroom built in. Users should allocate
+ * the headroom they think they need without accounting for the
+ * built in space. The built in space is used for optimisations.
+ *
+ * %NULL is returned if there is no free memory. Although this function
+ * allocates memory it can be called from an interrupt.
+ */
+static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev,
+ unsigned int length)
+{
+ return __netdev_alloc_skb(dev, length, GFP_ATOMIC);
+}
+
/**
* skb_cow - copy header of skb when it is required
* @skb: buffer to cow
Index: linux-2.6.17/include/linux/sunrpc/xprt.h
===================================================================
--- linux-2.6.17.orig/include/linux/sunrpc/xprt.h 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/include/linux/sunrpc/xprt.h 2006-09-14 17:27:17.000000000 +0100
@@ -229,7 +229,7 @@ int xprt_reserve_xprt(struct rpc_task
int xprt_reserve_xprt_cong(struct rpc_task *task);
int xprt_prepare_transmit(struct rpc_task *task);
void xprt_transmit(struct rpc_task *task);
-void xprt_abort_transmit(struct rpc_task *task);
+void xprt_end_transmit(struct rpc_task *task);
int xprt_adjust_timeout(struct rpc_rqst *req);
void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
Index: linux-2.6.17/include/linux/usb.h
===================================================================
--- linux-2.6.17.orig/include/linux/usb.h 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/include/linux/usb.h 2006-09-14 17:27:17.000000000 +0100
@@ -103,8 +103,7 @@ enum usb_interface_condition {
* @condition: binding state of the interface: not bound, binding
* (in probe()), bound to a driver, or unbinding (in disconnect())
* @dev: driver model's view of this device
- * @usb_dev: if an interface is bound to the USB major, this will point
- * to the sysfs representation for that device.
+ * @class_dev: driver model's class view of this device.
*
* USB device drivers attach to interfaces on a physical device. Each
* interface encapsulates a single high level function, such as feeding
@@ -144,7 +143,7 @@ struct usb_interface {
* bound to */
enum usb_interface_condition condition; /* state of binding */
struct device dev; /* interface specific device info */
- struct device *usb_dev; /* pointer to the usb class's device, if any */
+ struct class_device *class_dev;
};
#define to_usb_interface(d) container_of(d, struct usb_interface, dev)
#define interface_to_usbdev(intf) \
@@ -361,7 +360,7 @@ struct usb_device {
char *serial; /* iSerialNumber string, if present */
struct list_head filelist;
- struct device *usbfs_dev;
+ struct class_device *class_dev;
struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
/*
Index: linux-2.6.17/include/linux/usb_usual.h
===================================================================
--- linux-2.6.17.orig/include/linux/usb_usual.h 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/include/linux/usb_usual.h 2006-09-14 17:27:17.000000000 +0100
@@ -44,7 +44,9 @@
US_FLAG(NO_WP_DETECT, 0x00000200) \
/* Don't check for write-protect */ \
US_FLAG(MAX_SECTORS_64, 0x00000400) \
- /* Sets max_sectors to 64 */
+ /* Sets max_sectors to 64 */ \
+ US_FLAG(IGNORE_DEVICE, 0x00000800) \
+ /* Don't claim device */
#define US_FLAG(name, value) US_FL_##name = value ,
enum { US_DO_ALL_FLAGS };
Index: linux-2.6.17/include/linux/videodev.h
===================================================================
--- linux-2.6.17.orig/include/linux/videodev.h 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/include/linux/videodev.h 2006-09-14 17:27:17.000000000 +0100
@@ -12,10 +12,11 @@
#ifndef __LINUX_VIDEODEV_H
#define __LINUX_VIDEODEV_H
-#define HAVE_V4L1 1
-
#include
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+#define HAVE_V4L1 1
+
struct video_capability
{
char name[32];
@@ -336,6 +337,8 @@ struct video_code
#define VID_HARDWARE_SN9C102 38
#define VID_HARDWARE_ARV 39
+#endif /* CONFIG_VIDEO_V4L1_COMPAT */
+
#endif /* __LINUX_VIDEODEV_H */
/*
Index: linux-2.6.17/include/linux/videodev2.h
===================================================================
--- linux-2.6.17.orig/include/linux/videodev2.h 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/include/linux/videodev2.h 2006-09-14 17:27:17.000000000 +0100
@@ -716,7 +716,7 @@ struct v4l2_ext_control
__s64 value64;
void *reserved;
};
-};
+} __attribute__ ((packed));
struct v4l2_ext_controls
{
Index: linux-2.6.17/include/linux/vmstat.h
===================================================================
--- linux-2.6.17.orig/include/linux/vmstat.h 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/include/linux/vmstat.h 2006-09-14 17:27:17.000000000 +0100
@@ -41,23 +41,23 @@ DECLARE_PER_CPU(struct vm_event_state, v
static inline void __count_vm_event(enum vm_event_item item)
{
- __get_cpu_var(vm_event_states.event[item])++;
+ __get_cpu_var(vm_event_states).event[item]++;
}
static inline void count_vm_event(enum vm_event_item item)
{
- get_cpu_var(vm_event_states.event[item])++;
+ get_cpu_var(vm_event_states).event[item]++;
put_cpu();
}
static inline void __count_vm_events(enum vm_event_item item, long delta)
{
- __get_cpu_var(vm_event_states.event[item]) += delta;
+ __get_cpu_var(vm_event_states).event[item] += delta;
}
static inline void count_vm_events(enum vm_event_item item, long delta)
{
- get_cpu_var(vm_event_states.event[item]) += delta;
+ get_cpu_var(vm_event_states).event[item] += delta;
put_cpu();
}
Index: linux-2.6.17/include/media/v4l2-dev.h
===================================================================
--- linux-2.6.17.orig/include/media/v4l2-dev.h 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/include/media/v4l2-dev.h 2006-09-14 17:27:17.000000000 +0100
@@ -341,11 +341,14 @@ extern int video_usercopy(struct inode *
extern struct video_device* video_devdata(struct file*);
#define to_video_device(cd) container_of(cd, struct video_device, class_dev)
-static inline void
+static inline int
video_device_create_file(struct video_device *vfd,
struct class_device_attribute *attr)
{
- class_device_create_file(&vfd->class_dev, attr);
+ int ret = class_device_create_file(&vfd->class_dev, attr);
+ if (ret < 0)
+ printk(KERN_WARNING "%s error: %d\n", __FUNCTION__, ret);
+ return ret;
}
static inline void
video_device_remove_file(struct video_device *vfd,
Index: linux-2.6.17/include/net/af_unix.h
===================================================================
--- linux-2.6.17.orig/include/net/af_unix.h 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/include/net/af_unix.h 2006-09-14 17:27:17.000000000 +0100
@@ -54,15 +54,13 @@ struct unix_skb_parms {
struct ucred creds; /* Skb credentials */
struct scm_fp_list *fp; /* Passed files */
#ifdef CONFIG_SECURITY_NETWORK
- char *secdata; /* Security context */
- u32 seclen; /* Security length */
+ u32 secid; /* Security ID */
#endif
};
#define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb))
#define UNIXCREDS(skb) (&UNIXCB((skb)).creds)
-#define UNIXSECDATA(skb) (&UNIXCB((skb)).secdata)
-#define UNIXSECLEN(skb) (&UNIXCB((skb)).seclen)
+#define UNIXSID(skb) (&UNIXCB((skb)).secid)
#define unix_state_rlock(s) spin_lock(&unix_sk(s)->lock)
#define unix_state_runlock(s) spin_unlock(&unix_sk(s)->lock)
Index: linux-2.6.17/include/net/ip6_route.h
===================================================================
--- linux-2.6.17.orig/include/net/ip6_route.h 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/include/net/ip6_route.h 2006-09-14 17:27:17.000000000 +0100
@@ -139,16 +139,22 @@ extern rwlock_t rt6_lock;
/*
* Store a destination cache entry in a socket
*/
-static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
- struct in6_addr *daddr)
+static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst,
+ struct in6_addr *daddr)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct rt6_info *rt = (struct rt6_info *) dst;
- write_lock(&sk->sk_dst_lock);
sk_setup_caps(sk, dst);
np->daddr_cache = daddr;
np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
+}
+
+static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
+ struct in6_addr *daddr)
+{
+ write_lock(&sk->sk_dst_lock);
+ __ip6_dst_store(sk, dst, daddr);
write_unlock(&sk->sk_dst_lock);
}
Index: linux-2.6.17/include/net/ipv6.h
===================================================================
--- linux-2.6.17.orig/include/net/ipv6.h 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/include/net/ipv6.h 2006-09-14 17:27:17.000000000 +0100
@@ -468,6 +468,9 @@ extern void ip6_flush_pending_frames(s
extern int ip6_dst_lookup(struct sock *sk,
struct dst_entry **dst,
struct flowi *fl);
+extern int ip6_sk_dst_lookup(struct sock *sk,
+ struct dst_entry **dst,
+ struct flowi *fl);
/*
* skb processing functions
Index: linux-2.6.17/include/net/netdma.h
===================================================================
--- linux-2.6.17.orig/include/net/netdma.h 2006-09-14 17:25:56.000000000 +0100
+++ linux-2.6.17/include/net/netdma.h 2006-09-14 17:27:17.000000000 +0100
@@ -29,7 +29,7 @@ static inline struct dma_chan *get_softn
{
struct dma_chan *chan;
rcu_read_lock();
- chan = rcu_dereference(__get_cpu_var(softnet_data.net_dma));
+ chan = rcu_dereference(__get_cpu_var(softnet_data).net_dma);
if (chan)
dma_chan_get(chan);
rcu_read_unlock();
Index: linux-2.6.17/include/net/netevent.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.17/include/net/netevent.h 2006-09-14 17:27:17.000000000 +0100
@@ -0,0 +1,33 @@
+#ifndef _NET_EVENT_H
+#define _NET_EVENT_H
+
+/*
+ * Generic netevent notifiers
+ *
+ * Authors:
+ * Tom Tucker
+ * Steve Wise
+ *
+ * Changes:
+ */
+#ifdef __KERNEL__
+
+#include
+
+struct netevent_redirect {
+ struct dst_entry *old;
+ struct dst_entry *new;
+};
+
+enum netevent_notif_type {
+ NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */
+ NETEVENT_PMTU_UPDATE, /* arg is struct dst_entry ptr */
+ NETEVENT_REDIRECT, /* arg is struct netevent_redirect ptr */
+};
+
+extern int register_netevent_notifier(struct notifier_block *nb);
+extern int unregister_netevent_notifier(struct notifier_block *nb);
+extern int call_netevent_notifiers(unsigned long val, void *v);
+
+#endif
+#endif
Index: linux-2.6.17/include/net/red.h
===================================================================
--- linux-2.6.17.orig/include/net/red.h 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/include/net/red.h 2006-09-14 17:27:17.000000000 +0100
@@ -212,7 +212,7 @@ static inline unsigned long red_calc_qav
* Seems, it is the best solution to
* problem of too coarse exponent tabulation.
*/
- us_idle = (p->qavg * us_idle) >> p->Scell_log;
+ us_idle = (p->qavg * (u64)us_idle) >> p->Scell_log;
if (us_idle < (p->qavg >> 1))
return p->qavg - us_idle;
Index: linux-2.6.17/include/net/scm.h
===================================================================
--- linux-2.6.17.orig/include/net/scm.h 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/include/net/scm.h 2006-09-14 17:27:17.000000000 +0100
@@ -3,6 +3,7 @@
#include
#include
+#include
/* Well, we should have at least one descriptor open
* to accept passed FDs 8)
@@ -20,8 +21,7 @@ struct scm_cookie
struct ucred creds; /* Skb credentials */
struct scm_fp_list *fp; /* Passed files */
#ifdef CONFIG_SECURITY_NETWORK
- char *secdata; /* Security context */
- u32 seclen; /* Security length */
+ u32 secid; /* Passed security ID */
#endif
unsigned long seq; /* Connection seqno */
};
@@ -32,6 +32,16 @@ extern int __scm_send(struct socket *soc
extern void __scm_destroy(struct scm_cookie *scm);
extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
+#ifdef CONFIG_SECURITY_NETWORK
+static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
+{
+ security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
+}
+#else
+static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
+{ }
+#endif /* CONFIG_SECURITY_NETWORK */
+
static __inline__ void scm_destroy(struct scm_cookie *scm)
{
if (scm && scm->fp)
@@ -47,6 +57,7 @@ static __inline__ int scm_send(struct so
scm->creds.pid = p->tgid;
scm->fp = NULL;
scm->seq = 0;
+ unix_get_peersec_dgram(sock, scm);
if (msg->msg_controllen <= 0)
return 0;
return __scm_send(sock, msg, scm);
@@ -55,8 +66,18 @@ static __inline__ int scm_send(struct so
#ifdef CONFIG_SECURITY_NETWORK
static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
{
- if (test_bit(SOCK_PASSSEC, &sock->flags) && scm->secdata != NULL)
- put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, scm->seclen, scm->secdata);
+ char *secdata;
+ u32 seclen;
+ int err;
+
+ if (test_bit(SOCK_PASSSEC, &sock->flags)) {
+ err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
+
+ if (!err) {
+ put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
+ security_release_secctx(secdata, seclen);
+ }
+ }
}
#else
static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
Index: linux-2.6.17/include/net/tcp.h
===================================================================
--- linux-2.6.17.orig/include/net/tcp.h 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/include/net/tcp.h 2006-09-14 17:27:17.000000000 +0100
@@ -914,6 +914,9 @@ static inline void tcp_set_state(struct
static inline void tcp_done(struct sock *sk)
{
+ if(sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV)
+ TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
+
tcp_set_state(sk, TCP_CLOSE);
tcp_clear_xmit_timers(sk);
Index: linux-2.6.17/ipc/msg.c
===================================================================
--- linux-2.6.17.orig/ipc/msg.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/ipc/msg.c 2006-09-14 17:27:17.000000000 +0100
@@ -1,6 +1,6 @@
/*
* linux/ipc/msg.c
- * Copyright (C) 1992 Krishna Balasubramanian
+ * Copyright (C) 1992 Krishna Balasubramanian
*
* Removed all the remaining kerneld mess
* Catch the -EFAULT stuff properly
@@ -41,22 +41,24 @@ int msg_ctlmax = MSGMAX;
int msg_ctlmnb = MSGMNB;
int msg_ctlmni = MSGMNI;
-/* one msg_receiver structure for each sleeping receiver */
+/*
+ * one msg_receiver structure for each sleeping receiver:
+ */
struct msg_receiver {
- struct list_head r_list;
- struct task_struct* r_tsk;
+ struct list_head r_list;
+ struct task_struct *r_tsk;
- int r_mode;
- long r_msgtype;
- long r_maxsize;
+ int r_mode;
+ long r_msgtype;
+ long r_maxsize;
- struct msg_msg* volatile r_msg;
+ volatile struct msg_msg *r_msg;
};
/* one msg_sender for each sleeping sender */
struct msg_sender {
- struct list_head list;
- struct task_struct* tsk;
+ struct list_head list;
+ struct task_struct *tsk;
};
#define SEARCH_ANY 1
@@ -64,45 +66,42 @@ struct msg_sender {
#define SEARCH_NOTEQUAL 3
#define SEARCH_LESSEQUAL 4
-static atomic_t msg_bytes = ATOMIC_INIT(0);
-static atomic_t msg_hdrs = ATOMIC_INIT(0);
+static atomic_t msg_bytes = ATOMIC_INIT(0);
+static atomic_t msg_hdrs = ATOMIC_INIT(0);
static struct ipc_ids msg_ids;
-#define msg_lock(id) ((struct msg_queue*)ipc_lock(&msg_ids,id))
-#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
-#define msg_rmid(id) ((struct msg_queue*)ipc_rmid(&msg_ids,id))
-#define msg_checkid(msq, msgid) \
- ipc_checkid(&msg_ids,&msq->q_perm,msgid)
-#define msg_buildid(id, seq) \
- ipc_buildid(&msg_ids, id, seq)
+#define msg_lock(id) ((struct msg_queue *)ipc_lock(&msg_ids, id))
+#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
+#define msg_rmid(id) ((struct msg_queue *)ipc_rmid(&msg_ids, id))
+#define msg_checkid(msq, msgid) ipc_checkid(&msg_ids, &msq->q_perm, msgid)
+#define msg_buildid(id, seq) ipc_buildid(&msg_ids, id, seq)
-static void freeque (struct msg_queue *msq, int id);
-static int newque (key_t key, int msgflg);
+static void freeque(struct msg_queue *msq, int id);
+static int newque(key_t key, int msgflg);
#ifdef CONFIG_PROC_FS
static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
#endif
-void __init msg_init (void)
+void __init msg_init(void)
{
- ipc_init_ids(&msg_ids,msg_ctlmni);
+ ipc_init_ids(&msg_ids, msg_ctlmni);
ipc_init_proc_interface("sysvipc/msg",
" key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
&msg_ids,
sysvipc_msg_proc_show);
}
-static int newque (key_t key, int msgflg)
+static int newque(key_t key, int msgflg)
{
- int id;
- int retval;
struct msg_queue *msq;
+ int id, retval;
- msq = ipc_rcu_alloc(sizeof(*msq));
- if (!msq)
+ msq = ipc_rcu_alloc(sizeof(*msq));
+ if (!msq)
return -ENOMEM;
- msq->q_perm.mode = (msgflg & S_IRWXUGO);
+ msq->q_perm.mode = msgflg & S_IRWXUGO;
msq->q_perm.key = key;
msq->q_perm.security = NULL;
@@ -113,13 +112,13 @@ static int newque (key_t key, int msgflg
}
id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni);
- if(id == -1) {
+ if (id == -1) {
security_msg_queue_free(msq);
ipc_rcu_putref(msq);
return -ENOSPC;
}
- msq->q_id = msg_buildid(id,msq->q_perm.seq);
+ msq->q_id = msg_buildid(id, msq->q_perm.seq);
msq->q_stime = msq->q_rtime = 0;
msq->q_ctime = get_seconds();
msq->q_cbytes = msq->q_qnum = 0;
@@ -133,44 +132,44 @@ static int newque (key_t key, int msgflg
return msq->q_id;
}
-static inline void ss_add(struct msg_queue* msq, struct msg_sender* mss)
+static inline void ss_add(struct msg_queue *msq, struct msg_sender *mss)
{
- mss->tsk=current;
- current->state=TASK_INTERRUPTIBLE;
- list_add_tail(&mss->list,&msq->q_senders);
+ mss->tsk = current;
+ current->state = TASK_INTERRUPTIBLE;
+ list_add_tail(&mss->list, &msq->q_senders);
}
-static inline void ss_del(struct msg_sender* mss)
+static inline void ss_del(struct msg_sender *mss)
{
- if(mss->list.next != NULL)
+ if (mss->list.next != NULL)
list_del(&mss->list);
}
-static void ss_wakeup(struct list_head* h, int kill)
+static void ss_wakeup(struct list_head *h, int kill)
{
struct list_head *tmp;
tmp = h->next;
while (tmp != h) {
- struct msg_sender* mss;
-
- mss = list_entry(tmp,struct msg_sender,list);
+ struct msg_sender *mss;
+
+ mss = list_entry(tmp, struct msg_sender, list);
tmp = tmp->next;
- if(kill)
- mss->list.next=NULL;
+ if (kill)
+ mss->list.next = NULL;
wake_up_process(mss->tsk);
}
}
-static void expunge_all(struct msg_queue* msq, int res)
+static void expunge_all(struct msg_queue *msq, int res)
{
struct list_head *tmp;
tmp = msq->q_receivers.next;
while (tmp != &msq->q_receivers) {
- struct msg_receiver* msr;
-
- msr = list_entry(tmp,struct msg_receiver,r_list);
+ struct msg_receiver *msr;
+
+ msr = list_entry(tmp, struct msg_receiver, r_list);
tmp = tmp->next;
msr->r_msg = NULL;
wake_up_process(msr->r_tsk);
@@ -178,26 +177,28 @@ static void expunge_all(struct msg_queue
msr->r_msg = ERR_PTR(res);
}
}
-/*
- * freeque() wakes up waiters on the sender and receiver waiting queue,
- * removes the message queue from message queue ID
+
+/*
+ * freeque() wakes up waiters on the sender and receiver waiting queue,
+ * removes the message queue from message queue ID
* array, and cleans up all the messages associated with this queue.
*
* msg_ids.mutex and the spinlock for this message queue is hold
* before freeque() is called. msg_ids.mutex remains locked on exit.
*/
-static void freeque (struct msg_queue *msq, int id)
+static void freeque(struct msg_queue *msq, int id)
{
struct list_head *tmp;
- expunge_all(msq,-EIDRM);
- ss_wakeup(&msq->q_senders,1);
+ expunge_all(msq, -EIDRM);
+ ss_wakeup(&msq->q_senders, 1);
msq = msg_rmid(id);
msg_unlock(msq);
-
+
tmp = msq->q_messages.next;
- while(tmp != &msq->q_messages) {
- struct msg_msg* msg = list_entry(tmp,struct msg_msg,m_list);
+ while (tmp != &msq->q_messages) {
+ struct msg_msg *msg = list_entry(tmp, struct msg_msg, m_list);
+
tmp = tmp->next;
atomic_dec(&msg_hdrs);
free_msg(msg);
@@ -207,10 +208,10 @@ static void freeque (struct msg_queue *m
ipc_rcu_putref(msq);
}
-asmlinkage long sys_msgget (key_t key, int msgflg)
+asmlinkage long sys_msgget(key_t key, int msgflg)
{
- int id, ret = -EPERM;
struct msg_queue *msq;
+ int id, ret = -EPERM;
mutex_lock(&msg_ids.mutex);
if (key == IPC_PRIVATE)
@@ -224,31 +225,34 @@ asmlinkage long sys_msgget (key_t key, i
ret = -EEXIST;
} else {
msq = msg_lock(id);
- BUG_ON(msq==NULL);
+ BUG_ON(msq == NULL);
if (ipcperms(&msq->q_perm, msgflg))
ret = -EACCES;
else {
int qid = msg_buildid(id, msq->q_perm.seq);
- ret = security_msg_queue_associate(msq, msgflg);
+
+ ret = security_msg_queue_associate(msq, msgflg);
if (!ret)
ret = qid;
}
msg_unlock(msq);
}
mutex_unlock(&msg_ids.mutex);
+
return ret;
}
-static inline unsigned long copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version)
+static inline unsigned long
+copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version)
{
switch(version) {
case IPC_64:
- return copy_to_user (buf, in, sizeof(*in));
+ return copy_to_user(buf, in, sizeof(*in));
case IPC_OLD:
- {
+ {
struct msqid_ds out;
- memset(&out,0,sizeof(out));
+ memset(&out, 0, sizeof(out));
ipc64_perm_to_ipc_perm(&in->msg_perm, &out.msg_perm);
@@ -256,18 +260,18 @@ static inline unsigned long copy_msqid_t
out.msg_rtime = in->msg_rtime;
out.msg_ctime = in->msg_ctime;
- if(in->msg_cbytes > USHRT_MAX)
+ if (in->msg_cbytes > USHRT_MAX)
out.msg_cbytes = USHRT_MAX;
else
out.msg_cbytes = in->msg_cbytes;
out.msg_lcbytes = in->msg_cbytes;
- if(in->msg_qnum > USHRT_MAX)
+ if (in->msg_qnum > USHRT_MAX)
out.msg_qnum = USHRT_MAX;
else
out.msg_qnum = in->msg_qnum;
- if(in->msg_qbytes > USHRT_MAX)
+ if (in->msg_qbytes > USHRT_MAX)
out.msg_qbytes = USHRT_MAX;
else
out.msg_qbytes = in->msg_qbytes;
@@ -276,8 +280,8 @@ static inline unsigned long copy_msqid_t
out.msg_lspid = in->msg_lspid;
out.msg_lrpid = in->msg_lrpid;
- return copy_to_user (buf, &out, sizeof(out));
- }
+ return copy_to_user(buf, &out, sizeof(out));
+ }
default:
return -EINVAL;
}
@@ -290,14 +294,15 @@ struct msq_setbuf {
mode_t mode;
};
-static inline unsigned long copy_msqid_from_user(struct msq_setbuf *out, void __user *buf, int version)
+static inline unsigned long
+copy_msqid_from_user(struct msq_setbuf *out, void __user *buf, int version)
{
switch(version) {
case IPC_64:
- {
+ {
struct msqid64_ds tbuf;
- if (copy_from_user (&tbuf, buf, sizeof (tbuf)))
+ if (copy_from_user(&tbuf, buf, sizeof(tbuf)))
return -EFAULT;
out->qbytes = tbuf.msg_qbytes;
@@ -306,60 +311,61 @@ static inline unsigned long copy_msqid_f
out->mode = tbuf.msg_perm.mode;
return 0;
- }
+ }
case IPC_OLD:
- {
+ {
struct msqid_ds tbuf_old;
- if (copy_from_user (&tbuf_old, buf, sizeof (tbuf_old)))
+ if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old)))
return -EFAULT;
out->uid = tbuf_old.msg_perm.uid;
out->gid = tbuf_old.msg_perm.gid;
out->mode = tbuf_old.msg_perm.mode;
- if(tbuf_old.msg_qbytes == 0)
+ if (tbuf_old.msg_qbytes == 0)
out->qbytes = tbuf_old.msg_lqbytes;
else
out->qbytes = tbuf_old.msg_qbytes;
return 0;
- }
+ }
default:
return -EINVAL;
}
}
-asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
+asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
{
- int err, version;
- struct msg_queue *msq;
- struct msq_setbuf setbuf;
struct kern_ipc_perm *ipcp;
-
+ struct msq_setbuf setbuf;
+ struct msg_queue *msq;
+ int err, version;
+
if (msqid < 0 || cmd < 0)
return -EINVAL;
version = ipc_parse_version(&cmd);
switch (cmd) {
- case IPC_INFO:
- case MSG_INFO:
- {
+ case IPC_INFO:
+ case MSG_INFO:
+ {
struct msginfo msginfo;
int max_id;
+
if (!buf)
return -EFAULT;
- /* We must not return kernel stack data.
+ /*
+ * We must not return kernel stack data.
* due to padding, it's not enough
* to set all member fields.
*/
-
err = security_msg_queue_msgctl(NULL, cmd);
if (err)
return err;
- memset(&msginfo,0,sizeof(msginfo));
+ memset(&msginfo, 0, sizeof(msginfo));
msginfo.msgmni = msg_ctlmni;
msginfo.msgmax = msg_ctlmax;
msginfo.msgmnb = msg_ctlmnb;
@@ -377,36 +383,37 @@ asmlinkage long sys_msgctl (int msqid, i
}
max_id = msg_ids.max_id;
mutex_unlock(&msg_ids.mutex);
- if (copy_to_user (buf, &msginfo, sizeof(struct msginfo)))
+ if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
return -EFAULT;
- return (max_id < 0) ? 0: max_id;
+ return (max_id < 0) ? 0 : max_id;
}
case MSG_STAT:
case IPC_STAT:
{
struct msqid64_ds tbuf;
int success_return;
+
if (!buf)
return -EFAULT;
- if(cmd == MSG_STAT && msqid >= msg_ids.entries->size)
+ if (cmd == MSG_STAT && msqid >= msg_ids.entries->size)
return -EINVAL;
- memset(&tbuf,0,sizeof(tbuf));
+ memset(&tbuf, 0, sizeof(tbuf));
msq = msg_lock(msqid);
if (msq == NULL)
return -EINVAL;
- if(cmd == MSG_STAT) {
+ if (cmd == MSG_STAT) {
success_return = msg_buildid(msqid, msq->q_perm.seq);
} else {
err = -EIDRM;
- if (msg_checkid(msq,msqid))
+ if (msg_checkid(msq, msqid))
goto out_unlock;
success_return = 0;
}
err = -EACCES;
- if (ipcperms (&msq->q_perm, S_IRUGO))
+ if (ipcperms(&msq->q_perm, S_IRUGO))
goto out_unlock;
err = security_msg_queue_msgctl(msq, cmd);
@@ -430,7 +437,7 @@ asmlinkage long sys_msgctl (int msqid, i
case IPC_SET:
if (!buf)
return -EFAULT;
- if (copy_msqid_from_user (&setbuf, buf, version))
+ if (copy_msqid_from_user(&setbuf, buf, version))
return -EFAULT;
break;
case IPC_RMID:
@@ -441,12 +448,12 @@ asmlinkage long sys_msgctl (int msqid, i
mutex_lock(&msg_ids.mutex);
msq = msg_lock(msqid);
- err=-EINVAL;
+ err = -EINVAL;
if (msq == NULL)
goto out_up;
err = -EIDRM;
- if (msg_checkid(msq,msqid))
+ if (msg_checkid(msq, msqid))
goto out_unlock_up;
ipcp = &msq->q_perm;
@@ -454,15 +461,16 @@ asmlinkage long sys_msgctl (int msqid, i
if (err)
goto out_unlock_up;
if (cmd==IPC_SET) {
- err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode);
+ err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid,
+ setbuf.mode);
if (err)
goto out_unlock_up;
}
err = -EPERM;
- if (current->euid != ipcp->cuid &&
+ if (current->euid != ipcp->cuid &&
current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN))
- /* We _could_ check for CAP_CHOWN above, but we don't */
+ /* We _could_ check for CAP_CHOWN above, but we don't */
goto out_unlock_up;
err = security_msg_queue_msgctl(msq, cmd);
@@ -480,22 +488,22 @@ asmlinkage long sys_msgctl (int msqid, i
ipcp->uid = setbuf.uid;
ipcp->gid = setbuf.gid;
- ipcp->mode = (ipcp->mode & ~S_IRWXUGO) |
- (S_IRWXUGO & setbuf.mode);
+ ipcp->mode = (ipcp->mode & ~S_IRWXUGO) |
+ (S_IRWXUGO & setbuf.mode);
msq->q_ctime = get_seconds();
/* sleeping receivers might be excluded by
* stricter permissions.
*/
- expunge_all(msq,-EAGAIN);
+ expunge_all(msq, -EAGAIN);
/* sleeping senders might be able to send
* due to a larger queue size.
*/
- ss_wakeup(&msq->q_senders,0);
+ ss_wakeup(&msq->q_senders, 0);
msg_unlock(msq);
break;
}
case IPC_RMID:
- freeque (msq, msqid);
+ freeque(msq, msqid);
break;
}
err = 0;
@@ -510,41 +518,44 @@ out_unlock:
return err;
}
-static int testmsg(struct msg_msg* msg,long type,int mode)
+static int testmsg(struct msg_msg *msg, long type, int mode)
{
switch(mode)
{
case SEARCH_ANY:
return 1;
case SEARCH_LESSEQUAL:
- if(msg->m_type <=type)
+ if (msg->m_type <=type)
return 1;
break;
case SEARCH_EQUAL:
- if(msg->m_type == type)
+ if (msg->m_type == type)
return 1;
break;
case SEARCH_NOTEQUAL:
- if(msg->m_type != type)
+ if (msg->m_type != type)
return 1;
break;
}
return 0;
}
-static inline int pipelined_send(struct msg_queue* msq, struct msg_msg* msg)
+static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg)
{
- struct list_head* tmp;
+ struct list_head *tmp;
tmp = msq->q_receivers.next;
while (tmp != &msq->q_receivers) {
- struct msg_receiver* msr;
- msr = list_entry(tmp,struct msg_receiver,r_list);
+ struct msg_receiver *msr;
+
+ msr = list_entry(tmp, struct msg_receiver, r_list);
tmp = tmp->next;
- if(testmsg(msg,msr->r_msgtype,msr->r_mode) &&
- !security_msg_queue_msgrcv(msq, msg, msr->r_tsk, msr->r_msgtype, msr->r_mode)) {
+ if (testmsg(msg, msr->r_msgtype, msr->r_mode) &&
+ !security_msg_queue_msgrcv(msq, msg, msr->r_tsk,
+ msr->r_msgtype, msr->r_mode)) {
+
list_del(&msr->r_list);
- if(msr->r_maxsize < msg->m_ts) {
+ if (msr->r_maxsize < msg->m_ts) {
msr->r_msg = NULL;
wake_up_process(msr->r_tsk);
smp_mb();
@@ -556,6 +567,7 @@ static inline int pipelined_send(struct
wake_up_process(msr->r_tsk);
smp_mb();
msr->r_msg = msg;
+
return 1;
}
}
@@ -563,40 +575,41 @@ static inline int pipelined_send(struct
return 0;
}
-asmlinkage long sys_msgsnd (int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg)
+asmlinkage long
+sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg)
{
struct msg_queue *msq;
struct msg_msg *msg;
long mtype;
int err;
-
+
if (msgsz > msg_ctlmax || (long) msgsz < 0 || msqid < 0)
return -EINVAL;
if (get_user(mtype, &msgp->mtype))
- return -EFAULT;
+ return -EFAULT;
if (mtype < 1)
return -EINVAL;
msg = load_msg(msgp->mtext, msgsz);
- if(IS_ERR(msg))
+ if (IS_ERR(msg))
return PTR_ERR(msg);
msg->m_type = mtype;
msg->m_ts = msgsz;
msq = msg_lock(msqid);
- err=-EINVAL;
- if(msq==NULL)
+ err = -EINVAL;
+ if (msq == NULL)
goto out_free;
err= -EIDRM;
- if (msg_checkid(msq,msqid))
+ if (msg_checkid(msq, msqid))
goto out_unlock_free;
for (;;) {
struct msg_sender s;
- err=-EACCES;
+ err = -EACCES;
if (ipcperms(&msq->q_perm, S_IWUGO))
goto out_unlock_free;
@@ -604,14 +617,14 @@ asmlinkage long sys_msgsnd (int msqid, s
if (err)
goto out_unlock_free;
- if(msgsz + msq->q_cbytes <= msq->q_qbytes &&
+ if (msgsz + msq->q_cbytes <= msq->q_qbytes &&
1 + msq->q_qnum <= msq->q_qbytes) {
break;
}
/* queue full, wait: */
- if(msgflg&IPC_NOWAIT) {
- err=-EAGAIN;
+ if (msgflg & IPC_NOWAIT) {
+ err = -EAGAIN;
goto out_unlock_free;
}
ss_add(msq, &s);
@@ -626,9 +639,9 @@ asmlinkage long sys_msgsnd (int msqid, s
goto out_unlock_free;
}
ss_del(&s);
-
+
if (signal_pending(current)) {
- err=-ERESTARTNOHAND;
+ err = -ERESTARTNOHAND;
goto out_unlock_free;
}
}
@@ -636,47 +649,47 @@ asmlinkage long sys_msgsnd (int msqid, s
msq->q_lspid = current->tgid;
msq->q_stime = get_seconds();
- if(!pipelined_send(msq,msg)) {
+ if (!pipelined_send(msq, msg)) {
/* noone is waiting for this message, enqueue it */
- list_add_tail(&msg->m_list,&msq->q_messages);
+ list_add_tail(&msg->m_list, &msq->q_messages);
msq->q_cbytes += msgsz;
msq->q_qnum++;
- atomic_add(msgsz,&msg_bytes);
+ atomic_add(msgsz, &msg_bytes);
atomic_inc(&msg_hdrs);
}
-
+
err = 0;
msg = NULL;
out_unlock_free:
msg_unlock(msq);
out_free:
- if(msg!=NULL)
+ if (msg != NULL)
free_msg(msg);
return err;
}
-static inline int convert_mode(long* msgtyp, int msgflg)
+static inline int convert_mode(long *msgtyp, int msgflg)
{
- /*
+ /*
* find message of correct type.
* msgtyp = 0 => get first.
* msgtyp > 0 => get first message of matching type.
- * msgtyp < 0 => get message with least type must be < abs(msgtype).
+ * msgtyp < 0 => get message with least type must be < abs(msgtype).
*/
- if(*msgtyp==0)
+ if (*msgtyp == 0)
return SEARCH_ANY;
- if(*msgtyp<0) {
- *msgtyp=-(*msgtyp);
+ if (*msgtyp < 0) {
+ *msgtyp = -*msgtyp;
return SEARCH_LESSEQUAL;
}
- if(msgflg & MSG_EXCEPT)
+ if (msgflg & MSG_EXCEPT)
return SEARCH_NOTEQUAL;
return SEARCH_EQUAL;
}
-asmlinkage long sys_msgrcv (int msqid, struct msgbuf __user *msgp, size_t msgsz,
- long msgtyp, int msgflg)
+asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
+ long msgtyp, int msgflg)
{
struct msg_queue *msq;
struct msg_msg *msg;
@@ -684,44 +697,51 @@ asmlinkage long sys_msgrcv (int msqid, s
if (msqid < 0 || (long) msgsz < 0)
return -EINVAL;
- mode = convert_mode(&msgtyp,msgflg);
+ mode = convert_mode(&msgtyp, msgflg);
msq = msg_lock(msqid);
- if(msq==NULL)
+ if (msq == NULL)
return -EINVAL;
msg = ERR_PTR(-EIDRM);
- if (msg_checkid(msq,msqid))
+ if (msg_checkid(msq, msqid))
goto out_unlock;
for (;;) {
struct msg_receiver msr_d;
- struct list_head* tmp;
+ struct list_head *tmp;
msg = ERR_PTR(-EACCES);
- if (ipcperms (&msq->q_perm, S_IRUGO))
+ if (ipcperms(&msq->q_perm, S_IRUGO))
goto out_unlock;
msg = ERR_PTR(-EAGAIN);
tmp = msq->q_messages.next;
while (tmp != &msq->q_messages) {
struct msg_msg *walk_msg;
- walk_msg = list_entry(tmp,struct msg_msg,m_list);
- if(testmsg(walk_msg,msgtyp,mode) &&
- !security_msg_queue_msgrcv(msq, walk_msg, current, msgtyp, mode)) {
+
+ walk_msg = list_entry(tmp, struct msg_msg, m_list);
+ if (testmsg(walk_msg, msgtyp, mode) &&
+ !security_msg_queue_msgrcv(msq, walk_msg, current,
+ msgtyp, mode)) {
+
msg = walk_msg;
- if(mode == SEARCH_LESSEQUAL && walk_msg->m_type != 1) {
- msg=walk_msg;
- msgtyp=walk_msg->m_type-1;
+ if (mode == SEARCH_LESSEQUAL &&
+ walk_msg->m_type != 1) {
+ msg = walk_msg;
+ msgtyp = walk_msg->m_type - 1;
} else {
- msg=walk_msg;
+ msg = walk_msg;
break;
}
}
tmp = tmp->next;
}
- if(!IS_ERR(msg)) {
- /* Found a suitable message. Unlink it from the queue. */
+ if (!IS_ERR(msg)) {
+ /*
+ * Found a suitable message.
+ * Unlink it from the queue.
+ */
if ((msgsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
msg = ERR_PTR(-E2BIG);
goto out_unlock;
@@ -731,9 +751,9 @@ asmlinkage long sys_msgrcv (int msqid, s
msq->q_rtime = get_seconds();
msq->q_lrpid = current->tgid;
msq->q_cbytes -= msg->m_ts;
- atomic_sub(msg->m_ts,&msg_bytes);
+ atomic_sub(msg->m_ts, &msg_bytes);
atomic_dec(&msg_hdrs);
- ss_wakeup(&msq->q_senders,0);
+ ss_wakeup(&msq->q_senders, 0);
msg_unlock(msq);
break;
}
@@ -742,13 +762,13 @@ asmlinkage long sys_msgrcv (int msqid, s
msg = ERR_PTR(-ENOMSG);
goto out_unlock;
}
- list_add_tail(&msr_d.r_list,&msq->q_receivers);
+ list_add_tail(&msr_d.r_list, &msq->q_receivers);
msr_d.r_tsk = current;
msr_d.r_msgtype = msgtyp;
msr_d.r_mode = mode;
- if(msgflg & MSG_NOERROR)
+ if (msgflg & MSG_NOERROR)
msr_d.r_maxsize = INT_MAX;
- else
+ else
msr_d.r_maxsize = msgsz;
msr_d.r_msg = ERR_PTR(-EAGAIN);
current->state = TASK_INTERRUPTIBLE;
@@ -773,17 +793,17 @@ asmlinkage long sys_msgrcv (int msqid, s
* wake_up_process(). There is a race with exit(), see
* ipc/mqueue.c for the details.
*/
- msg = (struct msg_msg*) msr_d.r_msg;
+ msg = (struct msg_msg*)msr_d.r_msg;
while (msg == NULL) {
cpu_relax();
- msg = (struct msg_msg*) msr_d.r_msg;
+ msg = (struct msg_msg *)msr_d.r_msg;
}
/* Lockless receive, part 3:
* If there is a message or an error then accept it without
* locking.
*/
- if(msg != ERR_PTR(-EAGAIN)) {
+ if (msg != ERR_PTR(-EAGAIN)) {
rcu_read_unlock();
break;
}
@@ -798,7 +818,7 @@ asmlinkage long sys_msgrcv (int msqid, s
* Repeat test after acquiring the spinlock.
*/
msg = (struct msg_msg*)msr_d.r_msg;
- if(msg != ERR_PTR(-EAGAIN))
+ if (msg != ERR_PTR(-EAGAIN))
goto out_unlock;
list_del(&msr_d.r_list);
@@ -810,14 +830,15 @@ out_unlock:
}
}
if (IS_ERR(msg))
- return PTR_ERR(msg);
+ return PTR_ERR(msg);
msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz;
if (put_user (msg->m_type, &msgp->mtype) ||
store_msg(msgp->mtext, msg, msgsz)) {
- msgsz = -EFAULT;
+ msgsz = -EFAULT;
}
free_msg(msg);
+
return msgsz;
}
@@ -827,20 +848,20 @@ static int sysvipc_msg_proc_show(struct
struct msg_queue *msq = it;
return seq_printf(s,
- "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
- msq->q_perm.key,
- msq->q_id,
- msq->q_perm.mode,
- msq->q_cbytes,
- msq->q_qnum,
- msq->q_lspid,
- msq->q_lrpid,
- msq->q_perm.uid,
- msq->q_perm.gid,
- msq->q_perm.cuid,
- msq->q_perm.cgid,
- msq->q_stime,
- msq->q_rtime,
- msq->q_ctime);
+ "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
+ msq->q_perm.key,
+ msq->q_id,
+ msq->q_perm.mode,
+ msq->q_cbytes,
+ msq->q_qnum,
+ msq->q_lspid,
+ msq->q_lrpid,
+ msq->q_perm.uid,
+ msq->q_perm.gid,
+ msq->q_perm.cuid,
+ msq->q_perm.cgid,
+ msq->q_stime,
+ msq->q_rtime,
+ msq->q_ctime);
}
#endif
Index: linux-2.6.17/kernel/audit.c
===================================================================
--- linux-2.6.17.orig/kernel/audit.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/audit.c 2006-09-14 17:27:17.000000000 +0100
@@ -690,9 +690,7 @@ static const struct inotify_operations a
/* Initialize audit support at boot time. */
static int __init audit_init(void)
{
-#ifdef CONFIG_AUDITSYSCALL
int i;
-#endif
printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
audit_default ? "enabled" : "disabled");
@@ -717,10 +715,10 @@ static int __init audit_init(void)
audit_ih = inotify_init(&audit_inotify_ops);
if (IS_ERR(audit_ih))
audit_panic("cannot initialize inotify handle");
+#endif
for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
INIT_LIST_HEAD(&audit_inode_hash[i]);
-#endif
return 0;
}
Index: linux-2.6.17/kernel/auditfilter.c
===================================================================
--- linux-2.6.17.orig/kernel/auditfilter.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/auditfilter.c 2006-09-14 17:27:17.000000000 +0100
@@ -442,6 +442,7 @@ static struct audit_entry *audit_rule_to
case AUDIT_EQUAL:
break;
default:
+ err = -EINVAL;
goto exit_free;
}
}
@@ -579,6 +580,7 @@ static struct audit_entry *audit_data_to
case AUDIT_EQUAL:
break;
default:
+ err = -EINVAL;
goto exit_free;
}
}
@@ -1134,6 +1136,14 @@ static inline int audit_add_rule(struct
struct audit_watch *watch = entry->rule.watch;
struct nameidata *ndp, *ndw;
int h, err, putnd_needed = 0;
+#ifdef CONFIG_AUDITSYSCALL
+ int dont_count = 0;
+
+ /* If either of these, don't count towards total */
+ if (entry->rule.listnr == AUDIT_FILTER_USER ||
+ entry->rule.listnr == AUDIT_FILTER_TYPE)
+ dont_count = 1;
+#endif
if (inode_f) {
h = audit_hash_ino(inode_f->val);
@@ -1174,6 +1184,10 @@ static inline int audit_add_rule(struct
} else {
list_add_tail_rcu(&entry->list, list);
}
+#ifdef CONFIG_AUDITSYSCALL
+ if (!dont_count)
+ audit_n_rules++;
+#endif
mutex_unlock(&audit_filter_mutex);
if (putnd_needed)
@@ -1198,6 +1212,14 @@ static inline int audit_del_rule(struct
struct audit_watch *watch, *tmp_watch = entry->rule.watch;
LIST_HEAD(inotify_list);
int h, ret = 0;
+#ifdef CONFIG_AUDITSYSCALL
+ int dont_count = 0;
+
+ /* If either of these, don't count towards total */
+ if (entry->rule.listnr == AUDIT_FILTER_USER ||
+ entry->rule.listnr == AUDIT_FILTER_TYPE)
+ dont_count = 1;
+#endif
if (inode_f) {
h = audit_hash_ino(inode_f->val);
@@ -1235,6 +1257,10 @@ static inline int audit_del_rule(struct
list_del_rcu(&e->list);
call_rcu(&e->rcu, audit_free_rule_rcu);
+#ifdef CONFIG_AUDITSYSCALL
+ if (!dont_count)
+ audit_n_rules--;
+#endif
mutex_unlock(&audit_filter_mutex);
if (!list_empty(&inotify_list))
Index: linux-2.6.17/kernel/auditsc.c
===================================================================
--- linux-2.6.17.orig/kernel/auditsc.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/auditsc.c 2006-09-14 17:27:17.000000000 +0100
@@ -85,6 +85,9 @@ extern int audit_enabled;
/* Indicates that audit should log the full pathname. */
#define AUDIT_NAME_FULL -1
+/* number of audit rules */
+int audit_n_rules;
+
/* When fs/namei.c:getname() is called, we store the pointer in name and
* we don't let putname() free it (instead we free all of the saved
* pointers at syscall exit time).
@@ -174,6 +177,7 @@ struct audit_aux_data_path {
/* The per-task audit context. */
struct audit_context {
+ int dummy; /* must be the first element */
int in_syscall; /* 1 if task is in a syscall */
enum audit_state state;
unsigned int serial; /* serial number for record */
@@ -514,7 +518,7 @@ static inline struct audit_context *audi
context->return_valid = return_valid;
context->return_code = return_code;
- if (context->in_syscall && !context->auditable) {
+ if (context->in_syscall && !context->dummy && !context->auditable) {
enum audit_state state;
state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
@@ -530,17 +534,7 @@ static inline struct audit_context *audi
}
get_context:
- context->pid = tsk->pid;
- context->ppid = sys_getppid(); /* sic. tsk == current in all cases */
- context->uid = tsk->uid;
- context->gid = tsk->gid;
- context->euid = tsk->euid;
- context->suid = tsk->suid;
- context->fsuid = tsk->fsuid;
- context->egid = tsk->egid;
- context->sgid = tsk->sgid;
- context->fsgid = tsk->fsgid;
- context->personality = tsk->personality;
+
tsk->audit_context = NULL;
return context;
}
@@ -749,6 +743,17 @@ static void audit_log_exit(struct audit_
const char *tty;
/* tsk == current */
+ context->pid = tsk->pid;
+ context->ppid = sys_getppid(); /* sic. tsk == current in all cases */
+ context->uid = tsk->uid;
+ context->gid = tsk->gid;
+ context->euid = tsk->euid;
+ context->suid = tsk->suid;
+ context->fsuid = tsk->fsuid;
+ context->egid = tsk->egid;
+ context->sgid = tsk->sgid;
+ context->fsgid = tsk->fsgid;
+ context->personality = tsk->personality;
ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
if (!ab)
@@ -1066,7 +1071,8 @@ void audit_syscall_entry(int arch, int m
context->argv[3] = a4;
state = context->state;
- if (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT)
+ context->dummy = !audit_n_rules;
+ if (!context->dummy && (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT))
state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
if (likely(state == AUDIT_DISABLED))
return;
@@ -1199,14 +1205,18 @@ void audit_putname(const char *name)
#endif
}
-static void audit_inode_context(int idx, const struct inode *inode)
+/* Copy inode data into an audit_names. */
+static void audit_copy_inode(struct audit_names *name, const struct inode *inode)
{
- struct audit_context *context = current->audit_context;
-
- selinux_get_inode_sid(inode, &context->names[idx].osid);
+ name->ino = inode->i_ino;
+ name->dev = inode->i_sb->s_dev;
+ name->mode = inode->i_mode;
+ name->uid = inode->i_uid;
+ name->gid = inode->i_gid;
+ name->rdev = inode->i_rdev;
+ selinux_get_inode_sid(inode, &name->osid);
}
-
/**
* audit_inode - store the inode and device from a lookup
* @name: name being audited
@@ -1240,20 +1250,14 @@ void __audit_inode(const char *name, con
++context->ino_count;
#endif
}
- context->names[idx].ino = inode->i_ino;
- context->names[idx].dev = inode->i_sb->s_dev;
- context->names[idx].mode = inode->i_mode;
- context->names[idx].uid = inode->i_uid;
- context->names[idx].gid = inode->i_gid;
- context->names[idx].rdev = inode->i_rdev;
- audit_inode_context(idx, inode);
+ audit_copy_inode(&context->names[idx], inode);
}
/**
* audit_inode_child - collect inode info for created/removed objects
* @dname: inode's dentry name
* @inode: inode being audited
- * @pino: inode number of dentry parent
+ * @parent: inode of dentry parent
*
* For syscalls that create or remove filesystem objects, audit_inode
* can only collect information for the filesystem object's parent.
@@ -1264,7 +1268,7 @@ void __audit_inode(const char *name, con
* unsuccessful attempts.
*/
void __audit_inode_child(const char *dname, const struct inode *inode,
- unsigned long pino)
+ const struct inode *parent)
{
int idx;
struct audit_context *context = current->audit_context;
@@ -1278,7 +1282,7 @@ void __audit_inode_child(const char *dna
if (!dname)
goto update_context;
for (idx = 0; idx < context->name_count; idx++)
- if (context->names[idx].ino == pino) {
+ if (context->names[idx].ino == parent->i_ino) {
const char *name = context->names[idx].name;
if (!name)
@@ -1302,16 +1306,47 @@ update_context:
context->names[idx].name_len = AUDIT_NAME_FULL;
context->names[idx].name_put = 0; /* don't call __putname() */
- if (inode) {
- context->names[idx].ino = inode->i_ino;
- context->names[idx].dev = inode->i_sb->s_dev;
- context->names[idx].mode = inode->i_mode;
- context->names[idx].uid = inode->i_uid;
- context->names[idx].gid = inode->i_gid;
- context->names[idx].rdev = inode->i_rdev;
- audit_inode_context(idx, inode);
- } else
- context->names[idx].ino = (unsigned long)-1;
+ if (!inode)
+ context->names[idx].ino = (unsigned long)-1;
+ else
+ audit_copy_inode(&context->names[idx], inode);
+
+ /* A parent was not found in audit_names, so copy the inode data for the
+ * provided parent. */
+ if (!found_name) {
+ idx = context->name_count++;
+#if AUDIT_DEBUG
+ context->ino_count++;
+#endif
+ audit_copy_inode(&context->names[idx], parent);
+ }
+}
+
+/**
+ * audit_inode_update - update inode info for last collected name
+ * @inode: inode being audited
+ *
+ * When open() is called on an existing object with the O_CREAT flag, the inode
+ * data audit initially collects is incorrect. This additional hook ensures
+ * audit has the inode data for the actual object to be opened.
+ */
+void __audit_inode_update(const struct inode *inode)
+{
+ struct audit_context *context = current->audit_context;
+ int idx;
+
+ if (!context->in_syscall || !inode)
+ return;
+
+ if (context->name_count == 0) {
+ context->name_count++;
+#if AUDIT_DEBUG
+ context->ino_count++;
+#endif
+ }
+ idx = context->name_count - 1;
+
+ audit_copy_inode(&context->names[idx], inode);
}
/**
@@ -1642,7 +1677,7 @@ int audit_bprm(struct linux_binprm *bprm
unsigned long p, next;
void *to;
- if (likely(!audit_enabled || !context))
+ if (likely(!audit_enabled || !context || context->dummy))
return 0;
ax = kmalloc(sizeof(*ax) + PAGE_SIZE * MAX_ARG_PAGES - bprm->p,
@@ -1680,7 +1715,7 @@ int audit_socketcall(int nargs, unsigned
struct audit_aux_data_socketcall *ax;
struct audit_context *context = current->audit_context;
- if (likely(!context))
+ if (likely(!context || context->dummy))
return 0;
ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL);
@@ -1708,7 +1743,7 @@ int audit_sockaddr(int len, void *a)
struct audit_aux_data_sockaddr *ax;
struct audit_context *context = current->audit_context;
- if (likely(!context))
+ if (likely(!context || context->dummy))
return 0;
ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL);
Index: linux-2.6.17/kernel/delayacct.c
===================================================================
--- linux-2.6.17.orig/kernel/delayacct.c 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/kernel/delayacct.c 2006-09-14 17:27:17.000000000 +0100
@@ -19,15 +19,15 @@
#include
#include
-int delayacct_on __read_mostly; /* Delay accounting turned on/off */
+int delayacct_on __read_mostly = 1; /* Delay accounting turned on/off */
kmem_cache_t *delayacct_cache;
-static int __init delayacct_setup_enable(char *str)
+static int __init delayacct_setup_disable(char *str)
{
- delayacct_on = 1;
+ delayacct_on = 0;
return 1;
}
-__setup("delayacct", delayacct_setup_enable);
+__setup("nodelayacct", delayacct_setup_disable);
void delayacct_init(void)
{
Index: linux-2.6.17/kernel/fork.c
===================================================================
--- linux-2.6.17.orig/kernel/fork.c 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/kernel/fork.c 2006-09-14 17:27:17.000000000 +0100
@@ -1387,8 +1387,10 @@ long do_fork(unsigned long clone_flags,
if (clone_flags & CLONE_VFORK) {
wait_for_completion(&vfork);
- if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE))
+ if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) {
+ current->ptrace_message = nr;
ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
+ }
}
} else {
free_pid(pid);
Index: linux-2.6.17/kernel/futex.c
===================================================================
--- linux-2.6.17.orig/kernel/futex.c 2006-09-14 17:25:56.000000000 +0100
+++ linux-2.6.17/kernel/futex.c 2006-09-14 17:27:17.000000000 +0100
@@ -948,6 +948,7 @@ static int unqueue_me(struct futex_q *q)
/* In the common case we don't take the spinlock, which is nice. */
retry:
lock_ptr = q->lock_ptr;
+ barrier();
if (lock_ptr != 0) {
spin_lock(lock_ptr);
/*
Index: linux-2.6.17/kernel/futex_compat.c
===================================================================
--- linux-2.6.17.orig/kernel/futex_compat.c 2006-09-14 17:25:56.000000000 +0100
+++ linux-2.6.17/kernel/futex_compat.c 2006-09-14 17:27:17.000000000 +0100
@@ -39,7 +39,7 @@ void compat_exit_robust_list(struct task
{
struct compat_robust_list_head __user *head = curr->compat_robust_list;
struct robust_list __user *entry, *pending;
- unsigned int limit = ROBUST_LIST_LIMIT, pi;
+ unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
compat_uptr_t uentry, upending;
compat_long_t futex_offset;
@@ -59,10 +59,10 @@ void compat_exit_robust_list(struct task
* if it exists:
*/
if (fetch_robust_entry(&upending, &pending,
- &head->list_op_pending, &pi))
+ &head->list_op_pending, &pip))
return;
if (upending)
- handle_futex_death((void *)pending + futex_offset, curr, pi);
+ handle_futex_death((void *)pending + futex_offset, curr, pip);
while (compat_ptr(uentry) != &head->list) {
/*
Index: linux-2.6.17/kernel/hrtimer.c
===================================================================
--- linux-2.6.17.orig/kernel/hrtimer.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/hrtimer.c 2006-09-14 17:27:17.000000000 +0100
@@ -835,7 +835,7 @@ static void migrate_hrtimers(int cpu)
}
#endif /* CONFIG_HOTPLUG_CPU */
-static int __devinit hrtimer_cpu_notify(struct notifier_block *self,
+static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
long cpu = (long)hcpu;
@@ -859,7 +859,7 @@ static int __devinit hrtimer_cpu_notify(
return NOTIFY_OK;
}
-static struct notifier_block __devinitdata hrtimers_nb = {
+static struct notifier_block __cpuinitdata hrtimers_nb = {
.notifier_call = hrtimer_cpu_notify,
};
Index: linux-2.6.17/kernel/irq/manage.c
===================================================================
--- linux-2.6.17.orig/kernel/irq/manage.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/irq/manage.c 2006-09-14 17:27:17.000000000 +0100
@@ -137,16 +137,40 @@ EXPORT_SYMBOL(enable_irq);
* @irq: interrupt to control
* @on: enable/disable power management wakeup
*
- * Enable/disable power management wakeup mode
+ * Enable/disable power management wakeup mode, which is
+ * disabled by default. Enables and disables must match,
+ * just as they match for non-wakeup mode support.
+ *
+ * Wakeup mode lets this IRQ wake the system from sleep
+ * states like "suspend to RAM".
*/
int set_irq_wake(unsigned int irq, unsigned int on)
{
struct irq_desc *desc = irq_desc + irq;
unsigned long flags;
int ret = -ENXIO;
+ int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake;
+ /* wakeup-capable irqs can be shared between drivers that
+ * don't need to have the same sleep mode behaviors.
+ */
spin_lock_irqsave(&desc->lock, flags);
- if (desc->chip->set_wake)
+ if (on) {
+ if (desc->wake_depth++ == 0)
+ desc->status |= IRQ_WAKEUP;
+ else
+ set_wake = NULL;
+ } else {
+ if (desc->wake_depth == 0) {
+ printk(KERN_WARNING "Unbalanced IRQ %d "
+ "wake disable\n", irq);
+ WARN_ON(1);
+ } else if (--desc->wake_depth == 0)
+ desc->status &= ~IRQ_WAKEUP;
+ else
+ set_wake = NULL;
+ }
+ if (set_wake)
ret = desc->chip->set_wake(irq, on);
spin_unlock_irqrestore(&desc->lock, flags);
return ret;
Index: linux-2.6.17/kernel/kprobes.c
===================================================================
--- linux-2.6.17.orig/kernel/kprobes.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/kprobes.c 2006-09-14 17:27:17.000000000 +0100
@@ -393,6 +393,7 @@ static int __kprobes add_new_kprobe(stru
static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
{
copy_kprobe(p, ap);
+ flush_insn_slot(ap);
ap->addr = p->addr;
ap->pre_handler = aggr_pre_handler;
ap->fault_handler = aggr_fault_handler;
Index: linux-2.6.17/kernel/power/process.c
===================================================================
--- linux-2.6.17.orig/kernel/power/process.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/kernel/power/process.c 2006-09-14 17:27:17.000000000 +0100
@@ -66,13 +66,25 @@ static inline void freeze_process(struct
}
}
+static void cancel_freezing(struct task_struct *p)
+{
+ unsigned long flags;
+
+ if (freezing(p)) {
+ pr_debug(" clean up: %s\n", p->comm);
+ do_not_freeze(p);
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ recalc_sigpending_tsk(p);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ }
+}
+
/* 0 = success, else # of processes that we failed to stop */
int freeze_processes(void)
{
int todo, nr_user, user_frozen;
unsigned long start_time;
struct task_struct *g, *p;
- unsigned long flags;
printk( "Stopping tasks: " );
start_time = jiffies;
@@ -85,6 +97,10 @@ int freeze_processes(void)
continue;
if (frozen(p))
continue;
+ if (p->state == TASK_TRACED && frozen(p->parent)) {
+ cancel_freezing(p);
+ continue;
+ }
if (p->mm && !(p->flags & PF_BORROWED_MM)) {
/* The task is a user-space one.
* Freeze it unless there's a vfork completion
@@ -126,13 +142,7 @@ int freeze_processes(void)
do_each_thread(g, p) {
if (freezeable(p) && !frozen(p))
printk(KERN_ERR " %s\n", p->comm);
- if (freezing(p)) {
- pr_debug(" clean up: %s\n", p->comm);
- p->flags &= ~PF_FREEZE;
- spin_lock_irqsave(&p->sighand->siglock, flags);
- recalc_sigpending_tsk(p);
- spin_unlock_irqrestore(&p->sighand->siglock, flags);
- }
+ cancel_freezing(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
return todo;
Index: linux-2.6.17/kernel/printk.c
===================================================================
--- linux-2.6.17.orig/kernel/printk.c 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/kernel/printk.c 2006-09-14 17:27:17.000000000 +0100
@@ -799,6 +799,9 @@ void release_console_sem(void)
up(&secondary_console_sem);
return;
}
+
+ console_may_schedule = 0;
+
for ( ; ; ) {
spin_lock_irqsave(&logbuf_lock, flags);
wake_klogd |= log_start - log_end;
@@ -812,7 +815,6 @@ void release_console_sem(void)
local_irq_restore(flags);
}
console_locked = 0;
- console_may_schedule = 0;
up(&console_sem);
spin_unlock_irqrestore(&logbuf_lock, flags);
if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) {
Index: linux-2.6.17/kernel/rcupdate.c
===================================================================
--- linux-2.6.17.orig/kernel/rcupdate.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/rcupdate.c 2006-09-14 17:27:17.000000000 +0100
@@ -548,7 +548,7 @@ static void __devinit rcu_online_cpu(int
tasklet_init(&per_cpu(rcu_tasklet, cpu), rcu_process_callbacks, 0UL);
}
-static int __devinit rcu_cpu_notify(struct notifier_block *self,
+static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
long cpu = (long)hcpu;
@@ -565,7 +565,7 @@ static int __devinit rcu_cpu_notify(stru
return NOTIFY_OK;
}
-static struct notifier_block __devinitdata rcu_nb = {
+static struct notifier_block __cpuinitdata rcu_nb = {
.notifier_call = rcu_cpu_notify,
};
Index: linux-2.6.17/kernel/resource.c
===================================================================
--- linux-2.6.17.orig/kernel/resource.c 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/kernel/resource.c 2006-09-14 17:27:17.000000000 +0100
@@ -244,6 +244,7 @@ int find_next_system_ram(struct resource
start = res->start;
end = res->end;
+ BUG_ON(start >= end);
read_lock(&resource_lock);
for (p = iomem_resource.child; p ; p = p->sibling) {
@@ -254,15 +255,17 @@ int find_next_system_ram(struct resource
p = NULL;
break;
}
- if (p->start >= start)
+ if ((p->end >= start) && (p->start < end))
break;
}
read_unlock(&resource_lock);
if (!p)
return -1;
/* copy data */
- res->start = p->start;
- res->end = p->end;
+ if (res->start < p->start)
+ res->start = p->start;
+ if (res->end > p->end)
+ res->end = p->end;
return 0;
}
#endif
Index: linux-2.6.17/kernel/rtmutex.c
===================================================================
--- linux-2.6.17.orig/kernel/rtmutex.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/rtmutex.c 2006-09-14 17:27:17.000000000 +0100
@@ -7,6 +7,8 @@
* Copyright (C) 2005-2006 Timesys Corp., Thomas Gleixner
* Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt
* Copyright (C) 2006 Esben Nielsen
+ *
+ * See Documentation/rt-mutex-design.txt for details.
*/
#include
#include
Index: linux-2.6.17/kernel/sched.c
===================================================================
--- linux-2.6.17.orig/kernel/sched.c 2006-09-14 17:27:09.000000000 +0100
+++ linux-2.6.17/kernel/sched.c 2006-09-14 17:27:17.000000000 +0100
@@ -4456,9 +4456,9 @@ asmlinkage long sys_sched_yield(void)
return 0;
}
-static inline int __resched_legal(void)
+static inline int __resched_legal(int expected_preempt_count)
{
- if (unlikely(preempt_count()))
+ if (unlikely(preempt_count() != expected_preempt_count))
return 0;
if (unlikely(system_state != SYSTEM_RUNNING))
return 0;
@@ -4484,7 +4484,7 @@ static void __cond_resched(void)
int __sched cond_resched(void)
{
- if (need_resched() && __resched_legal()) {
+ if (need_resched() && __resched_legal(0)) {
__cond_resched();
return 1;
}
@@ -4510,7 +4510,7 @@ int cond_resched_lock(spinlock_t *lock)
ret = 1;
spin_lock(lock);
}
- if (need_resched() && __resched_legal()) {
+ if (need_resched() && __resched_legal(1)) {
spin_release(&lock->dep_map, 1, _THIS_IP_);
_raw_spin_unlock(lock);
preempt_enable_no_resched();
@@ -4526,7 +4526,7 @@ int __sched cond_resched_softirq(void)
{
BUG_ON(!in_softirq());
- if (need_resched() && __resched_legal()) {
+ if (need_resched() && __resched_legal(0)) {
raw_local_irq_disable();
_local_bh_enable();
raw_local_irq_enable();
@@ -6494,7 +6494,12 @@ static int build_sched_domains(const cpu
for (i = 0; i < MAX_NUMNODES; i++)
init_numa_sched_groups_power(sched_group_nodes[i]);
- init_numa_sched_groups_power(sched_group_allnodes);
+ if (sched_group_allnodes) {
+ int group = cpu_to_allnodes_group(first_cpu(*cpu_map));
+ struct sched_group *sg = &sched_group_allnodes[group];
+
+ init_numa_sched_groups_power(sg);
+ }
#endif
/* Attach the domains */
@@ -6761,6 +6766,11 @@ void __init sched_init(void)
}
set_load_weight(&init_task);
+
+#ifdef CONFIG_RT_MUTEXES
+ plist_head_init(&init_task.pi_waiters, &init_task.pi_lock);
+#endif
+
/*
* The boot idle thread does lazy MMU switching as well:
*/
Index: linux-2.6.17/kernel/signal.c
===================================================================
--- linux-2.6.17.orig/kernel/signal.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/signal.c 2006-09-14 17:27:17.000000000 +0100
@@ -791,22 +791,31 @@ out:
/*
* Force a signal that the process can't ignore: if necessary
* we unblock the signal and change any SIG_IGN to SIG_DFL.
+ *
+ * Note: If we unblock the signal, we always reset it to SIG_DFL,
+ * since we do not want to have a signal handler that was blocked
+ * be invoked when user space had explicitly blocked it.
+ *
+ * We don't want to have recursive SIGSEGV's etc, for example.
*/
-
int
force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
{
unsigned long int flags;
- int ret;
+ int ret, blocked, ignored;
+ struct k_sigaction *action;
spin_lock_irqsave(&t->sighand->siglock, flags);
- if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
- t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
- }
- if (sigismember(&t->blocked, sig)) {
- sigdelset(&t->blocked, sig);
+ action = &t->sighand->action[sig-1];
+ ignored = action->sa.sa_handler == SIG_IGN;
+ blocked = sigismember(&t->blocked, sig);
+ if (blocked || ignored) {
+ action->sa.sa_handler = SIG_DFL;
+ if (blocked) {
+ sigdelset(&t->blocked, sig);
+ recalc_sigpending_tsk(t);
+ }
}
- recalc_sigpending_tsk(t);
ret = specific_send_sig_info(sig, info, t);
spin_unlock_irqrestore(&t->sighand->siglock, flags);
Index: linux-2.6.17/kernel/softirq.c
===================================================================
--- linux-2.6.17.orig/kernel/softirq.c 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/kernel/softirq.c 2006-09-14 17:27:17.000000000 +0100
@@ -65,6 +65,7 @@ static inline void wakeup_softirqd(void)
* This one is for softirq.c-internal use,
* where hardirqs are disabled legitimately:
*/
+#ifdef CONFIG_TRACE_IRQFLAGS
static void __local_bh_disable(unsigned long ip)
{
unsigned long flags;
@@ -80,6 +81,13 @@ static void __local_bh_disable(unsigned
trace_softirqs_off(ip);
raw_local_irq_restore(flags);
}
+#else /* !CONFIG_TRACE_IRQFLAGS */
+static inline void __local_bh_disable(unsigned long ip)
+{
+ add_preempt_count(SOFTIRQ_OFFSET);
+ barrier();
+}
+#endif /* CONFIG_TRACE_IRQFLAGS */
void local_bh_disable(void)
{
@@ -121,12 +129,16 @@ EXPORT_SYMBOL(_local_bh_enable);
void local_bh_enable(void)
{
+#ifdef CONFIG_TRACE_IRQFLAGS
unsigned long flags;
WARN_ON_ONCE(in_irq());
+#endif
WARN_ON_ONCE(irqs_disabled());
+#ifdef CONFIG_TRACE_IRQFLAGS
local_irq_save(flags);
+#endif
/*
* Are softirqs going to be turned on now:
*/
@@ -142,18 +154,22 @@ void local_bh_enable(void)
do_softirq();
dec_preempt_count();
+#ifdef CONFIG_TRACE_IRQFLAGS
local_irq_restore(flags);
+#endif
preempt_check_resched();
}
EXPORT_SYMBOL(local_bh_enable);
void local_bh_enable_ip(unsigned long ip)
{
+#ifdef CONFIG_TRACE_IRQFLAGS
unsigned long flags;
WARN_ON_ONCE(in_irq());
local_irq_save(flags);
+#endif
/*
* Are softirqs going to be turned on now:
*/
@@ -169,7 +185,9 @@ void local_bh_enable_ip(unsigned long ip
do_softirq();
dec_preempt_count();
+#ifdef CONFIG_TRACE_IRQFLAGS
local_irq_restore(flags);
+#endif
preempt_check_resched();
}
EXPORT_SYMBOL(local_bh_enable_ip);
@@ -547,7 +565,7 @@ static void takeover_tasklets(unsigned i
}
#endif /* CONFIG_HOTPLUG_CPU */
-static int __devinit cpu_callback(struct notifier_block *nfb,
+static int __cpuinit cpu_callback(struct notifier_block *nfb,
unsigned long action,
void *hcpu)
{
@@ -587,7 +605,7 @@ static int __devinit cpu_callback(struct
return NOTIFY_OK;
}
-static struct notifier_block __devinitdata cpu_nfb = {
+static struct notifier_block __cpuinitdata cpu_nfb = {
.notifier_call = cpu_callback
};
Index: linux-2.6.17/kernel/softlockup.c
===================================================================
--- linux-2.6.17.orig/kernel/softlockup.c 2006-09-14 17:26:46.000000000 +0100
+++ linux-2.6.17/kernel/softlockup.c 2006-09-14 17:27:17.000000000 +0100
@@ -104,7 +104,7 @@ static int watchdog(void * __bind_cpu)
/*
* Create/destroy watchdog threads as CPUs come and go:
*/
-static int __devinit
+static int __cpuinit
cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
{
int hotcpu = (unsigned long)hcpu;
@@ -142,7 +142,7 @@ cpu_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
-static struct notifier_block __devinitdata cpu_nfb = {
+static struct notifier_block __cpuinitdata cpu_nfb = {
.notifier_call = cpu_callback
};
Index: linux-2.6.17/kernel/taskstats.c
===================================================================
--- linux-2.6.17.orig/kernel/taskstats.c 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/kernel/taskstats.c 2006-09-14 17:27:17.000000000 +0100
@@ -121,46 +121,45 @@ static int send_reply(struct sk_buff *sk
/*
* Send taskstats data in @skb to listeners registered for @cpu's exit data
*/
-static int send_cpu_listeners(struct sk_buff *skb, unsigned int cpu)
+static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu)
{
struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
struct listener_list *listeners;
struct listener *s, *tmp;
struct sk_buff *skb_next, *skb_cur = skb;
void *reply = genlmsg_data(genlhdr);
- int rc, ret, delcount = 0;
+ int rc, delcount = 0;
rc = genlmsg_end(skb, reply);
if (rc < 0) {
nlmsg_free(skb);
- return rc;
+ return;
}
rc = 0;
listeners = &per_cpu(listener_array, cpu);
down_read(&listeners->sem);
- list_for_each_entry_safe(s, tmp, &listeners->list, list) {
+ list_for_each_entry(s, &listeners->list, list) {
skb_next = NULL;
if (!list_is_last(&s->list, &listeners->list)) {
skb_next = skb_clone(skb_cur, GFP_KERNEL);
- if (!skb_next) {
- nlmsg_free(skb_cur);
- rc = -ENOMEM;
+ if (!skb_next)
break;
- }
}
- ret = genlmsg_unicast(skb_cur, s->pid);
- if (ret == -ECONNREFUSED) {
+ rc = genlmsg_unicast(skb_cur, s->pid);
+ if (rc == -ECONNREFUSED) {
s->valid = 0;
delcount++;
- rc = ret;
}
skb_cur = skb_next;
}
up_read(&listeners->sem);
+ if (skb_cur)
+ nlmsg_free(skb_cur);
+
if (!delcount)
- return rc;
+ return;
/* Delete invalidated entries */
down_write(&listeners->sem);
@@ -171,13 +170,12 @@ static int send_cpu_listeners(struct sk_
}
}
up_write(&listeners->sem);
- return rc;
}
static int fill_pid(pid_t pid, struct task_struct *pidtsk,
struct taskstats *stats)
{
- int rc;
+ int rc = 0;
struct task_struct *tsk = pidtsk;
if (!pidtsk) {
@@ -196,12 +194,10 @@ static int fill_pid(pid_t pid, struct ta
* Each accounting subsystem adds calls to its functions to
* fill in relevant parts of struct taskstsats as follows
*
- * rc = per-task-foo(stats, tsk);
- * if (rc)
- * goto err;
+ * per-task-foo(stats, tsk);
*/
- rc = delayacct_add_tsk(stats, tsk);
+ delayacct_add_tsk(stats, tsk);
stats->version = TASKSTATS_VERSION;
/* Define err: label here if needed */
Index: linux-2.6.17/kernel/timer.c
===================================================================
--- linux-2.6.17.orig/kernel/timer.c 2006-09-14 17:26:46.000000000 +0100
+++ linux-2.6.17/kernel/timer.c 2006-09-14 17:27:17.000000000 +0100
@@ -84,7 +84,7 @@ typedef struct tvec_t_base_s tvec_base_t
tvec_base_t boot_tvec_bases;
EXPORT_SYMBOL(boot_tvec_bases);
-static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = { &boot_tvec_bases };
+static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = &boot_tvec_bases;
static inline void set_running_timer(tvec_base_t *base,
struct timer_list *timer)
@@ -408,7 +408,7 @@ static int cascade(tvec_base_t *base, tv
* This function cascades all vectors and executes all expired timer
* vectors.
*/
-#define INDEX(N) (base->timer_jiffies >> (TVR_BITS + N * TVN_BITS)) & TVN_MASK
+#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
static inline void __run_timers(tvec_base_t *base)
{
@@ -1688,7 +1688,7 @@ static void __devinit migrate_timers(int
}
#endif /* CONFIG_HOTPLUG_CPU */
-static int __devinit timer_cpu_notify(struct notifier_block *self,
+static int __cpuinit timer_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
long cpu = (long)hcpu;
@@ -1708,7 +1708,7 @@ static int __devinit timer_cpu_notify(st
return NOTIFY_OK;
}
-static struct notifier_block __devinitdata timers_nb = {
+static struct notifier_block __cpuinitdata timers_nb = {
.notifier_call = timer_cpu_notify,
};
Index: linux-2.6.17/kernel/workqueue.c
===================================================================
--- linux-2.6.17.orig/kernel/workqueue.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/kernel/workqueue.c 2006-09-14 17:27:17.000000000 +0100
@@ -93,9 +93,12 @@ static void __queue_work(struct cpu_work
spin_unlock_irqrestore(&cwq->lock, flags);
}
-/*
- * Queue work on a workqueue. Return non-zero if it was successfully
- * added.
+/**
+ * queue_work - queue work on a workqueue
+ * @wq: workqueue to use
+ * @work: work to queue
+ *
+ * Returns non-zero if it was successfully added.
*
* We queue the work to the CPU it was submitted, but there is no
* guarantee that it will be processed by that CPU.
@@ -128,6 +131,14 @@ static void delayed_work_timer_fn(unsign
__queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
}
+/**
+ * queue_delayed_work - queue work on a workqueue after delay
+ * @wq: workqueue to use
+ * @work: work to queue
+ * @delay: number of jiffies to wait before queueing
+ *
+ * Returns non-zero if it was successfully added.
+ */
int fastcall queue_delayed_work(struct workqueue_struct *wq,
struct work_struct *work, unsigned long delay)
{
@@ -150,6 +161,15 @@ int fastcall queue_delayed_work(struct w
}
EXPORT_SYMBOL_GPL(queue_delayed_work);
+/**
+ * queue_delayed_work_on - queue work on specific CPU after delay
+ * @cpu: CPU number to execute work on
+ * @wq: workqueue to use
+ * @work: work to queue
+ * @delay: number of jiffies to wait before queueing
+ *
+ * Returns non-zero if it was successfully added.
+ */
int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
struct work_struct *work, unsigned long delay)
{
@@ -275,8 +295,9 @@ static void flush_cpu_workqueue(struct c
}
}
-/*
+/**
* flush_workqueue - ensure that any scheduled work has run to completion.
+ * @wq: workqueue to flush
*
* Forces execution of the workqueue and blocks until its completion.
* This is typically used in driver shutdown handlers.
@@ -400,6 +421,12 @@ static void cleanup_workqueue_thread(str
kthread_stop(p);
}
+/**
+ * destroy_workqueue - safely terminate a workqueue
+ * @wq: target workqueue
+ *
+ * Safely destroy a workqueue. All work currently pending will be done first.
+ */
void destroy_workqueue(struct workqueue_struct *wq)
{
int cpu;
@@ -425,18 +452,41 @@ EXPORT_SYMBOL_GPL(destroy_workqueue);
static struct workqueue_struct *keventd_wq;
+/**
+ * schedule_work - put work task in global workqueue
+ * @work: job to be done
+ *
+ * This puts a job in the kernel-global workqueue.
+ */
int fastcall schedule_work(struct work_struct *work)
{
return queue_work(keventd_wq, work);
}
EXPORT_SYMBOL(schedule_work);
+/**
+ * schedule_delayed_work - put work task in global workqueue after delay
+ * @work: job to be done
+ * @delay: number of jiffies to wait
+ *
+ * After waiting for a given time this puts a job in the kernel-global
+ * workqueue.
+ */
int fastcall schedule_delayed_work(struct work_struct *work, unsigned long delay)
{
return queue_delayed_work(keventd_wq, work, delay);
}
EXPORT_SYMBOL(schedule_delayed_work);
+/**
+ * schedule_delayed_work_on - queue work in global workqueue on CPU after delay
+ * @cpu: cpu to use
+ * @work: job to be done
+ * @delay: number of jiffies to wait
+ *
+ * After waiting for a given time this puts a job in the kernel-global
+ * workqueue on the specified CPU.
+ */
int schedule_delayed_work_on(int cpu,
struct work_struct *work, unsigned long delay)
{
Index: linux-2.6.17/lib/kobject_uevent.c
===================================================================
--- linux-2.6.17.orig/lib/kobject_uevent.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/lib/kobject_uevent.c 2006-09-14 17:27:17.000000000 +0100
@@ -50,10 +50,6 @@ static char *action_to_string(enum kobje
return "offline";
case KOBJ_ONLINE:
return "online";
- case KOBJ_DOCK:
- return "dock";
- case KOBJ_UNDOCK:
- return "undock";
default:
return NULL;
}
Index: linux-2.6.17/lib/spinlock_debug.c
===================================================================
--- linux-2.6.17.orig/lib/spinlock_debug.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/lib/spinlock_debug.c 2006-09-14 17:27:17.000000000 +0100
@@ -162,6 +162,7 @@ static void rwlock_bug(rwlock_t *lock, c
#define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg)
+#if 0 /* __write_lock_debug() can lock up - maybe this can too? */
static void __read_lock_debug(rwlock_t *lock)
{
int print_once = 1;
@@ -184,12 +185,12 @@ static void __read_lock_debug(rwlock_t *
}
}
}
+#endif
void _raw_read_lock(rwlock_t *lock)
{
RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
- if (unlikely(!__raw_read_trylock(&lock->raw_lock)))
- __read_lock_debug(lock);
+ __raw_read_lock(&lock->raw_lock);
}
int _raw_read_trylock(rwlock_t *lock)
@@ -235,6 +236,7 @@ static inline void debug_write_unlock(rw
lock->owner_cpu = -1;
}
+#if 0 /* This can cause lockups */
static void __write_lock_debug(rwlock_t *lock)
{
int print_once = 1;
@@ -257,12 +259,12 @@ static void __write_lock_debug(rwlock_t
}
}
}
+#endif
void _raw_write_lock(rwlock_t *lock)
{
debug_write_lock_before(lock);
- if (unlikely(!__raw_write_trylock(&lock->raw_lock)))
- __write_lock_debug(lock);
+ __raw_write_lock(&lock->raw_lock);
debug_write_lock_after(lock);
}
Index: linux-2.6.17/lib/zlib_inflate/inflate.c
===================================================================
--- linux-2.6.17.orig/lib/zlib_inflate/inflate.c 2006-09-14 16:26:44.000000000 +0100
+++ linux-2.6.17/lib/zlib_inflate/inflate.c 2006-09-14 17:27:17.000000000 +0100
@@ -347,7 +347,10 @@ int zlib_inflate(z_streamp strm, int flu
static const unsigned short order[19] = /* permutation of code lengths */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
- if (strm == NULL || strm->state == NULL || strm->next_out == NULL ||
+ /* Do not check for strm->next_out == NULL here as ppc zImage
+ inflates to strm->next_out = 0 */
+
+ if (strm == NULL || strm->state == NULL ||
(strm->next_in == NULL && strm->avail_in != 0))
return Z_STREAM_ERROR;
Index: linux-2.6.17/mm/fadvise.c
===================================================================
--- linux-2.6.17.orig/mm/fadvise.c 2006-09-14 17:21:48.000000000 +0100
+++ linux-2.6.17/mm/fadvise.c 2006-09-14 17:27:17.000000000 +0100
@@ -73,7 +73,6 @@ asmlinkage long sys_fadvise64_64(int fd,
file->f_ra.ra_pages = bdi->ra_pages * 2;
break;
case POSIX_FADV_WILLNEED:
- case POSIX_FADV_NOREUSE:
if (!mapping->a_ops->readpage) {
ret = -EINVAL;
break;
@@ -94,6 +93,8 @@ asmlinkage long sys_fadvise64_64(int fd,
if (ret > 0)
ret = 0;
break;
+ case POSIX_FADV_NOREUSE:
+ break;
case POSIX_FADV_DONTNEED:
if (!bdi_write_congested(mapping->backing_dev_info))
filemap_flush(mapping);
Index: linux-2.6.17/mm/memory_hotplug.c
===================================================================
--- linux-2.6.17.orig/mm/memory_hotplug.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/mm/memory_hotplug.c 2006-09-14 17:27:17.000000000 +0100
@@ -52,6 +52,9 @@ static int __add_section(struct zone *zo
int nr_pages = PAGES_PER_SECTION;
int ret;
+ if (pfn_valid(phys_start_pfn))
+ return -EEXIST;
+
ret = sparse_add_one_section(zone, phys_start_pfn, nr_pages);
if (ret < 0)
@@ -76,15 +79,22 @@ int __add_pages(struct zone *zone, unsig
{
unsigned long i;
int err = 0;
+ int start_sec, end_sec;
+ /* during initialize mem_map, align hot-added range to section */
+ start_sec = pfn_to_section_nr(phys_start_pfn);
+ end_sec = pfn_to_section_nr(phys_start_pfn + nr_pages - 1);
- for (i = 0; i < nr_pages; i += PAGES_PER_SECTION) {
- err = __add_section(zone, phys_start_pfn + i);
+ for (i = start_sec; i <= end_sec; i++) {
+ err = __add_section(zone, i << PFN_SECTION_SHIFT);
- /* We want to keep adding the rest of the
- * sections if the first ones already exist
+ /*
+ * EEXIST is finally dealed with by ioresource collision
+ * check. see add_memory() => register_memory_resource()
+ * Warning will be printed if there is collision.
*/
if (err && (err != -EEXIST))
break;
+ err = 0;
}
return err;
@@ -156,7 +166,7 @@ int online_pages(unsigned long pfn, unsi
res.flags = IORESOURCE_MEM; /* we just need system ram */
section_end = res.end;
- while (find_next_system_ram(&res) >= 0) {
+ while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) {
start_pfn = (unsigned long)(res.start >> PAGE_SHIFT);
nr_pages = (unsigned long)
((res.end + 1 - res.start) >> PAGE_SHIFT);
@@ -213,10 +223,9 @@ static void rollback_node_hotadd(int nid
}
/* add this memory to iomem resource */
-static void register_memory_resource(u64 start, u64 size)
+static struct resource *register_memory_resource(u64 start, u64 size)
{
struct resource *res;
-
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
BUG_ON(!res);
@@ -228,7 +237,18 @@ static void register_memory_resource(u64
printk("System RAM resource %llx - %llx cannot be added\n",
(unsigned long long)res->start, (unsigned long long)res->end);
kfree(res);
+ res = NULL;
}
+ return res;
+}
+
+static void release_memory_resource(struct resource *res)
+{
+ if (!res)
+ return;
+ release_resource(res);
+ kfree(res);
+ return;
}
@@ -237,8 +257,13 @@ int add_memory(int nid, u64 start, u64 s
{
pg_data_t *pgdat = NULL;
int new_pgdat = 0;
+ struct resource *res;
int ret;
+ res = register_memory_resource(start, size);
+ if (!res)
+ return -EEXIST;
+
if (!node_online(nid)) {
pgdat = hotadd_new_pgdat(nid, start);
if (!pgdat)
@@ -268,14 +293,13 @@ int add_memory(int nid, u64 start, u64 s
BUG_ON(ret);
}
- /* register this memory as resource */
- register_memory_resource(start, size);
-
return ret;
error:
/* rollback pgdat allocation and others */
if (new_pgdat)
rollback_node_hotadd(nid, pgdat);
+ if (res)
+ release_memory_resource(res);
return ret;
}
Index: linux-2.6.17/mm/slab.c
===================================================================
--- linux-2.6.17.orig/mm/slab.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/mm/slab.c 2006-09-14 17:27:17.000000000 +0100
@@ -1106,7 +1106,7 @@ static inline int cache_free_alien(struc
#endif
-static int __devinit cpuup_callback(struct notifier_block *nfb,
+static int __cpuinit cpuup_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
long cpu = (long)hcpu;
@@ -3224,7 +3224,7 @@ void *kmem_cache_alloc(struct kmem_cache
EXPORT_SYMBOL(kmem_cache_alloc);
/**
- * kmem_cache_alloc - Allocate an object. The memory is set to zero.
+ * kmem_cache_zalloc - Allocate an object. The memory is set to zero.
* @cache: The cache to allocate from.
* @flags: See kmalloc().
*
Index: linux-2.6.17/net/bridge/br_netlink.c
===================================================================
--- linux-2.6.17.orig/net/bridge/br_netlink.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/bridge/br_netlink.c 2006-09-14 17:27:17.000000000 +0100
@@ -85,7 +85,7 @@ void br_ifinfo_notify(int event, struct
goto err_out;
err = br_fill_ifinfo(skb, port, current->pid, 0, event, 0);
- if (err)
+ if (err < 0)
goto err_kfree;
NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
Index: linux-2.6.17/net/core/Makefile
===================================================================
--- linux-2.6.17.orig/net/core/Makefile 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/core/Makefile 2006-09-14 17:27:17.000000000 +0100
@@ -7,7 +7,7 @@ obj-y := sock.o request_sock.o skbuff.o
obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
-obj-y += dev.o ethtool.o dev_mcast.o dst.o \
+obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \
neighbour.o rtnetlink.o utils.o link_watch.o filter.o
obj-$(CONFIG_XFRM) += flow.o
Index: linux-2.6.17/net/core/dev.c
===================================================================
--- linux-2.6.17.orig/net/core/dev.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/net/core/dev.c 2006-09-14 17:27:17.000000000 +0100
@@ -1166,11 +1166,6 @@ int skb_checksum_help(struct sk_buff *sk
goto out_set_summed;
if (unlikely(skb_shinfo(skb)->gso_size)) {
- static int warned;
-
- WARN_ON(!warned);
- warned = 1;
-
/* Let GSO fix up the checksum. */
goto out_set_summed;
}
@@ -1220,11 +1215,6 @@ struct sk_buff *skb_gso_segment(struct s
__skb_pull(skb, skb->mac_len);
if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
- static int warned;
-
- WARN_ON(!warned);
- warned = 1;
-
if (skb_header_cloned(skb) &&
(err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
return ERR_PTR(err);
@@ -3429,12 +3419,9 @@ static void net_dma_rebalance(void)
unsigned int cpu, i, n;
struct dma_chan *chan;
- lock_cpu_hotplug();
-
if (net_dma_count == 0) {
for_each_online_cpu(cpu)
- rcu_assign_pointer(per_cpu(softnet_data.net_dma, cpu), NULL);
- unlock_cpu_hotplug();
+ rcu_assign_pointer(per_cpu(softnet_data, cpu).net_dma, NULL);
return;
}
@@ -3447,15 +3434,13 @@ static void net_dma_rebalance(void)
+ (i < (num_online_cpus() % net_dma_count) ? 1 : 0));
while(n) {
- per_cpu(softnet_data.net_dma, cpu) = chan;
+ per_cpu(softnet_data, cpu).net_dma = chan;
cpu = next_cpu(cpu, cpu_online_map);
n--;
}
i++;
}
rcu_read_unlock();
-
- unlock_cpu_hotplug();
}
/**
Index: linux-2.6.17/net/core/neighbour.c
===================================================================
--- linux-2.6.17.orig/net/core/neighbour.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/core/neighbour.c 2006-09-14 17:27:17.000000000 +0100
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -754,6 +755,7 @@ static void neigh_timer_handler(unsigned
neigh->nud_state = NUD_STALE;
neigh->updated = jiffies;
neigh_suspect(neigh);
+ notify = 1;
}
} else if (state & NUD_DELAY) {
if (time_before_eq(now,
@@ -762,6 +764,7 @@ static void neigh_timer_handler(unsigned
neigh->nud_state = NUD_REACHABLE;
neigh->updated = jiffies;
neigh_connect(neigh);
+ notify = 1;
next = neigh->confirmed + neigh->parms->reachable_time;
} else {
NEIGH_PRINTK2("neigh %p is probed.\n", neigh);
@@ -819,6 +822,8 @@ static void neigh_timer_handler(unsigned
out:
write_unlock(&neigh->lock);
}
+ if (notify)
+ call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
#ifdef CONFIG_ARPD
if (notify && neigh->parms->app_probes)
@@ -926,9 +931,7 @@ int neigh_update(struct neighbour *neigh
{
u8 old;
int err;
-#ifdef CONFIG_ARPD
int notify = 0;
-#endif
struct net_device *dev;
int update_isrouter = 0;
@@ -948,9 +951,7 @@ int neigh_update(struct neighbour *neigh
neigh_suspect(neigh);
neigh->nud_state = new;
err = 0;
-#ifdef CONFIG_ARPD
notify = old & NUD_VALID;
-#endif
goto out;
}
@@ -1022,9 +1023,7 @@ int neigh_update(struct neighbour *neigh
if (!(new & NUD_CONNECTED))
neigh->confirmed = jiffies -
(neigh->parms->base_reachable_time << 1);
-#ifdef CONFIG_ARPD
notify = 1;
-#endif
}
if (new == old)
goto out;
@@ -1056,6 +1055,9 @@ out:
(neigh->flags & ~NTF_ROUTER);
}
write_unlock_bh(&neigh->lock);
+
+ if (notify)
+ call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
#ifdef CONFIG_ARPD
if (notify && neigh->parms->app_probes)
neigh_app_notify(neigh);
Index: linux-2.6.17/net/core/netevent.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.17/net/core/netevent.c 2006-09-14 17:27:17.000000000 +0100
@@ -0,0 +1,69 @@
+/*
+ * Network event notifiers
+ *
+ * Authors:
+ * Tom Tucker
+ * Steve Wise
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Fixes:
+ */
+
+#include
+#include
+
+static ATOMIC_NOTIFIER_HEAD(netevent_notif_chain);
+
+/**
+ * register_netevent_notifier - register a netevent notifier block
+ * @nb: notifier
+ *
+ * Register a notifier to be called when a netevent occurs.
+ * The notifier passed is linked into the kernel structures and must
+ * not be reused until it has been unregistered. A negative errno code
+ * is returned on a failure.
+ */
+int register_netevent_notifier(struct notifier_block *nb)
+{
+ int err;
+
+ err = atomic_notifier_chain_register(&netevent_notif_chain, nb);
+ return err;
+}
+
+/**
+ * netevent_unregister_notifier - unregister a netevent notifier block
+ * @nb: notifier
+ *
+ * Unregister a notifier previously registered by
+ * register_neigh_notifier(). The notifier is unlinked into the
+ * kernel structures and may then be reused. A negative errno code
+ * is returned on a failure.
+ */
+
+int unregister_netevent_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&netevent_notif_chain, nb);
+}
+
+/**
+ * call_netevent_notifiers - call all netevent notifier blocks
+ * @val: value passed unmodified to notifier function
+ * @v: pointer passed unmodified to notifier function
+ *
+ * Call all neighbour notifier blocks. Parameters and return value
+ * are as for notifier_call_chain().
+ */
+
+int call_netevent_notifiers(unsigned long val, void *v)
+{
+ return atomic_notifier_call_chain(&netevent_notif_chain, val, v);
+}
+
+EXPORT_SYMBOL_GPL(register_netevent_notifier);
+EXPORT_SYMBOL_GPL(unregister_netevent_notifier);
+EXPORT_SYMBOL_GPL(call_netevent_notifiers);
Index: linux-2.6.17/net/core/skbuff.c
===================================================================
--- linux-2.6.17.orig/net/core/skbuff.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/net/core/skbuff.c 2006-09-14 17:27:17.000000000 +0100
@@ -71,13 +71,6 @@ static kmem_cache_t *skbuff_head_cache _
static kmem_cache_t *skbuff_fclone_cache __read_mostly;
/*
- * lockdep: lock class key used by skb_queue_head_init():
- */
-struct lock_class_key skb_queue_lock_key;
-
-EXPORT_SYMBOL(skb_queue_lock_key);
-
-/*
* Keep out-of-line to prevent kernel bloat.
* __builtin_return_address is not used because it is not always
* reliable.
@@ -256,6 +249,29 @@ nodata:
goto out;
}
+/**
+ * __netdev_alloc_skb - allocate an skbuff for rx on a specific device
+ * @dev: network device to receive on
+ * @length: length to allocate
+ * @gfp_mask: get_free_pages mask, passed to alloc_skb
+ *
+ * Allocate a new &sk_buff and assign it a usage count of one. The
+ * buffer has unspecified headroom built in. Users should allocate
+ * the headroom they think they need without accounting for the
+ * built in space. The built in space is used for optimisations.
+ *
+ * %NULL is returned if there is no free memory.
+ */
+struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
+ unsigned int length, gfp_t gfp_mask)
+{
+ struct sk_buff *skb;
+
+ skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
+ if (likely(skb))
+ skb_reserve(skb, NET_SKB_PAD);
+ return skb;
+}
static void skb_drop_list(struct sk_buff **listp)
{
@@ -846,7 +862,11 @@ int ___pskb_trim(struct sk_buff *skb, un
unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))))
return err;
- for (i = 0; i < nfrags; i++) {
+ i = 0;
+ if (offset >= len)
+ goto drop_pages;
+
+ for (; i < nfrags; i++) {
int end = offset + skb_shinfo(skb)->frags[i].size;
if (end < len) {
@@ -854,9 +874,9 @@ int ___pskb_trim(struct sk_buff *skb, un
continue;
}
- if (len > offset)
- skb_shinfo(skb)->frags[i++].size = len - offset;
+ skb_shinfo(skb)->frags[i++].size = len - offset;
+drop_pages:
skb_shinfo(skb)->nr_frags = i;
for (; i < nfrags; i++)
@@ -864,7 +884,7 @@ int ___pskb_trim(struct sk_buff *skb, un
if (skb_shinfo(skb)->frag_list)
skb_drop_fraglist(skb);
- break;
+ goto done;
}
for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp);
@@ -879,6 +899,7 @@ int ___pskb_trim(struct sk_buff *skb, un
return -ENOMEM;
nfrag->next = frag->next;
+ kfree_skb(frag);
frag = nfrag;
*fragp = frag;
}
@@ -897,6 +918,7 @@ int ___pskb_trim(struct sk_buff *skb, un
break;
}
+done:
if (len > skb_headlen(skb)) {
skb->data_len -= skb->len - len;
skb->len = len;
@@ -2042,6 +2064,7 @@ EXPORT_SYMBOL(__kfree_skb);
EXPORT_SYMBOL(kfree_skb);
EXPORT_SYMBOL(__pskb_pull_tail);
EXPORT_SYMBOL(__alloc_skb);
+EXPORT_SYMBOL(__netdev_alloc_skb);
EXPORT_SYMBOL(pskb_copy);
EXPORT_SYMBOL(pskb_expand_head);
EXPORT_SYMBOL(skb_checksum);
Index: linux-2.6.17/net/dccp/ipv6.c
===================================================================
--- linux-2.6.17.orig/net/dccp/ipv6.c 2006-09-14 17:25:56.000000000 +0100
+++ linux-2.6.17/net/dccp/ipv6.c 2006-09-14 17:27:17.000000000 +0100
@@ -230,7 +230,7 @@ static int dccp_v6_connect(struct sock *
ipv6_addr_copy(&np->saddr, saddr);
inet->rcv_saddr = LOOPBACK4_IPV6;
- ip6_dst_store(sk, dst, NULL);
+ __ip6_dst_store(sk, dst, NULL);
icsk->icsk_ext_hdr_len = 0;
if (np->opt != NULL)
@@ -863,7 +863,7 @@ static struct sock *dccp_v6_request_recv
* comment in that function for the gory details. -acme
*/
- ip6_dst_store(newsk, dst, NULL);
+ __ip6_dst_store(newsk, dst, NULL);
newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
NETIF_F_TSO);
newdp6 = (struct dccp6_sock *)newsk;
Index: linux-2.6.17/net/decnet/dn_route.c
===================================================================
--- linux-2.6.17.orig/net/decnet/dn_route.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/decnet/dn_route.c 2006-09-14 17:27:17.000000000 +0100
@@ -925,8 +925,13 @@ static int dn_route_output_slow(struct d
for(dev_out = dev_base; dev_out; dev_out = dev_out->next) {
if (!dev_out->dn_ptr)
continue;
- if (dn_dev_islocal(dev_out, oldflp->fld_src))
- break;
+ if (!dn_dev_islocal(dev_out, oldflp->fld_src))
+ continue;
+ if ((dev_out->flags & IFF_LOOPBACK) &&
+ oldflp->fld_dst &&
+ !dn_dev_islocal(dev_out, oldflp->fld_dst))
+ continue;
+ break;
}
read_unlock(&dev_base_lock);
if (dev_out == NULL)
Index: linux-2.6.17/net/ipv4/ip_output.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/ip_output.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/net/ipv4/ip_output.c 2006-09-14 17:27:17.000000000 +0100
@@ -526,6 +526,8 @@ int ip_fragment(struct sk_buff *skb, int
err = output(skb);
+ if (!err)
+ IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
if (err || !frag)
break;
@@ -649,9 +651,6 @@ slow_path:
/*
* Put this fragment into the sending queue.
*/
-
- IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
-
iph->tot_len = htons(len + hlen);
ip_send_check(iph);
@@ -659,6 +658,8 @@ slow_path:
err = output(skb2);
if (err)
goto fail;
+
+ IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
}
kfree_skb(skb);
IP_INC_STATS(IPSTATS_MIB_FRAGOKS);
Index: linux-2.6.17/net/ipv4/ip_sockglue.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/ip_sockglue.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv4/ip_sockglue.c 2006-09-14 17:27:17.000000000 +0100
@@ -112,14 +112,19 @@ static void ip_cmsg_recv_retopts(struct
static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
{
char *secdata;
- u32 seclen;
+ u32 seclen, secid;
int err;
- err = security_socket_getpeersec_dgram(skb, &secdata, &seclen);
+ err = security_socket_getpeersec_dgram(NULL, skb, &secid);
+ if (err)
+ return;
+
+ err = security_secid_to_secctx(secid, &secdata, &seclen);
if (err)
return;
put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata);
+ security_release_secctx(secdata, seclen);
}
Index: linux-2.6.17/net/ipv4/netfilter/ip_conntrack_sip.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/netfilter/ip_conntrack_sip.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv4/netfilter/ip_conntrack_sip.c 2006-09-14 17:27:17.000000000 +0100
@@ -442,7 +442,7 @@ static int __init init(void)
sip[i].tuple.src.u.udp.port = htons(ports[i]);
sip[i].mask.src.u.udp.port = 0xFFFF;
sip[i].mask.dst.protonum = 0xFF;
- sip[i].max_expected = 1;
+ sip[i].max_expected = 2;
sip[i].timeout = 3 * 60; /* 3 minutes */
sip[i].me = THIS_MODULE;
sip[i].help = sip_help;
Index: linux-2.6.17/net/ipv4/netfilter/ipt_hashlimit.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/netfilter/ipt_hashlimit.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv4/netfilter/ipt_hashlimit.c 2006-09-14 17:27:17.000000000 +0100
@@ -508,6 +508,9 @@ hashlimit_checkentry(const char *tablena
if (!r->cfg.expire)
return 0;
+ if (r->name[sizeof(r->name) - 1] != '\0')
+ return 0;
+
/* This is the best we've got: We cannot release and re-grab lock,
* since checkentry() is called before ip_tables.c grabs ipt_mutex.
* We also cannot grab the hashtable spinlock, since htable_create will
Index: linux-2.6.17/net/ipv4/route.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/route.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv4/route.c 2006-09-14 17:27:17.000000000 +0100
@@ -104,6 +104,7 @@
#include
#include
#include
+#include
#ifdef CONFIG_SYSCTL
#include
#endif
@@ -1125,6 +1126,7 @@ void ip_rt_redirect(u32 old_gw, u32 dadd
struct rtable *rth, **rthp;
u32 skeys[2] = { saddr, 0 };
int ikeys[2] = { dev->ifindex, 0 };
+ struct netevent_redirect netevent;
if (!in_dev)
return;
@@ -1216,6 +1218,11 @@ void ip_rt_redirect(u32 old_gw, u32 dadd
rt_drop(rt);
goto do_next;
}
+
+ netevent.old = &rth->u.dst;
+ netevent.new = &rt->u.dst;
+ call_netevent_notifiers(NETEVENT_REDIRECT,
+ &netevent);
rt_del(hash, rth);
if (!rt_intern_hash(hash, rt, &rt))
@@ -1452,6 +1459,7 @@ static void ip_rt_update_pmtu(struct dst
}
dst->metrics[RTAX_MTU-1] = mtu;
dst_set_expires(dst, ip_rt_mtu_expires);
+ call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
}
}
Index: linux-2.6.17/net/ipv4/tcp.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/tcp.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv4/tcp.c 2006-09-14 17:27:17.000000000 +0100
@@ -1132,7 +1132,7 @@ int tcp_recvmsg(struct kiocb *iocb, stru
tp->ucopy.dma_chan = NULL;
preempt_disable();
if ((len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) &&
- !sysctl_tcp_low_latency && __get_cpu_var(softnet_data.net_dma)) {
+ !sysctl_tcp_low_latency && __get_cpu_var(softnet_data).net_dma) {
preempt_enable_no_resched();
tp->ucopy.pinned_list = dma_pin_iovec_pages(msg->msg_iov, len);
} else
@@ -1659,7 +1659,8 @@ adjudge_to_death:
const int tmo = tcp_fin_time(sk);
if (tmo > TCP_TIMEWAIT_LEN) {
- inet_csk_reset_keepalive_timer(sk, tcp_fin_time(sk));
+ inet_csk_reset_keepalive_timer(sk,
+ tmo - TCP_TIMEWAIT_LEN);
} else {
tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
goto out;
Index: linux-2.6.17/net/ipv4/tcp_input.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/tcp_input.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv4/tcp_input.c 2006-09-14 17:27:17.000000000 +0100
@@ -3541,7 +3541,8 @@ void tcp_cwnd_application_limited(struct
if (inet_csk(sk)->icsk_ca_state == TCP_CA_Open &&
sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
/* Limited by application or receiver window. */
- u32 win_used = max(tp->snd_cwnd_used, 2U);
+ u32 init_win = tcp_init_cwnd(tp, __sk_dst_get(sk));
+ u32 win_used = max(tp->snd_cwnd_used, init_win);
if (win_used < tp->snd_cwnd) {
tp->snd_ssthresh = tcp_current_ssthresh(sk);
tp->snd_cwnd = (tp->snd_cwnd + win_used) >> 1;
Index: linux-2.6.17/net/ipv4/tcp_ipv4.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/tcp_ipv4.c 2006-09-14 17:25:57.000000000 +0100
+++ linux-2.6.17/net/ipv4/tcp_ipv4.c 2006-09-14 17:27:17.000000000 +0100
@@ -438,7 +438,6 @@ void tcp_v4_err(struct sk_buff *skb, u32
It can f.e. if SYNs crossed.
*/
if (!sock_owned_by_user(sk)) {
- TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
sk->sk_err = err;
sk->sk_error_report(sk);
@@ -874,7 +873,6 @@ int tcp_v4_conn_request(struct sock *sk,
drop_and_free:
reqsk_free(req);
drop:
- TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
return 0;
}
Index: linux-2.6.17/net/ipv4/tcp_minisocks.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/tcp_minisocks.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv4/tcp_minisocks.c 2006-09-14 17:27:17.000000000 +0100
@@ -589,8 +589,10 @@ struct sock *tcp_check_req(struct sock *
/* RFC793: "second check the RST bit" and
* "fourth, check the SYN bit"
*/
- if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN))
+ if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) {
+ TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
goto embryonic_reset;
+ }
/* ACK sequence verified above, just make sure ACK is
* set. If ACK not set, just silently drop the packet.
Index: linux-2.6.17/net/ipv4/tcp_probe.c
===================================================================
--- linux-2.6.17.orig/net/ipv4/tcp_probe.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv4/tcp_probe.c 2006-09-14 17:27:17.000000000 +0100
@@ -114,7 +114,7 @@ static int tcpprobe_open(struct inode *
static ssize_t tcpprobe_read(struct file *file, char __user *buf,
size_t len, loff_t *ppos)
{
- int error = 0, cnt;
+ int error = 0, cnt = 0;
unsigned char *tbuf;
if (!buf || len < 0)
Index: linux-2.6.17/net/ipv6/addrconf.c
===================================================================
--- linux-2.6.17.orig/net/ipv6/addrconf.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/net/ipv6/addrconf.c 2006-09-14 17:27:17.000000000 +0100
@@ -1869,15 +1869,21 @@ err_exit:
/*
* Manual configuration of address on an interface
*/
-static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen)
+static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen,
+ __u32 prefered_lft, __u32 valid_lft)
{
struct inet6_ifaddr *ifp;
struct inet6_dev *idev;
struct net_device *dev;
+ __u8 ifa_flags = 0;
int scope;
ASSERT_RTNL();
+ /* check the lifetime */
+ if (!valid_lft || prefered_lft > valid_lft)
+ return -EINVAL;
+
if ((dev = __dev_get_by_index(ifindex)) == NULL)
return -ENODEV;
@@ -1889,10 +1895,29 @@ static int inet6_addr_add(int ifindex, s
scope = ipv6_addr_scope(pfx);
- ifp = ipv6_add_addr(idev, pfx, plen, scope, IFA_F_PERMANENT);
+ if (valid_lft == INFINITY_LIFE_TIME)
+ ifa_flags |= IFA_F_PERMANENT;
+ else if (valid_lft >= 0x7FFFFFFF/HZ)
+ valid_lft = 0x7FFFFFFF/HZ;
+
+ if (prefered_lft == 0)
+ ifa_flags |= IFA_F_DEPRECATED;
+ else if ((prefered_lft >= 0x7FFFFFFF/HZ) &&
+ (prefered_lft != INFINITY_LIFE_TIME))
+ prefered_lft = 0x7FFFFFFF/HZ;
+
+ ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags);
+
if (!IS_ERR(ifp)) {
+ spin_lock(&ifp->lock);
+ ifp->valid_lft = valid_lft;
+ ifp->prefered_lft = prefered_lft;
+ ifp->tstamp = jiffies;
+ spin_unlock(&ifp->lock);
+
addrconf_dad_start(ifp, 0);
in6_ifa_put(ifp);
+ addrconf_verify(0);
return 0;
}
@@ -1945,7 +1970,8 @@ int addrconf_add_ifaddr(void __user *arg
return -EFAULT;
rtnl_lock();
- err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen);
+ err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen,
+ INFINITY_LIFE_TIME, INFINITY_LIFE_TIME);
rtnl_unlock();
return err;
}
@@ -2771,12 +2797,16 @@ restart:
ifp->idev->nd_parms->retrans_time / HZ;
#endif
- if (age >= ifp->valid_lft) {
+ if (ifp->valid_lft != INFINITY_LIFE_TIME &&
+ age >= ifp->valid_lft) {
spin_unlock(&ifp->lock);
in6_ifa_hold(ifp);
read_unlock(&addrconf_hash_lock);
ipv6_del_addr(ifp);
goto restart;
+ } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) {
+ spin_unlock(&ifp->lock);
+ continue;
} else if (age >= ifp->prefered_lft) {
/* jiffies - ifp->tsamp > age >= ifp->prefered_lft */
int deprecate = 0;
@@ -2853,7 +2883,8 @@ inet6_rtm_deladdr(struct sk_buff *skb, s
pfx = RTA_DATA(rta[IFA_ADDRESS-1]);
}
if (rta[IFA_LOCAL-1]) {
- if (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))
+ if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*pfx) ||
+ (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx))))
return -EINVAL;
pfx = RTA_DATA(rta[IFA_LOCAL-1]);
}
@@ -2864,11 +2895,61 @@ inet6_rtm_deladdr(struct sk_buff *skb, s
}
static int
+inet6_addr_modify(int ifindex, struct in6_addr *pfx,
+ __u32 prefered_lft, __u32 valid_lft)
+{
+ struct inet6_ifaddr *ifp = NULL;
+ struct net_device *dev;
+ int ifa_flags = 0;
+
+ if ((dev = __dev_get_by_index(ifindex)) == NULL)
+ return -ENODEV;
+
+ if (!(dev->flags&IFF_UP))
+ return -ENETDOWN;
+
+ if (!valid_lft || (prefered_lft > valid_lft))
+ return -EINVAL;
+
+ ifp = ipv6_get_ifaddr(pfx, dev, 1);
+ if (ifp == NULL)
+ return -ENOENT;
+
+ if (valid_lft == INFINITY_LIFE_TIME)
+ ifa_flags = IFA_F_PERMANENT;
+ else if (valid_lft >= 0x7FFFFFFF/HZ)
+ valid_lft = 0x7FFFFFFF/HZ;
+
+ if (prefered_lft == 0)
+ ifa_flags = IFA_F_DEPRECATED;
+ else if ((prefered_lft >= 0x7FFFFFFF/HZ) &&
+ (prefered_lft != INFINITY_LIFE_TIME))
+ prefered_lft = 0x7FFFFFFF/HZ;
+
+ spin_lock_bh(&ifp->lock);
+ ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED|IFA_F_PERMANENT)) | ifa_flags;
+
+ ifp->tstamp = jiffies;
+ ifp->valid_lft = valid_lft;
+ ifp->prefered_lft = prefered_lft;
+
+ spin_unlock_bh(&ifp->lock);
+ if (!(ifp->flags&IFA_F_TENTATIVE))
+ ipv6_ifa_notify(0, ifp);
+ in6_ifa_put(ifp);
+
+ addrconf_verify(0);
+
+ return 0;
+}
+
+static int
inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
struct rtattr **rta = arg;
struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
struct in6_addr *pfx;
+ __u32 valid_lft = INFINITY_LIFE_TIME, prefered_lft = INFINITY_LIFE_TIME;
pfx = NULL;
if (rta[IFA_ADDRESS-1]) {
@@ -2877,14 +2958,34 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
pfx = RTA_DATA(rta[IFA_ADDRESS-1]);
}
if (rta[IFA_LOCAL-1]) {
- if (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))
+ if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*pfx) ||
+ (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx))))
return -EINVAL;
pfx = RTA_DATA(rta[IFA_LOCAL-1]);
}
if (pfx == NULL)
return -EINVAL;
- return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen);
+ if (rta[IFA_CACHEINFO-1]) {
+ struct ifa_cacheinfo *ci;
+ if (RTA_PAYLOAD(rta[IFA_CACHEINFO-1]) < sizeof(*ci))
+ return -EINVAL;
+ ci = RTA_DATA(rta[IFA_CACHEINFO-1]);
+ valid_lft = ci->ifa_valid;
+ prefered_lft = ci->ifa_prefered;
+ }
+
+ if (nlh->nlmsg_flags & NLM_F_REPLACE) {
+ int ret;
+ ret = inet6_addr_modify(ifm->ifa_index, pfx,
+ prefered_lft, valid_lft);
+ if (ret == 0 || !(nlh->nlmsg_flags & NLM_F_CREATE))
+ return ret;
+ }
+
+ return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen,
+ prefered_lft, valid_lft);
+
}
/* Maximum length of ifa_cacheinfo attributes */
@@ -3121,6 +3222,62 @@ static int inet6_dump_ifacaddr(struct sk
return inet6_dump_addr(skb, cb, type);
}
+static int inet6_rtm_getaddr(struct sk_buff *in_skb,
+ struct nlmsghdr* nlh, void *arg)
+{
+ struct rtattr **rta = arg;
+ struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
+ struct in6_addr *addr = NULL;
+ struct net_device *dev = NULL;
+ struct inet6_ifaddr *ifa;
+ struct sk_buff *skb;
+ int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE);
+ int err;
+
+ if (rta[IFA_ADDRESS-1]) {
+ if (RTA_PAYLOAD(rta[IFA_ADDRESS-1]) < sizeof(*addr))
+ return -EINVAL;
+ addr = RTA_DATA(rta[IFA_ADDRESS-1]);
+ }
+ if (rta[IFA_LOCAL-1]) {
+ if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*addr) ||
+ (addr && memcmp(addr, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*addr))))
+ return -EINVAL;
+ addr = RTA_DATA(rta[IFA_LOCAL-1]);
+ }
+ if (addr == NULL)
+ return -EINVAL;
+
+ if (ifm->ifa_index)
+ dev = __dev_get_by_index(ifm->ifa_index);
+
+ if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL)
+ return -EADDRNOTAVAIL;
+
+ if ((skb = alloc_skb(size, GFP_KERNEL)) == NULL) {
+ err = -ENOBUFS;
+ goto out;
+ }
+
+ NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
+ err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
+ nlh->nlmsg_seq, RTM_NEWADDR, 0);
+ if (err < 0) {
+ err = -EMSGSIZE;
+ goto out_free;
+ }
+
+ err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
+ if (err > 0)
+ err = 0;
+out:
+ in6_ifa_put(ifa);
+ return err;
+out_free:
+ kfree_skb(skb);
+ goto out;
+}
+
static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
{
struct sk_buff *skb;
@@ -3363,7 +3520,8 @@ static struct rtnetlink_link inet6_rtnet
[RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, },
[RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, },
[RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, },
- [RTM_GETADDR - RTM_BASE] = { .dumpit = inet6_dump_ifaddr, },
+ [RTM_GETADDR - RTM_BASE] = { .doit = inet6_rtm_getaddr,
+ .dumpit = inet6_dump_ifaddr, },
[RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, },
[RTM_GETANYCAST - RTM_BASE] = { .dumpit = inet6_dump_ifacaddr, },
[RTM_NEWROUTE - RTM_BASE] = { .doit = inet6_rtm_newroute, },
Index: linux-2.6.17/net/ipv6/af_inet6.c
===================================================================
--- linux-2.6.17.orig/net/ipv6/af_inet6.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv6/af_inet6.c 2006-09-14 17:27:17.000000000 +0100
@@ -658,7 +658,7 @@ int inet6_sk_rebuild_header(struct sock
return err;
}
- ip6_dst_store(sk, dst, NULL);
+ __ip6_dst_store(sk, dst, NULL);
}
return 0;
Index: linux-2.6.17/net/ipv6/inet6_connection_sock.c
===================================================================
--- linux-2.6.17.orig/net/ipv6/inet6_connection_sock.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv6/inet6_connection_sock.c 2006-09-14 17:27:17.000000000 +0100
@@ -185,7 +185,7 @@ int inet6_csk_xmit(struct sk_buff *skb,
return err;
}
- ip6_dst_store(sk, dst, NULL);
+ __ip6_dst_store(sk, dst, NULL);
}
skb->dst = dst_clone(dst);
Index: linux-2.6.17/net/ipv6/ip6_output.c
===================================================================
--- linux-2.6.17.orig/net/ipv6/ip6_output.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/net/ipv6/ip6_output.c 2006-09-14 17:27:17.000000000 +0100
@@ -356,6 +356,7 @@ int ip6_forward(struct sk_buff *skb)
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
0, skb->dev);
+ IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
kfree_skb(skb);
return -ETIMEDOUT;
@@ -595,6 +596,9 @@ static int ip6_fragment(struct sk_buff *
}
err = output(skb);
+ if(!err)
+ IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
+
if (err || !frag)
break;
@@ -706,12 +710,11 @@ slow_path:
/*
* Put this fragment into the sending queue.
*/
-
- IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
-
err = output(frag);
if (err)
goto fail;
+
+ IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
}
kfree_skb(skb);
IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);
@@ -723,48 +726,51 @@ fail:
return err;
}
-int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
+static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
+ struct dst_entry *dst,
+ struct flowi *fl)
{
- int err = 0;
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct rt6_info *rt = (struct rt6_info *)dst;
- *dst = NULL;
- if (sk) {
- struct ipv6_pinfo *np = inet6_sk(sk);
-
- *dst = sk_dst_check(sk, np->dst_cookie);
- if (*dst) {
- struct rt6_info *rt = (struct rt6_info*)*dst;
-
- /* Yes, checking route validity in not connected
- * case is not very simple. Take into account,
- * that we do not support routing by source, TOS,
- * and MSG_DONTROUTE --ANK (980726)
- *
- * 1. If route was host route, check that
- * cached destination is current.
- * If it is network route, we still may
- * check its validity using saved pointer
- * to the last used address: daddr_cache.
- * We do not want to save whole address now,
- * (because main consumer of this service
- * is tcp, which has not this problem),
- * so that the last trick works only on connected
- * sockets.
- * 2. oif also should be the same.
- */
- if (((rt->rt6i_dst.plen != 128 ||
- !ipv6_addr_equal(&fl->fl6_dst,
- &rt->rt6i_dst.addr))
- && (np->daddr_cache == NULL ||
- !ipv6_addr_equal(&fl->fl6_dst,
- np->daddr_cache)))
- || (fl->oif && fl->oif != (*dst)->dev->ifindex)) {
- dst_release(*dst);
- *dst = NULL;
- }
- }
+ if (!dst)
+ goto out;
+
+ /* Yes, checking route validity in not connected
+ * case is not very simple. Take into account,
+ * that we do not support routing by source, TOS,
+ * and MSG_DONTROUTE --ANK (980726)
+ *
+ * 1. If route was host route, check that
+ * cached destination is current.
+ * If it is network route, we still may
+ * check its validity using saved pointer
+ * to the last used address: daddr_cache.
+ * We do not want to save whole address now,
+ * (because main consumer of this service
+ * is tcp, which has not this problem),
+ * so that the last trick works only on connected
+ * sockets.
+ * 2. oif also should be the same.
+ */
+ if (((rt->rt6i_dst.plen != 128 ||
+ !ipv6_addr_equal(&fl->fl6_dst, &rt->rt6i_dst.addr))
+ && (np->daddr_cache == NULL ||
+ !ipv6_addr_equal(&fl->fl6_dst, np->daddr_cache)))
+ || (fl->oif && fl->oif != dst->dev->ifindex)) {
+ dst_release(dst);
+ dst = NULL;
}
+out:
+ return dst;
+}
+
+static int ip6_dst_lookup_tail(struct sock *sk,
+ struct dst_entry **dst, struct flowi *fl)
+{
+ int err;
+
if (*dst == NULL)
*dst = ip6_route_output(sk, fl);
@@ -773,7 +779,6 @@ int ip6_dst_lookup(struct sock *sk, stru
if (ipv6_addr_any(&fl->fl6_src)) {
err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
-
if (err)
goto out_err_release;
}
@@ -786,8 +791,48 @@ out_err_release:
return err;
}
+/**
+ * ip6_dst_lookup - perform route lookup on flow
+ * @sk: socket which provides route info
+ * @dst: pointer to dst_entry * for result
+ * @fl: flow to lookup
+ *
+ * This function performs a route lookup on the given flow.
+ *
+ * It returns zero on success, or a standard errno code on error.
+ */
+int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
+{
+ *dst = NULL;
+ return ip6_dst_lookup_tail(sk, dst, fl);
+}
EXPORT_SYMBOL_GPL(ip6_dst_lookup);
+/**
+ * ip6_sk_dst_lookup - perform socket cached route lookup on flow
+ * @sk: socket which provides the dst cache and route info
+ * @dst: pointer to dst_entry * for result
+ * @fl: flow to lookup
+ *
+ * This function performs a route lookup on the given flow with the
+ * possibility of using the cached route in the socket if it is valid.
+ * It will take the socket dst lock when operating on the dst cache.
+ * As a result, this function can only be used in process context.
+ *
+ * It returns zero on success, or a standard errno code on error.
+ */
+int ip6_sk_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
+{
+ *dst = NULL;
+ if (sk) {
+ *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
+ *dst = ip6_sk_dst_check(sk, *dst, fl);
+ }
+
+ return ip6_dst_lookup_tail(sk, dst, fl);
+}
+EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup);
+
static inline int ip6_ufo_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb),
Index: linux-2.6.17/net/ipv6/route.c
===================================================================
--- linux-2.6.17.orig/net/ipv6/route.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv6/route.c 2006-09-14 17:27:17.000000000 +0100
@@ -53,6 +53,7 @@
#include
#include
#include
+#include
#include
@@ -742,6 +743,7 @@ static void ip6_rt_update_pmtu(struct ds
dst->metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
}
dst->metrics[RTAX_MTU-1] = mtu;
+ call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
}
}
@@ -1155,6 +1157,7 @@ void rt6_redirect(struct in6_addr *dest,
struct rt6_info *rt, *nrt = NULL;
int strict;
struct fib6_node *fn;
+ struct netevent_redirect netevent;
/*
* Get the "current" route for this destination and
@@ -1252,6 +1255,10 @@ restart:
if (ip6_ins_rt(nrt, NULL, NULL, NULL))
goto out;
+ netevent.old = &rt->u.dst;
+ netevent.new = &nrt->u.dst;
+ call_netevent_notifiers(NETEVENT_REDIRECT, &netevent);
+
if (rt->rt6i_flags&RTF_CACHE) {
ip6_del_rt(rt, NULL, NULL, NULL);
return;
Index: linux-2.6.17/net/ipv6/tcp_ipv6.c
===================================================================
--- linux-2.6.17.orig/net/ipv6/tcp_ipv6.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/net/ipv6/tcp_ipv6.c 2006-09-14 17:27:17.000000000 +0100
@@ -270,7 +270,7 @@ static int tcp_v6_connect(struct sock *s
inet->rcv_saddr = LOOPBACK4_IPV6;
sk->sk_gso_type = SKB_GSO_TCPV6;
- ip6_dst_store(sk, dst, NULL);
+ __ip6_dst_store(sk, dst, NULL);
icsk->icsk_ext_hdr_len = 0;
if (np->opt)
@@ -427,7 +427,6 @@ static void tcp_v6_err(struct sk_buff *s
case TCP_SYN_RECV: /* Cannot happen.
It can, it SYNs are crossed. --ANK */
if (!sock_owned_by_user(sk)) {
- TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
sk->sk_err = err;
sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */
@@ -831,7 +830,6 @@ drop:
if (req)
reqsk_free(req);
- TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
return 0; /* don't send reset */
}
@@ -947,7 +945,7 @@ static struct sock * tcp_v6_syn_recv_soc
*/
sk->sk_gso_type = SKB_GSO_TCPV6;
- ip6_dst_store(newsk, dst, NULL);
+ __ip6_dst_store(newsk, dst, NULL);
newtcp6sk = (struct tcp6_sock *)newsk;
inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
Index: linux-2.6.17/net/ipv6/udp.c
===================================================================
--- linux-2.6.17.orig/net/ipv6/udp.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/ipv6/udp.c 2006-09-14 17:27:17.000000000 +0100
@@ -782,7 +782,7 @@ do_udp_sendmsg:
connected = 0;
}
- err = ip6_dst_lookup(sk, &dst, fl);
+ err = ip6_sk_dst_lookup(sk, &dst, fl);
if (err)
goto out;
if (final_p)
Index: linux-2.6.17/net/ipv6/xfrm6_output.c
===================================================================
--- linux-2.6.17.orig/net/ipv6/xfrm6_output.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/net/ipv6/xfrm6_output.c 2006-09-14 17:27:17.000000000 +0100
@@ -125,7 +125,7 @@ static int xfrm6_output_finish(struct sk
if (!skb_is_gso(skb))
return xfrm6_output_finish2(skb);
- skb->protocol = htons(ETH_P_IP);
+ skb->protocol = htons(ETH_P_IPV6);
segs = skb_gso_segment(skb, 0);
kfree_skb(skb);
if (unlikely(IS_ERR(segs)))
Index: linux-2.6.17/net/lapb/lapb_iface.c
===================================================================
--- linux-2.6.17.orig/net/lapb/lapb_iface.c 2006-09-14 17:25:57.000000000 +0100
+++ linux-2.6.17/net/lapb/lapb_iface.c 2006-09-14 17:27:17.000000000 +0100
@@ -238,11 +238,13 @@ int lapb_setparms(struct net_device *dev
goto out_put;
if (lapb->state == LAPB_STATE_0) {
- if (((parms->mode & LAPB_EXTENDED) &&
- (parms->window < 1 || parms->window > 127)) ||
- (parms->window < 1 || parms->window > 7))
- goto out_put;
-
+ if (parms->mode & LAPB_EXTENDED) {
+ if (parms->window < 1 || parms->window > 127)
+ goto out_put;
+ } else {
+ if (parms->window < 1 || parms->window > 7)
+ goto out_put;
+ }
lapb->mode = parms->mode;
lapb->window = parms->window;
}
Index: linux-2.6.17/net/llc/af_llc.c
===================================================================
--- linux-2.6.17.orig/net/llc/af_llc.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/llc/af_llc.c 2006-09-14 17:27:17.000000000 +0100
@@ -784,24 +784,20 @@ static int llc_ui_recvmsg(struct kiocb *
copied += used;
len -= used;
- if (used + offset < skb->len)
- continue;
-
if (!(flags & MSG_PEEK)) {
sk_eat_skb(sk, skb, 0);
*seq = 0;
}
+
+ /* For non stream protcols we get one packet per recvmsg call */
+ if (sk->sk_type != SOCK_STREAM)
+ goto copy_uaddr;
+
+ /* Partial read */
+ if (used + offset < skb->len)
+ continue;
} while (len > 0);
- /*
- * According to UNIX98, msg_name/msg_namelen are ignored
- * on connected socket. -ANK
- * But... af_llc still doesn't have separate sets of methods for
- * SOCK_DGRAM and SOCK_STREAM :-( So we have to do this test, will
- * eventually fix this tho :-) -acme
- */
- if (sk->sk_type == SOCK_DGRAM)
- goto copy_uaddr;
out:
release_sock(sk);
return copied;
Index: linux-2.6.17/net/llc/llc_sap.c
===================================================================
--- linux-2.6.17.orig/net/llc/llc_sap.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/llc/llc_sap.c 2006-09-14 17:27:17.000000000 +0100
@@ -51,10 +51,10 @@ void llc_save_primitive(struct sock *sk,
{
struct sockaddr_llc *addr;
- if (skb->sk->sk_type == SOCK_STREAM) /* See UNIX98 */
- return;
/* save primitive for use by the user. */
addr = llc_ui_skb_cb(skb);
+
+ memset(addr, 0, sizeof(*addr));
addr->sllc_family = sk->sk_family;
addr->sllc_arphrd = skb->dev->type;
addr->sllc_test = prim == LLC_TEST_PRIM;
Index: linux-2.6.17/net/netfilter/xt_SECMARK.c
===================================================================
--- linux-2.6.17.orig/net/netfilter/xt_SECMARK.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/netfilter/xt_SECMARK.c 2006-09-14 17:27:17.000000000 +0100
@@ -57,6 +57,8 @@ static int checkentry_selinux(struct xt_
{
int err;
struct xt_secmark_target_selinux_info *sel = &info->u.sel;
+
+ sel->selctx[SECMARK_SELCTX_MAX - 1] = '\0';
err = selinux_string_to_sid(sel->selctx, &sel->selsid);
if (err) {
Index: linux-2.6.17/net/netfilter/xt_string.c
===================================================================
--- linux-2.6.17.orig/net/netfilter/xt_string.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/netfilter/xt_string.c 2006-09-14 17:27:17.000000000 +0100
@@ -55,7 +55,10 @@ static int checkentry(const char *tablen
/* Damn, can't handle this case properly with iptables... */
if (conf->from_offset > conf->to_offset)
return 0;
-
+ if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0')
+ return 0;
+ if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE)
+ return 0;
ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen,
GFP_KERNEL, TS_AUTOLOAD);
if (IS_ERR(ts_conf))
Index: linux-2.6.17/net/sched/sch_api.c
===================================================================
--- linux-2.6.17.orig/net/sched/sch_api.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/sched/sch_api.c 2006-09-14 17:27:17.000000000 +0100
@@ -430,7 +430,7 @@ qdisc_create(struct net_device *dev, u32
}
#endif
- err = -EINVAL;
+ err = -ENOENT;
if (ops == NULL)
goto err_out;
Index: linux-2.6.17/net/sunrpc/cache.c
===================================================================
--- linux-2.6.17.orig/net/sunrpc/cache.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/net/sunrpc/cache.c 2006-09-14 17:27:17.000000000 +0100
@@ -71,7 +71,12 @@ struct cache_head *sunrpc_cache_lookup(s
new = detail->alloc();
if (!new)
return NULL;
+ /* must fully initialise 'new', else
+ * we might get lose if we need to
+ * cache_put it soon.
+ */
cache_init(new);
+ detail->init(new, key);
write_lock(&detail->hash_lock);
@@ -85,7 +90,6 @@ struct cache_head *sunrpc_cache_lookup(s
return tmp;
}
}
- detail->init(new, key);
new->next = *head;
*head = new;
detail->entries++;
Index: linux-2.6.17/net/sunrpc/clnt.c
===================================================================
--- linux-2.6.17.orig/net/sunrpc/clnt.c 2006-09-14 17:25:57.000000000 +0100
+++ linux-2.6.17/net/sunrpc/clnt.c 2006-09-14 17:27:17.000000000 +0100
@@ -921,26 +921,43 @@ call_transmit(struct rpc_task *task)
task->tk_status = xprt_prepare_transmit(task);
if (task->tk_status != 0)
return;
+ task->tk_action = call_transmit_status;
/* Encode here so that rpcsec_gss can use correct sequence number. */
if (rpc_task_need_encode(task)) {
- task->tk_rqstp->rq_bytes_sent = 0;
+ BUG_ON(task->tk_rqstp->rq_bytes_sent != 0);
call_encode(task);
/* Did the encode result in an error condition? */
if (task->tk_status != 0)
- goto out_nosend;
+ return;
}
- task->tk_action = call_transmit_status;
xprt_transmit(task);
if (task->tk_status < 0)
return;
- if (!task->tk_msg.rpc_proc->p_decode) {
- task->tk_action = rpc_exit_task;
- rpc_wake_up_task(task);
- }
- return;
-out_nosend:
- /* release socket write lock before attempting to handle error */
- xprt_abort_transmit(task);
+ /*
+ * On success, ensure that we call xprt_end_transmit() before sleeping
+ * in order to allow access to the socket to other RPC requests.
+ */
+ call_transmit_status(task);
+ if (task->tk_msg.rpc_proc->p_decode != NULL)
+ return;
+ task->tk_action = rpc_exit_task;
+ rpc_wake_up_task(task);
+}
+
+/*
+ * 5a. Handle cleanup after a transmission
+ */
+static void
+call_transmit_status(struct rpc_task *task)
+{
+ task->tk_action = call_status;
+ /*
+ * Special case: if we've been waiting on the socket's write_space()
+ * callback, then don't call xprt_end_transmit().
+ */
+ if (task->tk_status == -EAGAIN)
+ return;
+ xprt_end_transmit(task);
rpc_task_force_reencode(task);
}
@@ -992,18 +1009,7 @@ call_status(struct rpc_task *task)
}
/*
- * 6a. Handle transmission errors.
- */
-static void
-call_transmit_status(struct rpc_task *task)
-{
- if (task->tk_status != -EAGAIN)
- rpc_task_force_reencode(task);
- call_status(task);
-}
-
-/*
- * 6b. Handle RPC timeout
+ * 6a. Handle RPC timeout
* We do not release the request slot, so we keep using the
* same XID for all retransmits.
*/
Index: linux-2.6.17/net/sunrpc/rpc_pipe.c
===================================================================
--- linux-2.6.17.orig/net/sunrpc/rpc_pipe.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/net/sunrpc/rpc_pipe.c 2006-09-14 17:27:17.000000000 +0100
@@ -667,10 +667,11 @@ rpc_mkdir(char *path, struct rpc_clnt *r
RPCAUTH_info, RPCAUTH_EOF);
if (error)
goto err_depopulate;
+ dget(dentry);
out:
mutex_unlock(&dir->i_mutex);
rpc_release_path(&nd);
- return dget(dentry);
+ return dentry;
err_depopulate:
rpc_depopulate(dentry);
__rpc_rmdir(dir, dentry);
@@ -731,10 +732,11 @@ rpc_mkpipe(char *path, void *private, st
rpci->flags = flags;
rpci->ops = ops;
inode_dir_notify(dir, DN_CREATE);
+ dget(dentry);
out:
mutex_unlock(&dir->i_mutex);
rpc_release_path(&nd);
- return dget(dentry);
+ return dentry;
err_dput:
dput(dentry);
dentry = ERR_PTR(-ENOMEM);
Index: linux-2.6.17/net/sunrpc/xprt.c
===================================================================
--- linux-2.6.17.orig/net/sunrpc/xprt.c 2006-09-14 17:25:57.000000000 +0100
+++ linux-2.6.17/net/sunrpc/xprt.c 2006-09-14 17:27:17.000000000 +0100
@@ -707,12 +707,9 @@ out_unlock:
return err;
}
-void
-xprt_abort_transmit(struct rpc_task *task)
+void xprt_end_transmit(struct rpc_task *task)
{
- struct rpc_xprt *xprt = task->tk_xprt;
-
- xprt_release_write(xprt, task);
+ xprt_release_write(task->tk_xprt, task);
}
/**
@@ -761,8 +758,6 @@ void xprt_transmit(struct rpc_task *task
task->tk_status = -ENOTCONN;
else if (!req->rq_received)
rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer);
-
- xprt->ops->release_xprt(xprt, task);
spin_unlock_bh(&xprt->transport_lock);
return;
}
@@ -772,18 +767,8 @@ void xprt_transmit(struct rpc_task *task
* schedq, and being picked up by a parallel run of rpciod().
*/
task->tk_status = status;
-
- switch (status) {
- case -ECONNREFUSED:
+ if (status == -ECONNREFUSED)
rpc_sleep_on(&xprt->sending, task, NULL, NULL);
- case -EAGAIN:
- case -ENOTCONN:
- return;
- default:
- break;
- }
- xprt_release_write(xprt, task);
- return;
}
static inline void do_xprt_reserve(struct rpc_task *task)
Index: linux-2.6.17/net/sunrpc/xprtsock.c
===================================================================
--- linux-2.6.17.orig/net/sunrpc/xprtsock.c 2006-09-14 17:25:57.000000000 +0100
+++ linux-2.6.17/net/sunrpc/xprtsock.c 2006-09-14 17:27:17.000000000 +0100
@@ -414,6 +414,33 @@ static int xs_tcp_send_request(struct rp
}
/**
+ * xs_tcp_release_xprt - clean up after a tcp transmission
+ * @xprt: transport
+ * @task: rpc task
+ *
+ * This cleans up if an error causes us to abort the transmission of a request.
+ * In this case, the socket may need to be reset in order to avoid confusing
+ * the server.
+ */
+static void xs_tcp_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
+{
+ struct rpc_rqst *req;
+
+ if (task != xprt->snd_task)
+ return;
+ if (task == NULL)
+ goto out_release;
+ req = task->tk_rqstp;
+ if (req->rq_bytes_sent == 0)
+ goto out_release;
+ if (req->rq_bytes_sent == req->rq_snd_buf.len)
+ goto out_release;
+ set_bit(XPRT_CLOSE_WAIT, &task->tk_xprt->state);
+out_release:
+ xprt_release_xprt(xprt, task);
+}
+
+/**
* xs_close - close a socket
* @xprt: transport
*
@@ -1250,7 +1277,7 @@ static struct rpc_xprt_ops xs_udp_ops =
static struct rpc_xprt_ops xs_tcp_ops = {
.reserve_xprt = xprt_reserve_xprt,
- .release_xprt = xprt_release_xprt,
+ .release_xprt = xs_tcp_release_xprt,
.set_port = xs_set_port,
.connect = xs_connect,
.buf_alloc = rpc_malloc,
Index: linux-2.6.17/net/unix/af_unix.c
===================================================================
--- linux-2.6.17.orig/net/unix/af_unix.c 2006-09-14 17:25:58.000000000 +0100
+++ linux-2.6.17/net/unix/af_unix.c 2006-09-14 17:27:17.000000000 +0100
@@ -128,23 +128,17 @@ static atomic_t unix_nr_socks = ATOMIC_I
#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE)
#ifdef CONFIG_SECURITY_NETWORK
-static void unix_get_peersec_dgram(struct sk_buff *skb)
+static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
- int err;
-
- err = security_socket_getpeersec_dgram(skb, UNIXSECDATA(skb),
- UNIXSECLEN(skb));
- if (err)
- *(UNIXSECDATA(skb)) = NULL;
+ memcpy(UNIXSID(skb), &scm->secid, sizeof(u32));
}
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
- scm->secdata = *UNIXSECDATA(skb);
- scm->seclen = *UNIXSECLEN(skb);
+ scm->secid = *UNIXSID(skb);
}
#else
-static inline void unix_get_peersec_dgram(struct sk_buff *skb)
+static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{ }
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
@@ -1322,8 +1316,7 @@ static int unix_dgram_sendmsg(struct kio
memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
if (siocb->scm->fp)
unix_attach_fds(siocb->scm, skb);
-
- unix_get_peersec_dgram(skb);
+ unix_get_secdata(siocb->scm, skb);
skb->h.raw = skb->data;
err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
Index: linux-2.6.17/scripts/Kbuild.include
===================================================================
--- linux-2.6.17.orig/scripts/Kbuild.include 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/scripts/Kbuild.include 2006-09-14 17:27:17.000000000 +0100
@@ -77,14 +77,20 @@ cc-option-align = $(subst -functions=0,,
# cc-version
# Usage gcc-ver := $(call cc-version, $(CC))
-cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \
- $(if $(1), $(1), $(CC)))
+cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))
# cc-ifversion
# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
cc-ifversion = $(shell if [ $(call cc-version, $(CC)) $(1) $(2) ]; then \
echo $(3); fi;)
+# ld-option
+# Usage: ldflags += $(call ld-option, -Wl$(comma)--hash-style=both)
+ld-option = $(shell if $(CC) $(1) \
+ -nostdlib -o ldtest$$$$.out -xc /dev/null \
+ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi; \
+ rm -f ldtest$$$$.out)
+
###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage:
Index: linux-2.6.17/scripts/Makefile.modpost
===================================================================
--- linux-2.6.17.orig/scripts/Makefile.modpost 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/scripts/Makefile.modpost 2006-09-14 17:27:17.000000000 +0100
@@ -40,7 +40,7 @@ include scripts/Kbuild.include
include scripts/Makefile.lib
kernelsymfile := $(objtree)/Module.symvers
-modulesymfile := $(KBUILD_EXTMOD)/Modules.symvers
+modulesymfile := $(KBUILD_EXTMOD)/Module.symvers
# Step 1), find all modules listed in $(MODVERDIR)/
__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
Index: linux-2.6.17/scripts/kconfig/confdata.c
===================================================================
--- linux-2.6.17.orig/scripts/kconfig/confdata.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/scripts/kconfig/confdata.c 2006-09-14 17:27:17.000000000 +0100
@@ -357,7 +357,7 @@ int conf_read(const char *name)
for (e = prop->expr; e; e = e->left.expr)
if (e->right.sym->visible != no)
flags &= e->right.sym->flags;
- sym->flags |= flags & SYMBOL_DEF_USER;
+ sym->flags &= flags | ~SYMBOL_DEF_USER;
}
sym_change_count += conf_warnings || conf_unsaved;
Index: linux-2.6.17/scripts/kernel-doc
===================================================================
--- linux-2.6.17.orig/scripts/kernel-doc 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/scripts/kernel-doc 2006-09-14 17:27:17.000000000 +0100
@@ -1518,6 +1518,7 @@ sub dump_function($$) {
$prototype =~ s/^asmlinkage +//;
$prototype =~ s/^inline +//;
$prototype =~ s/^__inline__ +//;
+ $prototype =~ s/__devinit +//;
$prototype =~ s/^#define +//; #ak added
$prototype =~ s/__attribute__ \(\([a-z,]*\)\)//;
Index: linux-2.6.17/scripts/mod/file2alias.c
===================================================================
--- linux-2.6.17.orig/scripts/mod/file2alias.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/scripts/mod/file2alias.c 2006-09-14 17:27:17.000000000 +0100
@@ -52,6 +52,23 @@ do {
sprintf(str + strlen(str), "*"); \
} while(0)
+/**
+ * Check that sizeof(device_id type) are consistent with size of section
+ * in .o file. If in-consistent then userspace and kernel does not agree
+ * on actual size which is a bug.
+ **/
+static void device_id_size_check(const char *modname, const char *device_id,
+ unsigned long size, unsigned long id_size)
+{
+ if (size % id_size || size < id_size) {
+ fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo "
+ "of the size of section __mod_%s_device_table=%lu.\n"
+ "Fix definition of struct %s_device_id "
+ "in mod_devicetable.h\n",
+ modname, device_id, id_size, device_id, size, device_id);
+ }
+}
+
/* USB is special because the bcdDevice can be matched against a numeric range */
/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
static void do_usb_entry(struct usb_device_id *id,
@@ -152,10 +169,8 @@ static void do_usb_table(void *symval, u
unsigned int i;
const unsigned long id_size = sizeof(struct usb_device_id);
- if (size % id_size || size < id_size) {
- warn("%s ids %lu bad size "
- "(each on %lu)\n", mod->name, size, id_size);
- }
+ device_id_size_check(mod->name, "usb", size, id_size);
+
/* Leave last one: it's the terminator. */
size -= id_size;
@@ -434,6 +449,7 @@ static inline int sym_is(const char *sym
static void do_table(void *symval, unsigned long size,
unsigned long id_size,
+ const char *device_id,
void *function,
struct module *mod)
{
@@ -441,10 +457,7 @@ static void do_table(void *symval, unsig
char alias[500];
int (*do_entry)(const char *, void *entry, char *alias) = function;
- if (size % id_size || size < id_size) {
- warn("%s ids %lu bad size "
- "(each on %lu)\n", mod->name, size, id_size);
- }
+ device_id_size_check(mod->name, device_id, size, id_size);
/* Leave last one: it's the terminator. */
size -= id_size;
@@ -476,40 +489,51 @@ void handle_moddevtable(struct module *m
+ sym->st_value;
if (sym_is(symname, "__mod_pci_device_table"))
- do_table(symval, sym->st_size, sizeof(struct pci_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct pci_device_id), "pci",
do_pci_entry, mod);
else if (sym_is(symname, "__mod_usb_device_table"))
/* special case to handle bcdDevice ranges */
do_usb_table(symval, sym->st_size, mod);
else if (sym_is(symname, "__mod_ieee1394_device_table"))
- do_table(symval, sym->st_size, sizeof(struct ieee1394_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct ieee1394_device_id), "ieee1394",
do_ieee1394_entry, mod);
else if (sym_is(symname, "__mod_ccw_device_table"))
- do_table(symval, sym->st_size, sizeof(struct ccw_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct ccw_device_id), "ccw",
do_ccw_entry, mod);
else if (sym_is(symname, "__mod_serio_device_table"))
- do_table(symval, sym->st_size, sizeof(struct serio_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct serio_device_id), "serio",
do_serio_entry, mod);
else if (sym_is(symname, "__mod_pnp_device_table"))
- do_table(symval, sym->st_size, sizeof(struct pnp_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct pnp_device_id), "pnp",
do_pnp_entry, mod);
else if (sym_is(symname, "__mod_pnp_card_device_table"))
- do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct pnp_card_device_id), "pnp_card",
do_pnp_card_entry, mod);
else if (sym_is(symname, "__mod_pcmcia_device_table"))
- do_table(symval, sym->st_size, sizeof(struct pcmcia_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct pcmcia_device_id), "pcmcia",
do_pcmcia_entry, mod);
else if (sym_is(symname, "__mod_of_device_table"))
- do_table(symval, sym->st_size, sizeof(struct of_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct of_device_id), "of",
do_of_entry, mod);
else if (sym_is(symname, "__mod_vio_device_table"))
- do_table(symval, sym->st_size, sizeof(struct vio_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct vio_device_id), "vio",
do_vio_entry, mod);
else if (sym_is(symname, "__mod_i2c_device_table"))
- do_table(symval, sym->st_size, sizeof(struct i2c_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct i2c_device_id), "i2c",
do_i2c_entry, mod);
else if (sym_is(symname, "__mod_input_device_table"))
- do_table(symval, sym->st_size, sizeof(struct input_device_id),
+ do_table(symval, sym->st_size,
+ sizeof(struct input_device_id), "input",
do_input_entry, mod);
}
Index: linux-2.6.17/security/dummy.c
===================================================================
--- linux-2.6.17.orig/security/dummy.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/security/dummy.c 2006-09-14 17:27:17.000000000 +0100
@@ -791,8 +791,7 @@ static int dummy_socket_getpeersec_strea
return -ENOPROTOOPT;
}
-static int dummy_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata,
- u32 *seclen)
+static int dummy_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
{
return -ENOPROTOOPT;
}
@@ -876,6 +875,15 @@ static int dummy_setprocattr(struct task
return -EINVAL;
}
+static int dummy_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+{
+ return -EOPNOTSUPP;
+}
+
+static void dummy_release_secctx(char *secdata, u32 seclen)
+{
+}
+
#ifdef CONFIG_KEYS
static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx,
unsigned long flags)
@@ -1028,6 +1036,8 @@ void security_fixup_ops (struct security
set_to_dummy_if_null(ops, d_instantiate);
set_to_dummy_if_null(ops, getprocattr);
set_to_dummy_if_null(ops, setprocattr);
+ set_to_dummy_if_null(ops, secid_to_secctx);
+ set_to_dummy_if_null(ops, release_secctx);
#ifdef CONFIG_SECURITY_NETWORK
set_to_dummy_if_null(ops, unix_stream_connect);
set_to_dummy_if_null(ops, unix_may_send);
Index: linux-2.6.17/security/selinux/hooks.c
===================================================================
--- linux-2.6.17.orig/security/selinux/hooks.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/security/selinux/hooks.c 2006-09-14 17:27:17.000000000 +0100
@@ -3524,25 +3524,21 @@ out:
return err;
}
-static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
+static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
{
+ u32 peer_secid = SECSID_NULL;
int err = 0;
- u32 peer_sid;
- if (skb->sk->sk_family == PF_UNIX)
- selinux_get_inode_sid(SOCK_INODE(skb->sk->sk_socket),
- &peer_sid);
- else
- peer_sid = selinux_socket_getpeer_dgram(skb);
-
- if (peer_sid == SECSID_NULL)
- return -EINVAL;
+ if (sock && (sock->sk->sk_family == PF_UNIX))
+ selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
+ else if (skb)
+ peer_secid = selinux_socket_getpeer_dgram(skb);
- err = security_sid_to_context(peer_sid, secdata, seclen);
- if (err)
- return err;
+ if (peer_secid == SECSID_NULL)
+ err = -EINVAL;
+ *secid = peer_secid;
- return 0;
+ return err;
}
static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
@@ -4407,6 +4403,17 @@ static int selinux_setprocattr(struct ta
return size;
}
+static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+{
+ return security_sid_to_context(secid, secdata, seclen);
+}
+
+static void selinux_release_secctx(char *secdata, u32 seclen)
+{
+ if (secdata)
+ kfree(secdata);
+}
+
#ifdef CONFIG_KEYS
static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
@@ -4587,6 +4594,9 @@ static struct security_operations selinu
.getprocattr = selinux_getprocattr,
.setprocattr = selinux_setprocattr,
+ .secid_to_secctx = selinux_secid_to_secctx,
+ .release_secctx = selinux_release_secctx,
+
.unix_stream_connect = selinux_socket_unix_stream_connect,
.unix_may_send = selinux_socket_unix_may_send,
Index: linux-2.6.17/security/selinux/ss/policydb.c
===================================================================
--- linux-2.6.17.orig/security/selinux/ss/policydb.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/security/selinux/ss/policydb.c 2006-09-14 17:27:17.000000000 +0100
@@ -644,10 +644,18 @@ void policydb_destroy(struct policydb *p
kfree(lra);
for (rt = p->range_tr; rt; rt = rt -> next) {
- kfree(lrt);
+ if (lrt) {
+ ebitmap_destroy(&lrt->range.level[0].cat);
+ ebitmap_destroy(&lrt->range.level[1].cat);
+ kfree(lrt);
+ }
lrt = rt;
}
- kfree(lrt);
+ if (lrt) {
+ ebitmap_destroy(&lrt->range.level[0].cat);
+ ebitmap_destroy(&lrt->range.level[1].cat);
+ kfree(lrt);
+ }
if (p->type_attr_map) {
for (i = 0; i < p->p_types.nprim; i++)
Index: linux-2.6.17/security/selinux/ss/services.c
===================================================================
--- linux-2.6.17.orig/security/selinux/ss/services.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/security/selinux/ss/services.c 2006-09-14 17:27:17.000000000 +0100
@@ -833,6 +833,8 @@ static int security_compute_sid(u32 ssid
goto out;
}
+ context_init(&newcontext);
+
POLICY_RDLOCK;
scontext = sidtab_search(&sidtab, ssid);
@@ -850,8 +852,6 @@ static int security_compute_sid(u32 ssid
goto out_unlock;
}
- context_init(&newcontext);
-
/* Set the user identity. */
switch (specified) {
case AVTAB_TRANSITION:
Index: linux-2.6.17/sound/aoa/codecs/snd-aoa-codec-toonie.c
===================================================================
--- linux-2.6.17.orig/sound/aoa/codecs/snd-aoa-codec-toonie.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/sound/aoa/codecs/snd-aoa-codec-toonie.c 2006-09-14 17:27:17.000000000 +0100
@@ -51,6 +51,13 @@ static struct transfer_info toonie_trans
{}
};
+static int toonie_usable(struct codec_info_item *cii,
+ struct transfer_info *ti,
+ struct transfer_info *out)
+{
+ return 1;
+}
+
#ifdef CONFIG_PM
static int toonie_suspend(struct codec_info_item *cii, pm_message_t state)
{
@@ -69,6 +76,7 @@ static struct codec_info toonie_codec_in
.sysclock_factor = 256,
.bus_factor = 64,
.owner = THIS_MODULE,
+ .usable = toonie_usable,
#ifdef CONFIG_PM
.suspend = toonie_suspend,
.resume = toonie_resume,
@@ -79,19 +87,20 @@ static int toonie_init_codec(struct aoa_
{
struct toonie *toonie = codec_to_toonie(codec);
+ /* nothing connected? what a joke! */
+ if (toonie->codec.connected != 1)
+ return -ENOTCONN;
+
if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, toonie, &ops)) {
printk(KERN_ERR PFX "failed to create toonie snd device!\n");
return -ENODEV;
}
- /* nothing connected? what a joke! */
- if (toonie->codec.connected != 1)
- return -ENOTCONN;
-
if (toonie->codec.soundbus_dev->attach_codec(toonie->codec.soundbus_dev,
aoa_get_card(),
&toonie_codec_info, toonie)) {
printk(KERN_ERR PFX "error creating toonie pcm\n");
+ snd_device_free(aoa_get_card(), toonie);
return -ENODEV;
}
Index: linux-2.6.17/sound/aoa/core/snd-aoa-gpio-feature.c
===================================================================
--- linux-2.6.17.orig/sound/aoa/core/snd-aoa-gpio-feature.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/sound/aoa/core/snd-aoa-gpio-feature.c 2006-09-14 17:27:17.000000000 +0100
@@ -112,7 +112,10 @@ static struct device_node *get_gpio(char
static void get_irq(struct device_node * np, int *irqptr)
{
- *irqptr = irq_of_parse_and_map(np, 0);
+ if (np)
+ *irqptr = irq_of_parse_and_map(np, 0);
+ else
+ *irqptr = NO_IRQ;
}
/* 0x4 is outenable, 0x1 is out, thus 4 or 5 */
@@ -322,7 +325,7 @@ static int ftr_set_notify(struct gpio_ru
return -EINVAL;
}
- if (irq == -1)
+ if (irq == NO_IRQ)
return -ENODEV;
mutex_lock(¬if->mutex);
Index: linux-2.6.17/sound/aoa/core/snd-aoa-gpio-pmf.c
===================================================================
--- linux-2.6.17.orig/sound/aoa/core/snd-aoa-gpio-pmf.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/sound/aoa/core/snd-aoa-gpio-pmf.c 2006-09-14 17:27:17.000000000 +0100
@@ -18,7 +18,7 @@ static void pmf_gpio_set_##name(struct g
\
if (unlikely(!rt)) return; \
rc = pmf_call_function(rt->node, #name "-mute", &args); \
- if (rc) \
+ if (rc && rc != -ENODEV) \
printk(KERN_WARNING "pmf_gpio_set_" #name \
" failed, rc: %d\n", rc); \
rt->implementation_private &= ~(1<index == 0 && (kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0)) != NULL) {
struct snd_ctl_elem_info *uinfo;
- uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL);
+ uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
if (! uinfo) {
up_read(&mixer->card->controls_rwsem);
return -ENOMEM;
}
- memset(uinfo, 0, sizeof(*uinfo));
if (kctl->info(kctl, uinfo)) {
up_read(&mixer->card->controls_rwsem);
return 0;
Index: linux-2.6.17/sound/core/oss/pcm_oss.c
===================================================================
--- linux-2.6.17.orig/sound/core/oss/pcm_oss.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/sound/core/oss/pcm_oss.c 2006-09-14 17:27:17.000000000 +0100
@@ -2228,6 +2228,8 @@ static int snd_pcm_oss_open_file(struct
for (idx = 0; idx < 2; idx++) {
if (setup[idx].disable)
continue;
+ if (! pcm->streams[idx].substream_count)
+ continue; /* no matching substream */
if (idx == SNDRV_PCM_STREAM_PLAYBACK) {
if (! (f_mode & FMODE_WRITE))
continue;
Index: linux-2.6.17/sound/core/seq/seq_device.c
===================================================================
--- linux-2.6.17.orig/sound/core/seq/seq_device.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/sound/core/seq/seq_device.c 2006-09-14 17:27:17.000000000 +0100
@@ -372,10 +372,9 @@ static struct ops_list * create_driver(c
{
struct ops_list *ops;
- ops = kmalloc(sizeof(*ops), GFP_KERNEL);
+ ops = kzalloc(sizeof(*ops), GFP_KERNEL);
if (ops == NULL)
return ops;
- memset(ops, 0, sizeof(*ops));
/* set up driver entry */
strlcpy(ops->id, id, sizeof(ops->id));
Index: linux-2.6.17/sound/core/sgbuf.c
===================================================================
--- linux-2.6.17.orig/sound/core/sgbuf.c 2006-09-14 16:26:48.000000000 +0100
+++ linux-2.6.17/sound/core/sgbuf.c 2006-09-14 17:27:17.000000000 +0100
@@ -68,21 +68,18 @@ void *snd_malloc_sgbuf_pages(struct devi
dmab->area = NULL;
dmab->addr = 0;
- dmab->private_data = sgbuf = kmalloc(sizeof(*sgbuf), GFP_KERNEL);
+ dmab->private_data = sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL);
if (! sgbuf)
return NULL;
- memset(sgbuf, 0, sizeof(*sgbuf));
sgbuf->dev = device;
pages = snd_sgbuf_aligned_pages(size);
sgbuf->tblsize = sgbuf_align_table(pages);
- sgbuf->table = kmalloc(sizeof(*sgbuf->table) * sgbuf->tblsize, GFP_KERNEL);
+ sgbuf->table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->table), GFP_KERNEL);
if (! sgbuf->table)
goto _failed;
- memset(sgbuf->table, 0, sizeof(*sgbuf->table) * sgbuf->tblsize);
- sgbuf->page_table = kmalloc(sizeof(*sgbuf->page_table) * sgbuf->tblsize, GFP_KERNEL);
+ sgbuf->page_table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->page_table), GFP_KERNEL);
if (! sgbuf->page_table)
goto _failed;
- memset(sgbuf->page_table, 0, sizeof(*sgbuf->page_table) * sgbuf->tblsize);
/* allocate each page */
for (i = 0; i < pages; i++) {
Index: linux-2.6.17/sound/drivers/vx/vx_pcm.c
===================================================================
--- linux-2.6.17.orig/sound/drivers/vx/vx_pcm.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/sound/drivers/vx/vx_pcm.c 2006-09-14 17:27:17.000000000 +0100
@@ -1252,18 +1252,15 @@ static int vx_init_audio_io(struct vx_co
chip->audio_info = rmh.Stat[1];
/* allocate pipes */
- chip->playback_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_outs, GFP_KERNEL);
+ chip->playback_pipes = kcalloc(chip->audio_outs, sizeof(struct vx_pipe *), GFP_KERNEL);
if (!chip->playback_pipes)
return -ENOMEM;
- chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL);
+ chip->capture_pipes = kcalloc(chip->audio_ins, sizeof(struct vx_pipe *), GFP_KERNEL);
if (!chip->capture_pipes) {
kfree(chip->playback_pipes);
return -ENOMEM;
}
- memset(chip->playback_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_outs);
- memset(chip->capture_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_ins);
-
preferred = chip->ibl.size;
chip->ibl.size = 0;
vx_set_ibl(chip, &chip->ibl); /* query the info */
Index: linux-2.6.17/sound/pci/echoaudio/echoaudio.c
===================================================================
--- linux-2.6.17.orig/sound/pci/echoaudio/echoaudio.c 2006-09-14 16:26:49.000000000 +0100
+++ linux-2.6.17/sound/pci/echoaudio/echoaudio.c 2006-09-14 17:27:17.000000000 +0100
@@ -236,9 +236,9 @@ static int pcm_open(struct snd_pcm_subst
chip = snd_pcm_substream_chip(substream);
runtime = substream->runtime;
- if (!(pipe = kmalloc(sizeof(struct audiopipe), GFP_KERNEL)))
+ pipe = kzalloc(sizeof(struct audiopipe), GFP_KERNEL);
+ if (!pipe)
return -ENOMEM;
- memset(pipe, 0, sizeof(struct audiopipe));
pipe->index = -1; /* Not configured yet */
/* Set up hw capabilities and contraints */
Index: linux-2.6.17/sound/pci/emu10k1/emu10k1_main.c
===================================================================
--- linux-2.6.17.orig/sound/pci/emu10k1/emu10k1_main.c 2006-09-14 17:21:49.000000000 +0100
+++ linux-2.6.17/sound/pci/emu10k1/emu10k1_main.c 2006-09-14 17:27:18.000000000 +0100
@@ -936,6 +936,17 @@ static struct snd_emu_chip_details emu_c
.ca0151_chip = 1,
.spk71 = 1,
.spdif_bug = 1} ,
+ /* Dell OEM/Creative Labs Audigy 2 ZS */
+ /* See ALSA bug#1365 */
+ {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102,
+ .driver = "Audigy2", .name = "Audigy 2 ZS [SB0353]",
+ .id = "Audigy2",
+ .emu10k2_chip = 1,
+ .ca0102_chip = 1,
+ .ca0151_chip = 1,
+ .spk71 = 1,
+ .spdif_bug = 1,
+ .ac97_chip = 1} ,
{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
.driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]",
.id = "Audigy2",
Index: linux-2.6.17/sound/pci/emu10k1/irq.c
===================================================================
--- linux-2.6.17.orig/sound/pci/emu10k1/irq.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/sound/pci/emu10k1/irq.c 2006-09-14 17:27:18.000000000 +0100
@@ -37,9 +37,13 @@ irqreturn_t snd_emu10k1_interrupt(int ir
int handled = 0;
while ((status = inl(emu->port + IPR)) != 0) {
- //printk("emu10k1 irq - status = 0x%x\n", status);
+ //snd_printk(KERN_INFO "emu10k1 irq - status = 0x%x\n", status);
orig_status = status;
handled = 1;
+ if ((status & 0xffffffff) == 0xffffffff) {
+ snd_printk(KERN_INFO "snd-emu10k1: Suspected sound card removal\n");
+ break;
+ }
if (status & IPR_PCIERROR) {
snd_printk(KERN_ERR "interrupt: PCI error\n");
snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
Index: linux-2.6.17/sound/ppc/awacs.c
===================================================================
--- linux-2.6.17.orig/sound/ppc/awacs.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/sound/ppc/awacs.c 2006-09-14 17:27:18.000000000 +0100
@@ -801,11 +801,10 @@ snd_pmac_awacs_init(struct snd_pmac *chi
chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf;
#ifdef PMAC_AMP_AVAIL
if (chip->revision == 3 && chip->has_iic && CHECK_CUDA_AMP()) {
- struct awacs_amp *amp = kmalloc(sizeof(*amp), GFP_KERNEL);
+ struct awacs_amp *amp = kzalloc(sizeof(*amp), GFP_KERNEL);
if (! amp)
return -ENOMEM;
chip->mixer_data = amp;
- memset(amp, 0, sizeof(*amp));
chip->mixer_free = awacs_amp_free;
awacs_amp_set_vol(amp, 0, 63, 63, 0); /* mute and zero vol */
awacs_amp_set_vol(amp, 1, 63, 63, 0);
Index: linux-2.6.17/sound/ppc/daca.c
===================================================================
--- linux-2.6.17.orig/sound/ppc/daca.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/sound/ppc/daca.c 2006-09-14 17:27:18.000000000 +0100
@@ -258,10 +258,9 @@ int __init snd_pmac_daca_init(struct snd
request_module("i2c-powermac");
#endif /* CONFIG_KMOD */
- mix = kmalloc(sizeof(*mix), GFP_KERNEL);
+ mix = kzalloc(sizeof(*mix), GFP_KERNEL);
if (! mix)
return -ENOMEM;
- memset(mix, 0, sizeof(*mix));
chip->mixer_data = mix;
chip->mixer_free = daca_cleanup;
mix->amp_on = 1; /* default on */
Index: linux-2.6.17/sound/ppc/keywest.c
===================================================================
--- linux-2.6.17.orig/sound/ppc/keywest.c 2006-06-18 02:49:35.000000000 +0100
+++ linux-2.6.17/sound/ppc/keywest.c 2006-09-14 17:27:18.000000000 +0100
@@ -64,11 +64,10 @@ static int keywest_attach_adapter(struct
if (strncmp(i2c_device_name(adapter), "mac-io", 6))
return 0; /* ignored */
- new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (! new_client)
return -ENOMEM;
- memset(new_client, 0, sizeof(*new_client));
new_client->addr = keywest_ctx->addr;
i2c_set_clientdata(new_client, keywest_ctx);
new_client->adapter = adapter;
Index: linux-2.6.17/sound/ppc/powermac.c
===================================================================
--- linux-2.6.17.orig/sound/ppc/powermac.c 2006-09-14 16:26:50.000000000 +0100
+++ linux-2.6.17/sound/ppc/powermac.c 2006-09-14 17:27:18.000000000 +0100
@@ -181,21 +181,14 @@ static int __init alsa_card_pmac_init(vo
if ((err = platform_driver_register(&snd_pmac_driver)) < 0)
return err;
device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0);
- if (!IS_ERR(device)) {
- if (platform_get_drvdata(device))
- return 0;
- platform_device_unregister(device);
- err = -ENODEV;
- } else
- err = PTR_ERR(device);
- platform_driver_unregister(&snd_pmac_driver);
- return err;
+ return 0;
}
static void __exit alsa_card_pmac_exit(void)
{
- platform_device_unregister(device);
+ if (!IS_ERR(device))
+ platform_device_unregister(device);
platform_driver_unregister(&snd_pmac_driver);
}
Index: linux-2.6.17/sound/ppc/tumbler.c
===================================================================
--- linux-2.6.17.orig/sound/ppc/tumbler.c 2006-09-14 16:26:50.000000000 +0100
+++ linux-2.6.17/sound/ppc/tumbler.c 2006-09-14 17:27:18.000000000 +0100
@@ -1316,10 +1316,9 @@ int __init snd_pmac_tumbler_init(struct
request_module("i2c-powermac");
#endif /* CONFIG_KMOD */
- mix = kmalloc(sizeof(*mix), GFP_KERNEL);
+ mix = kzalloc(sizeof(*mix), GFP_KERNEL);
if (! mix)
return -ENOMEM;
- memset(mix, 0, sizeof(*mix));
mix->headphone_irq = -1;
chip->mixer_data = mix;
Index: linux-2.6.17/sound/usb/usbaudio.c
===================================================================
--- linux-2.6.17.orig/sound/usb/usbaudio.c 2006-09-14 16:26:51.000000000 +0100
+++ linux-2.6.17/sound/usb/usbaudio.c 2006-09-14 17:27:18.000000000 +0100
@@ -2260,10 +2260,9 @@ static int add_audio_endpoint(struct snd
}
/* create a new pcm */
- as = kmalloc(sizeof(*as), GFP_KERNEL);
+ as = kzalloc(sizeof(*as), GFP_KERNEL);
if (! as)
return -ENOMEM;
- memset(as, 0, sizeof(*as));
as->pcm_index = chip->pcm_devs;
as->chip = chip;
as->fmt_type = fp->fmt_type;
@@ -2633,13 +2632,12 @@ static int parse_audio_endpoints(struct
csep = NULL;
}
- fp = kmalloc(sizeof(*fp), GFP_KERNEL);
+ fp = kzalloc(sizeof(*fp), GFP_KERNEL);
if (! fp) {
snd_printk(KERN_ERR "cannot malloc\n");
return -ENOMEM;
}
- memset(fp, 0, sizeof(*fp));
fp->iface = iface_no;
fp->altsetting = altno;
fp->altset_idx = i;