367 lines
11 KiB
Diff
367 lines
11 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index 2ed953d8e0f2a..68f2c6f3869e2 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 4
|
|
PATCHLEVEL = 9
|
|
-SUBLEVEL = 285
|
|
+SUBLEVEL = 286
|
|
EXTRAVERSION =
|
|
NAME = Roaring Lionus
|
|
|
|
diff --git a/arch/sparc/lib/iomap.c b/arch/sparc/lib/iomap.c
|
|
index c4d42a50ebc06..fa4abbaf27de3 100644
|
|
--- a/arch/sparc/lib/iomap.c
|
|
+++ b/arch/sparc/lib/iomap.c
|
|
@@ -18,8 +18,10 @@ void ioport_unmap(void __iomem *addr)
|
|
EXPORT_SYMBOL(ioport_map);
|
|
EXPORT_SYMBOL(ioport_unmap);
|
|
|
|
+#ifdef CONFIG_PCI
|
|
void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
|
|
{
|
|
/* nothing to do */
|
|
}
|
|
EXPORT_SYMBOL(pci_iounmap);
|
|
+#endif
|
|
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
|
|
index adbf0486422b8..d3804b215ffa6 100644
|
|
--- a/drivers/ata/libata-core.c
|
|
+++ b/drivers/ata/libata-core.c
|
|
@@ -2157,6 +2157,25 @@ static void ata_dev_config_ncq_non_data(struct ata_device *dev)
|
|
}
|
|
}
|
|
|
|
+static bool ata_dev_check_adapter(struct ata_device *dev,
|
|
+ unsigned short vendor_id)
|
|
+{
|
|
+ struct pci_dev *pcidev = NULL;
|
|
+ struct device *parent_dev = NULL;
|
|
+
|
|
+ for (parent_dev = dev->tdev.parent; parent_dev != NULL;
|
|
+ parent_dev = parent_dev->parent) {
|
|
+ if (dev_is_pci(parent_dev)) {
|
|
+ pcidev = to_pci_dev(parent_dev);
|
|
+ if (pcidev->vendor == vendor_id)
|
|
+ return true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
static int ata_dev_config_ncq(struct ata_device *dev,
|
|
char *desc, size_t desc_sz)
|
|
{
|
|
@@ -2173,6 +2192,13 @@ static int ata_dev_config_ncq(struct ata_device *dev,
|
|
snprintf(desc, desc_sz, "NCQ (not used)");
|
|
return 0;
|
|
}
|
|
+
|
|
+ if (dev->horkage & ATA_HORKAGE_NO_NCQ_ON_ATI &&
|
|
+ ata_dev_check_adapter(dev, PCI_VENDOR_ID_ATI)) {
|
|
+ snprintf(desc, desc_sz, "NCQ (not used)");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
if (ap->flags & ATA_FLAG_NCQ) {
|
|
hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
|
|
dev->flags |= ATA_DFLAG_NCQ;
|
|
@@ -4448,9 +4474,11 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|
{ "Samsung SSD 850*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
|
ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
{ "Samsung SSD 860*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
|
- ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
+ ATA_HORKAGE_ZERO_AFTER_TRIM |
|
|
+ ATA_HORKAGE_NO_NCQ_ON_ATI, },
|
|
{ "Samsung SSD 870*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
|
- ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
+ ATA_HORKAGE_ZERO_AFTER_TRIM |
|
|
+ ATA_HORKAGE_NO_NCQ_ON_ATI, },
|
|
{ "FCCT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
|
ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
|
|
@@ -6734,6 +6762,8 @@ static int __init ata_parse_force_one(char **cur,
|
|
{ "ncq", .horkage_off = ATA_HORKAGE_NONCQ },
|
|
{ "noncqtrim", .horkage_on = ATA_HORKAGE_NO_NCQ_TRIM },
|
|
{ "ncqtrim", .horkage_off = ATA_HORKAGE_NO_NCQ_TRIM },
|
|
+ { "noncqati", .horkage_on = ATA_HORKAGE_NO_NCQ_ON_ATI },
|
|
+ { "ncqati", .horkage_off = ATA_HORKAGE_NO_NCQ_ON_ATI },
|
|
{ "dump_id", .horkage_on = ATA_HORKAGE_DUMP_ID },
|
|
{ "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) },
|
|
{ "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) },
|
|
diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
|
|
index 9c88e6749b9a4..34600b0061bb7 100644
|
|
--- a/drivers/net/phy/mdio_device.c
|
|
+++ b/drivers/net/phy/mdio_device.c
|
|
@@ -135,6 +135,16 @@ static int mdio_remove(struct device *dev)
|
|
return 0;
|
|
}
|
|
|
|
+static void mdio_shutdown(struct device *dev)
|
|
+{
|
|
+ struct mdio_device *mdiodev = to_mdio_device(dev);
|
|
+ struct device_driver *drv = mdiodev->dev.driver;
|
|
+ struct mdio_driver *mdiodrv = to_mdio_driver(drv);
|
|
+
|
|
+ if (mdiodrv->shutdown)
|
|
+ mdiodrv->shutdown(mdiodev);
|
|
+}
|
|
+
|
|
/**
|
|
* mdio_driver_register - register an mdio_driver with the MDIO layer
|
|
* @new_driver: new mdio_driver to register
|
|
@@ -149,6 +159,7 @@ int mdio_driver_register(struct mdio_driver *drv)
|
|
mdiodrv->driver.bus = &mdio_bus_type;
|
|
mdiodrv->driver.probe = mdio_probe;
|
|
mdiodrv->driver.remove = mdio_remove;
|
|
+ mdiodrv->driver.shutdown = mdio_shutdown;
|
|
|
|
retval = driver_register(&mdiodrv->driver);
|
|
if (retval) {
|
|
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
|
|
index f7fd8b5a6a8cf..3016869b4afdc 100644
|
|
--- a/drivers/net/xen-netback/netback.c
|
|
+++ b/drivers/net/xen-netback/netback.c
|
|
@@ -492,7 +492,7 @@ check_frags:
|
|
* the header's copy failed, and they are
|
|
* sharing a slot, send an error
|
|
*/
|
|
- if (i == 0 && sharedslot)
|
|
+ if (i == 0 && !first_shinfo && sharedslot)
|
|
xenvif_idx_release(queue, pending_idx,
|
|
XEN_NETIF_RSP_ERROR);
|
|
else
|
|
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
|
|
index 671bf1e03ee1f..426f1b3aa15e2 100644
|
|
--- a/drivers/scsi/sd.c
|
|
+++ b/drivers/scsi/sd.c
|
|
@@ -3179,15 +3179,16 @@ static int sd_probe(struct device *dev)
|
|
}
|
|
|
|
device_initialize(&sdkp->dev);
|
|
- sdkp->dev.parent = dev;
|
|
+ sdkp->dev.parent = get_device(dev);
|
|
sdkp->dev.class = &sd_disk_class;
|
|
dev_set_name(&sdkp->dev, "%s", dev_name(dev));
|
|
|
|
error = device_add(&sdkp->dev);
|
|
- if (error)
|
|
- goto out_free_index;
|
|
+ if (error) {
|
|
+ put_device(&sdkp->dev);
|
|
+ goto out;
|
|
+ }
|
|
|
|
- get_device(dev);
|
|
dev_set_drvdata(dev, sdkp);
|
|
|
|
get_device(&sdkp->dev); /* prevent release before async_schedule */
|
|
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
|
|
index 4c40c0786e168..bd32140bdfee5 100644
|
|
--- a/fs/ext2/balloc.c
|
|
+++ b/fs/ext2/balloc.c
|
|
@@ -46,10 +46,9 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
|
|
struct ext2_sb_info *sbi = EXT2_SB(sb);
|
|
|
|
if (block_group >= sbi->s_groups_count) {
|
|
- ext2_error (sb, "ext2_get_group_desc",
|
|
- "block_group >= groups_count - "
|
|
- "block_group = %d, groups_count = %lu",
|
|
- block_group, sbi->s_groups_count);
|
|
+ WARN(1, "block_group >= groups_count - "
|
|
+ "block_group = %d, groups_count = %lu",
|
|
+ block_group, sbi->s_groups_count);
|
|
|
|
return NULL;
|
|
}
|
|
@@ -57,10 +56,9 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
|
|
group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(sb);
|
|
offset = block_group & (EXT2_DESC_PER_BLOCK(sb) - 1);
|
|
if (!sbi->s_group_desc[group_desc]) {
|
|
- ext2_error (sb, "ext2_get_group_desc",
|
|
- "Group descriptor not loaded - "
|
|
- "block_group = %d, group_desc = %lu, desc = %lu",
|
|
- block_group, group_desc, offset);
|
|
+ WARN(1, "Group descriptor not loaded - "
|
|
+ "block_group = %d, group_desc = %lu, desc = %lu",
|
|
+ block_group, group_desc, offset);
|
|
return NULL;
|
|
}
|
|
|
|
diff --git a/include/linux/libata.h b/include/linux/libata.h
|
|
index 3fabf57fd6e0d..de770d11a5c18 100644
|
|
--- a/include/linux/libata.h
|
|
+++ b/include/linux/libata.h
|
|
@@ -436,6 +436,7 @@ enum {
|
|
ATA_HORKAGE_NOTRIM = (1 << 24), /* don't use TRIM */
|
|
ATA_HORKAGE_MAX_SEC_1024 = (1 << 25), /* Limit max sects to 1024 */
|
|
ATA_HORKAGE_MAX_TRIM_128M = (1 << 26), /* Limit max trim size to 128M */
|
|
+ ATA_HORKAGE_NO_NCQ_ON_ATI = (1 << 27), /* Disable NCQ on ATI chipset */
|
|
|
|
/* DMA mask for user DMA control: User visible values; DO NOT
|
|
renumber */
|
|
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
|
|
index bf9d1d7506935..78b3cf50566f5 100644
|
|
--- a/include/linux/mdio.h
|
|
+++ b/include/linux/mdio.h
|
|
@@ -61,6 +61,9 @@ struct mdio_driver {
|
|
|
|
/* Clears up any memory if needed */
|
|
void (*remove)(struct mdio_device *mdiodev);
|
|
+
|
|
+ /* Quiesces the device on system shutdown, turns off interrupts etc */
|
|
+ void (*shutdown)(struct mdio_device *mdiodev);
|
|
};
|
|
#define to_mdio_driver(d) \
|
|
container_of(to_mdio_common_driver(d), struct mdio_driver, mdiodrv)
|
|
diff --git a/include/net/sock.h b/include/net/sock.h
|
|
index cf27f3688c39c..78c292f15ffc1 100644
|
|
--- a/include/net/sock.h
|
|
+++ b/include/net/sock.h
|
|
@@ -420,9 +420,11 @@ struct sock {
|
|
u32 sk_max_ack_backlog;
|
|
__u32 sk_priority;
|
|
__u32 sk_mark;
|
|
+ spinlock_t sk_peer_lock;
|
|
kuid_t sk_uid;
|
|
struct pid *sk_peer_pid;
|
|
const struct cred *sk_peer_cred;
|
|
+
|
|
long sk_rcvtimeo;
|
|
long sk_sndtimeo;
|
|
struct timer_list sk_timer;
|
|
diff --git a/net/core/sock.c b/net/core/sock.c
|
|
index d468ffb5a31c6..1845a37d9f7e1 100644
|
|
--- a/net/core/sock.c
|
|
+++ b/net/core/sock.c
|
|
@@ -1011,7 +1011,6 @@ set_rcvbuf:
|
|
}
|
|
EXPORT_SYMBOL(sock_setsockopt);
|
|
|
|
-
|
|
static void cred_to_ucred(struct pid *pid, const struct cred *cred,
|
|
struct ucred *ucred)
|
|
{
|
|
@@ -1171,7 +1170,11 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
|
struct ucred peercred;
|
|
if (len > sizeof(peercred))
|
|
len = sizeof(peercred);
|
|
+
|
|
+ spin_lock(&sk->sk_peer_lock);
|
|
cred_to_ucred(sk->sk_peer_pid, sk->sk_peer_cred, &peercred);
|
|
+ spin_unlock(&sk->sk_peer_lock);
|
|
+
|
|
if (copy_to_user(optval, &peercred, len))
|
|
return -EFAULT;
|
|
goto lenout;
|
|
@@ -1439,9 +1442,10 @@ static void __sk_destruct(struct rcu_head *head)
|
|
sk->sk_frag.page = NULL;
|
|
}
|
|
|
|
- if (sk->sk_peer_cred)
|
|
- put_cred(sk->sk_peer_cred);
|
|
+ /* We do not need to acquire sk->sk_peer_lock, we are the last user. */
|
|
+ put_cred(sk->sk_peer_cred);
|
|
put_pid(sk->sk_peer_pid);
|
|
+
|
|
if (likely(sk->sk_net_refcnt))
|
|
put_net(sock_net(sk));
|
|
sk_prot_free(sk->sk_prot_creator, sk);
|
|
@@ -2490,6 +2494,8 @@ void sock_init_data(struct socket *sock, struct sock *sk)
|
|
|
|
sk->sk_peer_pid = NULL;
|
|
sk->sk_peer_cred = NULL;
|
|
+ spin_lock_init(&sk->sk_peer_lock);
|
|
+
|
|
sk->sk_write_pending = 0;
|
|
sk->sk_rcvlowat = 1;
|
|
sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
|
|
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
|
index 2c643e1919aab..e7e012933714f 100644
|
|
--- a/net/unix/af_unix.c
|
|
+++ b/net/unix/af_unix.c
|
|
@@ -594,20 +594,42 @@ static void unix_release_sock(struct sock *sk, int embrion)
|
|
|
|
static void init_peercred(struct sock *sk)
|
|
{
|
|
- put_pid(sk->sk_peer_pid);
|
|
- if (sk->sk_peer_cred)
|
|
- put_cred(sk->sk_peer_cred);
|
|
+ const struct cred *old_cred;
|
|
+ struct pid *old_pid;
|
|
+
|
|
+ spin_lock(&sk->sk_peer_lock);
|
|
+ old_pid = sk->sk_peer_pid;
|
|
+ old_cred = sk->sk_peer_cred;
|
|
sk->sk_peer_pid = get_pid(task_tgid(current));
|
|
sk->sk_peer_cred = get_current_cred();
|
|
+ spin_unlock(&sk->sk_peer_lock);
|
|
+
|
|
+ put_pid(old_pid);
|
|
+ put_cred(old_cred);
|
|
}
|
|
|
|
static void copy_peercred(struct sock *sk, struct sock *peersk)
|
|
{
|
|
- put_pid(sk->sk_peer_pid);
|
|
- if (sk->sk_peer_cred)
|
|
- put_cred(sk->sk_peer_cred);
|
|
+ const struct cred *old_cred;
|
|
+ struct pid *old_pid;
|
|
+
|
|
+ if (sk < peersk) {
|
|
+ spin_lock(&sk->sk_peer_lock);
|
|
+ spin_lock_nested(&peersk->sk_peer_lock, SINGLE_DEPTH_NESTING);
|
|
+ } else {
|
|
+ spin_lock(&peersk->sk_peer_lock);
|
|
+ spin_lock_nested(&sk->sk_peer_lock, SINGLE_DEPTH_NESTING);
|
|
+ }
|
|
+ old_pid = sk->sk_peer_pid;
|
|
+ old_cred = sk->sk_peer_cred;
|
|
sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
|
|
sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
|
|
+
|
|
+ spin_unlock(&sk->sk_peer_lock);
|
|
+ spin_unlock(&peersk->sk_peer_lock);
|
|
+
|
|
+ put_pid(old_pid);
|
|
+ put_cred(old_cred);
|
|
}
|
|
|
|
static int unix_listen(struct socket *sock, int backlog)
|
|
diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c
|
|
index 0692d99b6d8f3..18c895654e767 100644
|
|
--- a/tools/usb/testusb.c
|
|
+++ b/tools/usb/testusb.c
|
|
@@ -278,12 +278,6 @@ nomem:
|
|
}
|
|
|
|
entry->ifnum = ifnum;
|
|
-
|
|
- /* FIXME update USBDEVFS_CONNECTINFO so it tells about high speed etc */
|
|
-
|
|
- fprintf(stderr, "%s speed\t%s\t%u\n",
|
|
- speed(entry->speed), entry->name, entry->ifnum);
|
|
-
|
|
entry->next = testdevs;
|
|
testdevs = entry;
|
|
return 0;
|
|
@@ -312,6 +306,14 @@ static void *handle_testdev (void *arg)
|
|
return 0;
|
|
}
|
|
|
|
+ status = ioctl(fd, USBDEVFS_GET_SPEED, NULL);
|
|
+ if (status < 0)
|
|
+ fprintf(stderr, "USBDEVFS_GET_SPEED failed %d\n", status);
|
|
+ else
|
|
+ dev->speed = status;
|
|
+ fprintf(stderr, "%s speed\t%s\t%u\n",
|
|
+ speed(dev->speed), dev->name, dev->ifnum);
|
|
+
|
|
restart:
|
|
for (i = 0; i < TEST_CASES; i++) {
|
|
if (dev->test != -1 && dev->test != i)
|