We (the -stable team) are announcing the release of the 2.6.22.14 kernel.
It fixes a bunch of issues, so any user of the 2.6.22 series is
encouraged to upgrade.
I'll also be replying to this message with a copy of the patch between
2.6.22.13 and 2.6.22.14
The updated 2.6.22.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.22.y.git
and can be browsed at the normal kernel.org git web browser:
http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.22.y.git;a=summary
thanks,
greg k-h
--------
Makefile | 2
arch/i386/kernel/tsc.c | 5
drivers/i2c/busses/i2c-pasemi.c | 5
drivers/i2c/chips/eeprom.c | 37 ++++---
drivers/ide/pci/serverworks.c | 1
drivers/isdn/hardware/avm/b1.c | 28 ++---
drivers/isdn/hardware/avm/c4.c | 14 ++
drivers/net/forcedeth.c | 19 ++-
drivers/scsi/hptiop.c | 5
drivers/usb/core/hcd.h | 8 +
drivers/usb/core/hub.c | 15 ++
drivers/usb/host/ehci-hcd.c | 8 +
drivers/usb/serial/generic.c | 7 -
drivers/usb/serial/kobil_sct.c | 170 +++++++++++++--------------------
fs/ocfs2/aops.c | 24 ++++
include/linux/netlink.h | 2
ipc/mqueue.c | 6 -
kernel/futex_compat.c | 24 +++-
kernel/params.c | 15 +-
mm/page-writeback.c | 4
mm/shmem.c | 15 ++
mm/slub.c | 22 ----
net/ipv4/ipcomp.c | 3
net/ipv6/ipcomp6.c | 3
net/netfilter/nf_conntrack_proto_tcp.c | 38 +++----
net/netlink/af_netlink.c | 10 -
net/sched/cls_u32.c | 4
net/sched/sch_teql.c | 3
net/socket.c | 5
sound/pci/hda/patch_sigmatel.c | 14 +-
sound/pci/rme9652/hdsp.c | 3
31 files changed, 291 insertions(+), 228 deletions(-)
Summary of changes from v2.6.22.13 to v2.6.22.14
================================================
Alan Stern (1):
USB: mutual exclusion for EHCI init and port resets
Andrew Morton (1):
writeback: don't propagate AOP_WRITEPAGE_ACTIVATE
Christoph Lameter (1):
SLUB: Fix memory leak by not reusing cpu_slab
Dave Johnson (1):
x86: fix TSC clock source calibration error
David Miller (2):
Fix compat futex hangs.
Fix error returns in sys_socketpair()
Evgeniy Polyakov (1):
Fix TEQL oops.
Frank Seidel (1):
USB: kobil_sct: trivial backport to fix libct
Greg Kroah-Hartman (1):
Linux 2.6.22.14
Herbert Xu (1):
Fix crypto_alloc_comp() error checking.
HighPoint Linux Team (1):
hptiop: avoid buffer overflow when returning sense data
Hugh Dickins (1):
fix tmpfs BUG and AOP_WRITEPAGE_ACTIVATE
Jan Kiszka (1):
fix param_sysfs_builtin name length check
Jean Delvare (3):
i2c-pasemi: Fix NACK detection
i2c/eeprom: Hide Sony Vaio serial numbers
i2c/eeprom: Recognize VGN as a valid Sony Vaio name prefix
Jiri Kosina (1):
USB: usbserial - fix potential deadlock between write() and IRQ
Jozsef Kadlecsik (1):
NETFILTER: nf_conntrack_tcp: fix connection reopening
Karsten Keil (2):
i4l: Fix random hard freeze with AVM c4 card
i4l: fix random freezes with AVM B1 drivers
Manfred Spraul (1):
forcedeth msi bugfix
Mark Fasheh (1):
ocfs2: fix write() performance regression
Patrick McHardy (1):
Fix netlink timeouts.
Radu Rendec (1):
Fix endianness bug in U32 classifier.
Takashi Iwai (2):
ALSA: hdsp - Fix zero division
ALSA: hda-codec - Add array terminator for dmic in STAC codec
Tony Battersby (1):
ide: fix serverworks.c UDMA regression
diff --git a/Makefile b/Makefile
index 500f6a8..873c786 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 22
-EXTRAVERSION = .13
+EXTRAVERSION = .14
NAME = Holy Dancing Manatees, Batman!
# *DOCUMENTATION*
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
index f64b81f..8e02ed6 100644
--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -122,7 +122,7 @@ unsigned long native_calculate_cpu_khz(void)
{
unsigned long long start, end;
unsigned long count;
- u64 delta64;
+ u64 delta64 = (u64)ULLONG_MAX;
int i;
unsigned long flags;
@@ -134,6 +134,7 @@ unsigned long native_calculate_cpu_khz(void)
rdtscll(start);
mach_countup(&count);
rdtscll(end);
+ delta64 = min(delta64, (end - start));
}
/*
* Error: ECTCNEVERSET
@@ -144,8 +145,6 @@ unsigned long native_calculate_cpu_khz(void)
if (count <= 1)
goto err;
- delta64 = end - start;
-
/* cpu freq too fast: */
if (delta64 > (1ULL<<32))
goto err;
diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c
index 58e3271..dcf5dec 100644
--- a/drivers/i2c/busses/i2c-pasemi.c
+++ b/drivers/i2c/busses/i2c-pasemi.c
@@ -51,6 +51,7 @@ struct pasemi_smbus {
#define MRXFIFO_DATA_M 0x000000ff
#define SMSTA_XEN 0x08000000
+#define SMSTA_MTN 0x00200000
#define CTL_MRR 0x00000400
#define CTL_MTR 0x00000200
@@ -98,6 +99,10 @@ static unsigned int pasemi_smb_waitready(struct pasemi_smbus *smbus)
status = reg_read(smbus, REG_SMSTA);
}
+ /* Got NACK? */
+ if (status & SMSTA_MTN)
+ return -ENXIO;
+
if (timeout < 0) {
dev_warn(&smbus->dev->dev, "Timeout, status 0x%08x\n", status);
reg_write(smbus, REG_SMSTA, status);
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
index bfce13c..5ad36ab 100644
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -125,13 +125,20 @@ static ssize_t eeprom_read(struct kobject *kobj, char *buf, loff_t off, size_t c
for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++)
eeprom_update_client(client, slice);
- /* Hide Vaio security settings to regular users (16 first bytes) */
- if (data->nature == VAIO && off < 16 && !capable(CAP_SYS_ADMIN)) {
- size_t in_row1 = 16 - off;
- in_row1 = min(in_row1, count);
- memset(buf, 0, in_row1);
- if (count - in_row1 > 0)
- memcpy(buf + in_row1, &data->data[16], count - in_row1);
+ /* Hide Vaio private settings to regular users:
+ - BIOS passwords: bytes 0x00 to 0x0f
+ - UUID: bytes 0x10 to 0x1f
+ - Serial number: 0xc0 to 0xdf */
+ if (data->nature == VAIO && !capable(CAP_SYS_ADMIN)) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if ((off + i <= 0x1f) ||
+ (off + i >= 0xc0 && off + i <= 0xdf))
+ buf[i] = 0;
+ else
+ buf[i] = data->data[off + i];
+ }
} else {
memcpy(buf, &data->data[off], count);
}
@@ -195,14 +202,18 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_kfree;
/* Detect the Vaio nature of EEPROMs.
- We use the "PCG-" prefix as the signature. */
+ We use the "PCG-" or "VGN-" prefix as the signature. */
if (address == 0x57) {
- if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P'
- && i2c_smbus_read_byte(new_client) == 'C'
- && i2c_smbus_read_byte(new_client) == 'G'
- && i2c_smbus_read_byte(new_client) == '-') {
+ char name[4];
+
+ name[0] = i2c_smbus_read_byte_data(new_client, 0x80);
+ name[1] = i2c_smbus_read_byte(new_client);
+ name[2] = i2c_smbus_read_byte(new_client);
+ name[3] = i2c_smbus_read_byte(new_client);
+
+ if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) {
dev_info(&new_client->dev, "Vaio EEPROM detected, "
- "enabling password protection\n");
+ "enabling privacy protection\n");
data->nature = VAIO;
}
}
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index d9c4fd1..096a081 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -101,6 +101,7 @@ static u8 svwks_udma_filter(ide_drive_t *drive)
mode = 2;
switch(mode) {
+ case 3: mask = 0x3f; break;
case 2: mask = 0x1f; break;
case 1: mask = 0x07; break;
default: mask = 0x00; break;
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index 7a69a18..4484a64 100644
--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -321,12 +321,15 @@ void b1_reset_ctr(struct capi_ctr *ctrl)
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card;
unsigned int port = card->port;
+ unsigned long flags;
b1_reset(port);
b1_reset(port);
memset(cinfo->version, 0, sizeof(cinfo->version));
+ spin_lock_irqsave(&card->lock, flags);
capilib_release(&cinfo->ncci_head);
+ spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_reseted(ctrl);
}
@@ -361,9 +364,8 @@ void b1_release_appl(struct capi_ctr *ctrl, u16 appl)
unsigned int port = card->port;
unsigned long flags;
- capilib_release_appl(&cinfo->ncci_head, appl);
-
spin_lock_irqsave(&card->lock, flags);
+ capilib_release_appl(&cinfo->ncci_head, appl);
b1_put_byte(port, SEND_RELEASE);
b1_put_word(port, appl);
spin_unlock_irqrestore(&card->lock, flags);
@@ -380,27 +382,27 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
u16 dlen, retval;
+ spin_lock_irqsave(&card->lock, flags);
if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
retval = capilib_data_b3_req(&cinfo->ncci_head,
CAPIMSG_APPID(skb->data),
CAPIMSG_NCCI(skb->data),
CAPIMSG_MSGID(skb->data));
- if (retval != CAPI_NOERROR)
+ if (retval != CAPI_NOERROR) {
+ spin_unlock_irqrestore(&card->lock, flags);
return retval;
+ }
dlen = CAPIMSG_DATALEN(skb->data);
- spin_lock_irqsave(&card->lock, flags);
b1_put_byte(port, SEND_DATA_B3_REQ);
b1_put_slice(port, skb->data, len);
b1_put_slice(port, skb->data + len, dlen);
- spin_unlock_irqrestore(&card->lock, flags);
} else {
- spin_lock_irqsave(&card->lock, flags);
b1_put_byte(port, SEND_MESSAGE);
b1_put_slice(port, skb->data, len);
- spin_unlock_irqrestore(&card->lock, flags);
}
+ spin_unlock_irqrestore(&card->lock, flags);
dev_kfree_skb_any(skb);
return CAPI_NOERROR;
@@ -534,17 +536,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
ApplId = (unsigned) b1_get_word(card->port);
MsgLen = b1_get_slice(card->port, card->msgbuf);
- spin_unlock_irqrestore(&card->lock, flags);
if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
printk(KERN_ERR "%s: incoming packet dropped\n",
card->name);
+ spin_unlock_irqrestore(&card->lock, flags);
} else {
memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
CAPIMSG_NCCI(skb->data),
CAPIMSG_MSGID(skb->data));
-
+ spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_handle_message(ctrl, ApplId, skb);
}
break;
@@ -554,21 +556,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
ApplId = b1_get_word(card->port);
NCCI = b1_get_word(card->port);
WindowSize = b1_get_word(card->port);
- spin_unlock_irqrestore(&card->lock, flags);
-
capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+ spin_unlock_irqrestore(&card->lock, flags);
break;
case RECEIVE_FREE_NCCI:
ApplId = b1_get_word(card->port);
NCCI = b1_get_word(card->port);
- spin_unlock_irqrestore(&card->lock, flags);
-
if (NCCI != 0xffffffff)
capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-
+ spin_unlock_irqrestore(&card->lock, flags);
break;
case RECEIVE_START:
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index d58f927..8710cf6 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -727,6 +727,7 @@ static void c4_send_init(avmcard *card)
{
struct sk_buff *skb;
void *p;
+ unsigned long flags;
skb = alloc_skb(15, GFP_ATOMIC);
if (!skb) {
@@ -744,12 +745,15 @@ static void c4_send_init(avmcard *card)
skb_put(skb, (u8 *)p - (u8 *)skb->data);
skb_queue_tail(&card->dma->send_queue, skb);
+ spin_lock_irqsave(&card->lock, flags);
c4_dispatch_tx(card);
+ spin_unlock_irqrestore(&card->lock, flags);
}
static int queue_sendconfigword(avmcard *card, u32 val)
{
struct sk_buff *skb;
+ unsigned long flags;
void *p;
skb = alloc_skb(3+4, GFP_ATOMIC);
@@ -766,7 +770,9 @@ static int queue_sendconfigword(avmcard *card, u32 val)
skb_put(skb, (u8 *)p - (u8 *)skb->data);
skb_queue_tail(&card->dma->send_queue, skb);
+ spin_lock_irqsave(&card->lock, flags);
c4_dispatch_tx(card);
+ spin_unlock_irqrestore(&card->lock, flags);
return 0;
}
@@ -986,7 +992,9 @@ static void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
struct sk_buff *skb;
void *p;
+ spin_lock_irqsave(&card->lock, flags);
capilib_release_appl(&cinfo->ncci_head, appl);
+ spin_unlock_irqrestore(&card->lock, flags);
if (ctrl->cnr == card->cardnr) {
skb = alloc_skb(7, GFP_ATOMIC);
@@ -1019,7 +1027,8 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
u16 retval = CAPI_NOERROR;
unsigned long flags;
- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+ spin_lock_irqsave(&card->lock, flags);
+ if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
retval = capilib_data_b3_req(&cinfo->ncci_head,
CAPIMSG_APPID(skb->data),
CAPIMSG_NCCI(skb->data),
@@ -1027,10 +1036,9 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
}
if (retval == CAPI_NOERROR) {
skb_queue_tail(&card->dma->send_queue, skb);
- spin_lock_irqsave(&card->lock, flags);
c4_dispatch_tx(card);
- spin_unlock_irqrestore(&card->lock, flags);
}
+ spin_unlock_irqrestore(&card->lock, flags);
return retval;
}
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 765fb75..06f6ec3 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -987,7 +987,7 @@ static void nv_enable_irq(struct net_device *dev)
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq(dev->irq);
+ enable_irq(np->pci_dev->irq);
} else {
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1003,7 +1003,7 @@ static void nv_disable_irq(struct net_device *dev)
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq(dev->irq);
+ disable_irq(np->pci_dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1600,7 +1600,7 @@ static void nv_do_rx_refill(unsigned long data)
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq(dev->irq);
+ disable_irq(np->pci_dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
@@ -1618,7 +1618,7 @@ static void nv_do_rx_refill(unsigned long data)
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq(dev->irq);
+ enable_irq(np->pci_dev->irq);
} else {
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
@@ -3556,10 +3556,12 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
np->msi_flags |= NV_MSI_ENABLED;
+ dev->irq = np->pci_dev->irq;
if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
pci_disable_msi(np->pci_dev);
np->msi_flags &= ~NV_MSI_ENABLED;
+ dev->irq = np->pci_dev->irq;
goto out_err;
}
@@ -3622,7 +3624,7 @@ static void nv_do_nic_poll(unsigned long data)
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq_lockdep(dev->irq);
+ disable_irq_lockdep(np->pci_dev->irq);
mask = np->irqmask;
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
@@ -3640,6 +3642,8 @@ static void nv_do_nic_poll(unsigned long data)
}
np->nic_poll_irq = 0;
+ /* disable_irq() contains synchronize_irq, thus no irq handler can run now */
+
if (np->recover_error) {
np->recover_error = 0;
printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
@@ -3676,7 +3680,6 @@ static void nv_do_nic_poll(unsigned long data)
}
}
- /* FIXME: Do we need synchronize_irq(dev->irq) here? */
writel(mask, base + NvRegIrqMask);
pci_push(base);
@@ -3689,7 +3692,7 @@ static void nv_do_nic_poll(unsigned long data)
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq_lockdep(dev->irq);
+ enable_irq_lockdep(np->pci_dev->irq);
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
nv_nic_irq_rx(0, dev);
@@ -4943,7 +4946,7 @@ static int nv_close(struct net_device *dev)
np->in_shutdown = 1;
spin_unlock_irq(&np->lock);
netif_poll_disable(dev);
- synchronize_irq(dev->irq);
+ synchronize_irq(np->pci_dev->irq);
del_timer_sync(&np->oom_kick);
del_timer_sync(&np->nic_poll);
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index bec83cb..7e40105 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -377,8 +377,9 @@ static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag)
scp->result = SAM_STAT_CHECK_CONDITION;
memset(&scp->sense_buffer,
0, sizeof(scp->sense_buffer));
- memcpy(&scp->sense_buffer,
- &req->sg_list, le32_to_cpu(req->dataxfer_length));
+ memcpy(&scp->sense_buffer, &req->sg_list,
+ min(sizeof(scp->sense_buffer),
+ le32_to_cpu(req->dataxfer_length)));
break;
default:
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index ef50fa4..87f6467 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -19,6 +19,8 @@
#ifdef __KERNEL__
+#include <linux/rwsem.h>
+
/* This file contains declarations of usbcore internals that are mostly
* used or exposed by Host Controller Drivers.
*/
@@ -464,5 +466,9 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {}
: (in_interrupt () ? "in_interrupt" : "can sleep"))
-#endif /* __KERNEL__ */
+/* This rwsem is for use only by the hub driver and ehci-hcd.
+ * Nobody else should touch it.
+ */
+extern struct rw_semaphore ehci_cf_port_reset_rwsem;
+#endif /* __KERNEL__ */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a1c1a11..bc93e06 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -117,6 +117,12 @@ MODULE_PARM_DESC(use_both_schemes,
"try the other device initialization scheme if the "
"first one fails");
+/* Mutual exclusion for EHCI CF initialization. This interferes with
+ * port reset on some companion controllers.
+ */
+DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
+EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
+
static inline char *portspeed(int portstatus)
{
@@ -1513,6 +1519,11 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
{
int i, status;
+ /* Block EHCI CF initialization during the port reset.
+ * Some companion controllers don't like it when they mix.
+ */
+ down_read(&ehci_cf_port_reset_rwsem);
+
/* Reset the port */
for (i = 0; i < PORT_RESET_TRIES; i++) {
status = set_port_feature(hub->hdev,
@@ -1543,7 +1554,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
usb_set_device_state(udev, status
? USB_STATE_NOTATTACHED
: USB_STATE_DEFAULT);
- return status;
+ goto done;
}
dev_dbg (hub->intfdev,
@@ -1556,6 +1567,8 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
"Cannot enable port %i. Maybe the USB cable is bad?\n",
port1);
+ done:
+ up_read(&ehci_cf_port_reset_rwsem);
return status;
}
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 099aff6..5caa8b3 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -566,10 +566,18 @@ static int ehci_run (struct usb_hcd *hcd)
* are explicitly handed to companion controller(s), so no TT is
* involved with the root hub. (Except where one is integrated,
* and there's no companion controller unless maybe for USB OTG.)
+ *
+ * Turning on the CF flag will transfer ownership of all ports
+ * from the companions to the EHCI controller. If any of the
+ * companions are in the middle of a port reset at the time, it
+ * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
+ * guarantees that no resets are in progress.
*/
+ down_write(&ehci_cf_port_reset_rwsem);
hcd->state = HC_STATE_RUNNING;
ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
+ up_write(&ehci_cf_port_reset_rwsem);
temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
ehci_info (ehci,
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 4f8282a..c36eb79 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -190,14 +190,15 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
/* only do something if we have a bulk out endpoint */
if (serial->num_bulk_out) {
- spin_lock_bh(&port->lock);
+ unsigned long flags;
+ spin_lock_irqsave(&port->lock, flags);
if (port->write_urb_busy) {
- spin_unlock_bh(&port->lock);
+ spin_unlock_irqrestore(&port->lock, flags);
dbg("%s - already writing", __FUNCTION__);
return 0;
}
port->write_urb_busy = 1;
- spin_unlock_bh(&port->lock);
+ spin_unlock_irqrestore(&port->lock, flags);
count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 0683b51..6f22419 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -82,6 +82,7 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file,
unsigned int set, unsigned int clear);
static void kobil_read_int_callback( struct urb *urb );
static void kobil_write_callback( struct urb *purb );
+static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old);
static struct usb_device_id id_table [] = {
@@ -119,6 +120,7 @@ static struct usb_serial_driver kobil_device = {
.attach = kobil_startup,
.shutdown = kobil_shutdown,
.ioctl = kobil_ioctl,
+ .set_termios = kobil_set_termios,
.tiocmget = kobil_tiocmget,
.tiocmset = kobil_tiocmset,
.open = kobil_open,
@@ -137,7 +139,6 @@ struct kobil_private {
int cur_pos; // index of the next char to send in buf
__u16 device_type;
int line_state;
- struct ktermios internal_termios;
};
@@ -216,7 +217,7 @@ static void kobil_shutdown (struct usb_serial *serial)
static int kobil_open (struct usb_serial_port *port, struct file *filp)
{
- int i, result = 0;
+ int result = 0;
struct kobil_private *priv;
unsigned char *transfer_buffer;
int transfer_buffer_length = 8;
@@ -242,16 +243,6 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp)
port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D)
- // set up internal termios structure
- priv->internal_termios.c_iflag = port->tty->termios->c_iflag;
- priv->internal_termios.c_oflag = port->tty->termios->c_oflag;
- priv->internal_termios.c_cflag = port->tty->termios->c_cflag;
- priv->internal_termios.c_lflag = port->tty->termios->c_lflag;
-
- for (i=0; i<NCCS; i++) {
- priv->internal_termios.c_cc[i] = port->tty->termios->c_cc[i];
- }
-
// allocate memory for transfer buffer
transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
if (! transfer_buffer) {
@@ -358,24 +349,26 @@ static void kobil_close (struct usb_serial_port *port, struct file *filp)
}
-static void kobil_read_int_callback( struct urb *purb)
+static void kobil_read_int_callback(struct urb *urb)
{
int result;
- struct usb_serial_port *port = (struct usb_serial_port *) purb->context;
+ struct usb_serial_port *port = urb->context;
struct tty_struct *tty;
- unsigned char *data = purb->transfer_buffer;
+ unsigned char *data = urb->transfer_buffer;
+ int status = urb->status;
// char *dbg_data;
dbg("%s - port %d", __FUNCTION__, port->number);
- if (purb->status) {
- dbg("%s - port %d Read int status not zero: %d", __FUNCTION__, port->number, purb->status);
+ if (status) {
+ dbg("%s - port %d Read int status not zero: %d",
+ __FUNCTION__, port->number, status);
return;
}
-
- tty = port->tty;
- if (purb->actual_length) {
-
+
+ tty = port->tty;
+ if (urb->actual_length) {
+
// BEGIN DEBUG
/*
dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
@@ -390,15 +383,15 @@ static void kobil_read_int_callback( struct urb *purb)
*/
// END DEBUG
- tty_buffer_request_room(tty, purb->actual_length);
- tty_insert_flip_string(tty, data, purb->actual_length);
+ tty_buffer_request_room(tty, urb->actual_length);
+ tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
// someone sets the dev to 0 if the close method has been called
port->interrupt_in_urb->dev = port->serial->dev;
- result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC );
+ result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
}
@@ -605,102 +598,79 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file,
return (result < 0) ? result : 0;
}
-
-static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg)
+static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old)
{
struct kobil_private * priv;
int result;
unsigned short urb_val = 0;
- unsigned char *transfer_buffer;
- int transfer_buffer_length = 8;
- char *settings;
- void __user *user_arg = (void __user *)arg;
+ int c_cflag = port->tty->termios->c_cflag;
+ speed_t speed;
+ void * settings;
priv = usb_get_serial_port_data(port);
- if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
+ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
// This device doesn't support ioctl calls
- return 0;
- }
-
- switch (cmd) {
- case TCGETS: // 0x5401
- if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct ktermios))) {
- dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
- return -EFAULT;
- }
- if (kernel_termios_to_user_termios((struct ktermios __user *)arg,
- &priv->internal_termios))
- return -EFAULT;
- return 0;
-
- case TCSETS: // 0x5402
- if (!(port->tty->termios)) {
- dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);
- return -ENOTTY;
- }
- if (!access_ok(VERIFY_READ, user_arg, sizeof(struct ktermios))) {
- dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
- return -EFAULT;
- }
- if (user_termios_to_kernel_termios(&priv->internal_termios,
- (struct ktermios __user *)arg))
- return -EFAULT;
-
- settings = kzalloc(50, GFP_KERNEL);
- if (! settings) {
- return -ENOBUFS;
- }
+ return;
- switch (priv->internal_termios.c_cflag & CBAUD) {
- case B1200:
+ switch (speed = tty_get_baud_rate(port->tty)) {
+ case 1200:
urb_val = SUSBCR_SBR_1200;
- strcat(settings, "1200 ");
break;
- case B9600:
+ case 9600:
default:
urb_val = SUSBCR_SBR_9600;
- strcat(settings, "9600 ");
break;
- }
+ }
+ urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;
- urb_val |= (priv->internal_termios.c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;
- strcat(settings, (priv->internal_termios.c_cflag & CSTOPB) ? "2 StopBits " : "1 StopBit ");
+ settings = kzalloc(50, GFP_KERNEL);
+ if (! settings)
+ return;
- if (priv->internal_termios.c_cflag & PARENB) {
- if (priv->internal_termios.c_cflag & PARODD) {
- urb_val |= SUSBCR_SPASB_OddParity;
- strcat(settings, "Odd Parity");
- } else {
- urb_val |= SUSBCR_SPASB_EvenParity;
- strcat(settings, "Even Parity");
- }
+ sprintf(settings, "%d ", speed);
+
+ if (c_cflag & PARENB) {
+ if (c_cflag & PARODD) {
+ urb_val |= SUSBCR_SPASB_OddParity;
+ strcat(settings, "Odd Parity");
} else {
- urb_val |= SUSBCR_SPASB_NoParity;
- strcat(settings, "No Parity");
+ urb_val |= SUSBCR_SPASB_EvenParity;
+ strcat(settings, "Even Parity");
}
- dbg("%s - port %d setting port to: %s", __FUNCTION__, port->number, settings );
+ } else {
+ urb_val |= SUSBCR_SPASB_NoParity;
+ strcat(settings, "No Parity");
+ }
- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_SetBaudRateParityAndStopBits,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- urb_val,
- 0,
- settings,
- 0,
- KOBIL_TIMEOUT
- );
+ result = usb_control_msg( port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0 ),
+ SUSBCRequest_SetBaudRateParityAndStopBits,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ urb_val,
+ 0,
+ settings,
+ 0,
+ KOBIL_TIMEOUT
+ );
+ kfree(settings);
+}
- dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result);
- kfree(settings);
+static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+{
+ struct kobil_private * priv = usb_get_serial_port_data(port);
+ unsigned char *transfer_buffer;
+ int transfer_buffer_length = 8;
+ int result;
+
+ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
+ // This device doesn't support ioctl calls
return 0;
+ switch (cmd) {
case TCFLSH: // 0x540B
transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
- if (! transfer_buffer) {
+ if (! transfer_buffer)
return -ENOBUFS;
- }
result = usb_control_msg( port->serial->dev,
usb_rcvctrlpipe(port->serial->dev, 0 ),
@@ -714,15 +684,13 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
);
dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result);
-
kfree(transfer_buffer);
- return ((result < 0) ? -EFAULT : 0);
-
+ return (result < 0) ? -EFAULT : 0;
+ default:
+ return -ENOIOCTLCMD;
}
- return -ENOIOCTLCMD;
}
-
static int __init kobil_init (void)
{
int retval;
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index a480b09..3175288 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -661,6 +661,27 @@ static void ocfs2_clear_page_regions(struct page *page,
}
/*
+ * Nonsparse file systems fully allocate before we get to the write
+ * code. This prevents ocfs2_write() from tagging the write as an
+ * allocating one, which means ocfs2_map_page_blocks() might try to
+ * read-in the blocks at the tail of our file. Avoid reading them by
+ * testing i_size against each block offset.
+ */
+static int ocfs2_should_read_blk(struct inode *inode, struct page *page,
+ unsigned int block_start)
+{
+ u64 offset = page_offset(page) + block_start;
+
+ if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
+ return 1;
+
+ if (i_size_read(inode) > offset)
+ return 1;
+
+ return 0;
+}
+
+/*
* Some of this taken from block_prepare_write(). We already have our
* mapping by now though, and the entire write will be allocating or
* it won't, so not much need to use BH_New.
@@ -711,7 +732,8 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
if (!buffer_uptodate(bh))
set_buffer_uptodate(bh);
} else if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
- (block_start < from || block_end > to)) {
+ ocfs2_should_read_blk(inode, page, block_start) &&
+ (block_start < from || block_end > to)) {
ll_rw_block(READ, 1, &bh);
*wait_bh++=bh;
}
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 2e23353..b2834d8 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -173,7 +173,7 @@ extern int netlink_unregister_notifier(struct notifier_block *nb);
/* finegrained unicast helpers: */
struct sock *netlink_getsockbyfilp(struct file *filp);
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
- long timeo, struct sock *ssk);
+ long *timeo, struct sock *ssk);
void netlink_detachskb(struct sock *sk, struct sk_buff *skb);
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol);
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index a242c83..1eef14b 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -1014,6 +1014,8 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
return -EINVAL;
}
if (notification.sigev_notify == SIGEV_THREAD) {
+ long timeo;
+
/* create the notify skb */
nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL);
ret = -ENOMEM;
@@ -1042,8 +1044,8 @@ retry:
goto out;
}
- ret = netlink_attachskb(sock, nc, 0,
- MAX_SCHEDULE_TIMEOUT, NULL);
+ timeo = MAX_SCHEDULE_TIMEOUT;
+ ret = netlink_attachskb(sock, nc, 0, &timeo, NULL);
if (ret == 1)
goto retry;
if (ret) {
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index 7e52eb0..589b1e4 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -29,6 +29,15 @@ fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
return 0;
}
+static void __user *futex_uaddr(struct robust_list *entry,
+ compat_long_t futex_offset)
+{
+ compat_uptr_t base = ptr_to_compat(entry);
+ void __user *uaddr = compat_ptr(base + futex_offset);
+
+ return uaddr;
+}
+
/*
* Walk curr->robust_list (very carefully, it's a userspace list!)
* and mark any locks found there dead, and notify any waiters.
@@ -61,18 +70,23 @@ void compat_exit_robust_list(struct task_struct *curr)
if (fetch_robust_entry(&upending, &pending,
&head->list_op_pending, &pip))
return;
- if (pending)
- handle_futex_death((void __user *)pending + futex_offset, curr, pip);
+ if (pending) {
+ void __user *uaddr = futex_uaddr(pending,
+ futex_offset);
+ handle_futex_death(uaddr, curr, pip);
+ }
while (entry != (struct robust_list __user *) &head->list) {
/*
* A pending lock might already be on the list, so
* dont process it twice:
*/
- if (entry != pending)
- if (handle_futex_death((void __user *)entry + futex_offset,
- curr, pi))
+ if (entry != pending) {
+ void __user *uaddr = futex_uaddr(entry,
+ futex_offset);
+ if (handle_futex_death(uaddr, curr, pi))
return;
+ }
/*
* Fetch the next entry in the list:
diff --git a/kernel/params.c b/kernel/params.c
index 8e8ca8f..1f17b58 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -591,19 +591,16 @@ static void __init param_sysfs_builtin(void)
for (i=0; i < __stop___param - __start___param; i++) {
char *dot;
- size_t kplen;
+ size_t max_name_len;
kp = &__start___param[i];
- kplen = strlen(kp->name);
+ max_name_len =
+ min_t(size_t, MAX_KBUILD_MODNAME, strlen(kp->name));
- /* We do not handle args without periods. */
- if (kplen > MAX_KBUILD_MODNAME) {
- DEBUGP("kernel parameter name is too long: %s\n", kp->name);
- continue;
- }
- dot = memchr(kp->name, '.', kplen);
+ dot = memchr(kp->name, '.', max_name_len);
if (!dot) {
- DEBUGP("couldn't find period in %s\n", kp->name);
+ DEBUGP("couldn't find period in first %d characters "
+ "of %s\n", MAX_KBUILD_MODNAME, kp->name);
continue;
}
name_len = dot - kp->name;
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index eec1481..2d39627 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -674,8 +674,10 @@ retry:
ret = (*writepage)(page, wbc, data);
- if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
+ if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) {
unlock_page(page);
+ ret = 0;
+ }
if (ret || (--(wbc->nr_to_write) <= 0))
done = 1;
if (wbc->nonblocking && bdi_write_congested(bdi)) {
diff --git a/mm/shmem.c b/mm/shmem.c
index b6aae2b..2320b60 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -911,6 +911,21 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
struct inode *inode;
BUG_ON(!PageLocked(page));
+ /*
+ * shmem_backing_dev_info's capabilities prevent regular writeback or
+ * sync from ever calling shmem_writepage; but a stacking filesystem
+ * may use the ->writepage of its underlying filesystem, in which case
+ * we want to do nothing when that underlying filesystem is tmpfs
+ * (writing out to swap is useful as a response to memory pressure, but
+ * of no use to stabilize the data) - just redirty the page, unlock it
+ * and claim success in this case. AOP_WRITEPAGE_ACTIVATE, and the
+ * page_mapped check below, must be avoided unless we're in reclaim.
+ */
+ if (!wbc->for_reclaim) {
+ set_page_dirty(page);
+ unlock_page(page);
+ return 0;
+ }
BUG_ON(page_mapped(page));
mapping = page->mapping;
diff --git a/mm/slub.c b/mm/slub.c
index e0cf621..648f2c7 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1431,28 +1431,8 @@ new_slab:
page = new_slab(s, gfpflags, node);
if (page) {
cpu = smp_processor_id();
- if (s->cpu_slab[cpu]) {
- /*
- * Someone else populated the cpu_slab while we
- * enabled interrupts, or we have gotten scheduled
- * on another cpu. The page may not be on the
- * requested node even if __GFP_THISNODE was
- * specified. So we need to recheck.
- */
- if (node == -1 ||
- page_to_nid(s->cpu_slab[cpu]) == node) {
- /*
- * Current cpuslab is acceptable and we
- * want the current one since its cache hot
- */
- discard_slab(s, page);
- page = s->cpu_slab[cpu];
- slab_lock(page);
- goto load_freelist;
- }
- /* New slab does not fit our expectations */
+ if (s->cpu_slab[cpu])
flush_slab(s, s->cpu_slab[cpu], cpu);
- }
slab_lock(page);
SetSlabFrozen(page);
s->cpu_slab[cpu] = page;
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index ab86137..630ebb7 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -17,6 +17,7 @@
#include <asm/scatterlist.h>
#include <asm/semaphore.h>
#include <linux/crypto.h>
+#include <linux/err.h>
#include <linux/pfkeyv2.h>
#include <linux/percpu.h>
#include <linux/smp.h>
@@ -355,7 +356,7 @@ static struct crypto_comp **ipcomp_alloc_tfms(const char *alg_name)
for_each_possible_cpu(cpu) {
struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
CRYPTO_ALG_ASYNC);
- if (!tfm)
+ if (IS_ERR(tfm))
goto error;
*per_cpu_ptr(tfms, cpu) = tfm;
}
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 1ee50b5..3680f64 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -37,6 +37,7 @@
#include <asm/scatterlist.h>
#include <asm/semaphore.h>
#include <linux/crypto.h>
+#include <linux/err.h>
#include <linux/pfkeyv2.h>
#include <linux/random.h>
#include <linux/percpu.h>
@@ -366,7 +367,7 @@ static struct crypto_comp **ipcomp6_alloc_tfms(const char *alg_name)
for_each_possible_cpu(cpu) {
struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
CRYPTO_ALG_ASYNC);
- if (!tfm)
+ if (IS_ERR(tfm))
goto error;
*per_cpu_ptr(tfms, cpu) = tfm;
}
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index ccdd5d2..2721ff4 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -839,6 +839,22 @@ static int tcp_packet(struct nf_conn *conntrack,
new_state = tcp_conntracks[dir][index][old_state];
switch (new_state) {
+ case TCP_CONNTRACK_SYN_SENT:
+ if (old_state < TCP_CONNTRACK_TIME_WAIT)
+ break;
+ if ((conntrack->proto.tcp.seen[!dir].flags &
+ IP_CT_TCP_FLAG_CLOSE_INIT)
+ || (conntrack->proto.tcp.last_dir == dir
+ && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+ /* Attempt to reopen a closed/aborted connection.
+ * Delete this connection and look up again. */
+ write_unlock_bh(&tcp_lock);
+ if (del_timer(&conntrack->timeout))
+ conntrack->timeout.function((unsigned long)
+ conntrack);
+ return -NF_REPEAT;
+ }
+ /* Fall through */
case TCP_CONNTRACK_IGNORE:
/* Ignored packets:
*
@@ -888,27 +904,6 @@ static int tcp_packet(struct nf_conn *conntrack,
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
"nf_ct_tcp: invalid state ");
return -NF_ACCEPT;
- case TCP_CONNTRACK_SYN_SENT:
- if (old_state < TCP_CONNTRACK_TIME_WAIT)
- break;
- if ((conntrack->proto.tcp.seen[dir].flags &
- IP_CT_TCP_FLAG_CLOSE_INIT)
- || after(ntohl(th->seq),
- conntrack->proto.tcp.seen[dir].td_end)) {
- /* Attempt to reopen a closed connection.
- * Delete this connection and look up again. */
- write_unlock_bh(&tcp_lock);
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)
- conntrack);
- return -NF_REPEAT;
- } else {
- write_unlock_bh(&tcp_lock);
- if (LOG_INVALID(IPPROTO_TCP))
- nf_log_packet(pf, 0, skb, NULL, NULL,
- NULL, "nf_ct_tcp: invalid SYN");
- return -NF_ACCEPT;
- }
case TCP_CONNTRACK_CLOSE:
if (index == TCP_RST_SET
&& ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
@@ -941,6 +936,7 @@ static int tcp_packet(struct nf_conn *conntrack,
in_window:
/* From now on we have got in-window packets */
conntrack->proto.tcp.last_index = index;
+ conntrack->proto.tcp.last_dir = dir;
DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
"syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 1f15821..6ac83c2 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -732,7 +732,7 @@ struct sock *netlink_getsockbyfilp(struct file *filp)
* 1: repeat lookup - reference dropped while waiting for socket memory.
*/
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
- long timeo, struct sock *ssk)
+ long *timeo, struct sock *ssk)
{
struct netlink_sock *nlk;
@@ -741,7 +741,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
test_bit(0, &nlk->state)) {
DECLARE_WAITQUEUE(wait, current);
- if (!timeo) {
+ if (!*timeo) {
if (!ssk || nlk_sk(ssk)->pid == 0)
netlink_overrun(sk);
sock_put(sk);
@@ -755,7 +755,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
test_bit(0, &nlk->state)) &&
!sock_flag(sk, SOCK_DEAD))
- timeo = schedule_timeout(timeo);
+ *timeo = schedule_timeout(*timeo);
__set_current_state(TASK_RUNNING);
remove_wait_queue(&nlk->wait, &wait);
@@ -763,7 +763,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
if (signal_pending(current)) {
kfree_skb(skb);
- return sock_intr_errno(timeo);
+ return sock_intr_errno(*timeo);
}
return 1;
}
@@ -827,7 +827,7 @@ retry:
kfree_skb(skb);
return PTR_ERR(sk);
}
- err = netlink_attachskb(sk, skb, nonblock, timeo, ssk);
+ err = netlink_attachskb(sk, skb, nonblock, &timeo, ssk);
if (err == 1)
goto retry;
if (err)
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index f2686ea..1d36265 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -107,7 +107,7 @@ static struct tc_u_common *u32_list;
static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift)
{
- unsigned h = (key & sel->hmask)>>fshift;
+ unsigned h = ntohl(key & sel->hmask)>>fshift;
return h;
}
@@ -631,7 +631,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
n->handle = handle;
{
u8 i = 0;
- u32 mask = s->hmask;
+ u32 mask = ntohl(s->hmask);
if (mask) {
while (!(mask & 1)) {
i++;
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index f05ad9a..656ccd9 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -263,6 +263,9 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *
static __inline__ int
teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev)
{
+ if (dev->qdisc == &noop_qdisc)
+ return -ENODEV;
+
if (dev->hard_header == NULL ||
skb->dst == NULL ||
skb->dst->neighbour == NULL)
diff --git a/net/socket.c b/net/socket.c
index 48bd793..8211578 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1246,11 +1246,14 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
goto out_release_both;
fd1 = sock_alloc_fd(&newfile1);
- if (unlikely(fd1 < 0))
+ if (unlikely(fd1 < 0)) {
+ err = fd1;
goto out_release_both;
+ }
fd2 = sock_alloc_fd(&newfile2);
if (unlikely(fd2 < 0)) {
+ err = fd2;
put_filp(newfile1);
put_unused_fd(fd1);
goto out_release_both;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index e3964fc..d5b2f53 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -153,8 +153,9 @@ static hda_nid_t stac925x_dac_nids[1] = {
0x02,
};
-static hda_nid_t stac925x_dmic_nids[1] = {
- 0x15,
+#define STAC925X_NUM_DMICS 1
+static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
+ 0x15, 0
};
static hda_nid_t stac922x_adc_nids[2] = {
@@ -181,8 +182,9 @@ static hda_nid_t stac9205_mux_nids[2] = {
0x19, 0x1a
};
-static hda_nid_t stac9205_dmic_nids[2] = {
- 0x17, 0x18,
+#define STAC9205_NUM_DMICS 2
+static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
+ 0x17, 0x18, 0
};
static hda_nid_t stac9200_pin_nids[8] = {
@@ -1972,7 +1974,7 @@ static int patch_stac925x(struct hda_codec *codec)
case 0x83847633: /* STAC9202D */
case 0x83847636: /* STAC9251 */
case 0x83847637: /* STAC9251D */
- spec->num_dmics = 1;
+ spec->num_dmics = STAC925X_NUM_DMICS;
spec->dmic_nids = stac925x_dmic_nids;
break;
default:
@@ -2202,7 +2204,7 @@ static int patch_stac9205(struct hda_codec *codec)
spec->mux_nids = stac9205_mux_nids;
spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
spec->dmic_nids = stac9205_dmic_nids;
- spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
+ spec->num_dmics = STAC9205_NUM_DMICS;
spec->dmux_nid = 0x1d;
spec->init = stac9205_core_init;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 3b3ef65..75dcb9a 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -3108,6 +3108,9 @@ static int hdsp_dds_offset(struct hdsp *hdsp)
unsigned int dds_value = hdsp->dds_value;
int system_sample_rate = hdsp->system_sample_rate;
+ if (!dds_value)
+ return 0;
+
n = DDS_NUMERATOR;
/*
* dds_value = n / rate
Hi Greg,
I think this hunk in the 2.6.22.14 stable patch may be a mis-patch --
compared to Linus's current git -- the new code should be inserted below
the while loop that follows.
Also see commit 9f96cb1e8bca179a92afa40dfc3c49990f1cfc71
Sven
On Wed, 2007-11-21 at 09:57 -0800, Greg Kroah-Hartman wrote:
> @@ -61,18 +70,23 @@ void compat_exit_robust_list(struct task_struct
> *curr)
> if (fetch_robust_entry(&upending, &pending,
> &head->list_op_pending, &pip))
> return;
> - if (pending)
> - handle_futex_death((void __user *)pending +
> futex_offset, curr, pip);
> + if (pending) {
> + void __user *uaddr = futex_uaddr(pending,
> + futex_offset);
> + handle_futex_death(uaddr, curr, pip);
> + }
On Sun, Nov 25, 2007 at 06:21:35AM -0800, Sven-Thorsten Dietrich wrote:
> Hi Greg,
>
> I think this hunk in the 2.6.22.14 stable patch may be a mis-patch --
> compared to Linus's current git -- the new code should be inserted below
> the while loop that follows.
>
> Also see commit 9f96cb1e8bca179a92afa40dfc3c49990f1cfc71
Hm, I'm confused. Why is this a mis-patch?
Care to send me a fix against 2.6.22.14 that solves this issue?
thanks,
greg k-h
On 11/25/2007 09:21 AM, Sven-Thorsten Dietrich wrote:
> Hi Greg,
>
> I think this hunk in the 2.6.22.14 stable patch may be a mis-patch --
> compared to Linus's current git -- the new code should be inserted below
> the while loop that follows.
>
patch looks fine to me.
> Also see commit 9f96cb1e8bca179a92afa40dfc3c49990f1cfc71
>
But this one does rearrange things quite a bit and is not included. That
is why things look out of order compared to current git.
On Mon, 2007-11-26 at 14:00 -0800, Greg KH wrote:
> On Sun, Nov 25, 2007 at 06:21:35AM -0800, Sven-Thorsten Dietrich wrote:
> > Hi Greg,
> >
> > I think this hunk in the 2.6.22.14 stable patch may be a mis-patch --
> > compared to Linus's current git -- the new code should be inserted below
> > the while loop that follows.
> >
> > Also see commit 9f96cb1e8bca179a92afa40dfc3c49990f1cfc71
>
> Hm, I'm confused. Why is this a mis-patch?
>
The implementation in 2.6.22.14 is just divergent in from mainline's,
and looked peculiar in context of what some RT bugfix was doing.
Sorry for the noise.
Sven
> Care to send me a fix against 2.6.22.14 that solves this issue?
>
> thanks,
>
> greg k-h