Re: Linux 2.6.27.29

From: Greg KH
Date: Thu Jul 30 2009 - 19:13:28 EST


diff --git a/Makefile b/Makefile
index 7598325..47d46f4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 27
-EXTRAVERSION = .28
+EXTRAVERSION = .29
NAME = Trembling Tortoise

# *DOCUMENTATION*
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
index 007bb06..73e6ce1 100644
--- a/arch/x86/mm/gup.c
+++ b/arch/x86/mm/gup.c
@@ -231,10 +231,15 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
start &= PAGE_MASK;
addr = start;
len = (unsigned long) nr_pages << PAGE_SHIFT;
+
end = start + len;
- if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
- start, len)))
+ if (end < start)
+ goto slow_irqon;
+
+#ifdef CONFIG_X86_64
+ if (end >> 47)
goto slow_irqon;
+#endif

/*
* XXX: batch / limit 'nr', to avoid large irq off latency
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 1b4763e..e353618 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -87,8 +87,10 @@ static __init void bad_srat(void)
found_add_area = 0;
for (i = 0; i < MAX_LOCAL_APIC; i++)
apicid_to_node[i] = NUMA_NO_NODE;
- for (i = 0; i < MAX_NUMNODES; i++)
- nodes_add[i].start = nodes[i].end = 0;
+ for (i = 0; i < MAX_NUMNODES; i++) {
+ nodes[i].start = nodes[i].end = 0;
+ nodes_add[i].start = nodes_add[i].end = 0;
+ }
remove_all_active_ranges();
}

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e618cbe..e6b3c7e 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1013,7 +1013,8 @@ int __init acpi_ec_ecdt_probe(void)
* which needs it, has fake EC._INI method, so use it as flag.
* Keep boot_ec struct as it will be needed soon.
*/
- if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy)))
+ if (!dmi_name_in_vendors("ASUS") ||
+ ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy)))
return -ENODEV;
install:
if (!ec_install_handlers(boot_ec)) {
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 842e9ed..993772c 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -484,8 +484,10 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
goto goodreturn;

case HIDIOCGCOLLECTIONINDEX:
+ i = field->usage[uref->usage_index].collection_index;
+ unlock_kernel();
kfree(uref_multi);
- return field->usage[uref->usage_index].collection_index;
+ return i;
case HIDIOCGUSAGES:
for (i = 0; i < uref_multi->num_values; i++)
uref_multi->values[i] =
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
index f27af6a..65cf25f 100644
--- a/drivers/hwmon/max6650.c
+++ b/drivers/hwmon/max6650.c
@@ -407,6 +407,7 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr,
data->count = 3;
break;
default:
+ mutex_unlock(&data->update_lock);
dev_err(&client->dev,
"illegal value for fan divider (%d)\n", div);
return -EINVAL;
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index fe268be..2dacc3e 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -627,6 +627,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
},
{
.callback = dmi_matched,
+ .ident = "Maxdata Pro 7000 DX",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"),
+ },
+ .driver_data = keymap_fs_amilo_pro_v2000
+ },
+ {
+ .callback = dmi_matched,
.ident = "Fujitsu N3510",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 5cbf64d..c712bcc 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -307,32 +307,33 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */
{RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}},
{RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}},
{RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}},
- {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"}, /* set "Endgeraetemodus" */
+ {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"},
{RSP_OK, 607,607, -1, 608,-1},
- //{RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 608, 0, {ACT_ERROR}},//DELETE
{RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}},
{RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}},

- {RSP_ZVLS, 608,608, 17, -1,-1, {ACT_DEBUG}},
- {RSP_ZCTP, 609,609, -1, -1,-1, {ACT_DEBUG}},
- {RSP_ZCPN, 609,609, -1, -1,-1, {ACT_DEBUG}},
{RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}},
{EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}},

- /* dialing */
- {RSP_ZCTP, 650,650, -1, -1,-1, {ACT_DEBUG}},
- {RSP_ZCPN, 650,650, -1, -1,-1, {ACT_DEBUG}},
- {RSP_ZSAU, 650,650,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, /* some devices don't send this */
-
- /* connection established */
- {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1
- {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1
-
- {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}}, //FIXME new constate + timeout
+ /* optional dialing responses */
+ {EV_BC_OPEN, 650,650, -1, 651,-1},
+ {RSP_ZVLS, 608,651, 17, -1,-1, {ACT_DEBUG}},
+ {RSP_ZCTP, 609,651, -1, -1,-1, {ACT_DEBUG}},
+ {RSP_ZCPN, 609,651, -1, -1,-1, {ACT_DEBUG}},
+ {RSP_ZSAU, 650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}},
+
+ /* connect */
+ {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}},
+ {RSP_ZSAU, 651,651,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT,
+ ACT_NOTIFY_BC_UP}},
+ {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}},
+ {RSP_ZSAU, 751,751,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT,
+ ACT_NOTIFY_BC_UP}},
+ {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}},

/* remote hangup */
- {RSP_ZSAU, 650,650,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}},
- {RSP_ZSAU, 750,750,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}},
+ {RSP_ZSAU, 650,651,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}},
+ {RSP_ZSAU, 750,751,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}},
{RSP_ZSAU, 800,800,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}},

/* hangup */
@@ -371,7 +372,8 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */
{RSP_ZSAU, 700,729,ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT}},
{RSP_ZSAU, 700,729,ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT}},

- {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}},
+ {EV_BC_OPEN, 750,750, -1, 751,-1},
+ {EV_TIMEOUT, 750,751, -1, 0, 0, {ACT_CONNTIMEOUT}},

/* B channel closed (general case) */
{EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME
@@ -914,12 +916,6 @@ static void bchannel_down(struct bc_state *bcs)

static void bchannel_up(struct bc_state *bcs)
{
- if (!(bcs->chstate & CHS_D_UP)) {
- dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__);
- bcs->chstate |= CHS_D_UP;
- gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
- }
-
if (bcs->chstate & CHS_B_UP) {
dev_notice(bcs->cs->dev, "%s: B channel already up\n",
__func__);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index ebbc3bb..b60d328 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3281,7 +3281,8 @@ suspend_lo_store(mddev_t *mddev, const char *buf, size_t len)
char *e;
unsigned long long new = simple_strtoull(buf, &e, 10);

- if (mddev->pers->quiesce == NULL)
+ if (mddev->pers == NULL ||
+ mddev->pers->quiesce == NULL)
return -EINVAL;
if (buf == e || (*e && *e != '\n'))
return -EINVAL;
@@ -3309,7 +3310,8 @@ suspend_hi_store(mddev_t *mddev, const char *buf, size_t len)
char *e;
unsigned long long new = simple_strtoull(buf, &e, 10);

- if (mddev->pers->quiesce == NULL)
+ if (mddev->pers == NULL ||
+ mddev->pers->quiesce == NULL)
return -EINVAL;
if (buf == e || (*e && *e != '\n'))
return -EINVAL;
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 5cf78d6..d991167 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1840,6 +1840,9 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,

if (ioread8(&nic->csr->scb.status) & rus_no_res)
nic->ru_running = RU_SUSPENDED;
+ pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
+ sizeof(struct rfd),
+ PCI_DMA_BIDIRECTIONAL);
return -ENODATA;
}

diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 0f501d2..91e4232 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -397,13 +397,14 @@ static DEFINE_RWLOCK(disc_data_lock);

static struct sixpack *sp_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct sixpack *sp;

- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
sp = tty->disc_data;
if (sp)
atomic_inc(&sp->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);

return sp;
}
@@ -687,12 +688,13 @@ out:
*/
static void sixpack_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct sixpack *sp;

- write_lock(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
sp = tty->disc_data;
tty->disc_data = NULL;
- write_unlock(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!sp)
return;

diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index b8e25c4..2a9adcc 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -246,15 +246,16 @@ static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc,
/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
static void ax_bump(struct mkiss *ax)
{
+ unsigned long flags;
struct sk_buff *skb;
int count;

- spin_lock_bh(&ax->buflock);
+ spin_lock_irqsave(&ax->buflock, flags);
if (ax->rbuff[0] > 0x0f) {
if (ax->rbuff[0] & 0x80) {
if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
ax->stats.rx_errors++;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);

return;
}
@@ -269,7 +270,7 @@ static void ax_bump(struct mkiss *ax)
} else if (ax->rbuff[0] & 0x20) {
if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
ax->stats.rx_errors++;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
return;
}
if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
@@ -296,7 +297,7 @@ static void ax_bump(struct mkiss *ax)
printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
ax->dev->name);
ax->stats.rx_dropped++;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
return;
}

@@ -306,11 +307,13 @@ static void ax_bump(struct mkiss *ax)
ax->dev->last_rx = jiffies;
ax->stats.rx_packets++;
ax->stats.rx_bytes += count;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
}

static void kiss_unesc(struct mkiss *ax, unsigned char s)
{
+ unsigned long flags;
+
switch (s) {
case END:
/* drop keeptest bit = VSV */
@@ -337,18 +340,18 @@ static void kiss_unesc(struct mkiss *ax, unsigned char s)
break;
}

- spin_lock_bh(&ax->buflock);
+ spin_lock_irqsave(&ax->buflock, flags);
if (!test_bit(AXF_ERROR, &ax->flags)) {
if (ax->rcount < ax->buffsize) {
ax->rbuff[ax->rcount++] = s;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
return;
}

ax->stats.rx_over_errors++;
set_bit(AXF_ERROR, &ax->flags);
}
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
}

static int ax_set_mac_address(struct net_device *dev, void *addr)
@@ -370,6 +373,7 @@ static void ax_changedmtu(struct mkiss *ax)
{
struct net_device *dev = ax->dev;
unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
+ unsigned long flags;
int len;

len = dev->mtu * 2;
@@ -395,7 +399,7 @@ static void ax_changedmtu(struct mkiss *ax)
return;
}

- spin_lock_bh(&ax->buflock);
+ spin_lock_irqsave(&ax->buflock, flags);

oxbuff = ax->xbuff;
ax->xbuff = xbuff;
@@ -426,7 +430,7 @@ static void ax_changedmtu(struct mkiss *ax)
ax->mtu = dev->mtu + 73;
ax->buffsize = len;

- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);

kfree(oxbuff);
kfree(orbuff);
@@ -436,6 +440,7 @@ static void ax_changedmtu(struct mkiss *ax)
static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
{
struct mkiss *ax = netdev_priv(dev);
+ unsigned long flags;
unsigned char *p;
int actual, count;

@@ -452,7 +457,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)

p = icp;

- spin_lock_bh(&ax->buflock);
+ spin_lock_irqsave(&ax->buflock, flags);
if ((*p & 0x0f) != 0) {
/* Configuration Command (kissparms(1).
* Protocol spec says: never append CRC.
@@ -482,7 +487,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
ax->crcauto = (cmd ? 0 : 1);
printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd);
}
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
netif_start_queue(dev);

return;
@@ -515,7 +520,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
}
}
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);

set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
@@ -711,13 +716,14 @@ static DEFINE_RWLOCK(disc_data_lock);

static struct mkiss *mkiss_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct mkiss *ax;

- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
ax = tty->disc_data;
if (ax)
atomic_inc(&ax->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);

return ax;
}
@@ -816,12 +822,13 @@ out:

static void mkiss_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct mkiss *ax;

- write_lock(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
ax = tty->disc_data;
tty->disc_data = NULL;
- write_unlock(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);

if (!ax)
return;
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 451bdb5..7dac631 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -132,13 +132,15 @@ static DEFINE_RWLOCK(disc_data_lock);

static struct asyncppp *ap_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct asyncppp *ap;

- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
if (ap != NULL)
atomic_inc(&ap->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
+
return ap;
}

@@ -212,12 +214,13 @@ ppp_asynctty_open(struct tty_struct *tty)
static void
ppp_asynctty_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct asyncppp *ap;

- write_lock_irq(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
tty->disc_data = NULL;
- write_unlock_irq(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!ap)
return;

diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 801d8f9..13cc986 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -182,13 +182,15 @@ static DEFINE_RWLOCK(disc_data_lock);

static struct syncppp *sp_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct syncppp *ap;

- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
if (ap != NULL)
atomic_inc(&ap->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
+
return ap;
}

@@ -259,12 +261,13 @@ ppp_sync_open(struct tty_struct *tty)
static void
ppp_sync_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct syncppp *ap;

- write_lock_irq(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
tty->disc_data = NULL;
- write_unlock_irq(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!ap)
return;

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 5952522..f718215 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2850,54 +2850,64 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
int handled = 0;
int status;

+ /* loop handling interrupts until we have no new ones or
+ * we hit a invalid/hotplug case.
+ */
status = RTL_R16(IntrStatus);
+ while (status && status != 0xffff) {
+ handled = 1;

- /* hotplug/major error/no more work/shared irq */
- if ((status == 0xffff) || !status)
- goto out;
-
- handled = 1;
+ /* Handle all of the error cases first. These will reset
+ * the chip, so just exit the loop.
+ */
+ if (unlikely(!netif_running(dev))) {
+ rtl8169_asic_down(ioaddr);
+ break;
+ }

- if (unlikely(!netif_running(dev))) {
- rtl8169_asic_down(ioaddr);
- goto out;
- }
+ /* Work around for rx fifo overflow */
+ if (unlikely(status & RxFIFOOver) &&
+ (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
+ netif_stop_queue(dev);
+ rtl8169_tx_timeout(dev);
+ break;
+ }

- status &= tp->intr_mask;
- RTL_W16(IntrStatus,
- (status & RxFIFOOver) ? (status | RxOverflow) : status);
+ if (unlikely(status & SYSErr)) {
+ rtl8169_pcierr_interrupt(dev);
+ break;
+ }

- if (!(status & tp->intr_event))
- goto out;
+ if (status & LinkChg)
+ rtl8169_check_link_status(dev, tp, ioaddr);

- /* Work around for rx fifo overflow */
- if (unlikely(status & RxFIFOOver) &&
- (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
- netif_stop_queue(dev);
- rtl8169_tx_timeout(dev);
- goto out;
- }
+ /* We need to see the lastest version of tp->intr_mask to
+ * avoid ignoring an MSI interrupt and having to wait for
+ * another event which may never come.
+ */
+ smp_rmb();
+ if (status & tp->intr_mask & tp->napi_event) {
+ RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+ tp->intr_mask = ~tp->napi_event;
+
+ if (likely(napi_schedule_prep(&tp->napi)))
+ __napi_schedule(&tp->napi);
+ else if (netif_msg_intr(tp)) {
+ printk(KERN_INFO "%s: interrupt %04x in poll\n",
+ dev->name, status);
+ }
+ }

- if (unlikely(status & SYSErr)) {
- rtl8169_pcierr_interrupt(dev);
- goto out;
+ /* We only get a new MSI interrupt when all active irq
+ * sources on the chip have been acknowledged. So, ack
+ * everything we've seen and check if new sources have become
+ * active to avoid blocking all interrupts from the chip.
+ */
+ RTL_W16(IntrStatus,
+ (status & RxFIFOOver) ? (status | RxOverflow) : status);
+ status = RTL_R16(IntrStatus);
}

- if (status & LinkChg)
- rtl8169_check_link_status(dev, tp, ioaddr);
-
- if (status & tp->napi_event) {
- RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
- tp->intr_mask = ~tp->napi_event;
-
- if (likely(netif_rx_schedule_prep(dev, &tp->napi)))
- __netif_rx_schedule(dev, &tp->napi);
- else if (netif_msg_intr(tp)) {
- printk(KERN_INFO "%s: interrupt %04x in poll\n",
- dev->name, status);
- }
- }
-out:
return IRQ_RETVAL(handled);
}

@@ -2913,13 +2923,15 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)

if (work_done < budget) {
netif_rx_complete(dev, napi);
- tp->intr_mask = 0xffff;
- /*
- * 20040426: the barrier is not strictly required but the
- * behavior of the irq handler could be less predictable
- * without it. Btw, the lack of flush for the posted pci
- * write is safe - FR
+
+ /* We need for force the visibility of tp->intr_mask
+ * for other CPUs, as we can loose an MSI interrupt
+ * and potentially wait for a retransmit timeout if we don't.
+ * The posted write to IntrMask is safe, as it will
+ * eventually make it to the chip and we won't loose anything
+ * until it does.
*/
+ tp->intr_mask = 0xffff;
smp_wmb();
RTL_W16(IntrMask, tp->intr_event);
}
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index b68bc39..42963a9 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -2393,7 +2393,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
if (likely(status >> 16 == (status & 0xffff))) {
skb = sky2->rx_ring[sky2->rx_next].skb;
skb->ip_summed = CHECKSUM_COMPLETE;
- skb->csum = status & 0xffff;
+ skb->csum = le16_to_cpu(status);
} else {
printk(KERN_NOTICE PFX "%s: hardware receive "
"checksum problem (status = %#x)\n",
diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c
index c66b9c3..ca39ace 100644
--- a/drivers/net/usb/cdc_subset.c
+++ b/drivers/net/usb/cdc_subset.c
@@ -307,9 +307,10 @@ static const struct usb_device_id products [] = {
USB_DEVICE (0x1286, 0x8001), // "blob" bootloader
.driver_info = (unsigned long) &blob_info,
}, {
- // Linux Ethernet/RNDIS gadget on pxa210/25x/26x, second config
- // e.g. Gumstix, current OpenZaurus, ...
- USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
+ // Linux Ethernet/RNDIS gadget, mostly on PXA, second config
+ // e.g. Gumstix, current OpenZaurus, ... or anything else
+ // that just enables this gadget option.
+ USB_DEVICE (0x0525, 0xa4a2),
.driver_info = (unsigned long) &linuxdev_info,
},
#endif
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 8c19307..a04a8b0 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -295,7 +295,7 @@ static int update_eth_regs_async(pegasus_t * pegasus)

pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
pegasus->dr.bRequest = PEGASUS_REQ_SET_REGS;
- pegasus->dr.wValue = 0;
+ pegasus->dr.wValue = cpu_to_le16(0);
pegasus->dr.wIndex = cpu_to_le16(EthCtrl0);
pegasus->dr.wLength = cpu_to_le16(3);
pegasus->ctrl_urb->transfer_buffer_length = 3;
@@ -444,11 +444,12 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
int i;
__u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE };
int ret;
+ __le16 le_data = cpu_to_le16(data);

set_registers(pegasus, EpromOffset, 4, d);
enable_eprom_write(pegasus);
set_register(pegasus, EpromOffset, index);
- set_registers(pegasus, EpromData, 2, &data);
+ set_registers(pegasus, EpromData, 2, &le_data);
set_register(pegasus, EpromCtrl, EPROM_WRITE);

for (i = 0; i < REG_TIMEOUT; i++) {
@@ -918,29 +919,32 @@ static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)

static inline void disable_net_traffic(pegasus_t * pegasus)
{
- int tmp = 0;
+ __le16 tmp = cpu_to_le16(0);

- set_registers(pegasus, EthCtrl0, 2, &tmp);
+ set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp);
}

static inline void get_interrupt_interval(pegasus_t * pegasus)
{
- __u8 data[2];
+ u16 data;
+ u8 interval;

- read_eprom_word(pegasus, 4, (__u16 *) data);
+ read_eprom_word(pegasus, 4, &data);
+ interval = data >> 8;
if (pegasus->usb->speed != USB_SPEED_HIGH) {
- if (data[1] < 0x80) {
+ if (interval < 0x80) {
if (netif_msg_timer(pegasus))
dev_info(&pegasus->intf->dev, "intr interval "
"changed from %ums to %ums\n",
- data[1], 0x80);
- data[1] = 0x80;
+ interval, 0x80);
+ interval = 0x80;
+ data = (data & 0x00FF) | ((u16)interval << 8);
#ifdef PEGASUS_WRITE_EEPROM
- write_eprom_word(pegasus, 4, *(__u16 *) data);
+ write_eprom_word(pegasus, 4, data);
#endif
}
}
- pegasus->intr_interval = data[1];
+ pegasus->intr_interval = interval;
}

static void set_carrier(struct net_device *net)
@@ -1293,7 +1297,8 @@ static int pegasus_blacklisted(struct usb_device *udev)
/* Special quirk to keep the driver from handling the Belkin Bluetooth
* dongle which happens to have the same ID.
*/
- if ((udd->idVendor == VENDOR_BELKIN && udd->idProduct == 0x0121) &&
+ if ((udd->idVendor == cpu_to_le16(VENDOR_BELKIN)) &&
+ (udd->idProduct == cpu_to_le16(0x0121)) &&
(udd->bDeviceClass == USB_CLASS_WIRELESS_CONTROLLER) &&
(udd->bDeviceProtocol == 1))
return 1;
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 417e9e6..1e26ddc 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -856,6 +856,7 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
unsigned char *orbuff = strip_info->rx_buff;
unsigned char *osbuff = strip_info->sx_buff;
unsigned char *otbuff = strip_info->tx_buff;
+ unsigned long flags;

if (new_mtu > MAX_SEND_MTU) {
printk(KERN_ERR
@@ -864,11 +865,11 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
}

- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
if (!allocate_buffers(strip_info, new_mtu)) {
printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n",
strip_info->dev->name);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
return -ENOMEM;
}

@@ -892,7 +893,7 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
}
}
strip_info->tx_head = strip_info->tx_buff;
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);

printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
strip_info->dev->name, old_mtu, strip_info->mtu);
@@ -981,10 +982,13 @@ static void strip_seq_neighbours(struct seq_file *seq,
const MetricomNodeTable * table,
const char *title)
{
- /* We wrap this in a do/while loop, so if the table changes */
- /* while we're reading it, we just go around and try again. */
+ unsigned long flags;
struct timeval t;

+ /*
+ * We wrap this in a do/while loop, so if the table changes
+ * while we're reading it, we just go around and try again.
+ */
do {
int i;
t = table->timestamp;
@@ -993,9 +997,9 @@ static void strip_seq_neighbours(struct seq_file *seq,
for (i = 0; i < table->num_nodes; i++) {
MetricomNode node;

- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
node = table->node[i];
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
seq_printf(seq, " %s\n", node.c);
}
} while (table->timestamp.tv_sec != t.tv_sec
@@ -1535,6 +1539,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct strip *strip_info = netdev_priv(dev);
+ unsigned long flags;

if (!netif_running(dev)) {
printk(KERN_ERR "%s: xmit call when iface is down\n",
@@ -1573,11 +1578,11 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
strip_info->dev->name, sx_pps_count / 8);
}

- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);

strip_send(strip_info, skb);

- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);

if (skb)
dev_kfree_skb(skb);
@@ -2263,12 +2268,13 @@ static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
{
struct strip *strip_info = (struct strip *) tty->disc_data;
const unsigned char *end = cp + count;
+ unsigned long flags;

if (!strip_info || strip_info->magic != STRIP_MAGIC
|| !netif_running(strip_info->dev))
return;

- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
#if 0
{
struct timeval tv;
@@ -2335,7 +2341,7 @@ static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
}
cp++;
}
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
}


@@ -2525,9 +2531,11 @@ static void strip_dev_setup(struct net_device *dev)

static void strip_free(struct strip *strip_info)
{
- spin_lock_bh(&strip_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&strip_lock, flags);
list_del_rcu(&strip_info->list);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);

strip_info->magic = 0;

@@ -2541,6 +2549,7 @@ static void strip_free(struct strip *strip_info)
static struct strip *strip_alloc(void)
{
struct list_head *n;
+ unsigned long flags;
struct net_device *dev;
struct strip *strip_info;

@@ -2564,7 +2573,7 @@ static struct strip *strip_alloc(void)
strip_info->idle_timer.function = strip_IdleTask;


- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
rescan:
/*
* Search the list to find where to put our new entry
@@ -2583,7 +2592,7 @@ static struct strip *strip_alloc(void)
sprintf(dev->name, "st%ld", dev->base_addr);

list_add_tail_rcu(&strip_info->list, &strip_list);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);

return strip_info;
}
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 98b9df7..c193540 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -84,7 +84,6 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
acpi_handle handle = dev->data;
struct acpi_buffer buffer;
int ret;
- acpi_status status;

dev_dbg(&dev->dev, "set resources\n");
ret = pnpacpi_build_resource_template(dev, &buffer);
@@ -95,21 +94,29 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
kfree(buffer.pointer);
return ret;
}
- status = acpi_set_current_resources(handle, &buffer);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
ret = -EINVAL;
+ else if (acpi_bus_power_manageable(handle))
+ ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
kfree(buffer.pointer);
return ret;
}

static int pnpacpi_disable_resources(struct pnp_dev *dev)
{
- acpi_status status;
+ acpi_handle handle = dev->data;
+ int ret;
+
+ dev_dbg(&dev->dev, "disable resources\n");

/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
- status = acpi_evaluate_object((acpi_handle) dev->data,
- "_DIS", NULL, NULL);
- return ACPI_FAILURE(status) ? -ENODEV : 0;
+ ret = 0;
+ if (acpi_bus_power_manageable(handle))
+ acpi_bus_set_power(handle, ACPI_STATE_D3);
+ /* continue even if acpi_bus_set_power() fails */
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
+ ret = -ENODEV;
+ return ret;
}

#ifdef CONFIG_ACPI_SLEEP
diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
index 3c4a300..b8171de 100644
--- a/drivers/scsi/zalon.c
+++ b/drivers/scsi/zalon.c
@@ -134,7 +134,7 @@ zalon_probe(struct parisc_device *dev)

host = ncr_attach(&zalon7xx_template, unit, &device);
if (!host)
- goto fail;
+ return -ENODEV;

if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) {
printk(KERN_ERR "%s: irq problem with %d, detaching\n ",
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 8d2d79e..1ff88af 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -976,7 +976,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
USBDEVFS_URB_ZERO_PACKET |
USBDEVFS_URB_NO_INTERRUPT))
return -EINVAL;
- if (!uurb->buffer)
+ if (uurb->buffer_length > 0 && !uurb->buffer)
return -EINVAL;
if (uurb->signr != 0 && (uurb->signr < SIGRTMIN ||
uurb->signr > SIGRTMAX))
@@ -1035,11 +1035,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
is_in = 0;
uurb->endpoint &= ~USB_DIR_IN;
}
- if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
- uurb->buffer, uurb->buffer_length)) {
- kfree(dr);
- return -EFAULT;
- }
snoop(&ps->dev->dev, "control urb: bRequest=%02x "
"bRrequestType=%02x wValue=%04x "
"wIndex=%04x wLength=%04x\n",
@@ -1059,9 +1054,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
uurb->number_of_packets = 0;
if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
return -EINVAL;
- if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
- uurb->buffer, uurb->buffer_length))
- return -EFAULT;
snoop(&ps->dev->dev, "bulk urb\n");
break;

@@ -1103,28 +1095,35 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
return -EINVAL;
if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
return -EINVAL;
- if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
- uurb->buffer, uurb->buffer_length))
- return -EFAULT;
snoop(&ps->dev->dev, "interrupt urb\n");
break;

default:
return -EINVAL;
}
- as = alloc_async(uurb->number_of_packets);
- if (!as) {
+ if (uurb->buffer_length > 0 &&
+ !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
+ uurb->buffer, uurb->buffer_length)) {
kfree(isopkt);
kfree(dr);
- return -ENOMEM;
+ return -EFAULT;
}
- as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL);
- if (!as->urb->transfer_buffer) {
+ as = alloc_async(uurb->number_of_packets);
+ if (!as) {
kfree(isopkt);
kfree(dr);
- free_async(as);
return -ENOMEM;
}
+ if (uurb->buffer_length > 0) {
+ as->urb->transfer_buffer = kmalloc(uurb->buffer_length,
+ GFP_KERNEL);
+ if (!as->urb->transfer_buffer) {
+ kfree(isopkt);
+ kfree(dr);
+ free_async(as);
+ return -ENOMEM;
+ }
+ }
as->urb->dev = ps->dev;
as->urb->pipe = (uurb->type << 30) |
__create_pipe(ps->dev, uurb->endpoint & 0xf) |
@@ -1166,7 +1165,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
kfree(isopkt);
as->ps = ps;
as->userurb = arg;
- if (uurb->endpoint & USB_DIR_IN)
+ if (is_in && uurb->buffer_length > 0)
as->userbuffer = uurb->buffer;
else
as->userbuffer = NULL;
@@ -1176,9 +1175,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
as->uid = current->uid;
as->euid = current->euid;
security_task_getsecid(current, &as->secid);
- if (!is_in) {
+ if (!is_in && uurb->buffer_length > 0) {
if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
- as->urb->transfer_buffer_length)) {
+ uurb->buffer_length)) {
free_async(as);
return -EFAULT;
}
@@ -1228,22 +1227,22 @@ static int processcompl(struct async *as, void __user * __user *arg)
if (as->userbuffer)
if (copy_to_user(as->userbuffer, urb->transfer_buffer,
urb->transfer_buffer_length))
- return -EFAULT;
+ goto err_out;
if (put_user(as->status, &userurb->status))
- return -EFAULT;
+ goto err_out;
if (put_user(urb->actual_length, &userurb->actual_length))
- return -EFAULT;
+ goto err_out;
if (put_user(urb->error_count, &userurb->error_count))
- return -EFAULT;
+ goto err_out;

if (usb_endpoint_xfer_isoc(&urb->ep->desc)) {
for (i = 0; i < urb->number_of_packets; i++) {
if (put_user(urb->iso_frame_desc[i].actual_length,
&userurb->iso_frame_desc[i].actual_length))
- return -EFAULT;
+ goto err_out;
if (put_user(urb->iso_frame_desc[i].status,
&userurb->iso_frame_desc[i].status))
- return -EFAULT;
+ goto err_out;
}
}

@@ -1252,6 +1251,10 @@ static int processcompl(struct async *as, void __user * __user *arg)
if (put_user(addr, (void __user * __user *)arg))
return -EFAULT;
return 0;
+
+err_out:
+ free_async(as);
+ return -EFAULT;
}

static struct async *reap_as(struct dev_state *ps)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index bcac2e6..c5d6765 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -273,15 +273,16 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
/* CDC Subset */
eth_config_driver.label = "CDC Subset/SAFE";

- device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM),
- device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM),
- device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+ device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM);
+ device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM);
+ if (!has_rndis())
+ device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
}

if (has_rndis()) {
/* RNDIS plus ECM-or-Subset */
- device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM),
- device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM),
+ device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM);
+ device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM);
device_desc.bNumConfigurations = 2;
}

diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 1d0b49e..18e8741 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1617,11 +1617,14 @@ itd_complete (
desc->status = -EPROTO;

/* HC need not update length with this error */
- if (!(t & EHCI_ISOC_BABBLE))
- desc->actual_length = EHCI_ITD_LENGTH (t);
+ if (!(t & EHCI_ISOC_BABBLE)) {
+ desc->actual_length = EHCI_ITD_LENGTH(t);
+ urb->actual_length += desc->actual_length;
+ }
} else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
desc->status = 0;
- desc->actual_length = EHCI_ITD_LENGTH (t);
+ desc->actual_length = EHCI_ITD_LENGTH(t);
+ urb->actual_length += desc->actual_length;
} else {
/* URB was too late */
desc->status = -EXDEV;
@@ -2012,7 +2015,8 @@ sitd_complete (
desc->status = -EPROTO;
} else {
desc->status = 0;
- desc->actual_length = desc->length - SITD_LENGTH (t);
+ desc->actual_length = desc->length - SITD_LENGTH(t);
+ urb->actual_length += desc->actual_length;
}
stream->depth -= stream->interval << 3;

diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index d8c41ae..bc5e905 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -240,7 +240,6 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
- { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
};

static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
@@ -1703,7 +1702,7 @@ static int ti_do_download(struct usb_device *dev, int pipe,
u8 cs = 0;
int done;
struct ti_firmware_header *header;
- int status;
+ int status = 0;
int len;

for (pos = sizeof(struct ti_firmware_header); pos < size; pos++)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index e57df48..a6f8b8f 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1517,11 +1517,11 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
info->thread = NULL;

psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
- fill_note(&info->psinfo, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
-
if (psinfo == NULL)
return 0;

+ fill_note(&info->psinfo, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
+
/*
* Figure out how many notes we're going to need for each thread.
*/
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 59b9833..247c0d4 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -730,6 +730,13 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
}
(*new_auth_tok)->session_key.encrypted_key_size =
(body_size - (ECRYPTFS_SALT_SIZE + 5));
+ if ((*new_auth_tok)->session_key.encrypted_key_size
+ > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) {
+ printk(KERN_WARNING "Tag 3 packet contains key larger "
+ "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES\n");
+ rc = -EINVAL;
+ goto out_free;
+ }
if (unlikely(data[(*packet_size)++] != 0x04)) {
printk(KERN_WARNING "Unknown version number [%d]\n",
data[(*packet_size) - 1]);
@@ -876,6 +883,12 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents,
rc = -EINVAL;
goto out;
}
+ if (unlikely((*tag_11_contents_size) > max_contents_bytes)) {
+ printk(KERN_ERR "Literal data section in tag 11 packet exceeds "
+ "expected size\n");
+ rc = -EINVAL;
+ goto out;
+ }
if (data[(*packet_size)++] != 0x62) {
printk(KERN_WARNING "Unrecognizable packet\n");
rc = -EINVAL;
diff --git a/include/net/x25.h b/include/net/x25.h
index fc3f03d..2cda040 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -187,7 +187,7 @@ extern int x25_addr_ntoa(unsigned char *, struct x25_address *,
extern int x25_addr_aton(unsigned char *, struct x25_address *,
struct x25_address *);
extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *);
-extern void x25_destroy_socket(struct sock *);
+extern void x25_destroy_socket_from_timer(struct sock *);
extern int x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int);
extern void x25_kill_by_neigh(struct x25_neigh *);

diff --git a/mm/filemap.c b/mm/filemap.c
index 8a477d3..bff0b00 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2441,6 +2441,7 @@ again:
pagefault_enable();
flush_dcache_page(page);

+ mark_page_accessed(page);
status = a_ops->write_end(file, mapping, pos, bytes, copied,
page, fsdata);
if (unlikely(status < 0))
diff --git a/mm/slab.c b/mm/slab.c
index e76eee4..600e864 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2580,7 +2580,7 @@ void kmem_cache_destroy(struct kmem_cache *cachep)
}

if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
- synchronize_rcu();
+ rcu_barrier();

__kmem_cache_destroy(cachep);
mutex_unlock(&cache_chain_mutex);
diff --git a/mm/slob.c b/mm/slob.c
index cb675d1..ed04252 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -561,6 +561,8 @@ EXPORT_SYMBOL(kmem_cache_create);

void kmem_cache_destroy(struct kmem_cache *c)
{
+ if (c->flags & SLAB_DESTROY_BY_RCU)
+ rcu_barrier();
slob_free(c, sizeof(struct kmem_cache));
}
EXPORT_SYMBOL(kmem_cache_destroy);
diff --git a/mm/slub.c b/mm/slub.c
index 0c83e6a..f0175b4 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2447,6 +2447,8 @@ static inline int kmem_cache_close(struct kmem_cache *s)
*/
void kmem_cache_destroy(struct kmem_cache *s)
{
+ if (s->flags & SLAB_DESTROY_BY_RCU)
+ rcu_barrier();
down_write(&slub_lock);
s->refcount--;
if (!s->refcount) {
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 76739e9..66cfe88 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1089,14 +1089,24 @@ static void
call_transmit_status(struct rpc_task *task)
{
task->tk_action = call_status;
- /*
- * Special case: if we've been waiting on the socket's write_space()
- * callback, then don't call xprt_end_transmit().
- */
- if (task->tk_status == -EAGAIN)
- return;
- xprt_end_transmit(task);
- rpc_task_force_reencode(task);
+ switch (task->tk_status) {
+ case -EAGAIN:
+ break;
+ default:
+ xprt_end_transmit(task);
+ /*
+ * Special cases: if we've been waiting on the
+ * socket's write_space() callback, or if the
+ * socket just returned a connection error,
+ * then hold onto the transport lock.
+ */
+ case -ECONNREFUSED:
+ case -ENOTCONN:
+ case -EHOSTDOWN:
+ case -EHOSTUNREACH:
+ case -ENETUNREACH:
+ rpc_task_force_reencode(task);
+ }
}

/*
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 4486c59..8f9295d 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1150,7 +1150,6 @@ static void xs_tcp_state_change(struct sock *sk)
break;
case TCP_CLOSE_WAIT:
/* The server initiated a shutdown of the socket */
- set_bit(XPRT_CLOSING, &xprt->state);
xprt_force_disconnect(xprt);
case TCP_SYN_SENT:
xprt->connect_cookie++;
@@ -1163,6 +1162,7 @@ static void xs_tcp_state_change(struct sock *sk)
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
break;
case TCP_LAST_ACK:
+ set_bit(XPRT_CLOSING, &xprt->state);
smp_mb__before_clear_bit();
clear_bit(XPRT_CONNECTED, &xprt->state);
smp_mb__after_clear_bit();
@@ -1560,10 +1560,9 @@ out:
* We need to preserve the port number so the reply cache on the server can
* find our cached RPC replies when we get around to reconnecting.
*/
-static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
+static void xs_abort_connection(struct rpc_xprt *xprt, struct sock_xprt *transport)
{
int result;
- struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
struct sockaddr any;

dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt);
@@ -1580,6 +1579,17 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
result);
}

+static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *transport)
+{
+ unsigned int state = transport->inet->sk_state;
+
+ if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED)
+ return;
+ if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT))
+ return;
+ xs_abort_connection(xprt, transport);
+}
+
static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
{
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
@@ -1650,7 +1660,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work)
}
} else
/* "close" the socket, preserving the local port */
- xs_tcp_reuse_connection(xprt);
+ xs_tcp_reuse_connection(xprt, transport);

dprintk("RPC: worker connecting xprt %p to address: %s\n",
xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
@@ -1710,7 +1720,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work)
}
} else
/* "close" the socket, preserving the local port */
- xs_tcp_reuse_connection(xprt);
+ xs_tcp_reuse_connection(xprt, transport);

dprintk("RPC: worker connecting xprt %p to address: %s\n",
xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
@@ -1780,9 +1790,6 @@ static void xs_tcp_connect(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;

- /* Initiate graceful shutdown of the socket if not already done */
- if (test_bit(XPRT_CONNECTED, &xprt->state))
- xs_tcp_shutdown(xprt);
/* Exit if we need to wait for socket shutdown to complete */
if (test_bit(XPRT_CLOSING, &xprt->state))
return;
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 88d80f5..220a5e3 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -332,14 +332,14 @@ static unsigned int x25_new_lci(struct x25_neigh *nb)
/*
* Deferred destroy.
*/
-void x25_destroy_socket(struct sock *);
+static void __x25_destroy_socket(struct sock *);

/*
* handler for deferred kills.
*/
static void x25_destroy_timer(unsigned long data)
{
- x25_destroy_socket((struct sock *)data);
+ x25_destroy_socket_from_timer((struct sock *)data);
}

/*
@@ -349,12 +349,10 @@ static void x25_destroy_timer(unsigned long data)
* will touch it and we are (fairly 8-) ) safe.
* Not static as it's used by the timer
*/
-void x25_destroy_socket(struct sock *sk)
+static void __x25_destroy_socket(struct sock *sk)
{
struct sk_buff *skb;

- sock_hold(sk);
- lock_sock(sk);
x25_stop_heartbeat(sk);
x25_stop_timer(sk);

@@ -385,7 +383,22 @@ void x25_destroy_socket(struct sock *sk)
/* drop last reference so sock_put will free */
__sock_put(sk);
}
+}

+void x25_destroy_socket_from_timer(struct sock *sk)
+{
+ sock_hold(sk);
+ bh_lock_sock(sk);
+ __x25_destroy_socket(sk);
+ bh_unlock_sock(sk);
+ sock_put(sk);
+}
+
+static void x25_destroy_socket(struct sock *sk)
+{
+ sock_hold(sk);
+ lock_sock(sk);
+ __x25_destroy_socket(sk);
release_sock(sk);
sock_put(sk);
}
diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c
index d3e3e54..5c5db1a 100644
--- a/net/x25/x25_timer.c
+++ b/net/x25/x25_timer.c
@@ -113,7 +113,7 @@ static void x25_heartbeat_expiry(unsigned long param)
(sk->sk_state == TCP_LISTEN &&
sock_flag(sk, SOCK_DEAD))) {
bh_unlock_sock(sk);
- x25_destroy_socket(sk);
+ x25_destroy_socket_from_timer(sk);
return;
}
break;
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 96036cf..79d78f4 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -292,8 +292,8 @@ static struct xfrm_algo_desc ealg_list[] = {
}
},
{
- .name = "cbc(cast128)",
- .compat = "cast128",
+ .name = "cbc(cast5)",
+ .compat = "cast5",

.uinfo = {
.encr = {
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 6abe8a3..2b8b1ed 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -311,9 +311,9 @@ static struct snd_pcm_hardware snd_ca0106_capture_hw = {
.rate_max = 192000,
.channels_min = 2,
.channels_max = 2,
- .buffer_bytes_max = ((65536 - 64) * 8),
+ .buffer_bytes_max = 65536 - 128,
.period_bytes_min = 64,
- .period_bytes_max = (65536 - 64),
+ .period_bytes_max = 32768 - 64,
.periods_min = 2,
.periods_max = 2,
.fifo_size = 0,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 3b5c6c2..07f8dcc 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -9214,6 +9214,18 @@ static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
alc262_lenovo_3000_automute(codec, 1);
}

+static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
+ int dir, int idx, long *valp)
+{
+ int i, change = 0;
+
+ for (i = 0; i < 2; i++, valp++)
+ change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
+ HDA_AMP_MUTE,
+ *valp ? 0 : HDA_AMP_MUTE);
+ return change;
+}
+
/* bind hp and internal speaker mute (with plug check) */
static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -9222,13 +9234,8 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
long *valp = ucontrol->value.integer.value;
int change;

- change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- valp ? 0 : HDA_AMP_MUTE);
- change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- valp ? 0 : HDA_AMP_MUTE);
-
+ change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
+ change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
if (change)
alc262_fujitsu_automute(codec, 0);
return change;
@@ -9265,10 +9272,7 @@ static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
long *valp = ucontrol->value.integer.value;
int change;

- change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- valp ? 0 : HDA_AMP_MUTE);
-
+ change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
if (change)
alc262_lenovo_3000_automute(codec, 0);
return change;
@@ -10280,12 +10284,7 @@ static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
long *valp = ucontrol->value.integer.value;
int change;

- change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- valp[0] ? 0 : HDA_AMP_MUTE);
- change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- valp[1] ? 0 : HDA_AMP_MUTE);
+ change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
if (change)
alc268_acer_automute(codec, 0);
return change;
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 01d7b75..d1773f6 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -376,6 +376,8 @@ static void xonar_d2_resume(struct oxygen *chip)

static void xonar_d1_resume(struct oxygen *chip)
{
+ oxygen_set_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
+ msleep(1);
cs43xx_init(chip);
xonar_enable_output(chip);
}
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c10e476..915a131 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2674,7 +2674,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
struct usb_interface_descriptor *altsd;
int i, altno, err, stream;
int format;
- struct audioformat *fp;
+ struct audioformat *fp = NULL;
unsigned char *fmt, *csep;
int num;

@@ -2747,6 +2747,18 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
continue;
}

+ /*
+ * Blue Microphones workaround: The last altsetting is identical
+ * with the previous one, except for a larger packet size, but
+ * is actually a mislabeled two-channel setting; ignore it.
+ */
+ if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
+ fp && fp->altsetting == 1 && fp->channels == 1 &&
+ fp->format == SNDRV_PCM_FORMAT_S16_LE &&
+ le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
+ fp->maxpacksize * 2)
+ continue;
+
csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
/* Creamware Noah has this descriptor after the 2nd endpoint */
if (!csep && altsd->bNumEndpoints >= 2)
--
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/