Re: Linux 2.6.28.3

From: Greg KH
Date: Mon Feb 02 2009 - 13:28:06 EST



diff --git a/Makefile b/Makefile
index 445c142..00d1f9a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 28
-EXTRAVERSION = .2
+EXTRAVERSION = .3
NAME = Erotic Pickled Herring

# *DOCUMENTATION*
diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c
index 3221201..a03fbca 100644
--- a/arch/alpha/kernel/irq_srm.c
+++ b/arch/alpha/kernel/irq_srm.c
@@ -63,6 +63,8 @@ init_srm_irqs(long max, unsigned long ignore_mask)
{
long i;

+ if (NR_IRQS <= 16)
+ return;
for (i = 16; i < max; ++i) {
if (i < 64 && ((ignore_mask >> i) & 1))
continue;
diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h
index cb7c151..dd14c54 100644
--- a/arch/x86/include/asm/pgalloc.h
+++ b/arch/x86/include/asm/pgalloc.h
@@ -42,6 +42,7 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)

static inline void pte_free(struct mm_struct *mm, struct page *pte)
{
+ pgtable_page_dtor(pte);
__free_page(pte);
}

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index e89d248..84ba748 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -534,6 +534,36 @@ out_unlock:
return 0;
}

+static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
+ int primary)
+{
+ /*
+ * Ignore all non primary paths.
+ */
+ if (!primary)
+ return 0;
+
+ /*
+ * Ignore the NULL PTE for kernel identity mapping, as it is expected
+ * to have holes.
+ * Also set numpages to '1' indicating that we processed cpa req for
+ * one virtual address page and its pfn. TBD: numpages can be set based
+ * on the initial value and the level returned by lookup_address().
+ */
+ if (within(vaddr, PAGE_OFFSET,
+ PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
+ cpa->numpages = 1;
+ cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
+ return 0;
+ } else {
+ WARN(1, KERN_WARNING "CPA: called for zero pte. "
+ "vaddr = %lx cpa->vaddr = %lx\n", vaddr,
+ *cpa->vaddr);
+
+ return -EFAULT;
+ }
+}
+
static int __change_page_attr(struct cpa_data *cpa, int primary)
{
unsigned long address;
@@ -549,17 +579,11 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)
repeat:
kpte = lookup_address(address, &level);
if (!kpte)
- return 0;
+ return __cpa_process_fault(cpa, address, primary);

old_pte = *kpte;
- if (!pte_val(old_pte)) {
- if (!primary)
- return 0;
- WARN(1, KERN_WARNING "CPA: called for zero pte. "
- "vaddr = %lx cpa->vaddr = %lx\n", address,
- *cpa->vaddr);
- return -EINVAL;
- }
+ if (!pte_val(old_pte))
+ return __cpa_process_fault(cpa, address, primary);

if (level == PG_LEVEL_4K) {
pte_t new_pte;
@@ -657,12 +681,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
vaddr = *cpa->vaddr;

if (!(within(vaddr, PAGE_OFFSET,
- PAGE_OFFSET + (max_low_pfn_mapped << PAGE_SHIFT))
-#ifdef CONFIG_X86_64
- || within(vaddr, PAGE_OFFSET + (1UL<<32),
- PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))
-#endif
- )) {
+ PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) {

alias_cpa = *cpa;
temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index eb1bf00..bd8bcce 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -333,11 +333,23 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
req_type & _PAGE_CACHE_MASK);
}

- is_range_ram = pagerange_is_ram(start, end);
- if (is_range_ram == 1)
- return reserve_ram_pages_type(start, end, req_type, new_type);
- else if (is_range_ram < 0)
- return -EINVAL;
+ if (new_type)
+ *new_type = actual_type;
+
+ /*
+ * For legacy reasons, some parts of the physical address range in the
+ * legacy 1MB region is treated as non-RAM (even when listed as RAM in
+ * the e820 tables). So we will track the memory attributes of this
+ * legacy 1MB region using the linear memtype_list always.
+ */
+ if (end >= ISA_END_ADDRESS) {
+ is_range_ram = pagerange_is_ram(start, end);
+ if (is_range_ram == 1)
+ return reserve_ram_pages_type(start, end, req_type,
+ new_type);
+ else if (is_range_ram < 0)
+ return -EINVAL;
+ }

new = kmalloc(sizeof(struct memtype), GFP_KERNEL);
if (!new)
@@ -347,9 +359,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
new->end = end;
new->type = actual_type;

- if (new_type)
- *new_type = actual_type;
-
spin_lock(&memtype_lock);

if (cached_entry && start >= cached_start)
@@ -437,11 +446,19 @@ int free_memtype(u64 start, u64 end)
if (is_ISA_range(start, end - 1))
return 0;

- is_range_ram = pagerange_is_ram(start, end);
- if (is_range_ram == 1)
- return free_ram_pages_type(start, end);
- else if (is_range_ram < 0)
- return -EINVAL;
+ /*
+ * For legacy reasons, some parts of the physical address range in the
+ * legacy 1MB region is treated as non-RAM (even when listed as RAM in
+ * the e820 tables). So we will track the memory attributes of this
+ * legacy 1MB region using the linear memtype_list always.
+ */
+ if (end >= ISA_END_ADDRESS) {
+ is_range_ram = pagerange_is_ram(start, end);
+ if (is_range_ram == 1)
+ return free_ram_pages_type(start, end);
+ else if (is_range_ram < 0)
+ return -EINVAL;
+ }

spin_lock(&memtype_lock);
list_for_each_entry(entry, &memtype_list, nd) {
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index dcbf1be..c5d71aa 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -124,6 +124,8 @@ void async_tx_run_dependencies(struct dma_async_tx_descriptor *tx)
if (!dep)
return;

+ /* we'll submit tx->next now, so clear the link */
+ tx->next = NULL;
chan = dep->chan;

/* keep submitting up until a channel switch is detected
diff --git a/crypto/authenc.c b/crypto/authenc.c
index fd9f06c..0861dc2 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -157,16 +157,19 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,
dstp = sg_page(dst);
vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset;

- sg_init_table(cipher, 2);
- sg_set_buf(cipher, iv, ivsize);
- authenc_chain(cipher, dst, vdst == iv + ivsize);
+ if (ivsize) {
+ sg_init_table(cipher, 2);
+ sg_set_buf(cipher, iv, ivsize);
+ authenc_chain(cipher, dst, vdst == iv + ivsize);
+ dst = cipher;
+ }

cryptlen = req->cryptlen + ivsize;
- hash = crypto_authenc_hash(req, flags, cipher, cryptlen);
+ hash = crypto_authenc_hash(req, flags, dst, cryptlen);
if (IS_ERR(hash))
return PTR_ERR(hash);

- scatterwalk_map_and_copy(hash, cipher, cryptlen,
+ scatterwalk_map_and_copy(hash, dst, cryptlen,
crypto_aead_authsize(authenc), 1);
return 0;
}
@@ -284,11 +287,14 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
srcp = sg_page(src);
vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset;

- sg_init_table(cipher, 2);
- sg_set_buf(cipher, iv, ivsize);
- authenc_chain(cipher, src, vsrc == iv + ivsize);
+ if (ivsize) {
+ sg_init_table(cipher, 2);
+ sg_set_buf(cipher, iv, ivsize);
+ authenc_chain(cipher, src, vsrc == iv + ivsize);
+ src = cipher;
+ }

- return crypto_authenc_verify(req, cipher, cryptlen + ivsize);
+ return crypto_authenc_verify(req, src, cryptlen + ivsize);
}

static int crypto_authenc_decrypt(struct aead_request *req)
diff --git a/crypto/ccm.c b/crypto/ccm.c
index 7cf7e5a..c36d654 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -266,6 +266,8 @@ static int crypto_ccm_auth(struct aead_request *req, struct scatterlist *plain,
if (assoclen) {
pctx->ilen = format_adata(idata, assoclen);
get_data_to_compute(cipher, pctx, req->assoc, req->assoclen);
+ } else {
+ pctx->ilen = 0;
}

/* compute plaintext into mac */
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 681169c..79a6c9a 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -86,6 +86,10 @@ enum {
VIA_SATA_PATA = 0x800, /* SATA/PATA combined configuration */
};

+enum {
+ VIA_IDFLAG_SINGLE = (1 << 0), /* single channel controller) */
+};
+
/*
* VIA SouthBridge chips.
*/
@@ -97,8 +101,12 @@ static const struct via_isa_bridge {
u8 rev_max;
u16 flags;
} via_isa_bridges[] = {
+ { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f,
+ VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
{ "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 |
VIA_BAD_AST | VIA_SATA_PATA },
+ { "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f,
+ VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
@@ -122,6 +130,8 @@ static const struct via_isa_bridge {
{ "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
+ { "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f,
+ VIA_UDMA_133 | VIA_BAD_AST },
{ NULL }
};

@@ -460,6 +470,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int printed_version;
u8 enable;
u32 timing;
+ unsigned long flags = id->driver_data;
int rc;

if (!printed_version++)
@@ -469,9 +480,13 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;

+ if (flags & VIA_IDFLAG_SINGLE)
+ ppi[1] = &ata_dummy_port_info;
+
/* To find out how the IDE will behave and what features we
actually have to look at the bridge not the IDE controller */
- for (config = via_isa_bridges; config->id; config++)
+ for (config = via_isa_bridges; config->id != PCI_DEVICE_ID_VIA_ANON;
+ config++)
if ((isa = pci_get_device(PCI_VENDOR_ID_VIA +
!!(config->flags & VIA_BAD_ID),
config->id, NULL))) {
@@ -482,10 +497,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_dev_put(isa);
}

- if (!config->id) {
- printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n");
- return -ENODEV;
- }
pci_dev_put(isa);

if (!(config->flags & VIA_NO_ENABLES)) {
@@ -587,6 +598,7 @@ static const struct pci_device_id via[] = {
{ PCI_VDEVICE(VIA, 0x1571), },
{ PCI_VDEVICE(VIA, 0x3164), },
{ PCI_VDEVICE(VIA, 0x5324), },
+ { PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE },

{ },
};
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 82020ab..a4424c8 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -789,6 +789,7 @@ int gpio_request(unsigned gpio, const char *label)
} else {
status = -EBUSY;
module_put(chip->owner);
+ goto done;
}

if (chip->request) {
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
index 3d33b82..1479659 100644
--- a/drivers/gpu/drm/drm_agpsupport.c
+++ b/drivers/gpu/drm/drm_agpsupport.c
@@ -33,10 +33,11 @@

#include "drmP.h"
#include <linux/module.h>
-#include <asm/agp.h>

#if __OS_HAS_AGP

+#include <asm/agp.h>
+
/**
* Get AGP information.
*
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index ef00408..011e6d6 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -68,6 +68,8 @@

#define DRV_NAME "it821x"

+#define QUIRK_VORTEX86 1
+
struct it821x_dev
{
unsigned int smart:1, /* Are we in smart raid mode */
@@ -79,6 +81,7 @@ struct it821x_dev
u16 pio[2]; /* Cached PIO values */
u16 mwdma[2]; /* Cached MWDMA values */
u16 udma[2]; /* Cached UDMA values (per drive) */
+ u16 quirks;
};

#define ATA_66 0
@@ -580,6 +583,12 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)

hwif->ultra_mask = ATA_UDMA6;
hwif->mwdma_mask = ATA_MWDMA2;
+
+ /* Vortex86SX quirk: prevent Ultra-DMA mode to fix BadCRC issue */
+ if (idev->quirks & QUIRK_VORTEX86) {
+ if (dev->revision == 0x11)
+ hwif->ultra_mask = 0;
+ }
}

static void it8212_disable_raid(struct pci_dev *dev)
@@ -652,6 +661,8 @@ static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_devic
return -ENOMEM;
}

+ itdevs->quirks = id->driver_data;
+
rc = ide_pci_init_one(dev, &it821x_chipset, itdevs);
if (rc)
kfree(itdevs);
@@ -671,6 +682,7 @@ static void __devexit it821x_remove(struct pci_dev *dev)
static const struct pci_device_id it821x_pci_tbl[] = {
{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), 0 },
{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), 0 },
+ { PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1010), QUIRK_VORTEX86 },
{ 0, },
};

diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index d32c1ee..59ff816 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -1841,6 +1841,7 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
*/
xpc_clear_remote_msgqueue_flags_sn2(ch);

+ smp_wmb(); /* ensure flags have been cleared before bte_copy */
ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put;

dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
@@ -1939,7 +1940,7 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)
break;

get = ch_sn2->w_local_GP.get;
- rmb(); /* guarantee that .get loads before .put */
+ smp_rmb(); /* guarantee that .get loads before .put */
if (get == ch_sn2->w_remote_GP.put)
break;

@@ -1961,11 +1962,13 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)

msg = xpc_pull_remote_msg_sn2(ch, get);

- DBUG_ON(msg != NULL && msg->number != get);
- DBUG_ON(msg != NULL && (msg->flags & XPC_M_SN2_DONE));
- DBUG_ON(msg != NULL && !(msg->flags & XPC_M_SN2_READY));
+ if (msg != NULL) {
+ DBUG_ON(msg->number != get);
+ DBUG_ON(msg->flags & XPC_M_SN2_DONE);
+ DBUG_ON(!(msg->flags & XPC_M_SN2_READY));

- payload = &msg->payload;
+ payload = &msg->payload;
+ }
break;
}

@@ -2058,7 +2061,7 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
while (1) {

put = ch_sn2->w_local_GP.put;
- rmb(); /* guarantee that .put loads before .get */
+ smp_rmb(); /* guarantee that .put loads before .get */
if (put - ch_sn2->w_remote_GP.get < ch->local_nentries) {

/* There are available message entries. We need to try
@@ -2191,7 +2194,7 @@ xpc_send_payload_sn2(struct xpc_channel *ch, u32 flags, void *payload,
* The preceding store of msg->flags must occur before the following
* load of local_GP->put.
*/
- mb();
+ smp_mb();

/* see if the message is next in line to be sent, if so send it */

@@ -2292,7 +2295,7 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
* The preceding store of msg->flags must occur before the following
* load of local_GP->get.
*/
- mb();
+ smp_mb();

/*
* See if this message is next in line to be acknowledged as having
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index 1ac694c..b8f8d50 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -1238,7 +1238,7 @@ xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload,
atomic_inc(&ch->n_to_notify);

msg_slot->key = key;
- wmb(); /* a non-NULL func must hit memory after the key */
+ smp_wmb(); /* a non-NULL func must hit memory after the key */
msg_slot->func = func;

if (ch->flags & XPC_C_DISCONNECTING) {
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 600210d..d672d40 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -8079,6 +8079,9 @@ static int bnx2x_get_eeprom(struct net_device *dev,
struct bnx2x *bp = netdev_priv(dev);
int rc;

+ if (!netif_running(dev))
+ return -EAGAIN;
+
DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 2d14255..e521555 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -2157,7 +2157,8 @@ ath5k_beacon_config(struct ath5k_softc *sc)

if (sc->opmode == NL80211_IFTYPE_STATION) {
sc->imask |= AR5K_INT_BMISS;
- } else if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+ } else if (sc->opmode == NL80211_IFTYPE_ADHOC ||
+ sc->opmode == NL80211_IFTYPE_MESH_POINT) {
/*
* In IBSS mode we use a self-linked tx descriptor and let the
* hardware send the beacons automatically. We have to load it
@@ -2748,6 +2749,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
switch (conf->type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
case NL80211_IFTYPE_MONITOR:
sc->opmode = conf->type;
break;
@@ -2819,7 +2821,8 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}

if (conf->changed & IEEE80211_IFCC_BEACON &&
- vif->type == NL80211_IFTYPE_ADHOC) {
+ (vif->type == NL80211_IFTYPE_ADHOC ||
+ vif->type == NL80211_IFTYPE_MESH_POINT)) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
if (!beacon) {
ret = -ENOMEM;
@@ -2951,6 +2954,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
sc->opmode == NL80211_IFTYPE_ADHOC) {
rfilt |= AR5K_RX_FILTER_BEACON;
}
+ if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
+ rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
+ AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;

/* Set filters */
ath5k_hw_set_rx_filter(ah,rfilt);
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 69eb013..47c1c48 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -263,6 +263,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)

usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
buf, skb->len, rtl8187_tx_cb, skb);
+ urb->transfer_flags |= URB_ZERO_PACKET;
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (rc < 0) {
usb_free_urb(urb);
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
index 1bae899..487593f 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -287,7 +287,10 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
ofdm_power = priv->channels[channel - 1].hw_value >> 4;

cck_power = min(cck_power, (u8)11);
- ofdm_power = min(ofdm_power, (u8)35);
+ if (ofdm_power > (u8)15)
+ ofdm_power = 25;
+ else
+ ofdm_power += 10;

rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
@@ -540,7 +543,10 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
cck_power += priv->txpwr_base & 0xF;
cck_power = min(cck_power, (u8)35);

- ofdm_power = min(ofdm_power, (u8)15);
+ if (ofdm_power > (u8)15)
+ ofdm_power = 25;
+ else
+ ofdm_power += 10;
ofdm_power += priv->txpwr_base >> 4;
ofdm_power = min(ofdm_power, (u8)35);

diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 39cf248..b2ecff4 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -126,8 +126,10 @@ static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status)
mutex_lock(&slot->ctrl->crit_sect);

/* has it been >1 sec since our last toggle? */
- if ((get_seconds() - slot->last_emi_toggle) < 1)
+ if ((get_seconds() - slot->last_emi_toggle) < 1) {
+ mutex_unlock(&slot->ctrl->crit_sect);
return -EINVAL;
+ }

/* see what our current state is */
retval = get_lock_status(hotplug_slot, &value);
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 5450a0e..222cffa 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -2271,6 +2271,9 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b2_8_115200 },
+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_7803,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b2_8_460800 },
{ PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b2_8_115200 },
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 2bccefe..c7e5339 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1703,7 +1703,7 @@ const struct file_operations usbdev_file_operations = {
.release = usbdev_release,
};

-void usb_fs_classdev_common_remove(struct usb_device *udev)
+static void usbdev_remove(struct usb_device *udev)
{
struct dev_state *ps;
struct siginfo sinfo;
@@ -1745,10 +1745,15 @@ static void usb_classdev_remove(struct usb_device *dev)
{
if (dev->usb_classdev)
device_unregister(dev->usb_classdev);
- usb_fs_classdev_common_remove(dev);
}

-static int usb_classdev_notify(struct notifier_block *self,
+#else
+#define usb_classdev_add(dev) 0
+#define usb_classdev_remove(dev) do {} while (0)
+
+#endif
+
+static int usbdev_notify(struct notifier_block *self,
unsigned long action, void *dev)
{
switch (action) {
@@ -1758,15 +1763,15 @@ static int usb_classdev_notify(struct notifier_block *self,
break;
case USB_DEVICE_REMOVE:
usb_classdev_remove(dev);
+ usbdev_remove(dev);
break;
}
return NOTIFY_OK;
}

static struct notifier_block usbdev_nb = {
- .notifier_call = usb_classdev_notify,
+ .notifier_call = usbdev_notify,
};
-#endif

static struct cdev usb_device_cdev;

@@ -1801,9 +1806,8 @@ int __init usb_devio_init(void)
* to /sys/dev
*/
usb_classdev_class->dev_kobj = NULL;
-
- usb_register_notify(&usbdev_nb);
#endif
+ usb_register_notify(&usbdev_nb);
out:
return retval;

@@ -1814,8 +1818,8 @@ error_cdev:

void usb_devio_cleanup(void)
{
-#ifdef CONFIG_USB_DEVICE_CLASS
usb_unregister_notify(&usbdev_nb);
+#ifdef CONFIG_USB_DEVICE_CLASS
class_destroy(usb_classdev_class);
#endif
cdev_del(&usb_device_cdev);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 7c3710e..f9473fb 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -269,7 +269,7 @@ static int usb_unbind_interface(struct device *dev)
* supports "soft" unbinding.
*/
if (!driver->soft_unbind)
- usb_disable_interface(udev, intf);
+ usb_disable_interface(udev, intf, false);

driver->disconnect(intf);

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 81eea42..da11baf 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2383,8 +2383,8 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)

void usb_ep0_reinit(struct usb_device *udev)
{
- usb_disable_endpoint(udev, 0 + USB_DIR_IN);
- usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+ usb_disable_endpoint(udev, 0 + USB_DIR_IN, true);
+ usb_disable_endpoint(udev, 0 + USB_DIR_OUT, true);
usb_enable_endpoint(udev, &udev->ep0, true);
}
EXPORT_SYMBOL_GPL(usb_ep0_reinit);
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 9463226..3181d7d 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -718,7 +718,6 @@ static void usbfs_remove_device(struct usb_device *dev)
fs_remove_file (dev->usbfs_dentry);
dev->usbfs_dentry = NULL;
}
- usb_fs_classdev_common_remove(dev);
}

static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index bdcfe92..8497f63 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1009,14 +1009,15 @@ EXPORT_SYMBOL_GPL(usb_clear_halt);
* @dev: the device whose endpoint is being disabled
* @epaddr: the endpoint's address. Endpoint number for output,
* endpoint number + USB_DIR_IN for input
+ * @reset_hardware: flag to erase any endpoint state stored in the
+ * controller hardware
*
- * Deallocates hcd/hardware state for this endpoint ... and nukes all
- * pending urbs.
- *
- * If the HCD hasn't registered a disable() function, this sets the
- * endpoint's maxpacket size to 0 to prevent further submissions.
+ * Disables the endpoint for URB submission and nukes all pending URBs.
+ * If @reset_hardware is set then also deallocates hcd/hardware state
+ * for the endpoint.
*/
-void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
+void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
+ bool reset_hardware)
{
unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
struct usb_host_endpoint *ep;
@@ -1026,15 +1027,18 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)

if (usb_endpoint_out(epaddr)) {
ep = dev->ep_out[epnum];
- dev->ep_out[epnum] = NULL;
+ if (reset_hardware)
+ dev->ep_out[epnum] = NULL;
} else {
ep = dev->ep_in[epnum];
- dev->ep_in[epnum] = NULL;
+ if (reset_hardware)
+ dev->ep_in[epnum] = NULL;
}
if (ep) {
ep->enabled = 0;
usb_hcd_flush_endpoint(dev, ep);
- usb_hcd_disable_endpoint(dev, ep);
+ if (reset_hardware)
+ usb_hcd_disable_endpoint(dev, ep);
}
}

@@ -1042,17 +1046,21 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
* usb_disable_interface -- Disable all endpoints for an interface
* @dev: the device whose interface is being disabled
* @intf: pointer to the interface descriptor
+ * @reset_hardware: flag to erase any endpoint state stored in the
+ * controller hardware
*
* Disables all the endpoints for the interface's current altsetting.
*/
-void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf)
+void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
+ bool reset_hardware)
{
struct usb_host_interface *alt = intf->cur_altsetting;
int i;

for (i = 0; i < alt->desc.bNumEndpoints; ++i) {
usb_disable_endpoint(dev,
- alt->endpoint[i].desc.bEndpointAddress);
+ alt->endpoint[i].desc.bEndpointAddress,
+ reset_hardware);
}
}

@@ -1073,8 +1081,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
skip_ep0 ? "non-ep0" : "all");
for (i = skip_ep0; i < 16; ++i) {
- usb_disable_endpoint(dev, i);
- usb_disable_endpoint(dev, i + USB_DIR_IN);
+ usb_disable_endpoint(dev, i, true);
+ usb_disable_endpoint(dev, i + USB_DIR_IN, true);
}
dev->toggle[0] = dev->toggle[1] = 0;

@@ -1242,7 +1250,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
/* prevent submissions using previous endpoint settings */
if (iface->cur_altsetting != alt)
usb_remove_sysfs_intf_files(iface);
- usb_disable_interface(dev, iface);
+ usb_disable_interface(dev, iface, true);

iface->cur_altsetting = alt;

@@ -1320,8 +1328,8 @@ int usb_reset_configuration(struct usb_device *dev)
*/

for (i = 1; i < 16; ++i) {
- usb_disable_endpoint(dev, i);
- usb_disable_endpoint(dev, i + USB_DIR_IN);
+ usb_disable_endpoint(dev, i, true);
+ usb_disable_endpoint(dev, i + USB_DIR_IN, true);
}

config = dev->actconfig;
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 1d450e9..6c90be1 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -13,9 +13,10 @@ extern void usb_enable_endpoint(struct usb_device *dev,
struct usb_host_endpoint *ep, bool reset_toggle);
extern void usb_enable_interface(struct usb_device *dev,
struct usb_interface *intf, bool reset_toggles);
-extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr);
+extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
+ bool reset_hardware);
extern void usb_disable_interface(struct usb_device *dev,
- struct usb_interface *intf);
+ struct usb_interface *intf, bool reset_hardware);
extern void usb_release_interface_cache(struct kref *ref);
extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
extern int usb_deauthorize_device(struct usb_device *);
@@ -147,7 +148,6 @@ extern struct usb_driver usbfs_driver;
extern const struct file_operations usbfs_devices_fops;
extern const struct file_operations usbdev_file_operations;
extern void usbfs_conn_disc_event(void);
-extern void usb_fs_classdev_common_remove(struct usb_device *udev);

extern int usb_devio_init(void);
extern void usb_devio_cleanup(void);
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index e06810a..4cf27c7 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -37,6 +37,7 @@
#define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
#define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
#define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)
+
#ifdef CONFIG_COMPAT
#define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32)
#define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32)
@@ -921,21 +922,6 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
}
break;

-#ifdef CONFIG_COMPAT
- case MON_IOCX_GET32: {
- struct mon_bin_get32 getb;
-
- if (copy_from_user(&getb, (void __user *)arg,
- sizeof(struct mon_bin_get32)))
- return -EFAULT;
-
- ret = mon_bin_get_event(file, rp,
- compat_ptr(getb.hdr32), compat_ptr(getb.data32),
- getb.alloc32);
- }
- break;
-#endif
-
case MON_IOCX_MFETCH:
{
struct mon_bin_mfetch mfetch;
@@ -962,7 +948,57 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
}
break;

+ case MON_IOCG_STATS: {
+ struct mon_bin_stats __user *sp;
+ unsigned int nevents;
+ unsigned int ndropped;
+
+ spin_lock_irqsave(&rp->b_lock, flags);
+ ndropped = rp->cnt_lost;
+ rp->cnt_lost = 0;
+ spin_unlock_irqrestore(&rp->b_lock, flags);
+ nevents = mon_bin_queued(rp);
+
+ sp = (struct mon_bin_stats __user *)arg;
+ if (put_user(rp->cnt_lost, &sp->dropped))
+ return -EFAULT;
+ if (put_user(nevents, &sp->queued))
+ return -EFAULT;
+
+ }
+ break;
+
+ default:
+ return -ENOTTY;
+ }
+
+ return ret;
+}
+
#ifdef CONFIG_COMPAT
+static long mon_bin_compat_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct mon_reader_bin *rp = file->private_data;
+ int ret;
+
+ switch (cmd) {
+
+ case MON_IOCX_GET32: {
+ struct mon_bin_get32 getb;
+
+ if (copy_from_user(&getb, (void __user *)arg,
+ sizeof(struct mon_bin_get32)))
+ return -EFAULT;
+
+ ret = mon_bin_get_event(file, rp,
+ compat_ptr(getb.hdr32), compat_ptr(getb.data32),
+ getb.alloc32);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+
case MON_IOCX_MFETCH32:
{
struct mon_bin_mfetch32 mfetch;
@@ -986,37 +1022,25 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
return ret;
if (put_user(ret, &uptr->nfetch32))
return -EFAULT;
- ret = 0;
}
- break;
-#endif
-
- case MON_IOCG_STATS: {
- struct mon_bin_stats __user *sp;
- unsigned int nevents;
- unsigned int ndropped;
-
- spin_lock_irqsave(&rp->b_lock, flags);
- ndropped = rp->cnt_lost;
- rp->cnt_lost = 0;
- spin_unlock_irqrestore(&rp->b_lock, flags);
- nevents = mon_bin_queued(rp);
+ return 0;

- sp = (struct mon_bin_stats __user *)arg;
- if (put_user(rp->cnt_lost, &sp->dropped))
- return -EFAULT;
- if (put_user(nevents, &sp->queued))
- return -EFAULT;
+ case MON_IOCG_STATS:
+ return mon_bin_ioctl(NULL, file, cmd,
+ (unsigned long) compat_ptr(arg));

- }
- break;
+ case MON_IOCQ_URB_LEN:
+ case MON_IOCQ_RING_SIZE:
+ case MON_IOCT_RING_SIZE:
+ case MON_IOCH_MFLUSH:
+ return mon_bin_ioctl(NULL, file, cmd, arg);

default:
- return -ENOTTY;
+ ;
}
-
- return ret;
+ return -ENOTTY;
}
+#endif /* CONFIG_COMPAT */

static unsigned int
mon_bin_poll(struct file *file, struct poll_table_struct *wait)
@@ -1094,6 +1118,9 @@ static const struct file_operations mon_fops_binary = {
/* .write = mon_text_write, */
.poll = mon_bin_poll,
.ioctl = mon_bin_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = mon_bin_compat_ioctl,
+#endif
.release = mon_bin_release,
.mmap = mon_bin_mmap,
};
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index ce7f746..443122f 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1970,6 +1970,12 @@ UNUSUAL_DEV( 0x19d2, 0x2000, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_DEVICE),

+UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
+ "ST",
+ "2A",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY),
+
/* patch submitted by Davide Perini <perini.davide@xxxxxxxxxxxxxx>
* and Renato Perini <rperini@xxxxxxxx>
*/
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index ba2f9ec..011b9b8 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -234,8 +234,6 @@ struct ep_pqueue {
/*
* Configuration options available inside /proc/sys/fs/epoll/
*/
-/* Maximum number of epoll devices, per user */
-static int max_user_instances __read_mostly;
/* Maximum number of epoll watched descriptors, per user */
static int max_user_watches __read_mostly;

@@ -261,14 +259,6 @@ static int zero;

ctl_table epoll_table[] = {
{
- .procname = "max_user_instances",
- .data = &max_user_instances,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_minmax,
- .extra1 = &zero,
- },
- {
.procname = "max_user_watches",
.data = &max_user_watches,
.maxlen = sizeof(int),
@@ -491,7 +481,6 @@ static void ep_free(struct eventpoll *ep)

mutex_unlock(&epmutex);
mutex_destroy(&ep->mtx);
- atomic_dec(&ep->user->epoll_devs);
free_uid(ep->user);
kfree(ep);
}
@@ -581,10 +570,6 @@ static int ep_alloc(struct eventpoll **pep)
struct eventpoll *ep;

user = get_current_user();
- error = -EMFILE;
- if (unlikely(atomic_read(&user->epoll_devs) >=
- max_user_instances))
- goto free_uid;
error = -ENOMEM;
ep = kzalloc(sizeof(*ep), GFP_KERNEL);
if (unlikely(!ep))
@@ -1141,7 +1126,6 @@ SYSCALL_DEFINE1(epoll_create1, int, flags)
flags & O_CLOEXEC);
if (fd < 0)
ep_free(ep);
- atomic_inc(&ep->user->epoll_devs);

error_return:
DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
@@ -1366,8 +1350,10 @@ static int __init eventpoll_init(void)
struct sysinfo si;

si_meminfo(&si);
- max_user_instances = 128;
- max_user_watches = (((si.totalram - si.totalhigh) / 32) << PAGE_SHIFT) /
+ /*
+ * Allows top 4% of lomem to be allocated for epoll watches (per user).
+ */
+ max_user_watches = (((si.totalram - si.totalhigh) / 25) << PAGE_SHIFT) /
EP_ITEM_COST;

/* Initialize the structure used to perform safe poll wait head wake ups */
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index a48e965..83bd869 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1357,7 +1357,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
struct fake_dirent *fde;

blocksize = dir->i_sb->s_blocksize;
- dxtrace(printk("Creating index\n"));
+ dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino));
retval = ext3_journal_get_write_access(handle, bh);
if (retval) {
ext3_std_error(dir->i_sb, retval);
@@ -1366,6 +1366,19 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
}
root = (struct dx_root *) bh->b_data;

+ /* The 0th block becomes the root, move the dirents out */
+ fde = &root->dotdot;
+ de = (struct ext3_dir_entry_2 *)((char *)fde +
+ ext3_rec_len_from_disk(fde->rec_len));
+ if ((char *) de >= (((char *) root) + blocksize)) {
+ ext3_error(dir->i_sb, __func__,
+ "invalid rec_len for '..' in inode %lu",
+ dir->i_ino);
+ brelse(bh);
+ return -EIO;
+ }
+ len = ((char *) root) + blocksize - (char *) de;
+
bh2 = ext3_append (handle, dir, &block, &retval);
if (!(bh2)) {
brelse(bh);
@@ -1374,11 +1387,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
data1 = bh2->b_data;

- /* The 0th block becomes the root, move the dirents out */
- fde = &root->dotdot;
- de = (struct ext3_dir_entry_2 *)((char *)fde +
- ext3_rec_len_from_disk(fde->rec_len));
- len = ((char *) root) + blocksize - (char *) de;
memcpy (data1, de, len);
de = (struct ext3_dir_entry_2 *) data1;
top = data1 + len;
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index b723614..2e37f14 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -281,7 +281,8 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
fc->blocked = 0;
wake_up_all(&fc->blocked_waitq);
}
- if (fc->num_background == FUSE_CONGESTION_THRESHOLD) {
+ if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
+ fc->connected) {
clear_bdi_congested(&fc->bdi, READ);
clear_bdi_congested(&fc->bdi, WRITE);
}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 4c9ee70..d8029d8 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -54,7 +54,7 @@ struct fuse_file *fuse_file_alloc(void)
ff->reserved_req = fuse_request_alloc();
if (!ff->reserved_req) {
kfree(ff);
- ff = NULL;
+ return NULL;
} else {
INIT_LIST_HEAD(&ff->write_entry);
atomic_set(&ff->count, 0);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 2e99f34..755fe24 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -292,6 +292,7 @@ static void fuse_put_super(struct super_block *sb)
list_del(&fc->entry);
fuse_ctl_remove_conn(fc);
mutex_unlock(&fuse_mutex);
+ bdi_destroy(&fc->bdi);
fuse_conn_put(fc);
}

@@ -531,7 +532,6 @@ void fuse_conn_put(struct fuse_conn *fc)
if (fc->destroy_req)
fuse_request_free(fc->destroy_req);
mutex_destroy(&fc->inst_mutex);
- bdi_destroy(&fc->bdi);
kfree(fc);
}
}
@@ -825,12 +825,16 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
if (!file)
return -EINVAL;

- if (file->f_op != &fuse_dev_operations)
+ if (file->f_op != &fuse_dev_operations) {
+ fput(file);
return -EINVAL;
+ }

fc = new_conn(sb);
- if (!fc)
+ if (!fc) {
+ fput(file);
return -ENOMEM;
+ }

fc->flags = d.flags;
fc->user_id = d.user_id;
diff --git a/fs/inotify_user.c b/fs/inotify_user.c
index a7aea80..12533a6 100644
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -427,10 +427,61 @@ static unsigned int inotify_poll(struct file *file, poll_table *wait)
return ret;
}

+/*
+ * Get an inotify_kernel_event if one exists and is small
+ * enough to fit in "count". Return an error pointer if
+ * not large enough.
+ *
+ * Called with the device ev_mutex held.
+ */
+static struct inotify_kernel_event *get_one_event(struct inotify_device *dev,
+ size_t count)
+{
+ size_t event_size = sizeof(struct inotify_event);
+ struct inotify_kernel_event *kevent;
+
+ if (list_empty(&dev->events))
+ return NULL;
+
+ kevent = inotify_dev_get_event(dev);
+ if (kevent->name)
+ event_size += kevent->event.len;
+
+ if (event_size > count)
+ return ERR_PTR(-EINVAL);
+
+ remove_kevent(dev, kevent);
+ return kevent;
+}
+
+/*
+ * Copy an event to user space, returning how much we copied.
+ *
+ * We already checked that the event size is smaller than the
+ * buffer we had in "get_one_event()" above.
+ */
+static ssize_t copy_event_to_user(struct inotify_kernel_event *kevent,
+ char __user *buf)
+{
+ size_t event_size = sizeof(struct inotify_event);
+
+ if (copy_to_user(buf, &kevent->event, event_size))
+ return -EFAULT;
+
+ if (kevent->name) {
+ buf += event_size;
+
+ if (copy_to_user(buf, kevent->name, kevent->event.len))
+ return -EFAULT;
+
+ event_size += kevent->event.len;
+ }
+ return event_size;
+}
+
static ssize_t inotify_read(struct file *file, char __user *buf,
size_t count, loff_t *pos)
{
- size_t event_size = sizeof (struct inotify_event);
struct inotify_device *dev;
char __user *start;
int ret;
@@ -440,81 +491,43 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
dev = file->private_data;

while (1) {
+ struct inotify_kernel_event *kevent;

prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE);

mutex_lock(&dev->ev_mutex);
- if (!list_empty(&dev->events)) {
- ret = 0;
- break;
- }
+ kevent = get_one_event(dev, count);
mutex_unlock(&dev->ev_mutex);

- if (file->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- break;
- }
-
- if (signal_pending(current)) {
- ret = -EINTR;
- break;
+ if (kevent) {
+ ret = PTR_ERR(kevent);
+ if (IS_ERR(kevent))
+ break;
+ ret = copy_event_to_user(kevent, buf);
+ free_kevent(kevent);
+ if (ret < 0)
+ break;
+ buf += ret;
+ count -= ret;
+ continue;
}

- schedule();
- }
-
- finish_wait(&dev->wq, &wait);
- if (ret)
- return ret;
-
- while (1) {
- struct inotify_kernel_event *kevent;
-
- ret = buf - start;
- if (list_empty(&dev->events))
+ ret = -EAGAIN;
+ if (file->f_flags & O_NONBLOCK)
break;
-
- kevent = inotify_dev_get_event(dev);
- if (event_size + kevent->event.len > count) {
- if (ret == 0 && count > 0) {
- /*
- * could not get a single event because we
- * didn't have enough buffer space.
- */
- ret = -EINVAL;
- }
+ ret = -EINTR;
+ if (signal_pending(current))
break;
- }
- remove_kevent(dev, kevent);

- /*
- * Must perform the copy_to_user outside the mutex in order
- * to avoid a lock order reversal with mmap_sem.
- */
- mutex_unlock(&dev->ev_mutex);
-
- if (copy_to_user(buf, &kevent->event, event_size)) {
- ret = -EFAULT;
+ if (start != buf)
break;
- }
- buf += event_size;
- count -= event_size;
-
- if (kevent->name) {
- if (copy_to_user(buf, kevent->name, kevent->event.len)){
- ret = -EFAULT;
- break;
- }
- buf += kevent->event.len;
- count -= kevent->event.len;
- }
-
- free_kevent(kevent);

- mutex_lock(&dev->ev_mutex);
+ schedule();
}
- mutex_unlock(&dev->ev_mutex);

+ finish_wait(&dev->wq, &wait);
+ if (start != buf && ret != -EFAULT)
+ ret = buf - start;
return ret;
}

diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 66f6e58..f2c478c 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -63,6 +63,9 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
int count = min_t(size_t, bytes, PAGE_SIZE);
char *temp;

+ if (!bytes)
+ return 0;
+
if (size) {
if (offs > size)
return 0;
@@ -131,6 +134,9 @@ static ssize_t write(struct file *file, const char __user *userbuf,
int count = min_t(size_t, bytes, PAGE_SIZE);
char *temp;

+ if (!bytes)
+ return 0;
+
if (size) {
if (offs > size)
return 0;
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index e531783..3a025d9 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -41,6 +41,7 @@ header-y += baycom.h
header-y += bfs_fs.h
header-y += blkpg.h
header-y += bpqether.h
+header-y += bsg.h
header-y += can.h
header-y += cdk.h
header-y += chio.h
diff --git a/include/linux/klist.h b/include/linux/klist.h
index 8ea98db..a21cd7a 100644
--- a/include/linux/klist.h
+++ b/include/linux/klist.h
@@ -23,7 +23,7 @@ struct klist {
struct list_head k_list;
void (*get)(struct klist_node *);
void (*put)(struct klist_node *);
-};
+} __attribute__ ((aligned (4)));

#define KLIST_INIT(_name, _get, _put) \
{ .k_lock = __SPIN_LOCK_UNLOCKED(_name.k_lock), \
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 1800f1d..52df0cb 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1357,6 +1357,7 @@
#define PCI_DEVICE_ID_VIA_8783_0 0x3208
#define PCI_DEVICE_ID_VIA_8237 0x3227
#define PCI_DEVICE_ID_VIA_8251 0x3287
+#define PCI_DEVICE_ID_VIA_8261 0x3402
#define PCI_DEVICE_ID_VIA_8237A 0x3337
#define PCI_DEVICE_ID_VIA_8237S 0x3372
#define PCI_DEVICE_ID_VIA_SATA_EIDE 0x5324
@@ -1366,10 +1367,13 @@
#define PCI_DEVICE_ID_VIA_CX700 0x8324
#define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581
#define PCI_DEVICE_ID_VIA_VX800 0x8353
+#define PCI_DEVICE_ID_VIA_VX855 0x8409
#define PCI_DEVICE_ID_VIA_8371_1 0x8391
#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
#define PCI_DEVICE_ID_VIA_838X_1 0xB188
#define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198
+#define PCI_DEVICE_ID_VIA_C409_IDE 0XC409
+#define PCI_DEVICE_ID_VIA_ANON 0xFFFF

#define PCI_VENDOR_ID_SIEMENS 0x110A
#define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102
@@ -1795,6 +1799,7 @@
#define PCI_DEVICE_ID_SEALEVEL_UCOMM232 0x7202
#define PCI_DEVICE_ID_SEALEVEL_COMM4 0x7401
#define PCI_DEVICE_ID_SEALEVEL_COMM8 0x7801
+#define PCI_DEVICE_ID_SEALEVEL_7803 0x7803
#define PCI_DEVICE_ID_SEALEVEL_UCOMM8 0x7804

#define PCI_VENDOR_ID_HYPERCOPE 0x1365
@@ -2171,6 +2176,7 @@
#define PCI_DEVICE_ID_RDC_R6040 0x6040
#define PCI_DEVICE_ID_RDC_R6060 0x6060
#define PCI_DEVICE_ID_RDC_R6061 0x6061
+#define PCI_DEVICE_ID_RDC_D1010 0x1010

#define PCI_VENDOR_ID_LENOVO 0x17aa

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 55e30d1..3883c32 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -631,7 +631,6 @@ struct user_struct {
atomic_t inotify_devs; /* How many inotify devs does this user have opened? */
#endif
#ifdef CONFIG_EPOLL
- atomic_t epoll_devs; /* The number of epoll descriptors currently open */
atomic_t epoll_watches; /* The number of file descriptors currently watched */
#endif
#ifdef CONFIG_POSIX_MQUEUE
diff --git a/kernel/relay.c b/kernel/relay.c
index 09ac200..9d79b78 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -663,8 +663,10 @@ int relay_late_setup_files(struct rchan *chan,

mutex_lock(&relay_channels_mutex);
/* Is chan already set up? */
- if (unlikely(chan->has_base_filename))
+ if (unlikely(chan->has_base_filename)) {
+ mutex_unlock(&relay_channels_mutex);
return -EEXIST;
+ }
chan->has_base_filename = 1;
chan->parent = parent;
curr_cpu = get_cpu();
diff --git a/kernel/resource.c b/kernel/resource.c
index 4337063..e633106 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -853,6 +853,15 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
if (PFN_DOWN(p->start) <= PFN_DOWN(addr) &&
PFN_DOWN(p->end) >= PFN_DOWN(addr + size - 1))
continue;
+ /*
+ * if a resource is "BUSY", it's not a hardware resource
+ * but a driver mapping of such a resource; we don't want
+ * to warn for those; some drivers legitimately map only
+ * partial hardware resources. (example: vesafb)
+ */
+ if (p->flags & IORESOURCE_BUSY)
+ continue;
+
printk(KERN_WARNING "resource map sanity check conflict: "
"0x%llx 0x%llx 0x%llx 0x%llx %s\n",
(unsigned long long)addr,
diff --git a/mm/mmap.c b/mm/mmap.c
index 937b44f..9c3f4f8 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1095,6 +1095,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma, *prev;
+ struct vm_area_struct *merged_vma;
int correct_wcount = 0;
int error;
struct rb_node **rb_link, *rb_parent;
@@ -1207,13 +1208,17 @@ munmap_back:
if (vma_wants_writenotify(vma))
vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED);

- if (file && vma_merge(mm, prev, addr, vma->vm_end,
- vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
+ merged_vma = NULL;
+ if (file)
+ merged_vma = vma_merge(mm, prev, addr, vma->vm_end,
+ vma->vm_flags, NULL, file, pgoff, vma_policy(vma));
+ if (merged_vma) {
mpol_put(vma_policy(vma));
kmem_cache_free(vm_area_cachep, vma);
fput(file);
if (vm_flags & VM_EXECUTABLE)
removed_exe_file_vma(mm);
+ vma = merged_vma;
} else {
vma_link(mm, vma, prev, rb_link, rb_parent);
file = vma->vm_file;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 7465f22..0380ea5 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -23,6 +23,7 @@
#include <linux/rbtree.h>
#include <linux/radix-tree.h>
#include <linux/rcupdate.h>
+#include <linux/bootmem.h>

#include <asm/atomic.h>
#include <asm/uaccess.h>
@@ -960,6 +961,8 @@ EXPORT_SYMBOL(vm_map_ram);

void __init vmalloc_init(void)
{
+ struct vmap_area *va;
+ struct vm_struct *tmp;
int i;

for_each_possible_cpu(i) {
@@ -972,6 +975,14 @@ void __init vmalloc_init(void)
vbq->nr_dirty = 0;
}

+ /* Import existing vmlist entries. */
+ for (tmp = vmlist; tmp; tmp = tmp->next) {
+ va = alloc_bootmem(sizeof(struct vmap_area));
+ va->flags = tmp->flags | VM_VM_AREA;
+ va->va_start = (unsigned long)tmp->addr;
+ va->va_end = va->va_start + tmp->size;
+ __insert_vmap_area(va);
+ }
vmap_initialized = true;
}

diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 1895a4c..0bc398c 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -342,8 +342,8 @@ again:
rv = register_pernet_operations(first_device, ops);
if (rv < 0)
ida_remove(&net_generic_ids, *id);
- mutex_unlock(&net_mutex);
out:
+ mutex_unlock(&net_mutex);
return rv;
}
EXPORT_SYMBOL_GPL(register_pernet_gen_subsys);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1460537..077be80 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1299,8 +1299,10 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (is_multicast_ether_addr(hdr->addr3))
memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
else
- if (mesh_nexthop_lookup(skb, osdata))
- return 0;
+ if (mesh_nexthop_lookup(skb, osdata)) {
+ dev_put(odev);
+ return 0;
+ }
if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
fwded_frames);
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 7c1eb23..a50089f 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1470,6 +1470,7 @@ static struct snd_pci_quirk cxt5047_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV2000T/DV3000T", CXT5047_LAPTOP),
SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2000Z", CXT5047_LAPTOP),
+ SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6700", CXT5047_LAPTOP),
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
{}
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index befb699..75101d8 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -6780,6 +6780,7 @@ static int patch_alc882(struct hda_codec *codec)
case 0x106b00a4: /* MacbookPro4,1 */
case 0x106b2c00: /* Macbook Pro rev3 */
case 0x106b3600: /* Macbook 3.1 */
+ case 0x106b3800: /* MacbookPro4,1 - latter revision */
board_config = ALC885_MBP3;
break;
default:
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 8b204b8..1f9fcfe 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2428,6 +2428,8 @@ static int stac92xx_build_pcms(struct hda_codec *codec)

info->name = "STAC92xx Analog";
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
+ spec->multiout.dac_nids[0];
info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index e9e829e..a962166 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -908,6 +908,7 @@ static const struct oxygen_model model_xonar_hdav = {
.dac_channels = 8,
.dac_volume_min = 0x0f,
.dac_volume_max = 0xff,
+ .misc_flags = OXYGEN_MISC_MIDI,
.function_flags = OXYGEN_FUNCTION_2WIRE,
.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/