Linux 3.4 and stable queue updates

This commit is contained in:
Justin M. Forbes 2012-06-02 23:57:09 -05:00
parent 506e7ae6a2
commit 39acffae26
41 changed files with 314 additions and 41716 deletions

BIN
3.4.1-stable-queue.patch.xz Normal file

Binary file not shown.

View File

@ -1,37 +0,0 @@
From a9e1e167d934aa74f48008393ade4f09fc587432 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Thu, 12 Apr 2012 13:55:36 -0400
Subject: [PATCH] ALSA: hda/realtek - Add quirk for Mac Pro 5,1 machines
A user reported that setting model=imac24 used to allow sound to work on their
Mac Pro 5,1 machine. Commit 5671087ffa "Move ALC885 macpro and imac24 models
to auto-parser" removed this model option. All Mac machines are now explicitly
handled with a quirk and the auto-parser. This adds a quirk for the device
found on the Mac Pro 5,1 machines.
This (partially) fixes https://bugzilla.redhat.com/show_bug.cgi?id=808559
[sorted the new entry in the ID number order by tiwai]
Reported-by: Gabriel Somlo <somlo@cmu.edu>
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
sound/pci/hda/patch_realtek.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 22c73b7..bd34b51 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4659,6 +4659,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
+ SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
--
1.7.7.6

View File

@ -1,393 +0,0 @@
commit 626cf236608505d376e4799adb4f7eb00a8594af
Author: Hans Verkuil <hans.verkuil@cisco.com>
Date: Fri Mar 23 15:02:27 2012 -0700
poll: add poll_requested_events() and poll_does_not_wait() functions
In some cases the poll() implementation in a driver has to do different
things depending on the events the caller wants to poll for. An example
is when a driver needs to start a DMA engine if the caller polls for
POLLIN, but doesn't want to do that if POLLIN is not requested but instead
only POLLOUT or POLLPRI is requested. This is something that can happen
in the video4linux subsystem among others.
Unfortunately, the current epoll/poll/select implementation doesn't
provide that information reliably. The poll_table_struct does have it: it
has a key field with the event mask. But once a poll() call matches one
or more bits of that mask any following poll() calls are passed a NULL
poll_table pointer.
Also, the eventpoll implementation always left the key field at ~0 instead
of using the requested events mask.
This was changed in eventpoll.c so the key field now contains the actual
events that should be polled for as set by the caller.
The solution to the NULL poll_table pointer is to set the qproc field to
NULL in poll_table once poll() matches the events, not the poll_table
pointer itself. That way drivers can obtain the mask through a new
poll_requested_events inline.
The poll_table_struct can still be NULL since some kernel code calls it
internally (netfs_state_poll() in ./drivers/staging/pohmelfs/netfs.h). In
that case poll_requested_events() returns ~0 (i.e. all events).
Very rarely drivers might want to know whether poll_wait will actually
wait. If another earlier file descriptor in the set already matched the
events the caller wanted to wait for, then the kernel will return from the
select() call without waiting. This might be useful information in order
to avoid doing expensive work.
A new helper function poll_does_not_wait() is added that drivers can use
to detect this situation. This is now used in sock_poll_wait() in
include/net/sock.h. This was the only place in the kernel that needed
this information.
Drivers should no longer access any of the poll_table internals, but use
the poll_requested_events() and poll_does_not_wait() access functions
instead. In order to enforce that the poll_table fields are now prepended
with an underscore and a comment was added warning against using them
directly.
This required a change in unix_dgram_poll() in unix/af_unix.c which used
the key field to get the requested events. It's been replaced by a call
to poll_requested_events().
For qproc it was especially important to change its name since the
behavior of that field changes with this patch since this function pointer
can now be NULL when that wasn't possible in the past.
Any driver accessing the qproc or key fields directly will now fail to compile.
Some notes regarding the correctness of this patch: the driver's poll()
function is called with a 'struct poll_table_struct *wait' argument. This
pointer may or may not be NULL, drivers can never rely on it being one or
the other as that depends on whether or not an earlier file descriptor in
the select()'s fdset matched the requested events.
There are only three things a driver can do with the wait argument:
1) obtain the key field:
events = wait ? wait->key : ~0;
This will still work although it should be replaced with the new
poll_requested_events() function (which does exactly the same).
This will now even work better, since wait is no longer set to NULL
unnecessarily.
2) use the qproc callback. This could be deadly since qproc can now be
NULL. Renaming qproc should prevent this from happening. There are no
kernel drivers that actually access this callback directly, BTW.
3) test whether wait == NULL to determine whether poll would return without
waiting. This is no longer sufficient as the correct test is now
wait == NULL || wait->_qproc == NULL.
However, the worst that can happen here is a slight performance hit in
the case where wait != NULL and wait->_qproc == NULL. In that case the
driver will assume that poll_wait() will actually add the fd to the set
of waiting file descriptors. Of course, poll_wait() will not do that
since it tests for wait->_qproc. This will not break anything, though.
There is only one place in the whole kernel where this happens
(sock_poll_wait() in include/net/sock.h) and that code will be replaced
by a call to poll_does_not_wait() in the next patch.
Note that even if wait->_qproc != NULL drivers cannot rely on poll_wait()
actually waiting. The next file descriptor from the set might match the
event mask and thus any possible waits will never happen.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Jonathan Corbet <corbet@lwn.net>
Reviewed-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: Davide Libenzi <davidel@xmailserver.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: David Miller <davem@davemloft.net>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 4d9d3a4..ca30007 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -699,9 +699,12 @@ static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head,
void *priv)
{
struct epitem *epi, *tmp;
+ poll_table pt;
+ init_poll_funcptr(&pt, NULL);
list_for_each_entry_safe(epi, tmp, head, rdllink) {
- if (epi->ffd.file->f_op->poll(epi->ffd.file, NULL) &
+ pt._key = epi->event.events;
+ if (epi->ffd.file->f_op->poll(epi->ffd.file, &pt) &
epi->event.events)
return POLLIN | POLLRDNORM;
else {
@@ -1097,6 +1100,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
/* Initialize the poll table using the queue callback */
epq.epi = epi;
init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);
+ epq.pt._key = event->events;
/*
* Attach the item to the poll hooks and get current event bits.
@@ -1191,6 +1195,9 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
{
int pwake = 0;
unsigned int revents;
+ poll_table pt;
+
+ init_poll_funcptr(&pt, NULL);
/*
* Set the new event interest mask before calling f_op->poll();
@@ -1198,13 +1205,14 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
* f_op->poll() call and the new event set registering.
*/
epi->event.events = event->events;
+ pt._key = event->events;
epi->event.data = event->data; /* protected by mtx */
/*
* Get current event bits. We can safely use the file* here because
* its usage count has been increased by the caller of this function.
*/
- revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
+ revents = epi->ffd.file->f_op->poll(epi->ffd.file, &pt);
/*
* If the item is "hot" and it is not registered inside the ready
@@ -1239,6 +1247,9 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head,
unsigned int revents;
struct epitem *epi;
struct epoll_event __user *uevent;
+ poll_table pt;
+
+ init_poll_funcptr(&pt, NULL);
/*
* We can loop without lock because we are passed a task private list.
@@ -1251,7 +1262,8 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head,
list_del_init(&epi->rdllink);
- revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL) &
+ pt._key = epi->event.events;
+ revents = epi->ffd.file->f_op->poll(epi->ffd.file, &pt) &
epi->event.events;
/*
diff --git a/fs/select.c b/fs/select.c
index e782258..ecfd0b1 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -223,7 +223,7 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
get_file(filp);
entry->filp = filp;
entry->wait_address = wait_address;
- entry->key = p->key;
+ entry->key = p->_key;
init_waitqueue_func_entry(&entry->wait, pollwake);
entry->wait.private = pwq;
add_wait_queue(wait_address, &entry->wait);
@@ -386,13 +386,11 @@ get_max:
static inline void wait_key_set(poll_table *wait, unsigned long in,
unsigned long out, unsigned long bit)
{
- if (wait) {
- wait->key = POLLEX_SET;
- if (in & bit)
- wait->key |= POLLIN_SET;
- if (out & bit)
- wait->key |= POLLOUT_SET;
- }
+ wait->_key = POLLEX_SET;
+ if (in & bit)
+ wait->_key |= POLLIN_SET;
+ if (out & bit)
+ wait->_key |= POLLOUT_SET;
}
int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
@@ -414,7 +412,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
poll_initwait(&table);
wait = &table.pt;
if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
- wait = NULL;
+ wait->_qproc = NULL;
timed_out = 1;
}
@@ -459,17 +457,17 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
if ((mask & POLLIN_SET) && (in & bit)) {
res_in |= bit;
retval++;
- wait = NULL;
+ wait->_qproc = NULL;
}
if ((mask & POLLOUT_SET) && (out & bit)) {
res_out |= bit;
retval++;
- wait = NULL;
+ wait->_qproc = NULL;
}
if ((mask & POLLEX_SET) && (ex & bit)) {
res_ex |= bit;
retval++;
- wait = NULL;
+ wait->_qproc = NULL;
}
}
}
@@ -481,7 +479,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
*rexp = res_ex;
cond_resched();
}
- wait = NULL;
+ wait->_qproc = NULL;
if (retval || timed_out || signal_pending(current))
break;
if (table.error) {
@@ -720,7 +718,7 @@ struct poll_list {
* interested in events matching the pollfd->events mask, and the result
* matching that mask is both recorded in pollfd->revents and returned. The
* pwait poll_table will be used by the fd-provided poll handler for waiting,
- * if non-NULL.
+ * if pwait->_qproc is non-NULL.
*/
static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
{
@@ -738,9 +736,7 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
if (file != NULL) {
mask = DEFAULT_POLLMASK;
if (file->f_op && file->f_op->poll) {
- if (pwait)
- pwait->key = pollfd->events |
- POLLERR | POLLHUP;
+ pwait->_key = pollfd->events|POLLERR|POLLHUP;
mask = file->f_op->poll(file, pwait);
}
/* Mask out unneeded events. */
@@ -763,7 +759,7 @@ static int do_poll(unsigned int nfds, struct poll_list *list,
/* Optimise the no-wait case */
if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
- pt = NULL;
+ pt->_qproc = NULL;
timed_out = 1;
}
@@ -781,22 +777,22 @@ static int do_poll(unsigned int nfds, struct poll_list *list,
for (; pfd != pfd_end; pfd++) {
/*
* Fish for events. If we found one, record it
- * and kill the poll_table, so we don't
+ * and kill poll_table->_qproc, so we don't
* needlessly register any other waiters after
* this. They'll get immediately deregistered
* when we break out and return.
*/
if (do_pollfd(pfd, pt)) {
count++;
- pt = NULL;
+ pt->_qproc = NULL;
}
}
}
/*
* All waiters have already been registered, so don't provide
- * a poll_table to them on the next loop iteration.
+ * a poll_table->_qproc to them on the next loop iteration.
*/
- pt = NULL;
+ pt->_qproc = NULL;
if (!count) {
count = wait->error;
if (signal_pending(current))
diff --git a/include/linux/poll.h b/include/linux/poll.h
index cf40010..48fe8bc 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -32,21 +32,46 @@ struct poll_table_struct;
*/
typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_table_struct *);
+/*
+ * Do not touch the structure directly, use the access functions
+ * poll_does_not_wait() and poll_requested_events() instead.
+ */
typedef struct poll_table_struct {
- poll_queue_proc qproc;
- unsigned long key;
+ poll_queue_proc _qproc;
+ unsigned long _key;
} poll_table;
static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{
- if (p && wait_address)
- p->qproc(filp, wait_address, p);
+ if (p && p->_qproc && wait_address)
+ p->_qproc(filp, wait_address, p);
+}
+
+/*
+ * Return true if it is guaranteed that poll will not wait. This is the case
+ * if the poll() of another file descriptor in the set got an event, so there
+ * is no need for waiting.
+ */
+static inline bool poll_does_not_wait(const poll_table *p)
+{
+ return p == NULL || p->_qproc == NULL;
+}
+
+/*
+ * Return the set of events that the application wants to poll for.
+ * This is useful for drivers that need to know whether a DMA transfer has
+ * to be started implicitly on poll(). You typically only want to do that
+ * if the application is actually polling for POLLIN and/or POLLOUT.
+ */
+static inline unsigned long poll_requested_events(const poll_table *p)
+{
+ return p ? p->_key : ~0UL;
}
static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc)
{
- pt->qproc = qproc;
- pt->key = ~0UL; /* all events enabled */
+ pt->_qproc = qproc;
+ pt->_key = ~0UL; /* all events enabled */
}
struct poll_table_entry {
diff --git a/include/net/sock.h b/include/net/sock.h
index 04bc0b3..a6ba1f8 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1854,7 +1854,7 @@ static inline bool wq_has_sleeper(struct socket_wq *wq)
static inline void sock_poll_wait(struct file *filp,
wait_queue_head_t *wait_address, poll_table *p)
{
- if (p && wait_address) {
+ if (!poll_does_not_wait(p) && wait_address) {
poll_wait(filp, wait_address, p);
/*
* We need to be sure we are in sync with the
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index eb4277c..d510353 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2206,7 +2206,7 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
}
/* No write status requested, avoid expensive OUT tests. */
- if (wait && !(wait->key & (POLLWRBAND | POLLWRNORM | POLLOUT)))
+ if (!(poll_requested_events(wait) & (POLLWRBAND|POLLWRNORM|POLLOUT)))
return mask;
writable = unix_writable(sk);

View File

@ -1,99 +0,0 @@
From 83e72dd97a25a831ff270ce4437416943a1e4b36 Mon Sep 17 00:00:00 2001
From: Seth Forshee <seth.forshee@canonical.com>
Date: Fri, 16 Mar 2012 14:41:21 -0500
Subject: [PATCH] apple_bl: Add register/unregister functions
Add functions to allow other modules to enable or disable apple_bl. This
will be used by the gmux driver to disable apple_bl when the gmux is
present, as it is a better and more reliable option for brightness
control.
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
---
drivers/video/backlight/apple_bl.c | 23 +++++++++++++++++++++--
include/linux/apple_bl.h | 26 ++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 2 deletions(-)
create mode 100644 include/linux/apple_bl.h
diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c
index be98d15..a523b25 100644
--- a/drivers/video/backlight/apple_bl.c
+++ b/drivers/video/backlight/apple_bl.c
@@ -24,6 +24,7 @@
#include <linux/io.h>
#include <linux/pci.h>
#include <linux/acpi.h>
+#include <linux/atomic.h>
static struct backlight_device *apple_backlight_device;
@@ -221,14 +222,32 @@ static struct acpi_driver apple_bl_driver = {
},
};
+static atomic_t apple_bl_registered = ATOMIC_INIT(0);
+
+int apple_bl_register(void)
+{
+ if (atomic_xchg(&apple_bl_registered, 1) == 0)
+ return acpi_bus_register_driver(&apple_bl_driver);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(apple_bl_register);
+
+void apple_bl_unregister(void)
+{
+ if (atomic_xchg(&apple_bl_registered, 0) == 1)
+ acpi_bus_unregister_driver(&apple_bl_driver);
+}
+EXPORT_SYMBOL_GPL(apple_bl_unregister);
+
static int __init apple_bl_init(void)
{
- return acpi_bus_register_driver(&apple_bl_driver);
+ return apple_bl_register();
}
static void __exit apple_bl_exit(void)
{
- acpi_bus_unregister_driver(&apple_bl_driver);
+ apple_bl_unregister();
}
module_init(apple_bl_init);
diff --git a/include/linux/apple_bl.h b/include/linux/apple_bl.h
new file mode 100644
index 0000000..47bedc0
--- /dev/null
+++ b/include/linux/apple_bl.h
@@ -0,0 +1,26 @@
+/*
+ * apple_bl exported symbols
+ */
+
+#ifndef _LINUX_APPLE_BL_H
+#define _LINUX_APPLE_BL_H
+
+#ifdef CONFIG_BACKLIGHT_APPLE
+
+extern int apple_bl_register(void);
+extern void apple_bl_unregister(void);
+
+#else /* !CONFIG_BACKLIGHT_APPLE */
+
+static inline int apple_bl_register(void)
+{
+ return 0;
+}
+
+static inline void apple_bl_unregister(void)
+{
+}
+
+#endif /* !CONFIG_BACKLIGHT_APPLE */
+
+#endif /* _LINUX_APPLE_BL_H */
--
1.7.7.6

View File

@ -119,9 +119,9 @@ index 198d1e6..043b251 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -111,7 +111,8 @@ struct omap_uart_port_info;
struct omap_uart_port_info;
extern void omap_serial_init(void);
extern int omap_uart_can_sleep(void);
-extern void omap_serial_board_init(struct omap_uart_port_info *platform_data);
+extern void omap_serial_board_init(struct omap_uart_port_info *platform_data,
+ u8 port_id);

View File

@ -178,7 +178,7 @@ index 0a9326a..859ea84 100644
static int atl1c_get_eeprom_len(struct net_device *netdev)
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
index 23f2ab0..2ea6a21 100644
index bd1667c..ff9c738 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
@@ -43,7 +43,7 @@ int atl1c_check_eeprom_exist(struct atl1c_hw *hw)
@ -376,14 +376,14 @@ index 23f2ab0..2ea6a21 100644
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, 0);
+ atl1c_wait_mdio_idle(hw);
+}
+
+void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel)
+{
+ u32 val;
+
+ if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
+ return;
+
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ FIELDX(MDIO_CTRL_REG, 1) |
@ -2024,7 +2024,7 @@ index 655fc6c..17d935b 100644
#endif /*_ATL1C_HW_H_*/
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 47a9bb2..f6f3fe3 100644
index 1ef0c92..9cc1570 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -24,14 +24,6 @@
@ -2282,16 +2282,16 @@ index 47a9bb2..f6f3fe3 100644
}
@@ -469,7 +474,7 @@ static int atl1c_set_mac_addr(struct net_device *netdev, void *p)
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
@@ -470,7 +475,7 @@ static int atl1c_set_mac_addr(struct net_device *netdev, void *p)
memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
- atl1c_hw_set_mac_addr(&adapter->hw);
+ atl1c_hw_set_mac_addr(&adapter->hw, adapter->hw.mac_addr);
return 0;
}
@@ -522,11 +527,16 @@ static int atl1c_set_features(struct net_device *netdev,
@@ -523,11 +528,16 @@ static int atl1c_set_features(struct net_device *netdev,
static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
@ -2310,7 +2310,7 @@ index 47a9bb2..f6f3fe3 100644
if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
return -EINVAL;
@@ -542,14 +552,6 @@ static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
@@ -543,14 +553,6 @@ static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
netdev_update_features(netdev);
atl1c_up(adapter);
clear_bit(__AT_RESETTING, &adapter->flags);
@ -2325,7 +2325,7 @@ index 47a9bb2..f6f3fe3 100644
}
return 0;
}
@@ -562,7 +564,7 @@ static int atl1c_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
@@ -563,7 +565,7 @@ static int atl1c_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
struct atl1c_adapter *adapter = netdev_priv(netdev);
u16 result;
@ -2334,7 +2334,7 @@ index 47a9bb2..f6f3fe3 100644
return result;
}
@@ -571,7 +573,7 @@ static void atl1c_mdio_write(struct net_device *netdev, int phy_id,
@@ -572,7 +574,7 @@ static void atl1c_mdio_write(struct net_device *netdev, int phy_id,
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
@ -2343,7 +2343,7 @@ index 47a9bb2..f6f3fe3 100644
}
/*
@@ -686,21 +688,15 @@ static void atl1c_set_mac_type(struct atl1c_hw *hw)
@@ -687,21 +689,15 @@ static void atl1c_set_mac_type(struct atl1c_hw *hw)
static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
{
@ -2367,7 +2367,7 @@ index 47a9bb2..f6f3fe3 100644
hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON;
if (hw->nic_type == athr_l1c ||
@@ -709,6 +705,55 @@ static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
@@ -710,6 +706,55 @@ static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
hw->link_cap_flags |= ATL1C_LINK_CAP_1000M;
return 0;
}
@ -2423,7 +2423,7 @@ index 47a9bb2..f6f3fe3 100644
/*
* atl1c_sw_init - Initialize general software structures (struct atl1c_adapter)
* @adapter: board private structure to initialize
@@ -728,9 +773,8 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
@@ -729,9 +774,8 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
device_set_wakeup_enable(&pdev->dev, false);
adapter->link_speed = SPEED_0;
adapter->link_duplex = FULL_DUPLEX;
@ -2434,7 +2434,7 @@ index 47a9bb2..f6f3fe3 100644
hw->vendor_id = pdev->vendor;
hw->device_id = pdev->device;
@@ -745,26 +789,18 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
@@ -746,26 +790,18 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
dev_err(&pdev->dev, "set mac function pointers failed\n");
return -1;
}
@ -2463,7 +2463,7 @@ index 47a9bb2..f6f3fe3 100644
hw->rx_imt = 200;
hw->tx_imt = 1000;
@@ -772,9 +808,6 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
@@ -773,9 +809,6 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
hw->rfd_burst = 8;
hw->dma_order = atl1c_dma_ord_out;
hw->dmar_block = atl1c_dma_req_1024;
@ -2473,7 +2473,7 @@ index 47a9bb2..f6f3fe3 100644
if (atl1c_alloc_queues(adapter)) {
dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
@@ -850,24 +883,22 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
@@ -851,24 +884,22 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
*/
static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
{
@ -2510,7 +2510,7 @@ index 47a9bb2..f6f3fe3 100644
}
/*
@@ -876,8 +907,8 @@ static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
@@ -877,8 +908,8 @@ static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
{
struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
@ -2521,7 +2521,7 @@ index 47a9bb2..f6f3fe3 100644
struct atl1c_buffer *buffer_info;
int i, j;
@@ -889,15 +920,13 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
@@ -890,15 +921,13 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
ATL1C_SET_BUFFER_STATE(&buffer_info[i],
ATL1C_BUFFER_FREE);
}
@ -2544,7 +2544,7 @@ index 47a9bb2..f6f3fe3 100644
}
}
@@ -934,27 +963,23 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
@@ -935,27 +964,23 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
@ -2576,7 +2576,7 @@ index 47a9bb2..f6f3fe3 100644
tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
if (unlikely(!tpd_ring->buffer_info)) {
dev_err(&pdev->dev, "kzalloc failed, size = %d\n",
@@ -967,12 +992,11 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
@@ -968,12 +993,11 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
count += tpd_ring[i].count;
}
@ -2594,7 +2594,7 @@ index 47a9bb2..f6f3fe3 100644
/*
* real ring DMA buffer
* each ring/block may need up to 8 bytes for alignment, hence the
@@ -982,8 +1006,7 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
@@ -983,8 +1007,7 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
sizeof(struct atl1c_tpd_desc) * tpd_ring->count * 2 +
sizeof(struct atl1c_rx_free_desc) * rx_desc_count +
sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
@ -2604,7 +2604,7 @@ index 47a9bb2..f6f3fe3 100644
ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
&ring_header->dma);
@@ -1004,25 +1027,18 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
@@ -1005,25 +1028,18 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
offset += roundup(tpd_ring[i].size, 8);
}
/* init RFD ring */
@ -2639,7 +2639,7 @@ index 47a9bb2..f6f3fe3 100644
return 0;
err_nomem:
@@ -1033,26 +1049,20 @@ err_nomem:
@@ -1034,26 +1050,20 @@ err_nomem:
static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
{
struct atl1c_hw *hw = &adapter->hw;
@ -2670,7 +2670,7 @@ index 47a9bb2..f6f3fe3 100644
(u32)(tpd_ring[atl1c_trans_high].dma &
AT_DMA_LO_ADDR_MASK));
AT_WRITE_REG(hw, REG_TPD_RING_SIZE,
@@ -1061,31 +1071,21 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
@@ -1062,31 +1072,21 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
/* RFD */
AT_WRITE_REG(hw, REG_RX_BASE_ADDR_HI,
@ -2709,7 +2709,7 @@ index 47a9bb2..f6f3fe3 100644
if (hw->nic_type == athr_l2c_b) {
AT_WRITE_REG(hw, REG_SRAM_RXF_LEN, 0x02a0L);
AT_WRITE_REG(hw, REG_SRAM_TXF_LEN, 0x0100L);
@@ -1096,13 +1096,6 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
@@ -1097,13 +1097,6 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
AT_WRITE_REG(hw, REG_TXF_WATER_MARK, 0); /* TX watermark, to enter l1 state.*/
AT_WRITE_REG(hw, REG_RXD_DMA_CTRL, 0); /* RXD threshold.*/
}
@ -2723,7 +2723,7 @@ index 47a9bb2..f6f3fe3 100644
/* Load all of base address above */
AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
}
@@ -1110,32 +1103,26 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
@@ -1111,32 +1104,26 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
static void atl1c_configure_tx(struct atl1c_adapter *adapter)
{
struct atl1c_hw *hw = &adapter->hw;
@ -2770,7 +2770,7 @@ index 47a9bb2..f6f3fe3 100644
AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data);
}
@@ -1150,34 +1137,13 @@ static void atl1c_configure_rx(struct atl1c_adapter *adapter)
@@ -1151,34 +1138,13 @@ static void atl1c_configure_rx(struct atl1c_adapter *adapter)
if (hw->ctrl_flags & ATL1C_RX_IPV6_CHKSUM)
rxq_ctrl_data |= IPV6_CHKSUM_CTRL_EN;
@ -2810,7 +2810,7 @@ index 47a9bb2..f6f3fe3 100644
}
static void atl1c_configure_dma(struct atl1c_adapter *adapter)
@@ -1185,36 +1151,11 @@ static void atl1c_configure_dma(struct atl1c_adapter *adapter)
@@ -1186,36 +1152,11 @@ static void atl1c_configure_dma(struct atl1c_adapter *adapter)
struct atl1c_hw *hw = &adapter->hw;
u32 dma_ctrl_data;
@ -2852,7 +2852,7 @@ index 47a9bb2..f6f3fe3 100644
AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
}
@@ -1229,52 +1170,53 @@ static int atl1c_stop_mac(struct atl1c_hw *hw)
@@ -1230,52 +1171,53 @@ static int atl1c_stop_mac(struct atl1c_hw *hw)
u32 data;
AT_READ_REG(hw, REG_RXQ_CTRL, &data);
@ -2874,13 +2874,10 @@ index 47a9bb2..f6f3fe3 100644
AT_WRITE_REG(hw, REG_MAC_CTRL, data);
- return (int)atl1c_wait_until_idle(hw);
+ return (int)atl1c_wait_until_idle(hw,
+ IDLE_STATUS_TXMAC_BUSY | IDLE_STATUS_RXMAC_BUSY);
}
-}
-
-static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
+static void atl1c_start_mac(struct atl1c_adapter *adapter)
{
-{
- u32 data;
-
- AT_READ_REG(hw, REG_RXQ_CTRL, &data);
@ -2899,10 +2896,13 @@ index 47a9bb2..f6f3fe3 100644
- }
- data |= RXQ_CTRL_EN;
- AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
-}
-
+ return (int)atl1c_wait_until_idle(hw,
+ IDLE_STATUS_TXMAC_BUSY | IDLE_STATUS_RXMAC_BUSY);
}
-static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw)
-{
+static void atl1c_start_mac(struct atl1c_adapter *adapter)
{
- u32 data;
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 mac, txq, rxq;
@ -2938,7 +2938,7 @@ index 47a9bb2..f6f3fe3 100644
}
/*
@@ -1286,10 +1228,7 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
@@ -1287,10 +1229,7 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
struct pci_dev *pdev = adapter->pdev;
@ -2950,7 +2950,7 @@ index 47a9bb2..f6f3fe3 100644
atl1c_stop_mac(hw);
/*
@@ -1298,194 +1237,148 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
@@ -1299,194 +1238,148 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
* the current PCI configuration. The global reset bit is self-
* clearing, and should clear within a microsecond.
*/
@ -3238,7 +3238,7 @@ index 47a9bb2..f6f3fe3 100644
/* clear interrupt status */
AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF);
/* Clear any WOL status */
@@ -1524,30 +1417,39 @@ static int atl1c_configure(struct atl1c_adapter *adapter)
@@ -1525,30 +1418,39 @@ static int atl1c_configure(struct atl1c_adapter *adapter)
master_ctrl_data |= MASTER_CTRL_SA_TIMER_EN;
AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
@ -3290,7 +3290,7 @@ index 47a9bb2..f6f3fe3 100644
static void atl1c_update_hw_stats(struct atl1c_adapter *adapter)
{
u16 hw_reg_addr = 0;
@@ -1634,16 +1536,11 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
@@ -1635,16 +1537,11 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
struct pci_dev *pdev = adapter->pdev;
u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
u16 hw_next_to_clean;
@ -3310,7 +3310,7 @@ index 47a9bb2..f6f3fe3 100644
while (next_to_clean != hw_next_to_clean) {
buffer_info = &tpd_ring->buffer_info[next_to_clean];
@@ -1745,9 +1642,9 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
@@ -1746,9 +1643,9 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
skb_checksum_none_assert(skb);
}
@ -3322,7 +3322,7 @@ index 47a9bb2..f6f3fe3 100644
struct pci_dev *pdev = adapter->pdev;
struct atl1c_buffer *buffer_info, *next_info;
struct sk_buff *skb;
@@ -1799,7 +1696,7 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid
@@ -1800,7 +1697,7 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid
/* TODO: update mailbox here */
wmb();
rfd_ring->next_to_use = rfd_next_to_use;
@ -3331,7 +3331,7 @@ index 47a9bb2..f6f3fe3 100644
rfd_ring->next_to_use & MB_RFDX_PROD_IDX_MASK);
}
@@ -1838,7 +1735,7 @@ static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring,
@@ -1839,7 +1736,7 @@ static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring,
rfd_ring->next_to_clean = rfd_index;
}
@ -3340,7 +3340,7 @@ index 47a9bb2..f6f3fe3 100644
int *work_done, int work_to_do)
{
u16 rfd_num, rfd_index;
@@ -1846,8 +1743,8 @@ static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
@@ -1847,8 +1744,8 @@ static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
u16 length;
struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
@ -3351,7 +3351,7 @@ index 47a9bb2..f6f3fe3 100644
struct sk_buff *skb;
struct atl1c_recv_ret_status *rrs;
struct atl1c_buffer *buffer_info;
@@ -1913,7 +1810,7 @@ rrs_checked:
@@ -1914,7 +1811,7 @@ rrs_checked:
count++;
}
if (count)
@ -3360,7 +3360,7 @@ index 47a9bb2..f6f3fe3 100644
}
/*
@@ -1930,7 +1827,7 @@ static int atl1c_clean(struct napi_struct *napi, int budget)
@@ -1931,7 +1828,7 @@ static int atl1c_clean(struct napi_struct *napi, int budget)
if (!netif_carrier_ok(adapter->netdev))
goto quit_polling;
/* just enable one RXQ */
@ -3369,7 +3369,7 @@ index 47a9bb2..f6f3fe3 100644
if (work_done < budget) {
quit_polling:
@@ -2205,23 +2102,10 @@ static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
@@ -2206,23 +2103,10 @@ static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
struct atl1c_tpd_desc *tpd, enum atl1c_trans_queue type)
{
struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
@ -3396,7 +3396,17 @@ index 47a9bb2..f6f3fe3 100644
}
static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
@@ -2327,44 +2211,38 @@ static int atl1c_request_irq(struct atl1c_adapter *adapter)
@@ -2307,8 +2191,7 @@ static int atl1c_request_irq(struct atl1c_adapter *adapter)
"Unable to allocate MSI interrupt Error: %d\n",
err);
adapter->have_msi = false;
- } else
- netdev->irq = pdev->irq;
+ }
if (!adapter->have_msi)
flags |= IRQF_SHARED;
@@ -2328,44 +2211,38 @@ static int atl1c_request_irq(struct atl1c_adapter *adapter)
return err;
}
@ -3420,7 +3430,7 @@ index 47a9bb2..f6f3fe3 100644
- atl1c_init_ring_ptrs(adapter);
- atl1c_set_multi(netdev);
- atl1c_restore_vlan(adapter);
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- num = atl1c_alloc_rx_buffer(adapter, i);
- if (unlikely(num == 0)) {
@ -3428,7 +3438,7 @@ index 47a9bb2..f6f3fe3 100644
- goto err_alloc_rx;
- }
- }
-
- if (atl1c_configure(adapter)) {
- err = -EIO;
+ err = atl1c_configure(adapter);
@ -3453,7 +3463,7 @@ index 47a9bb2..f6f3fe3 100644
atl1c_clean_rx_ring(adapter);
return err;
}
@@ -2382,15 +2260,15 @@ static void atl1c_down(struct atl1c_adapter *adapter)
@@ -2383,15 +2260,15 @@ static void atl1c_down(struct atl1c_adapter *adapter)
napi_disable(&adapter->napi);
atl1c_irq_disable(adapter);
atl1c_free_irq(adapter);
@ -3472,7 +3482,7 @@ index 47a9bb2..f6f3fe3 100644
}
/*
@@ -2423,13 +2301,6 @@ static int atl1c_open(struct net_device *netdev)
@@ -2424,13 +2301,6 @@ static int atl1c_open(struct net_device *netdev)
if (unlikely(err))
goto err_up;
@ -3486,7 +3496,7 @@ index 47a9bb2..f6f3fe3 100644
return 0;
err_up:
@@ -2455,6 +2326,8 @@ static int atl1c_close(struct net_device *netdev)
@@ -2456,6 +2326,8 @@ static int atl1c_close(struct net_device *netdev)
struct atl1c_adapter *adapter = netdev_priv(netdev);
WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
@ -3495,7 +3505,7 @@ index 47a9bb2..f6f3fe3 100644
atl1c_down(adapter);
atl1c_free_ring_resources(adapter);
return 0;
@@ -2466,10 +2339,6 @@ static int atl1c_suspend(struct device *dev)
@@ -2467,10 +2339,6 @@ static int atl1c_suspend(struct device *dev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
@ -3506,7 +3516,7 @@ index 47a9bb2..f6f3fe3 100644
u32 wufc = adapter->wol;
atl1c_disable_l0s_l1(hw);
@@ -2480,75 +2349,10 @@ static int atl1c_suspend(struct device *dev)
@@ -2481,75 +2349,10 @@ static int atl1c_suspend(struct device *dev)
netif_device_detach(netdev);
if (wufc)
@ -3584,7 +3594,7 @@ index 47a9bb2..f6f3fe3 100644
return 0;
}
@@ -2561,8 +2365,7 @@ static int atl1c_resume(struct device *dev)
@@ -2562,8 +2365,7 @@ static int atl1c_resume(struct device *dev)
struct atl1c_adapter *adapter = netdev_priv(netdev);
AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
@ -3594,7 +3604,22 @@ index 47a9bb2..f6f3fe3 100644
atl1c_phy_reset(&adapter->hw);
atl1c_reset_mac(&adapter->hw);
@@ -2713,7 +2516,7 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
@@ -2616,7 +2418,6 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
SET_NETDEV_DEV(netdev, &pdev->dev);
pci_set_drvdata(pdev, netdev);
- netdev->irq = pdev->irq;
netdev->netdev_ops = &atl1c_netdev_ops;
netdev->watchdog_timeo = AT_TX_WATCHDOG;
atl1c_set_ethtool_ops(netdev);
@@ -2706,14 +2507,13 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
dev_err(&pdev->dev, "cannot map device registers\n");
goto err_ioremap;
}
- netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
/* init mii data */
adapter->mii.dev = netdev;
adapter->mii.mdio_read = atl1c_mdio_read;
adapter->mii.mdio_write = atl1c_mdio_write;
adapter->mii.phy_id_mask = 0x1f;
@ -3603,7 +3628,7 @@ index 47a9bb2..f6f3fe3 100644
netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64);
setup_timer(&adapter->phy_config_timer, atl1c_phy_config,
(unsigned long)adapter);
@@ -2723,8 +2526,7 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
@@ -2723,8 +2523,7 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
dev_err(&pdev->dev, "net device private data init failed\n");
goto err_sw_init;
}
@ -3613,7 +3638,7 @@ index 47a9bb2..f6f3fe3 100644
/* Init GPHY as early as possible due to power saving issue */
atl1c_phy_reset(&adapter->hw);
@@ -2753,7 +2555,7 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
@@ -2752,7 +2551,7 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
dev_dbg(&pdev->dev, "mac address : %pM\n",
adapter->hw.mac_addr);
@ -3622,7 +3647,7 @@ index 47a9bb2..f6f3fe3 100644
INIT_WORK(&adapter->common_task, atl1c_common_task);
adapter->work_event = 0;
err = register_netdev(netdev);
@@ -2798,6 +2600,8 @@ static void __devexit atl1c_remove(struct pci_dev *pdev)
@@ -2796,6 +2595,8 @@ static void __devexit atl1c_remove(struct pci_dev *pdev)
struct atl1c_adapter *adapter = netdev_priv(netdev);
unregister_netdev(netdev);

View File

@ -1,105 +0,0 @@
From 2a5a5ec620a29d4ba07743c3151cdf0a417c8f8c Mon Sep 17 00:00:00 2001
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Date: Thu, 2 Feb 2012 10:32:18 +0200
Subject: [PATCH] Bluetooth: Use list _safe deleting from conn chan_list
Fixes possible bug when deleting element from the list in
function hci_chan_list_flush. list_for_each_entry_rcu is used
and after deleting element from the list we also free pointer
and then list_entry_rcu is taken from freed pointer.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/hci_conn.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index b074bd6..b4ecdde 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -975,10 +975,10 @@ int hci_chan_del(struct hci_chan *chan)
void hci_chan_list_flush(struct hci_conn *conn)
{
- struct hci_chan *chan;
+ struct hci_chan *chan, *n;
BT_DBG("conn %p", conn);
- list_for_each_entry_rcu(chan, &conn->chan_list, list)
+ list_for_each_entry_safe(chan, n, &conn->chan_list, list)
hci_chan_del(chan);
}
--
1.7.6.5
From 3c4e0df028935618d052235ba85bc7079be13394 Mon Sep 17 00:00:00 2001
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Date: Thu, 2 Feb 2012 10:32:17 +0200
Subject: [PATCH] Bluetooth: Use list _safe deleting from conn_hash_list
Use list_for_each_entry_safe which is safe version against removal
of list entry. Otherwise we remove hci_conn element and reference
next element which result in accessing LIST_POISON.
[ 95.571834] Bluetooth: unknown link type 127
[ 95.578349] BUG: unable to handle kernel paging request at 20002000
[ 95.580236] IP: [<20002000>] 0x20001fff
[ 95.580763] *pde = 00000000
[ 95.581196] Oops: 0000 [#1] SMP
...
[ 95.582298] Pid: 3355, comm: hciconfig Tainted: G O 3.2.0-VirttualBox
[ 95.582298] EIP: 0060:[<20002000>] EFLAGS: 00210206 CPU: 0
[ 95.582298] EIP is at 0x20002000
...
[ 95.582298] Call Trace:
[ 95.582298] [<f8231ab6>] ? hci_conn_hash_flush+0x76/0xf0 [bluetooth]
[ 95.582298] [<f822bcb1>] hci_dev_do_close+0xc1/0x2e0 [bluetooth]
[ 95.582298] [<f822d679>] ? hci_dev_get+0x69/0xb0 [bluetooth]
[ 95.582298] [<f822e1da>] hci_dev_close+0x2a/0x50 [bluetooth]
[ 95.582298] [<f824102f>] hci_sock_ioctl+0x1af/0x3f0 [bluetooth]
[ 95.582298] [<c11153ea>] ? handle_pte_fault+0x8a/0x8f0
[ 95.582298] [<c146becf>] sock_ioctl+0x5f/0x260
[ 95.582298] [<c146be70>] ? sock_fasync+0x90/0x90
[ 95.582298] [<c1152b33>] do_vfs_ioctl+0x83/0x5b0
[ 95.582298] [<c1563f87>] ? do_page_fault+0x297/0x500
[ 95.582298] [<c1563cf0>] ? spurious_fault+0xd0/0xd0
[ 95.582298] [<c107165b>] ? up_read+0x1b/0x30
[ 95.582298] [<c1563f87>] ? do_page_fault+0x297/0x500
[ 95.582298] [<c100aa9f>] ? init_fpu+0xef/0x160
[ 95.582298] [<c15617c0>] ? do_debug+0x180/0x180
[ 95.582298] [<c100a958>] ? fpu_finit+0x28/0x80
[ 95.582298] [<c11530e7>] sys_ioctl+0x87/0x90
[ 95.582298] [<c156795f>] sysenter_do_call+0x12/0x38
...
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/hci_conn.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index aca71c0..b074bd6 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -795,11 +795,11 @@ timer:
void hci_conn_hash_flush(struct hci_dev *hdev)
{
struct hci_conn_hash *h = &hdev->conn_hash;
- struct hci_conn *c;
+ struct hci_conn *c, *n;
BT_DBG("hdev %s", hdev->name);
- list_for_each_entry_rcu(c, &h->list, list) {
+ list_for_each_entry_safe(c, n, &h->list, list) {
c->state = BT_CLOSED;
hci_proto_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM);
--
1.7.6.5

View File

@ -12,6 +12,7 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_VEXPRESS_CA9X4=y
CONFIG_ARCH_VEXPRESS_DT=yG
CONFIG_PLAT_VERSATILE_CLCD=y
CONFIG_PLAT_VERSATILE_SCHED_CLOCK=y
CONFIG_PLAT_VERSATILE=y
@ -119,6 +120,8 @@ CONFIG_USB_TUSB6010=y
CONFIG_MMC_ARMMMCI=m
CONFIG_MMC_DW=m
CONFIG_MMC_DW_PLTFM=y
# CONFIG_MMC_DW_PCI is not set
# CONFIG_MMC_DW_IDMAC is not set
CONFIG_RTC_DRV_PL030=m
@ -130,6 +133,7 @@ CONFIG_RTC_DRV_PL031=m
# CONFIG_DEBUG_ERRORS is not set
# CONFIG_DEBUG_LL is not set
# CONFIG_DEBUG_PER_CPU_MAPS is not set
# CONFIG_IRQ_DOMAIN_DEBUG is not set
CONFIG_ARM_UNWIND=y
@ -271,3 +275,5 @@ CONFIG_OMAP4_ERRATA_I688=y
# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
CONFIG_OF_GPIO=y
CONFIG_BPF_JIT=y

View File

@ -11,6 +11,7 @@ CONFIG_MACH_MX51_EFIKASB=y
# CONFIG_THUMB2_KERNEL is not set
CONFIG_CPU_FREQ_IMX=y
CONFIG_W1_MASTER_MXC=m
CONFIG_IMX_DMA=m
CONFIG_IMX_SDMA=y
CONFIG_MACH_MX31ADS=y
CONFIG_MACH_MX31LILLY=y
@ -49,6 +50,7 @@ CONFIG_HW_RANDOM_MXC_RNGA=m
CONFIG_I2C_IMX=m
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_MCP23S08=m
CONFIG_GPIO_MC9S08DZ60=y
CONFIG_SND_IMX_SOC=m
CONFIG_USB_EHCI_MXC=y
# CONFIG_USB_IMX21_HCD is not set
@ -83,3 +85,5 @@ CONFIG_LEDS_RENESAS_TPU=y
# CONFIG_INPUT_GP2A is not set
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
CONFIG_MFD_ANATOP=y

View File

@ -1,4 +1,7 @@
CONFIG_ARCH_KIRKWOOD=y
CONFIG_ARCH_KIRKWOOD_DT=y
# CONFIG_SMP is not set
# CONFIG_VFP is not set
CONFIG_MACH_DB88F6281_BP=y
CONFIG_MACH_RD88F6192_NAS=y
CONFIG_MACH_RD88F6281=y
@ -6,6 +9,7 @@ CONFIG_MACH_MV88F6281GTW_GE=y
CONFIG_MACH_SHEEVAPLUG=y
CONFIG_MACH_ESATA_SHEEVAPLUG=y
CONFIG_MACH_GURUPLUG=y
CONFIG_MACH_DREAMPLUG_DT=y
CONFIG_MACH_DOCKSTAR=y
CONFIG_MACH_TS219=y
CONFIG_MACH_TS41X=y

View File

@ -222,6 +222,7 @@ CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND=y
# CONFIG_MTD_SM_COMMON is not set
# CONFIG_MTD_NAND_GPIO is not set
# CONFIG_MTD_NAND_DOCG4 is not set
CONFIG_MTD_NAND_OMAP2=y
CONFIG_MTD_NAND_OMAP_PREFETCH=y
CONFIG_MTD_NAND_OMAP_PREFETCH_DMA=y
@ -357,6 +358,7 @@ CONFIG_TOUCHSCREEN_AD7879_I2C=m
CONFIG_TOUCHSCREEN_CY8CTMG110=m
CONFIG_TOUCHSCREEN_HAMPSHIRE=m
CONFIG_TOUCHSCREEN_QT602240=m
CONFIG_TOUCHSCREEN_TI_TSCADC=m
CONFIG_TOUCHSCREEN_TPS6507X=m
# CONFIG_TOUCHSCREEN_TSC2005 is not set
CONFIG_INPUT_AD714X=m
@ -557,14 +559,17 @@ CONFIG_TWL4030_CORE=y
CONFIG_TWL4030_POWER=y
CONFIG_TWL4030_CODEC=y
# CONFIG_TWL6030_PWM is not set
# CONFIG_TWL6040_CORE is not set
# CONFIG_MFD_STMPE is not set
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_MFD_TPS65090 is not set/
# CONFIG_PMIC_DA903X is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_MAX8997 is not set
# CONFIG_MFD_MAX8998 is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM831X_SPI is not set
@ -592,6 +597,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_TWL4030=y
# CONFIG_REGULATOR_LP3971 is not set
# CONFIG_REGULATOR_LP3972 is not set
# CONFIG_REGULATOR_TPS62360 is not set
# CONFIG_REGULATOR_TPS65023 is not set
# CONFIG_REGULATOR_TPS6507X is not set
# CONFIG_REGULATOR_ISL6271A is not set
@ -710,6 +716,7 @@ CONFIG_PANEL_TPO_TD043MTEA1=y
# CONFIG_LCD_S6E63M0 is not set
# CONFIG_LCD_AMS369FG06 is not set
CONFIG_BACKLIGHT_GENERIC=m
# CONFIG_BACKLIGHT_PANDORA is not set
CONFIG_DISPLAY_SUPPORT=y
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
CONFIG_LOGO_LINUX_MONO=y
@ -1073,5 +1080,6 @@ CONFIG_USB_RENESAS_USBHS_HCD=m
# CONFIG_MFD_DA9052_I2C is not set
# CONFIG_MFD_S5M_CORE is not set
# CONFIG_VIDEO_AS3645A is not set
# CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set
#

View File

@ -70,6 +70,7 @@ CONFIG_MFD_NVEC=y
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_RCU_CPU_STALL_VERBOSE is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_DEBUG_PINCTRL is not set
CONFIG_KEYBOARD_NVEC=y
CONFIG_SERIO_NVEC_PS2=y
CONFIG_NVEC_POWER=y
@ -80,6 +81,8 @@ CONFIG_CPU_PM=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_CRYPTO_DEV_TEGRA_AES=m
CONFIG_CRYSTALHD=m
CONFIG_PL310_ERRATA_753970=y
@ -100,3 +103,5 @@ CONFIG_OF_GPIO=y
CONFIG_OF_PCI=y
CONFIG_OF_PCI_IRQ=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y

View File

@ -91,6 +91,7 @@ CONFIG_PCI_PRI=y
CONFIG_PCI_PASID=y
CONFIG_HT_IRQ=y
CONFIG_PCI_MSI=y
# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
CONFIG_PCIEASPM=y
@ -424,6 +425,8 @@ CONFIG_SCSI_MPT2SAS=m
CONFIG_SCSI_MPT2SAS_MAX_SGE=128
CONFIG_SCSI_MPT2SAS_LOGGING=y
CONFIG_SCSI_UFSHCD=m
CONFIG_SCSI_MVUMI=m
CONFIG_SCSI_OSD_INITIATOR=m
@ -587,6 +590,7 @@ CONFIG_DM_MULTIPATH_QL=m
CONFIG_DM_MULTIPATH_ST=m
CONFIG_DM_RAID=m
CONFIG_DM_FLAKEY=m
CONFIG_DM_VERITY=m
#
# Fusion MPT device support
@ -775,6 +779,7 @@ CONFIG_NETFILTER_XT_TARGET_CT=m
CONFIG_NETFILTER_XT_TARGET_DSCP=m
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
CONFIG_NETFILTER_XT_TARGET_LED=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@ -853,6 +858,7 @@ CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CONNTRACK_IPV4=y
CONFIG_NF_CONNTRACK_IPV6=y
# CONFIG_NF_CONNTRACK_TIMEOUT is not set
CONFIG_NF_CONNTRACK_TIMESTAMP=y
CONFIG_NF_CONNTRACK_SNMP=m
CONFIG_NF_NAT=m
@ -860,6 +866,7 @@ CONFIG_NF_NAT_SNMP_BASIC=m
CONFIG_NF_CT_PROTO_DCCP=m
CONFIG_NF_CT_PROTO_SCTP=m
CONFIG_NF_CT_NETLINK=m
# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
CONFIG_NF_CT_PROTO_UDPLITE=m
CONFIG_IP_NF_MATCH_AH=m
@ -1024,6 +1031,7 @@ CONFIG_NET_SCH_MQPRIO=m
CONFIG_NET_SCH_MULTIQ=m
CONFIG_NET_SCH_CHOKE=m
CONFIG_NET_SCH_QFQ=m
CONFIG_NET_SCH_PLUG=m
CONFIG_NET_CLS=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_CLS_BASIC=m
@ -1261,6 +1269,7 @@ CONFIG_FORCEDETH=m
CONFIG_NET_VENDOR_OKI=y
# CONFIG_PCH_GBE is not set
# CONFIG_PCH_PTP is not set
CONFIG_NET_PACKET_ENGINE=y
CONFIG_HAMACHI=m
@ -1329,6 +1338,7 @@ CONFIG_NET_VENDOR_XIRCOM=y
CONFIG_PCMCIA_XIRC2PS=m
CONFIG_PHYLIB=y
CONFIG_AMD_PHY=m
CONFIG_BROADCOM_PHY=m
CONFIG_CICADA_PHY=m
CONFIG_DAVICOM_PHY=m
@ -1378,6 +1388,9 @@ CONFIG_IP1000=m
CONFIG_MLX4_EN=m
# CONFIG_MLX4_DEBUG is not set
CONFIG_SFC=m
CONFIG_SFC_MCDI_MON=y
CONFIG_SFC_SRIOV=y
# CONFIG_SFC_MTD is not set
# CONFIG_FDDI is not set
@ -1449,10 +1462,13 @@ CONFIG_ATH5K_DEBUG=y
# CONFIG_ATH5K_TRACER is not set
CONFIG_ATH6KL=m
CONFIG_ATH6KL_DEBUG=y
CONFIG_ATH6KL_SDIO=m
CONFIG_ATH6KL_USB=m
CONFIG_ATH9K=m
CONFIG_ATH9K_PCI=y
CONFIG_ATH9K_AHB=y
# CONFIG_ATH9K_DEBUG is not set
# CONFIG_ATH9K_MAC_DEBUG is not set
CONFIG_ATH9K_DEBUGFS=y
CONFIG_ATH9K_HTC=m
CONFIG_ATH9K_BTCOEX_SUPPORT=y
@ -1486,6 +1502,7 @@ CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
CONFIG_BRCMSMAC=m
CONFIG_BRCMFMAC=m
CONFIG_BRCMFMAC_SDIO=y
CONFIG_BRCMFMAC_USB=y
# CONFIG_BRCMDBG is not set
CONFIG_HERMES=m
CONFIG_HERMES_CACHE_FW_ON_INIT=y
@ -1519,6 +1536,7 @@ CONFIG_IWLWIFI=m
CONFIG_IWLWIFI_DEBUG=y
CONFIG_IWLWIFI_DEBUGFS=y
CONFIG_IWLWIFI_DEVICE_SVTOOL=y
# CONFIG_IWLWIFI_EXPERIMENTAL_MFP is not set
# CONFIG_IWLWIFI_P2P is not set
CONFIG_IWLEGACY=m
CONFIG_IWLEGACY_DEBUG=y
@ -1559,10 +1577,12 @@ CONFIG_RT2800PCI_RT53XX=y
CONFIG_RT73USB=m
CONFIG_RTL8180=m
CONFIG_RTL8187=m
# CONFIG_RTLWIFI_DEBUG is not set
CONFIG_TMD_HERMES=m
CONFIG_USB_ZD1201=m
CONFIG_USB_NET_RNDIS_WLAN=m
CONFIG_USB_NET_KALMIA=m
CONFIG_USB_NET_QMI_WWAN=m
CONFIG_USB_NET_SMSC75XX=m
CONFIG_ZD1211RW=m
# CONFIG_ZD1211RW_DEBUG is not set
@ -1906,6 +1926,7 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_QT2160 is not set
# CONFIG_KEYBOARD_TCA6416 is not set
# CONFIG_KEYBOARD_TCA8418 is not set
# CONFIG_KEYBOARD_OMAP4 is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
@ -1916,6 +1937,7 @@ CONFIG_MOUSE_VSXXXAA=m
CONFIG_MOUSE_APPLETOUCH=m
CONFIG_MOUSE_BCM5974=m
CONFIG_MOUSE_SYNAPTICS_I2C=m
CONFIG_MOUSE_SYNAPTICS_USB=m
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_ANALOG=m
CONFIG_JOYSTICK_A3D=m
@ -1952,6 +1974,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_AD7879 is not set
CONFIG_TOUCHSCREEN_AD7879_I2C=m
# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
CONFIG_TOUCHSCREEN_DYNAPRO=m
CONFIG_TOUCHSCREEN_EETI=m
CONFIG_TOUCHSCREEN_EGALAX=m
@ -1960,6 +1983,7 @@ CONFIG_TOUCHSCREEN_FUJITSU=m
CONFIG_TOUCHSCREEN_GUNZE=m
# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
CONFIG_TOUCHSCREEN_INEXIO=m
CONFIG_TOUCHSCREEN_ILI210X=m
CONFIG_TOUCHSCREEN_MTOUCH=m
CONFIG_TOUCHSCREEN_MCS5000=m
CONFIG_TOUCHSCREEN_MK712=m
@ -2188,12 +2212,14 @@ CONFIG_SENSORS_LM93=m
CONFIG_SENSORS_LTC4245=m
CONFIG_SENSORS_MAX1619=m
CONFIG_SENSORS_MAX6650=m
CONFIG_SENSORS_MCP3021=m
CONFIG_SENSORS_NTC_THERMISTOR=m
CONFIG_SENSORS_PC87360=m
CONFIG_SENSORS_PC87427=m
CONFIG_SENSORS_PCF8591=m
CONFIG_SENSORS_SHT15=m
CONFIG_SENSORS_SIS5595=m
CONFIG_CHARGER_SMB347=m
CONFIG_SENSORS_SMSC47M1=m
CONFIG_SENSORS_SMSC47M192=m
CONFIG_SENSORS_SMSC47B397=m
@ -2402,6 +2428,7 @@ CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_STUB_POULSBO is not set
CONFIG_DRM=m
# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
CONFIG_DRM_RADEON=m
@ -2419,6 +2446,7 @@ CONFIG_DRM_NOUVEAU_DEBUG=y
# CONFIG_DRM_PSB is not set
CONFIG_DRM_I2C_CH7006=m
CONFIG_DRM_I2C_SIL164=m
CONFIG_DRM_UDL=m
CONFIG_DRM_VMWGFX=m
CONFIG_DRM_VGEM=m
@ -2526,6 +2554,7 @@ CONFIG_USB_KEENE=n
# CONFIG_VIDEO_TIMBERDALE is not set
# CONFIG_VIDEO_M5MOLS is not set
# CONFIG_EXYNOS_VIDEO is not set
CONFIG_USB_VIDEO_CLASS=m
CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
@ -2694,6 +2723,7 @@ CONFIG_FB=y
# CONFIG_FB_GEODE is not set
# CONFIG_FB_HECUBA is not set
# CONFIG_FB_HGA is not set
# CONFIG_FB_I740 is not set
CONFIG_FB_I810=m
CONFIG_FB_I810_GTF=y
CONFIG_FB_I810_I2C=y
@ -2955,8 +2985,10 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_EHCI_MV is not set
# CONFIG_USB_EHCI_HCD_PLATFORM is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_SSB is not set
# CONFIG_USB_OHCI_HCD_PLATFORM is not set
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_SL811_HCD=m
CONFIG_USB_SL811_HCD_ISO=y
@ -3067,6 +3099,9 @@ CONFIG_HOLTEK_FF=y
CONFIG_HID_SPEEDLINK=m
CONFIG_HID_WIIMOTE=m
CONFIG_HID_WIIMOTE_EXT=y
CONFIG_HID_KYE=m
CONFIG_HID_SAITEK=m
CONFIG_HID_TIVO=m
#
# USB Imaging devices
@ -3202,6 +3237,7 @@ CONFIG_USB_SERIAL_SYMBOL=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_EMPEG=m
# CONFIG_USB_SERIAL_F81232 is not set
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_FUNSOFT=m
CONFIG_USB_SERIAL_GARMIN=m
@ -3227,6 +3263,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
# CONFIG_USB_SERIAL_METRO is not set
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7715_PARPORT=y
# CONFIG_USB_SERIAL_ZIO is not set
@ -3366,6 +3403,7 @@ CONFIG_MFD_WM8400=m
# CONFIG_MFD_TPS6586X is not set
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_WL1273_CORE is not set
# CONFIG_MFD_TPS65217 is not set
#
# File systems
@ -3485,6 +3523,7 @@ CONFIG_SQUASHFS_ZLIB=y
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX6FS_FS is not set
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
@ -3505,6 +3544,7 @@ CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4_1=y
CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
@ -3522,6 +3562,7 @@ CONFIG_EXPORTFS=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_SUNRPC_XPRT_RDMA=m
CONFIG_SUNRPC_DEBUG=y
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
CONFIG_CIFS_STATS=y
@ -3729,6 +3770,7 @@ CONFIG_SECURITY_SELINUX_AVC_STATS=y
# CONFIG_SECURITY_SMACK is not set
# CONFIG_SECURITY_TOMOYO is not set
# CONFIG_SECURITY_APPARMOR is not set
# CONFIG_SECURITY_YAMA is not set
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set
@ -3812,6 +3854,7 @@ CONFIG_CRYPTO_USER=m
#
CONFIG_CRC16=y
CONFIG_CRC32=m
# CONFIG_CRC32_SELFTEST is not set
CONFIG_CRC_CCITT=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC_T10DIF=m
@ -3846,6 +3889,7 @@ CONFIG_FB_ATY128_BACKLIGHT=y
CONFIG_FB_ATY_BACKLIGHT=y
# CONFIG_BACKLIGHT_SAHARA is not set
CONFIG_BACKLIGHT_WM831X=m
CONFIG_BACKLIGHT_LP855X=m
CONFIG_LCD_CLASS_DEVICE=m
CONFIG_LCD_PLATFORM=m
@ -3967,6 +4011,7 @@ CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_BD2802 is not set
# CONFIG_LEDS_S3C24XX is not set
# CONFIG_LEDS_PCA9633 is not set
CONFIG_LEDS_DELL_NETBOOKS=m
# CONFIG_LEDS_TCA6507 is not set
# CONFIG_LEDS_OT200 is not set
@ -4043,6 +4088,7 @@ CONFIG_APM_POWER=m
# CONFIG_WM831X_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
# CONFIG_BATTERY_DS2781 is not set
# CONFIG_BATTERY_DS2782 is not set
# CONFIG_BATTERY_SBS is not set
# CONFIG_BATTERY_BQ20Z75 is not set
@ -4216,6 +4262,9 @@ CONFIG_ALTERA_STAPL=m
# CONFIG_RTS5139 is not set
# CONFIG_NVEC_LEDS is not set
# CONFIG_VT6655 is not set
# CONFIG_ZSMALLOC is not set
# CONFIG_RAMSTER is not set
# CONFIG_USB_WPAN_HCD is not set
#
# END OF STAGING
@ -4242,6 +4291,7 @@ CONFIG_STRIP_ASM_SYMS=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_TRACE is not set
# CONFIG_RCU_CPU_STALL_INFO is not set
CONFIG_SPARSE_RCU_POINTER=y
CONFIG_KSM=y
@ -4266,6 +4316,7 @@ CONFIG_PPS_CLIENT_GPIO=m
CONFIG_NTP_PPS=y
CONFIG_PTP_1588_CLOCK=m
CONFIG_PTP_1588_CLOCK_PCH=m
CONFIG_CLEANCACHE=y
@ -4333,4 +4384,6 @@ CONFIG_BCMA_HOST_PCI=y
# CONFIG_GOOGLE_FIRMWARE is not set
CONFIG_IOMMU_SUPPORT=y
# CONFIG_HSI is not set
# CONFIG_PM_DEVFREQ is not set

View File

@ -359,3 +359,6 @@ CONFIG_RFKILL_GPIO=m
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
CONFIG_STRICT_DEVMEM=y
# CONFIG_IRQ_DOMAIN_DEBUG is not set
# CONFIG_MPIC_MSGR is not set
# CONFIG_FA_DUMP is not set

View File

@ -197,6 +197,7 @@ CONFIG_QETH_L3=m
CONFIG_CRYPTO_SHA512_S390=m
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
# CONFIG_KVM_S390_UCONTROL is not set
CONFIG_S390_GUEST=y

View File

@ -155,6 +155,8 @@ CONFIG_OLPC_XO1_SCI=y
# staging
# CONFIG_FB_OLPC_DCON is not set
# CONFIG_IRQ_DOMAIN_DEBUG is not set
# CONFIG_SPARSE_IRQ is not set
CONFIG_RCU_FANOUT=32
@ -208,3 +210,7 @@ CONFIG_I2O_BUS=m
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
# CONFIG_INPUT_GP2A is not set
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
# CONFIG_GEOS is not set
# CONFIG_NET5501 is not set
# CONFIG_GPIO_SODAVILLE is not set
# CONFIG_BACKLIGHT_OT200 is not set

View File

@ -91,6 +91,7 @@ CONFIG_ACPI_APEI_MEMORY_FAILURE=y
# CONFIG_ACPI_APEI_EINJ is not set
CONFIG_ACPI_IPMI=m
CONFIG_ACPI_CUSTOM_METHOD=m
CONFIG_ACPI_BGRT=m
CONFIG_X86_ACPI_CPUFREQ=y
CONFIG_X86_PCC_CPUFREQ=y
@ -251,6 +252,7 @@ CONFIG_XEN_BALLOON=y
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_SAVE_RESTORE=y
CONFIG_HVC_XEN=y
CONFIG_HVC_XEN_FRONTEND=y
CONFIG_XEN_FBDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_NETDEV_FRONTEND=m
@ -268,6 +270,7 @@ CONFIG_XEN_GNTDEV=m
CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m
CONFIG_XEN_SELFBALLOONING=y
CONFIG_XEN_PCIDEV_BACKEND=m
CONFIG_XEN_ACPI_PROCESSOR=m
CONFIG_MTD_ESB2ROM=m
CONFIG_MTD_CK804XROM=m

View File

@ -1,5 +1,6 @@
CONFIG_64BIT=y
# CONFIG_X86_X32 is not set
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
CONFIG_GENERIC_CPU=y
@ -44,6 +45,7 @@ CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m
CONFIG_CRYPTO_SHA1_SSSE3=m
CONFIG_CRYPTO_BLOWFISH_X86_64=m
CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m
CONFIG_CRYPTO_CAMELLIA_X86_64=m
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set

File diff suppressed because it is too large Load Diff

View File

@ -1,133 +0,0 @@
From 268671ffd23264564a62c0893135e2e42e8c4f66 Mon Sep 17 00:00:00 2001
From: Eugeni Dodonov <eugeni.dodonov@intel.com>
Date: Fri, 23 Mar 2012 11:57:18 -0300
Subject: [PATCH] drm/i915: allow to select rc6 modes via kernel parameter
This allows to select which rc6 modes are to be used via kernel parameter,
via a bitmask parameter. E.g.:
- to enable rc6, i915_enable_rc6=1
- to enable rc6 and deep rc6, i915_enable_rc6=3
- to enable rc6 and deepest rc6, use i915_enable_rc6=5
- to enable rc6, deep and deepest rc6, use i915_enable_rc6=7
Please keep in mind that the deepest RC6 state really should NOT be used
by default, as it could potentially worsen the issues with deep RC6. So do
enable it only when you know what you are doing. However, having it around
could help solving possible future rc6-related issues and their debugging
on user machines.
Note that this changes behavior - previously, value of 1 would enable both
RC6 and deep RC6. Now it should only enable RC6 and deep/deepest RC6
stages must be enabled manually.
v2: address Chris Wilson comments and clean up the code.
References: https://bugs.freedesktop.org/show_bug.cgi?id=42579
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Ben Widawsky <benjamin.widawsky@intel.com>
Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/i915_drv.c | 6 +++++-
drivers/gpu/drm/i915/i915_drv.h | 21 +++++++++++++++++++++
drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++++++++----
3 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 84ecbb9..7990e27 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -66,7 +66,11 @@ MODULE_PARM_DESC(semaphores,
int i915_enable_rc6 __read_mostly = -1;
module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400);
MODULE_PARM_DESC(i915_enable_rc6,
- "Enable power-saving render C-state 6 (default: -1 (use per-chip default)");
+ "Enable power-saving render C-state 6. "
+ "Different stages can be selected via bitmask values "
+ "(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). "
+ "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. "
+ "default: -1 (use per-chip default)");
int i915_enable_fbc __read_mostly = -1;
module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9689ca3..a7d488e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1006,6 +1006,27 @@ struct drm_i915_file_private {
#include "i915_trace.h"
+/**
+ * RC6 is a special power stage which allows the GPU to enter an very
+ * low-voltage mode when idle, using down to 0V while at this stage. This
+ * stage is entered automatically when the GPU is idle when RC6 support is
+ * enabled, and as soon as new workload arises GPU wakes up automatically as well.
+ *
+ * There are different RC6 modes available in Intel GPU, which differentiate
+ * among each other with the latency required to enter and leave RC6 and
+ * voltage consumed by the GPU in different states.
+ *
+ * The combination of the following flags define which states GPU is allowed
+ * to enter, while RC6 is the normal RC6 state, RC6p is the deep RC6, and
+ * RC6pp is deepest RC6. Their support by hardware varies according to the
+ * GPU, BIOS, chipset and platform. RC6 is usually the safest one and the one
+ * which brings the most power savings; deeper states save more power, but
+ * require higher latency to switch to and wake up.
+ */
+#define INTEL_RC6_ENABLE (1<<0)
+#define INTEL_RC6p_ENABLE (1<<1)
+#define INTEL_RC6pp_ENABLE (1<<2)
+
extern struct drm_ioctl_desc i915_ioctls[];
extern int i915_max_ioctl;
extern unsigned int i915_fbpercrtc __always_unused;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2163818..dc90644 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8138,7 +8138,7 @@ void intel_init_emon(struct drm_device *dev)
dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
}
-static bool intel_enable_rc6(struct drm_device *dev)
+static int intel_enable_rc6(struct drm_device *dev)
{
/*
* Respect the kernel parameter if it is set
@@ -8169,6 +8169,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
u32 pcu_mbox, rc6_mask = 0;
int cur_freq, min_freq, max_freq;
+ int rc6_mode;
int i;
/* Here begins a magic sequence of register writes to enable
@@ -8199,9 +8200,20 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
- if (intel_enable_rc6(dev_priv->dev))
- rc6_mask = GEN6_RC_CTL_RC6_ENABLE |
- ((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0);
+ rc6_mode = intel_enable_rc6(dev_priv->dev);
+ if (rc6_mode & INTEL_RC6_ENABLE)
+ rc6_mask |= GEN6_RC_CTL_RC6_ENABLE;
+
+ if (rc6_mode & INTEL_RC6p_ENABLE)
+ rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE;
+
+ if (rc6_mode & INTEL_RC6pp_ENABLE)
+ rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE;
+
+ DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n",
+ (rc6_mode & INTEL_RC6_ENABLE) ? "on" : "off",
+ (rc6_mode & INTEL_RC6p_ENABLE) ? "on" : "off",
+ (rc6_mode & INTEL_RC6pp_ENABLE) ? "on" : "off");
I915_WRITE(GEN6_RC_CONTROL,
rc6_mask |
--
1.7.7.6

View File

@ -1,59 +0,0 @@
From 666a130a1a9046994d8a3c5c3ff62316ed980ba6 Mon Sep 17 00:00:00 2001
From: Eugeni Dodonov <eugeni.dodonov@intel.com>
Date: Fri, 23 Mar 2012 11:57:19 -0300
Subject: [PATCH 2/2] drm/i915: enable plain RC6 on Sandy Bridge by default
This is yet another chapter in the ongoing saga of bringing RC6 to Sandy
Bridge machines by default.
Now that we have discovered that RC6 issues are triggered by RC6+ state,
let's try to disable it by default. Plain RC6 is the one responsible for
most energy savings, and so far it haven't given any problems - at least,
none we are aware of.
So with this, when i915_enable_rc6=-1 (e.g., the default value), we'll
attempt to enable plain RC6 only on SNB. For Ivy Bridge, the behavior
stays the same as always - we enable both RC6 and deep RC6.
Note that while this exact patch does not has explicit tested-by's, the
equivalent settings were fixed in 3.3 kernel by a smaller patch. And it
has also received considerable testing through Canonical RC6 task-force
testing at https://wiki.ubuntu.com/Kernel/PowerManagementRC6. Up to date,
it looks like all the known issues are gone.
v2: improve description and reference a couple of open bugs related to
RC6 which seem to be fixed with this change.
References: https://bugs.freedesktop.org/show_bug.cgi?id=41682
References: https://bugs.freedesktop.org/show_bug.cgi?id=38567
References: https://bugs.freedesktop.org/show_bug.cgi?id=44867
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1430f09..0fad1b3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8150,11 +8150,11 @@ static int intel_enable_rc6(struct drm_device *dev)
* Disable rc6 on Sandybridge
*/
if (INTEL_INFO(dev)->gen == 6) {
- DRM_DEBUG_DRIVER("Sandybridge: RC6 disabled\n");
- return 0;
+ DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n");
+ return INTEL_RC6_ENABLE;
}
- DRM_DEBUG_DRIVER("RC6 enabled\n");
- return 1;
+ DRM_DEBUG_DRIVER("RC6 and deep RC6 enabled\n");
+ return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE);
}
void gen6_enable_rps(struct drm_i915_private *dev_priv)
--
1.7.9.3

View File

@ -1,51 +0,0 @@
From ea75f7357e3a881bd1bd0db5e483fc6a8681567b Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Tue, 10 Jan 2012 09:39:02 -0500
Subject: [PATCH] ext4: Support "check=none" "nocheck" mount options
The ext2/ext3 filesystems supported "check=none" and "nocheck" as mount options
even though that was already the default behavior and it essentially did
nothing. When using ext4 to mount ext2/ext3 filesystems, that mount option
causes the mount to fail. That isn't as backward compatible as it could be,
so add support to ext4 to accept the option.
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
---
fs/ext4/super.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 3e1329e..5ff09e7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1333,7 +1333,7 @@ enum {
Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
Opt_inode_readahead_blks, Opt_journal_ioprio,
Opt_dioread_nolock, Opt_dioread_lock,
- Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
+ Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable, Opt_nocheck,
};
static const match_table_t tokens = {
@@ -1409,6 +1409,8 @@ static const match_table_t tokens = {
{Opt_init_itable, "init_itable=%u"},
{Opt_init_itable, "init_itable"},
{Opt_noinit_itable, "noinit_itable"},
+ {Opt_nocheck, "check=none"},
+ {Opt_nocheck, "nocheck"},
{Opt_err, NULL},
};
@@ -1905,6 +1907,9 @@ set_qf_format:
case Opt_noinit_itable:
clear_opt(sb, INIT_INODE_TABLE);
break;
+ case Opt_nocheck:
+ /* ext2/ext3 used to "support" this option. Silently eat it */
+ break;
default:
ext4_msg(sb, KERN_ERR,
"Unrecognized mount option \"%s\" "
--
1.7.7.5

View File

@ -1,82 +0,0 @@
From a0ade1deb86d2325aecc36272bb4505a6eec9235 Mon Sep 17 00:00:00 2001
From: Lukas Czerner <lczerner@redhat.com>
Date: Mon, 20 Feb 2012 23:02:06 -0500
Subject: [PATCH] ext4: fix resize when resizing within single group
When resizing file system in the way that the new size of the file
system is still in the same group (no new groups are added), then we can
hit a BUG_ON in ext4_alloc_group_tables()
BUG_ON(flex_gd->count == 0 || group_data == NULL);
because flex_gd->count is zero. The reason is the missing check for such
case, so the code always extend the last group fully and then attempt to
add more groups, but at that time n_blocks_count is actually smaller
than o_blocks_count.
It can be easily reproduced like this:
mkfs.ext4 -b 4096 /dev/sda 30M
mount /dev/sda /mnt/test
resize2fs /dev/sda 50M
Fix this by checking whether the resize happens within the singe group
and only add that many blocks into the last group to satisfy user
request. Then o_blocks_count == n_blocks_count and the resize will exit
successfully without and attempt to add more groups into the fs.
Also fix mixing together block number and blocks count which might be
confusing and can easily lead to off-by-one errors (but it is actually
not the case here since the two occurrence of this mix-up will cancel
each other).
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Reported-by: Milan Broz <mbroz@redhat.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
fs/ext4/resize.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index f9d948f..3fed79d 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1582,7 +1582,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
ext4_fsblk_t o_blocks_count;
ext4_group_t o_group;
ext4_group_t n_group;
- ext4_grpblk_t offset;
+ ext4_grpblk_t offset, add;
unsigned long n_desc_blocks;
unsigned long o_desc_blocks;
unsigned long desc_blocks;
@@ -1605,7 +1605,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
return 0;
ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset);
- ext4_get_group_no_and_offset(sb, o_blocks_count, &o_group, &offset);
+ ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
n_desc_blocks = (n_group + EXT4_DESC_PER_BLOCK(sb)) /
EXT4_DESC_PER_BLOCK(sb);
@@ -1634,10 +1634,12 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
}
brelse(bh);
- if (offset != 0) {
- /* extend the last group */
- ext4_grpblk_t add;
- add = EXT4_BLOCKS_PER_GROUP(sb) - offset;
+ /* extend the last group */
+ if (n_group == o_group)
+ add = n_blocks_count - o_blocks_count;
+ else
+ add = EXT4_BLOCKS_PER_GROUP(sb) - (offset + 1);
+ if (add > 0) {
err = ext4_group_extend_no_check(sb, o_blocks_count, add);
if (err)
goto out;
--
1.7.6.5

View File

@ -1,107 +0,0 @@
From 5c21b39ab123ada8ce248efc733420bd8c9ea255 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@redhat.com>
Date: Fri, 28 Oct 2011 15:38:06 -0400
Subject: [PATCH] floppy: Remove _hlt related functions
It's close enough to 2012 and the WARN_ONCE is causing things like abrt to
auto-file bugs that aren't really bugs.
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index d5ac362..df1e87c 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,14 +6,6 @@ be removed from this file.
---------------------------
-What: x86 floppy disable_hlt
-When: 2012
-Why: ancient workaround of dubious utility clutters the
- code used by everybody else.
-Who: Len Brown <len.brown@intel.com>
-
----------------------------
-
What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
When: 2012
Why: This optional sub-feature of APM is of dubious reliability,
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 9955a53..40bf4c2 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -1032,37 +1032,6 @@ static int fd_wait_for_completion(unsigned long delay, timeout_fn function)
return 0;
}
-static DEFINE_SPINLOCK(floppy_hlt_lock);
-static int hlt_disabled;
-static void floppy_disable_hlt(void)
-{
- unsigned long flags;
-
- WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2012");
- spin_lock_irqsave(&floppy_hlt_lock, flags);
- if (!hlt_disabled) {
- hlt_disabled = 1;
-#ifdef HAVE_DISABLE_HLT
- disable_hlt();
-#endif
- }
- spin_unlock_irqrestore(&floppy_hlt_lock, flags);
-}
-
-static void floppy_enable_hlt(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&floppy_hlt_lock, flags);
- if (hlt_disabled) {
- hlt_disabled = 0;
-#ifdef HAVE_DISABLE_HLT
- enable_hlt();
-#endif
- }
- spin_unlock_irqrestore(&floppy_hlt_lock, flags);
-}
-
static void setup_DMA(void)
{
unsigned long f;
@@ -1107,7 +1076,6 @@ static void setup_DMA(void)
fd_enable_dma();
release_dma_lock(f);
#endif
- floppy_disable_hlt();
}
static void show_floppy(void);
@@ -1709,7 +1677,6 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id)
fd_disable_dma();
release_dma_lock(f);
- floppy_enable_hlt();
do_floppy = NULL;
if (fdc >= N_FDC || FDCS->address == -1) {
/* we don't even know which FDC is the culprit */
@@ -1858,8 +1825,6 @@ static void floppy_shutdown(unsigned long data)
show_floppy();
cancel_activity();
- floppy_enable_hlt();
-
flags = claim_dma_lock();
fd_disable_dma();
release_dma_lock(flags);
@@ -4504,7 +4469,6 @@ static void floppy_release_irq_and_dma(void)
#if N_FDC > 1
set_dor(1, ~8, 0);
#endif
- floppy_enable_hlt();
if (floppy_track_buffer && max_buffer_sectors) {
tmpsize = max_buffer_sectors * 1024;
--
1.7.6.4

View File

@ -1,26 +0,0 @@
The finder_info block in the hfsplus volume header is currently defined as
an array of 8 bit values, but TN1150 defines it as being an array of 32 bit
values. Fix for convenience.
Signed-off-by: Matthew Garrett <mjg@redhat.com>
---
fs/hfsplus/hfsplus_raw.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h
index 927cdd6..921967e 100644
--- a/fs/hfsplus/hfsplus_raw.h
+++ b/fs/hfsplus/hfsplus_raw.h
@@ -117,7 +117,7 @@ struct hfsplus_vh {
__be32 write_count;
__be64 encodings_bmp;
- u8 finder_info[32];
+ u32 finder_info[8];
struct hfsplus_fork_raw alloc_file;
struct hfsplus_fork_raw ext_file;
--
1.7.7.1

View File

@ -54,19 +54,19 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
%global baserelease 3
%global baserelease 1
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
# on top of -- for example, 2.6.22-rc7-git1 starts with a 2.6.21 base,
# which yields a base_sublevel of 21.
%define base_sublevel 3
%define base_sublevel 4
## If this is a released kernel ##
%if 0%{?released_kernel}
# Do we have a -stable update to apply?
%define stable_update 7
%define stable_update 0
# Is it a -stable RC?
%define stable_rc 0
# Set rpm version accordingly
@ -646,8 +646,6 @@ Patch160: linux-2.6-32bit-mmap-exec-randomization.patch
Patch161: linux-2.6-i386-nx-emulation.patch
Patch162: nx-emu-remove-cpuinitdata-for-disable_nx-on-x86_32.patch
Patch383: linux-2.6-defaults-aspm.patch
Patch390: linux-2.6-defaults-acpi-video.patch
Patch391: linux-2.6-acpi-video-dos.patch
Patch394: linux-2.6-acpi-debug-infinite-loop.patch
@ -659,10 +657,8 @@ Patch452: linux-2.6.30-no-pcspkr-modalias.patch
Patch460: linux-2.6-serial-460800.patch
Patch470: die-floppy-die.patch
Patch471: floppy-Remove-_hlt-related-functions.patch
Patch510: linux-2.6-silence-noise.patch
Patch511: silence-timekeeping-spew.patch
Patch520: quite-apm.patch
Patch530: linux-2.6-silence-fbcon-logo.patch
@ -675,7 +671,6 @@ Patch800: linux-2.6-crash-driver.patch
# virt + ksm patches
Patch1555: fix_xen_guest_on_old_EC2.patch
Patch1556: linux-3.3-virtio-scsi.patch
# DRM
#atch1700: drm-edid-try-harder-to-fix-up-broken-headers.patch
@ -688,8 +683,6 @@ Patch1825: drm-i915-dp-stfu.patch
Patch1900: linux-2.6-intel-iommu-igfx.patch
Patch1950: drm-i915-allow-to-select-rc6-modes-via-kernel-parame.patch
Patch1951: drm-i915-enable-plain-RC6-on-Sandy-Bridge-by-default.patch
Patch1952: drm-i915-lvds-dual-channel.patch
# Quiet boot fixes
@ -697,25 +690,11 @@ Patch1952: drm-i915-lvds-dual-channel.patch
Patch2802: linux-2.6-silence-acpi-blacklist.patch
# media patches
Patch2900: add-poll-requested-events.patch
Patch2901: drivers-media-update.patch
# fs fixes
Patch4000: ext4-fix-resize-when-resizing-within-single-group.patch
# NFSv4
Patch4101: linux-3.1-keys-remove-special-keyring.patch
Patch4102: linux-3.3-newidmapper-01.patch
Patch4103: linux-3.3-newidmapper-02.patch
Patch4104: linux-3.3-newidmapper-03.patch
Patch4105: NFSv4-Reduce-the-footprint-of-the-idmapper.patch
Patch4106: NFSv4-Further-reduce-the-footprint-of-the-idmapper.patch
Patch4107: NFSv4-Minor-cleanups-for-nfs4_handle_exception-and-n.patch
# NFS Client Patch set from Upstream
Patch4113: NFS-optimise-away-unnecessary-setattrs-for-open-O_TRUNC.patch
Patch4114: NFSv4-fix-open-O_TRUNC-and-ftruncate-error-handling.patch
Patch4115: NFSv4-Rate-limit-the-state-manager-for-lock-reclaim-.patch
# patches headed upstream
Patch10000: fs-proc-devtree-remove_proc_entry.patch
@ -728,12 +707,8 @@ Patch13003: efi-dont-map-boot-services-on-32bit.patch
Patch14010: lis3-improve-handling-of-null-rate.patch
Patch15000: bluetooth-use-after-free.patch
Patch19000: ips-noirq.patch
Patch20000: utrace.patch
# ARM
# Flattened devicetree support
Patch21000: arm-omap-dt-compat.patch
@ -748,42 +723,20 @@ Patch21006: arm-beagle-usb-init.patch
# Highbank clock functions need to be EXPORT for module builds
Patch21010: highbank-export-clock-functions.patch
Patch21070: ext4-Support-check-none-nocheck-mount-options.patch
Patch21093: rt2x00_fix_MCU_request_failures.patch
Patch21094: power-x86-destdir.patch
Patch21095: hfsplus-Change-finder_info-to-u32.patch
Patch21096: hfsplus-Add-an-ioctl-to-bless-files.patch
Patch21097: hfsplus-initialise-userflags.patch
Patch21098: hfsplus-Fix-bless-ioctl-when-used-with-hardlinks.patch
#rhbz 754518
Patch21235: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
Patch21250: mcelog-rcu-splat.patch
Patch21270: x86-Avoid-invoking-RCU-when-CPU-is-idle.patch
#rhbz 804957 CVE-2012-1568
Patch21306: shlib_base_randomize.patch
#rhbz 804347
Patch21351: x86-add-io_apic_ops-to-allow-interception.patch
Patch21352: x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch
Patch21353: xen-x86-Implement-x86_apic_ops.patch
#rhbz 807632
Patch21385: libata-forbid-port-runtime-pm-by-default.patch
Patch21400: unhandled-irqs-switch-to-polling.patch
#rhbz 808559
Patch21530: ALSA-hda-realtek-Add-quirk-for-Mac-Pro-5-1-machines.patch
Patch21600: apple_bl-Add-register-unregister-functions.patch
Patch21601: platform-x86-Add-driver-for-Apple-gmux-device.patch
Patch21620: vgaarb-vga_default_device.patch
Patch22000: weird-root-dentry-name-debug.patch
@ -803,20 +756,20 @@ Patch22014: efifb-skip-DMI-checks-if-bootloader-knows.patch
Patch22017: 0001-drm-radeon-don-t-mess-with-hot-plug-detect-for-eDP-o.patch
#rhbz 749276
Patch22018: atl1c_net_next_update-3.3.patch
Patch22018: atl1c_net_next_update-3.4.patch
#rhbz 795176
Patch22019: rtl818x-fix-sleeping-function-called-from-invalid-context.patch
#rhbz 822120
Patch22020: rtlwifi-fix-for-race-condition-when-firmware-is-cach.patch
#rhbz 822825 822821 CVE-2012-2372
Patch22021: mm-pmd_read_atomic-fix-32bit-PAE-pmd-walk-vs-pmd_populate-SMP-race-condition.patch
#rhbz 824352 824345 CVE-2012-2390
Patch22022: hugetlb-fix-resv_map-leak-in-error-path.patch
#Stable Queue for 3.4.1
Patch22023: 3.4.1-stable-queue.patch.xz
# END OF PATCH DEFINITIONS
%endif
@ -1358,6 +1311,9 @@ ApplyOptionalPatch linux-2.6-upstream-reverts.patch -R
ApplyPatch taint-vbox.patch
#Stable Queue for 3.4.1
ApplyPatch 3.4.1-stable-queue.patch.xz
# Architecture patches
# x86(-64)
ApplyPatch linux-2.6-32bit-mmap-exec-randomization.patch
@ -1368,7 +1324,7 @@ ApplyPatch nx-emu-remove-cpuinitdata-for-disable_nx-on-x86_32.patch
# ARM
#
#pplyPatch arm-omap-dt-compat.patch
ApplyPatch arm-smsc-support-reading-mac-address-from-device-tree.patch
# ApplyPatch arm-smsc-support-reading-mac-address-from-device-tree.patch
ApplyPatch arm-tegra-nvec-kconfig.patch
ApplyPatch arm-tegra-usb-no-reset-linux33.patch
ApplyPatch arm-beagle-usb-init.patch
@ -1378,7 +1334,6 @@ ApplyPatch arm-beagle-usb-init.patch
#
# ext4
ApplyPatch ext4-fix-resize-when-resizing-within-single-group.patch
# xfs
@ -1388,18 +1343,6 @@ ApplyPatch ext4-fix-resize-when-resizing-within-single-group.patch
# eCryptfs
# NFSv4
ApplyPatch linux-3.1-keys-remove-special-keyring.patch
ApplyPatch linux-3.3-newidmapper-01.patch
ApplyPatch linux-3.3-newidmapper-02.patch
ApplyPatch linux-3.3-newidmapper-03.patch
ApplyPatch NFSv4-Reduce-the-footprint-of-the-idmapper.patch
ApplyPatch NFSv4-Further-reduce-the-footprint-of-the-idmapper.patch
ApplyPatch NFSv4-Minor-cleanups-for-nfs4_handle_exception-and-n.patch
# NFS Client Patch set from Upstream
ApplyPatch NFS-optimise-away-unnecessary-setattrs-for-open-O_TRUNC.patch
ApplyPatch NFSv4-fix-open-O_TRUNC-and-ftruncate-error-handling.patch
ApplyPatch NFSv4-Rate-limit-the-state-manager-for-lock-reclaim-.patch
# USB
@ -1414,8 +1357,6 @@ ApplyPatch acpi-sony-nonvs-blacklist.patch
#
# PCI
#
# enable ASPM by default on hardware we expect to work
ApplyPatch linux-2.6-defaults-aspm.patch
#
# SCSI Bits.
@ -1425,9 +1366,6 @@ ApplyPatch linux-2.6-defaults-aspm.patch
# ALSA
#rhbz 808559
ApplyPatch ALSA-hda-realtek-Add-quirk-for-Mac-Pro-5-1-machines.patch
# Networking
# Misc fixes
@ -1436,7 +1374,6 @@ ApplyPatch linux-2.6-input-kill-stupid-messages.patch
# stop floppy.ko from autoloading during udev...
ApplyPatch die-floppy-die.patch
ApplyPatch floppy-Remove-_hlt-related-functions.patch
ApplyPatch linux-2.6.30-no-pcspkr-modalias.patch
@ -1446,8 +1383,6 @@ ApplyPatch linux-2.6-serial-460800.patch
# Silence some useless messages that still get printed with 'quiet'
ApplyPatch linux-2.6-silence-noise.patch
ApplyPatch silence-timekeeping-spew.patch
# Make fbcon not show the penguins with 'quiet'
ApplyPatch linux-2.6-silence-fbcon-logo.patch
@ -1477,8 +1412,6 @@ ApplyPatch drm-i915-dp-stfu.patch
ApplyPatch linux-2.6-intel-iommu-igfx.patch
ApplyPatch drm-i915-allow-to-select-rc6-modes-via-kernel-parame.patch
ApplyPatch drm-i915-enable-plain-RC6-on-Sandy-Bridge-by-default.patch
ApplyPatch drm-i915-lvds-dual-channel.patch
# silence the ACPI blacklist code
@ -1487,14 +1420,12 @@ ApplyPatch quite-apm.patch
# Media (V4L/DVB/IR) updates/fixes/experimental drivers
# apply if non-empty
ApplyPatch add-poll-requested-events.patch
ApplyOptionalPatch drivers-media-update.patch
# Patches headed upstream
ApplyPatch fs-proc-devtree-remove_proc_entry.patch
ApplyPatch disable-i8042-check-on-apple-mac.patch
ApplyPatch linux-3.3-virtio-scsi.patch
# rhbz#605888
ApplyPatch dmar-disable-when-ricoh-multifunction.patch
@ -1503,30 +1434,15 @@ ApplyPatch efi-dont-map-boot-services-on-32bit.patch
ApplyPatch lis3-improve-handling-of-null-rate.patch
ApplyPatch bluetooth-use-after-free.patch
ApplyPatch ips-noirq.patch
# utrace.
ApplyPatch utrace.patch
ApplyPatch ext4-Support-check-none-nocheck-mount-options.patch
#rhbz 772772
ApplyPatch rt2x00_fix_MCU_request_failures.patch
ApplyPatch power-x86-destdir.patch
ApplyPatch hfsplus-Change-finder_info-to-u32.patch
ApplyPatch hfsplus-Add-an-ioctl-to-bless-files.patch
ApplyPatch hfsplus-initialise-userflags.patch
ApplyPatch hfsplus-Fix-bless-ioctl-when-used-with-hardlinks.patch
#rhbz 754518
ApplyPatch scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
ApplyPatch mcelog-rcu-splat.patch
#rhbz 804957 CVE-2012-1568
ApplyPatch shlib_base_randomize.patch
@ -1534,24 +1450,12 @@ ApplyPatch unhandled-irqs-switch-to-polling.patch
ApplyPatch weird-root-dentry-name-debug.patch
#rhbz 804347
ApplyPatch x86-add-io_apic_ops-to-allow-interception.patch
ApplyPatch x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch
ApplyPatch xen-x86-Implement-x86_apic_ops.patch
#Highbank clock functions
ApplyPatch highbank-export-clock-functions.patch
#rhbz 807632
ApplyPatch libata-forbid-port-runtime-pm-by-default.patch
#selinux ptrace child permissions
ApplyPatch selinux-apply-different-permission-to-ptrace-child.patch
#apple gmux. blame mjg59
ApplyPatch apple_bl-Add-register-unregister-functions.patch
ApplyPatch platform-x86-Add-driver-for-Apple-gmux-device.patch
#vgaarb patches. blame mjg59
ApplyPatch vgaarb-vga_default_device.patch
@ -1567,14 +1471,11 @@ ApplyPatch efifb-skip-DMI-checks-if-bootloader-knows.patch
ApplyPatch 0001-drm-radeon-don-t-mess-with-hot-plug-detect-for-eDP-o.patch
#rhbz 749276
ApplyPatch atl1c_net_next_update-3.3.patch
ApplyPatch atl1c_net_next_update-3.4.patch
#rhbz 795176
ApplyPatch rtl818x-fix-sleeping-function-called-from-invalid-context.patch
#rhbz 822120
ApplyPatch rtlwifi-fix-for-race-condition-when-firmware-is-cach.patch
#rhbz 822825 822821 CVE-2012-2372
ApplyPatch mm-pmd_read_atomic-fix-32bit-PAE-pmd-walk-vs-pmd_populate-SMP-race-condition.patch
@ -2435,6 +2336,10 @@ fi
# '-' | |
# '-'
%changelog
* Sun Jun 02 2012 Justin M. Forbes <jforbes@redhat.com> 3.4.0-1
- Linux 3.4
- Stable queue updates
* Wed May 30 2012 Josh Boyer <jwboyer@redhat.com>
- CVE-2012-2390 huge pages: memory leak on mmap failure (rhbz 824352 824345)

View File

@ -1,24 +0,0 @@
From: Lin Ming <ming.m.lin@xxxxxxxxx>
Date: Wed, 18 Apr 2012 09:13:41 +0800
Subject: [PATCH] libata: forbid port runtime pm by default
Forbid port runtime pm by default because it has known hotplug issue.
User can allow it by, for example
echo auto > /sys/devices/pci0000:00/0000:00:1f.2/ata2/power/control
Signed-off-by: Lin Ming <ming.m.lin@xxxxxxxxx>
---
drivers/ata/libata-transport.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
--- linux-3.3.noarch.orig/drivers/ata/libata-transport.c
+++ linux-3.3.noarch/drivers/ata/libata-transport.c
@@ -294,6 +294,7 @@ int ata_tport_add(struct device *parent,
device_enable_async_suspend(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
+ pm_runtime_forbid(dev);
transport_add_device(dev);
transport_configure_device(dev);

View File

@ -7,10 +7,96 @@ Heap randomisation test (PIE) : 19 bits (guessed)
Main executable randomisation (PIE) : 12 bits (guessed)
--- b/include/linux/sched.h
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 1d92a5a..81fef23 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -753,6 +753,16 @@ unsigned long arch_align_stack(unsigned long sp)
unsigned long arch_randomize_brk(struct mm_struct *mm)
{
unsigned long range_end = mm->brk + 0x02000000;
- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+ unsigned long bump = 0;
+#ifdef CONFIG_X86_32
+ /* in the case of NX emulation, shove the brk segment way out of the
+ way of the exec randomization area, since it can collide with
+ future allocations if not. */
+ if ( (mm->get_unmapped_exec_area == arch_get_unmapped_exec_area) &&
+ (mm->brk < 0x08000000) ) {
+ bump = (TASK_SIZE/6);
+ }
+#endif
+ return bump + (randomize_range(mm->brk, range_end, 0) ? : mm->brk);
}
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 845df68..d437466 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -119,6 +119,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
} else {
mm->mmap_base = mmap_base();
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+#ifdef CONFIG_X86_32
+ if (!(current->personality & READ_IMPLIES_EXEC)
+ && !(__supported_pte_mask & _PAGE_NX)
+ && mmap_is_ia32())
+ mm->get_unmapped_exec_area = arch_get_unmapped_exec_area;
+#endif
mm->unmap_area = arch_unmap_area_topdown;
}
}
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index 66e6d93..b80cde7 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -330,7 +330,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
if (compat)
addr = VDSO_HIGH_BASE;
else {
- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+ addr = get_unmapped_area_prot(NULL, 0, PAGE_SIZE, 0, 0, 1);
if (IS_ERR_VALUE(addr)) {
ret = addr;
goto up_fail;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 74aa71b..d9971db 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1391,7 +1391,13 @@ extern int install_special_mapping(struct mm_struct *mm,
unsigned long addr, unsigned long len,
unsigned long flags, struct page **pages);
-extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+extern unsigned long get_unmapped_area_prot(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, int);
+
+static inline unsigned long get_unmapped_area(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0);
+}
extern unsigned long mmap_region(struct file *file, unsigned long addr,
unsigned long len, unsigned long flags,
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 3cc3062..b42f00b 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -293,6 +293,9 @@ struct mm_struct {
unsigned long (*get_unmapped_area) (struct file *filp,
unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags);
+ unsigned long (*get_unmapped_exec_area) (struct file *filp,
+ unsigned long addr, unsigned long len,
+ unsigned long pgoff, unsigned long flags);
void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
#endif
unsigned long mmap_base; /* base of mmap area */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 81a173c..3f9f5c4 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -397,6 +397,10 @@
@@ -390,6 +390,10 @@ extern void arch_pick_mmap_layout(struct mm_struct *mm);
extern unsigned long
arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
unsigned long, unsigned long);
@ -21,9 +107,11 @@ Main executable randomisation (PIE) : 12 bits (guessed)
extern unsigned long
arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff,
--- b/mm/mmap.c
diff --git a/mm/mmap.c b/mm/mmap.c
index 848ef52..65650a5 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -28,6 +28,7 @@
@@ -30,6 +30,7 @@
#include <linux/perf_event.h>
#include <linux/audit.h>
#include <linux/khugepaged.h>
@ -31,7 +119,7 @@ Main executable randomisation (PIE) : 12 bits (guessed)
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
@@ -1000,7 +1001,8 @@
@@ -995,7 +996,8 @@ static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
/* Obtain the address to map to. we verify (or select) it and ensure
* that it represents a valid section of the address space.
*/
@ -41,7 +129,7 @@ Main executable randomisation (PIE) : 12 bits (guessed)
if (addr & ~PAGE_MASK)
return addr;
@@ -1552,8 +1554,8 @@
@@ -1580,8 +1582,8 @@ void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
}
unsigned long
@ -52,7 +140,7 @@ Main executable randomisation (PIE) : 12 bits (guessed)
{
unsigned long (*get_area)(struct file *, unsigned long,
unsigned long, unsigned long, unsigned long);
@@ -1566,7 +1568,11 @@
@@ -1594,7 +1596,11 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
if (len > TASK_SIZE)
return -ENOMEM;
@ -65,7 +153,7 @@ Main executable randomisation (PIE) : 12 bits (guessed)
if (file && file->f_op && file->f_op->get_unmapped_area)
get_area = file->f_op->get_unmapped_area;
addr = get_area(file, addr, len, pgoff, flags);
@@ -1580,8 +1586,83 @@
@@ -1608,8 +1614,83 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
return arch_rebalance_pgtables(addr, len);
}
@ -150,71 +238,11 @@ Main executable randomisation (PIE) : 12 bits (guessed)
/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -124,13 +124,19 @@ static unsigned long mmap_legacy_base(void)
*/
void arch_pick_mmap_layout(struct mm_struct *mm)
{
if (mmap_is_legacy()) {
mm->mmap_base = mmap_legacy_base();
mm->get_unmapped_area = arch_get_unmapped_area;
mm->unmap_area = arch_unmap_area;
} else {
mm->mmap_base = mmap_base();
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+#ifdef CONFIG_X86_32
+ if (!(current->personality & READ_IMPLIES_EXEC)
+ && !(__supported_pte_mask & _PAGE_NX)
+ && mmap_is_ia32())
+ mm->get_unmapped_exec_area = arch_get_unmapped_exec_area;
+#endif
mm->unmap_area = arch_unmap_area_topdown;
}
}
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
if (compat)
addr = VDSO_HIGH_BASE;
else {
- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+ addr = get_unmapped_area_prot(NULL, 0, PAGE_SIZE, 0, 0, 1);
if (IS_ERR_VALUE(addr)) {
ret = addr;
goto up_fail;
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1263,7 +1263,13 @@ extern int install_special_mapping(struct mm_struct *mm,
unsigned long addr, unsigned long len,
unsigned long flags, struct page **pages);
-extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+extern unsigned long get_unmapped_area_prot(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, int);
+
+static inline unsigned long get_unmapped_area(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0);
+}
extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -227,6 +227,9 @@ struct mm_struct {
unsigned long (*get_unmapped_area) (struct file *filp,
unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags);
+ unsigned long (*get_unmapped_exec_area) (struct file *filp,
+ unsigned long addr, unsigned long len,
+ unsigned long pgoff, unsigned long flags);
void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
#endif
unsigned long mmap_base; /* base of mmap area */
diff --git a/mm/mremap.c b/mm/mremap.c
index db8d983..3a2d940 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -487,10 +487,10 @@ unsigned long do_mremap(unsigned long addr,
@@ -521,10 +521,10 @@ unsigned long do_mremap(unsigned long addr,
if (vma->vm_flags & VM_MAYSHARE)
map_flags |= MAP_SHARED;
@ -227,25 +255,3 @@ Main executable randomisation (PIE) : 12 bits (guessed)
if (new_addr & ~PAGE_MASK) {
ret = new_addr;
goto out;
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 57d1868..29c0c35 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -669,6 +669,16 @@ unsigned long arch_align_stack(unsigned long sp)
unsigned long arch_randomize_brk(struct mm_struct *mm)
{
unsigned long range_end = mm->brk + 0x02000000;
- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+ unsigned long bump = 0;
+#ifdef CONFIG_X86_32
+ /* in the case of NX emulation, shove the brk segment way out of the
+ way of the exec randomization area, since it can collide with
+ future allocations if not. */
+ if ( (mm->get_unmapped_exec_area == arch_get_unmapped_exec_area) &&
+ (mm->brk < 0x08000000) ) {
+ bump = (TASK_SIZE/6);
+ }
+#endif
+ return bump + (randomize_range(mm->brk, range_end, 0) ? : mm->brk);
}

View File

@ -1,5 +1,5 @@
--- linux-2.6.34.noarch/drivers/acpi/acpica/acconfig.h~ 2010-07-01 14:49:03.000000000 -0400
+++ linux-2.6.34.noarch/drivers/acpi/acpica/acconfig.h 2010-07-01 14:49:17.000000000 -0400
--- linux-2.6.34.noarch/include/acpi/acconfig.h~ 2010-07-01 14:49:03.000000000 -0400
+++ linux-2.6.34.noarch/include/acpi/acconfig.h 2010-07-01 14:49:17.000000000 -0400
@@ -117,7 +117,7 @@
/* Maximum number of While() loop iterations before forced abort */

View File

@ -1,12 +0,0 @@
diff -up linux-2.6.30.noarch/drivers/pci/pcie/aspm.c.mjg linux-2.6.30.noarch/drivers/pci/pcie/aspm.c
--- linux-2.6.30.noarch/drivers/pci/pcie/aspm.c.mjg 2009-07-16 22:01:11.000000000 +0100
+++ linux-2.6.30.noarch/drivers/pci/pcie/aspm.c 2009-07-16 22:01:30.000000000 +0100
@@ -65,7 +65,7 @@ static LIST_HEAD(link_list);
#define POLICY_DEFAULT 0 /* BIOS default setting */
#define POLICY_PERFORMANCE 1 /* high performance */
#define POLICY_POWERSAVE 2 /* high power saving */
-static int aspm_policy;
+static int aspm_policy = POLICY_POWERSAVE;
static const char *policy_str[] = {
[POLICY_DEFAULT] = "default",
[POLICY_PERFORMANCE] = "performance",

View File

@ -333,9 +333,9 @@ index 4d42300..4cb14a1 100644
+#endif /*CONFIG_X86_32*/
+
tsk->thread.error_code = error_code;
tsk->thread.trap_no = 13;
tsk->thread.trap_nr = X86_TRAP_GP;
@@ -650,19 +745,37 @@ do_device_not_available(struct pt_regs *regs, long error_code)
@@ -650,20 +745,37 @@ do_device_not_available(struct pt_regs *regs, long error_code)
}
#ifdef CONFIG_X86_32
@ -362,10 +362,11 @@ index 4d42300..4cb14a1 100644
- info.si_errno = 0;
- info.si_code = ILL_BADSTK;
- info.si_addr = NULL;
- if (notify_die(DIE_TRAP, "iret exception",
- regs, error_code, 32, SIGILL) == NOTIFY_STOP)
- if (notify_die(DIE_TRAP, "iret exception", regs, error_code,
- X86_TRAP_IRET, SIGILL) == NOTIFY_STOP)
- return;
- do_trap(32, SIGILL, "iret exception", regs, error_code, &info);
- do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code,
- &info);
+ cpu = get_cpu();
+ ok = check_lazy_exec_limit(cpu, regs, error_code);
+ put_cpu();
@ -476,10 +477,10 @@ index 12eb07b..c48ed49 100644
.load_idt = xen_load_idt,
.load_tls = xen_load_tls,
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index bcb884e..94e82fa 100644
index 81878b7..2536ec3 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -711,6 +711,15 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
@@ -711,6 +711,16 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
if (retval)
goto out_free_dentry;
@ -491,10 +492,11 @@ index bcb884e..94e82fa 100644
+ if (disable_nx || executable_stack != EXSTACK_DISABLE_X || (__supported_pte_mask & _PAGE_NX))
+ arch_add_exec_range(current->mm, -1);
+#endif
+
+
/* OK, This is the point of no return */
current->flags &= ~PF_FORKNOEXEC;
current->mm->def_flags = def_flags;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 7d379a6..90ccb05 100644
--- a/include/linux/sched.h
@ -576,10 +578,10 @@ index 3f758c7..0e29e1b 100644
err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
/* Success. */
@@ -2243,6 +2265,7 @@ void exit_mmap(struct mm_struct *mm)
@@ -2266,6 +2266,7 @@ void exit_mmap(struct mm_struct *mm)
free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
tlb_finish_mmu(&tlb, 0, end);
tlb_finish_mmu(&tlb, 0, -1);
+ arch_flush_exec_range(mm);
/*

View File

@ -1,110 +0,0 @@
diff -up linux-3.1.x86_64/Documentation/networking/dns_resolver.txt.orig linux-3.1.x86_64/Documentation/networking/dns_resolver.txt
--- linux-3.1.x86_64/Documentation/networking/dns_resolver.txt.orig 2011-10-24 03:10:05.000000000 -0400
+++ linux-3.1.x86_64/Documentation/networking/dns_resolver.txt 2011-12-13 15:09:35.705766078 -0500
@@ -102,6 +102,10 @@ implemented in the module can be called
If _expiry is non-NULL, the expiry time (TTL) of the result will be
returned also.
+The kernel maintains an internal keyring in which it caches looked up keys.
+This can be cleared by any process that has the CAP_SYS_ADMIN capability by
+the use of KEYCTL_KEYRING_CLEAR on the keyring ID.
+
===============================
READING DNS KEYS FROM USERSPACE
diff -up linux-3.1.x86_64/Documentation/security/keys.txt.orig linux-3.1.x86_64/Documentation/security/keys.txt
--- linux-3.1.x86_64/Documentation/security/keys.txt.orig 2011-10-24 03:10:05.000000000 -0400
+++ linux-3.1.x86_64/Documentation/security/keys.txt 2011-12-13 15:09:35.706766099 -0500
@@ -554,6 +554,10 @@ The keyctl syscall functions are:
process must have write permission on the keyring, and it must be a
keyring (or else error ENOTDIR will result).
+ This function can also be used to clear special kernel keyrings if they
+ are appropriately marked if the user has CAP_SYS_ADMIN capability. The
+ DNS resolver cache keyring is an example of this.
+
(*) Link a key into a keyring:
diff -up linux-3.1.x86_64/fs/cifs/cifsacl.c.orig linux-3.1.x86_64/fs/cifs/cifsacl.c
--- linux-3.1.x86_64/fs/cifs/cifsacl.c.orig 2011-12-13 12:54:12.221145867 -0500
+++ linux-3.1.x86_64/fs/cifs/cifsacl.c 2011-12-13 15:09:35.707766122 -0500
@@ -556,6 +556,7 @@ init_cifs_idmap(void)
/* instruct request_key() to use this special keyring as a cache for
* the results it looks up */
+ set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
cred->thread_keyring = keyring;
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
root_cred = cred;
diff -up linux-3.1.x86_64/fs/nfs/idmap.c.orig linux-3.1.x86_64/fs/nfs/idmap.c
--- linux-3.1.x86_64/fs/nfs/idmap.c.orig 2011-12-13 12:54:14.657203507 -0500
+++ linux-3.1.x86_64/fs/nfs/idmap.c 2011-12-13 15:10:14.731681691 -0500
@@ -115,6 +115,7 @@ int nfs_idmap_init(void)
if (ret < 0)
goto failed_put_key;
+ set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
cred->thread_keyring = keyring;
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
id_resolver_cache = cred;
@@ -185,7 +186,7 @@ static ssize_t nfs_idmap_request_key(con
}
rcu_read_lock();
- rkey->perm |= KEY_USR_VIEW;
+ rkey->perm |= KEY_USR_VIEW|KEY_USR_WRITE;
ret = key_validate(rkey);
if (ret < 0)
diff -up linux-3.1.x86_64/include/linux/key.h.orig linux-3.1.x86_64/include/linux/key.h
--- linux-3.1.x86_64/include/linux/key.h.orig 2011-10-24 03:10:05.000000000 -0400
+++ linux-3.1.x86_64/include/linux/key.h 2011-12-13 15:09:35.748767078 -0500
@@ -155,6 +155,7 @@ struct key {
#define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */
#define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */
#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */
+#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
/* the description string
* - this is used to match a key against search criteria
diff -up linux-3.1.x86_64/net/dns_resolver/dns_key.c.orig linux-3.1.x86_64/net/dns_resolver/dns_key.c
--- linux-3.1.x86_64/net/dns_resolver/dns_key.c.orig 2011-10-24 03:10:05.000000000 -0400
+++ linux-3.1.x86_64/net/dns_resolver/dns_key.c 2011-12-13 15:09:35.748767078 -0500
@@ -281,6 +281,7 @@ static int __init init_dns_resolver(void
/* instruct request_key() to use this special keyring as a cache for
* the results it looks up */
+ set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
cred->thread_keyring = keyring;
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
dns_resolver_cache = cred;
diff -up linux-3.1.x86_64/security/keys/keyctl.c.orig linux-3.1.x86_64/security/keys/keyctl.c
--- linux-3.1.x86_64/security/keys/keyctl.c.orig 2011-12-13 12:54:30.322571289 -0500
+++ linux-3.1.x86_64/security/keys/keyctl.c 2011-12-13 15:09:35.756767271 -0500
@@ -388,11 +388,24 @@ long keyctl_keyring_clear(key_serial_t r
keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
if (IS_ERR(keyring_ref)) {
ret = PTR_ERR(keyring_ref);
+
+ /* Root is permitted to invalidate certain special keyrings */
+ if (capable(CAP_SYS_ADMIN)) {
+ keyring_ref = lookup_user_key(ringid, 0, 0);
+ if (IS_ERR(keyring_ref))
+ goto error;
+ if (test_bit(KEY_FLAG_ROOT_CAN_CLEAR,
+ &key_ref_to_ptr(keyring_ref)->flags))
+ goto clear;
+ goto error_put;
+ }
+
goto error;
}
+clear:
ret = keyring_clear(key_ref_to_ptr(keyring_ref));
-
+error_put:
key_ref_put(keyring_ref);
error:
return ret;

View File

@ -1,993 +0,0 @@
From 43cf1b6a4ee31e69581042a0c85d1398f83dcedc Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 20 Jan 2012 17:27:20 +0100
Cc: <linux-scsi@vger.kernel.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: kvm@vger.kernel.org
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>, Mike Christie <michaelc@cs.wisc.edu>
Subject: [PATCH v5 0/3] virtio-scsi driver
This is the first implementation of the virtio-scsi driver, a virtual
HBA that will be supported by KVM. It implements a subset of the spec,
in particular it does not implement asynchronous notifications for either
LUN reset/removal/addition or CD-ROM media events, but it is already
functional and usable.
Other matching bits:
- spec at http://people.redhat.com/pbonzini/virtio-spec.pdf
- QEMU implementation at git://github.com/bonzini/qemu.git,
branch virtio-scsi
Please review. Getting this in 3.3 is starting to look like wishful thinking,
but the possibility of regressions is obviously zero so I'm still dreaming.
Otherwise, that would be 3.4.
Paolo Bonzini (3):
virtio-scsi: first version
virtio-scsi: add error handling
virtio-scsi: add power management support
v4->v5: change virtio id from 7 to 8
v3->v4: renamed VIRTIO_SCSI_S_UNDERRUN to VIRTIO_SCSI_S_OVERRUN;
fixed 32-bit compilation; added power management support;
adjusted calls to virtqueue_add_buf
drivers/scsi/Kconfig | 8 +
drivers/scsi/Makefile | 1 +
drivers/scsi/virtio_scsi.c | 594 +++++++++++++++++++++++++++++++++++++++++++
include/linux/virtio_ids.h | 1 +
include/linux/virtio_scsi.h | 114 +++++++++
5 files changed, 718 insertions(+), 0 deletions(-)
create mode 100644 drivers/scsi/virtio_scsi.c
create mode 100644 include/linux/virtio_scsi.h
From 84ad93b7215e18ab1755a625ede0fb00175e79bb Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 29 Nov 2011 16:31:09 +0100
Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>, Mike Christie <michaelc@cs.wisc.edu>, Pekka Enberg <penberg@kernel.org>
Subject: [PATCH v5 1/3] virtio-scsi: first version
The virtio-scsi HBA is the basis of an alternative storage stack
for QEMU-based virtual machines (including KVM). Compared to
virtio-blk it is more scalable, because it supports many LUNs
on a single PCI slot), more powerful (it more easily supports
passthrough of host devices to the guest) and more easily
extensible (new SCSI features implemented by QEMU should not
require updating the driver in the guest).
Cc: linux-scsi <linux-scsi@vger.kernel.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: kvm@vger.kernel.org
Acked-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
v4->v5: change virtio id from 7 to 8
v3->v4: renamed VIRTIO_SCSI_S_UNDERRUN to VIRTIO_SCSI_S_OVERRUN;
fixed 32-bit compilation; adjust call to virtqueue_add_buf
v2->v3: added mempool, formatting fixes
v1->v2: use dbg_dev, sdev_printk, scmd_printk
- renamed lock to vq_lock
- renamed cmd_vq to req_vq (and other similar changes)
- fixed missing break in VIRTIO_SCSI_S_OVERRUN
- added VIRTIO_SCSI_S_BUSY
- removed unused argument from virtscsi_map_cmd
- fixed two tabs that had slipped in
- moved max_sectors and cmd_per_lun from template to config space
- __attribute__((packed)) -> __packed
drivers/scsi/Kconfig | 8 +
drivers/scsi/Makefile | 1 +
drivers/scsi/virtio_scsi.c | 503 +++++++++++++++++++++++++++++++++++++++++++
include/linux/virtio_ids.h | 1 +
include/linux/virtio_scsi.h | 114 ++++++++++
5 files changed, 627 insertions(+), 0 deletions(-)
create mode 100644 drivers/scsi/virtio_scsi.c
create mode 100644 include/linux/virtio_scsi.h
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 16570aa..827ebaf 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1897,6 +1897,14 @@ config SCSI_BFA_FC
To compile this driver as a module, choose M here. The module will
be called bfa.
+config SCSI_VIRTIO
+ tristate "virtio-scsi support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && VIRTIO
+ help
+ This is the virtual HBA driver for virtio. If the kernel will
+ be used in a virtual machine, say Y or M.
+
+
endif # SCSI_LOWLEVEL
source "drivers/scsi/pcmcia/Kconfig"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 2b88749..351b28b 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -141,6 +141,7 @@ obj-$(CONFIG_SCSI_CXGB4_ISCSI) += libiscsi.o libiscsi_tcp.o cxgbi/
obj-$(CONFIG_SCSI_BNX2_ISCSI) += libiscsi.o bnx2i/
obj-$(CONFIG_BE2ISCSI) += libiscsi.o be2iscsi/
obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o
+obj-$(CONFIG_SCSI_VIRTIO) += virtio_scsi.o
obj-$(CONFIG_VMWARE_PVSCSI) += vmw_pvscsi.o
obj-$(CONFIG_ARM) += arm/
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
new file mode 100644
index 0000000..3f87ae0
--- /dev/null
+++ b/drivers/scsi/virtio_scsi.c
@@ -0,0 +1,503 @@
+/*
+ * Virtio SCSI HBA driver
+ *
+ * Copyright IBM Corp. 2010
+ * Copyright Red Hat, Inc. 2011
+ *
+ * Authors:
+ * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+ * Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+
+#define VIRTIO_SCSI_MEMPOOL_SZ 64
+
+/* Command queue element */
+struct virtio_scsi_cmd {
+ struct scsi_cmnd *sc;
+ union {
+ struct virtio_scsi_cmd_req cmd;
+ struct virtio_scsi_ctrl_tmf_req tmf;
+ struct virtio_scsi_ctrl_an_req an;
+ } req;
+ union {
+ struct virtio_scsi_cmd_resp cmd;
+ struct virtio_scsi_ctrl_tmf_resp tmf;
+ struct virtio_scsi_ctrl_an_resp an;
+ struct virtio_scsi_event evt;
+ } resp;
+} ____cacheline_aligned_in_smp;
+
+/* Driver instance state */
+struct virtio_scsi {
+ /* Protects ctrl_vq, req_vq and sg[] */
+ spinlock_t vq_lock;
+
+ struct virtio_device *vdev;
+ struct virtqueue *ctrl_vq;
+ struct virtqueue *event_vq;
+ struct virtqueue *req_vq;
+
+ /* For sglist construction when adding commands to the virtqueue. */
+ struct scatterlist sg[];
+};
+
+static struct kmem_cache *virtscsi_cmd_cache;
+static mempool_t *virtscsi_cmd_pool;
+
+static inline struct Scsi_Host *virtio_scsi_host(struct virtio_device *vdev)
+{
+ return vdev->priv;
+}
+
+static void virtscsi_compute_resid(struct scsi_cmnd *sc, u32 resid)
+{
+ if (!resid)
+ return;
+
+ if (!scsi_bidi_cmnd(sc)) {
+ scsi_set_resid(sc, resid);
+ return;
+ }
+
+ scsi_in(sc)->resid = min(resid, scsi_in(sc)->length);
+ scsi_out(sc)->resid = resid - scsi_in(sc)->resid;
+}
+
+/**
+ * virtscsi_complete_cmd - finish a scsi_cmd and invoke scsi_done
+ *
+ * Called with vq_lock held.
+ */
+static void virtscsi_complete_cmd(void *buf)
+{
+ struct virtio_scsi_cmd *cmd = buf;
+ struct scsi_cmnd *sc = cmd->sc;
+ struct virtio_scsi_cmd_resp *resp = &cmd->resp.cmd;
+
+ dev_dbg(&sc->device->sdev_gendev,
+ "cmd %p response %u status %#02x sense_len %u\n",
+ sc, resp->response, resp->status, resp->sense_len);
+
+ sc->result = resp->status;
+ virtscsi_compute_resid(sc, resp->resid);
+ switch (resp->response) {
+ case VIRTIO_SCSI_S_OK:
+ set_host_byte(sc, DID_OK);
+ break;
+ case VIRTIO_SCSI_S_OVERRUN:
+ set_host_byte(sc, DID_ERROR);
+ break;
+ case VIRTIO_SCSI_S_ABORTED:
+ set_host_byte(sc, DID_ABORT);
+ break;
+ case VIRTIO_SCSI_S_BAD_TARGET:
+ set_host_byte(sc, DID_BAD_TARGET);
+ break;
+ case VIRTIO_SCSI_S_RESET:
+ set_host_byte(sc, DID_RESET);
+ break;
+ case VIRTIO_SCSI_S_BUSY:
+ set_host_byte(sc, DID_BUS_BUSY);
+ break;
+ case VIRTIO_SCSI_S_TRANSPORT_FAILURE:
+ set_host_byte(sc, DID_TRANSPORT_DISRUPTED);
+ break;
+ case VIRTIO_SCSI_S_TARGET_FAILURE:
+ set_host_byte(sc, DID_TARGET_FAILURE);
+ break;
+ case VIRTIO_SCSI_S_NEXUS_FAILURE:
+ set_host_byte(sc, DID_NEXUS_FAILURE);
+ break;
+ default:
+ scmd_printk(KERN_WARNING, sc, "Unknown response %d",
+ resp->response);
+ /* fall through */
+ case VIRTIO_SCSI_S_FAILURE:
+ set_host_byte(sc, DID_ERROR);
+ break;
+ }
+
+ WARN_ON(resp->sense_len > VIRTIO_SCSI_SENSE_SIZE);
+ if (sc->sense_buffer) {
+ memcpy(sc->sense_buffer, resp->sense,
+ min_t(u32, resp->sense_len, VIRTIO_SCSI_SENSE_SIZE));
+ if (resp->sense_len)
+ set_driver_byte(sc, DRIVER_SENSE);
+ }
+
+ mempool_free(cmd, virtscsi_cmd_pool);
+ sc->scsi_done(sc);
+}
+
+static void virtscsi_vq_done(struct virtqueue *vq, void (*fn)(void *buf))
+{
+ struct Scsi_Host *sh = virtio_scsi_host(vq->vdev);
+ struct virtio_scsi *vscsi = shost_priv(sh);
+ void *buf;
+ unsigned long flags;
+ unsigned int len;
+
+ spin_lock_irqsave(&vscsi->vq_lock, flags);
+
+ do {
+ virtqueue_disable_cb(vq);
+ while ((buf = virtqueue_get_buf(vq, &len)) != NULL)
+ fn(buf);
+ } while (!virtqueue_enable_cb(vq));
+
+ spin_unlock_irqrestore(&vscsi->vq_lock, flags);
+}
+
+static void virtscsi_req_done(struct virtqueue *vq)
+{
+ virtscsi_vq_done(vq, virtscsi_complete_cmd);
+};
+
+/* These are still stubs. */
+static void virtscsi_complete_free(void *buf)
+{
+ struct virtio_scsi_cmd *cmd = buf;
+
+ mempool_free(cmd, virtscsi_cmd_pool);
+}
+
+static void virtscsi_ctrl_done(struct virtqueue *vq)
+{
+ virtscsi_vq_done(vq, virtscsi_complete_free);
+};
+
+static void virtscsi_event_done(struct virtqueue *vq)
+{
+ virtscsi_vq_done(vq, virtscsi_complete_free);
+};
+
+static void virtscsi_map_sgl(struct scatterlist *sg, unsigned int *p_idx,
+ struct scsi_data_buffer *sdb)
+{
+ struct sg_table *table = &sdb->table;
+ struct scatterlist *sg_elem;
+ unsigned int idx = *p_idx;
+ int i;
+
+ for_each_sg(table->sgl, sg_elem, table->nents, i)
+ sg_set_buf(&sg[idx++], sg_virt(sg_elem), sg_elem->length);
+
+ *p_idx = idx;
+}
+
+/**
+ * virtscsi_map_cmd - map a scsi_cmd to a virtqueue scatterlist
+ * @vscsi : virtio_scsi state
+ * @cmd : command structure
+ * @out_num : number of read-only elements
+ * @in_num : number of write-only elements
+ * @req_size : size of the request buffer
+ * @resp_size : size of the response buffer
+ *
+ * Called with vq_lock held.
+ */
+static void virtscsi_map_cmd(struct virtio_scsi *vscsi,
+ struct virtio_scsi_cmd *cmd,
+ unsigned *out_num, unsigned *in_num,
+ size_t req_size, size_t resp_size)
+{
+ struct scsi_cmnd *sc = cmd->sc;
+ struct scatterlist *sg = vscsi->sg;
+ unsigned int idx = 0;
+
+ if (sc) {
+ struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev);
+ BUG_ON(scsi_sg_count(sc) > shost->sg_tablesize);
+
+ /* TODO: check feature bit and fail if unsupported? */
+ BUG_ON(sc->sc_data_direction == DMA_BIDIRECTIONAL);
+ }
+
+ /* Request header. */
+ sg_set_buf(&sg[idx++], &cmd->req, req_size);
+
+ /* Data-out buffer. */
+ if (sc && sc->sc_data_direction != DMA_FROM_DEVICE)
+ virtscsi_map_sgl(sg, &idx, scsi_out(sc));
+
+ *out_num = idx;
+
+ /* Response header. */
+ sg_set_buf(&sg[idx++], &cmd->resp, resp_size);
+
+ /* Data-in buffer */
+ if (sc && sc->sc_data_direction != DMA_TO_DEVICE)
+ virtscsi_map_sgl(sg, &idx, scsi_in(sc));
+
+ *in_num = idx - *out_num;
+}
+
+static int virtscsi_kick_cmd(struct virtio_scsi *vscsi, struct virtqueue *vq,
+ struct virtio_scsi_cmd *cmd,
+ size_t req_size, size_t resp_size, gfp_t gfp)
+{
+ unsigned int out_num, in_num;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&vscsi->vq_lock, flags);
+
+ virtscsi_map_cmd(vscsi, cmd, &out_num, &in_num, req_size, resp_size);
+
+ ret = virtqueue_add_buf(vq, vscsi->sg, out_num, in_num, cmd, gfp);
+ if (ret >= 0)
+ virtqueue_kick(vq);
+
+ spin_unlock_irqrestore(&vscsi->vq_lock, flags);
+ return ret;
+}
+
+static int virtscsi_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
+{
+ struct virtio_scsi *vscsi = shost_priv(sh);
+ struct virtio_scsi_cmd *cmd;
+ int ret;
+
+ dev_dbg(&sc->device->sdev_gendev,
+ "cmd %p CDB: %#02x\n", sc, sc->cmnd[0]);
+
+ ret = SCSI_MLQUEUE_HOST_BUSY;
+ cmd = mempool_alloc(virtscsi_cmd_pool, GFP_ATOMIC);
+ if (!cmd)
+ goto out;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->sc = sc;
+ cmd->req.cmd = (struct virtio_scsi_cmd_req){
+ .lun[0] = 1,
+ .lun[1] = sc->device->id,
+ .lun[2] = (sc->device->lun >> 8) | 0x40,
+ .lun[3] = sc->device->lun & 0xff,
+ .tag = (unsigned long)sc,
+ .task_attr = VIRTIO_SCSI_S_SIMPLE,
+ .prio = 0,
+ .crn = 0,
+ };
+
+ BUG_ON(sc->cmd_len > VIRTIO_SCSI_CDB_SIZE);
+ memcpy(cmd->req.cmd.cdb, sc->cmnd, sc->cmd_len);
+
+ if (virtscsi_kick_cmd(vscsi, vscsi->req_vq, cmd,
+ sizeof cmd->req.cmd, sizeof cmd->resp.cmd,
+ GFP_ATOMIC) >= 0)
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static struct scsi_host_template virtscsi_host_template = {
+ .module = THIS_MODULE,
+ .name = "Virtio SCSI HBA",
+ .proc_name = "virtio_scsi",
+ .queuecommand = virtscsi_queuecommand,
+ .this_id = -1,
+
+ .can_queue = 1024,
+ .dma_boundary = UINT_MAX,
+ .use_clustering = ENABLE_CLUSTERING,
+};
+
+#define virtscsi_config_get(vdev, fld) \
+ ({ \
+ typeof(((struct virtio_scsi_config *)0)->fld) __val; \
+ vdev->config->get(vdev, \
+ offsetof(struct virtio_scsi_config, fld), \
+ &__val, sizeof(__val)); \
+ __val; \
+ })
+
+#define virtscsi_config_set(vdev, fld, val) \
+ (void)({ \
+ typeof(((struct virtio_scsi_config *)0)->fld) __val = (val); \
+ vdev->config->set(vdev, \
+ offsetof(struct virtio_scsi_config, fld), \
+ &__val, sizeof(__val)); \
+ })
+
+static int __devinit virtscsi_init(struct virtio_device *vdev,
+ struct virtio_scsi *vscsi)
+{
+ int err;
+ struct virtqueue *vqs[3];
+ vq_callback_t *callbacks[] = {
+ virtscsi_ctrl_done,
+ virtscsi_event_done,
+ virtscsi_req_done
+ };
+ const char *names[] = {
+ "control",
+ "event",
+ "request"
+ };
+
+ /* Discover virtqueues and write information to configuration. */
+ err = vdev->config->find_vqs(vdev, 3, vqs, callbacks, names);
+ if (err)
+ return err;
+
+ vscsi->ctrl_vq = vqs[0];
+ vscsi->event_vq = vqs[1];
+ vscsi->req_vq = vqs[2];
+
+ virtscsi_config_set(vdev, cdb_size, VIRTIO_SCSI_CDB_SIZE);
+ virtscsi_config_set(vdev, sense_size, VIRTIO_SCSI_SENSE_SIZE);
+ return 0;
+}
+
+static int __devinit virtscsi_probe(struct virtio_device *vdev)
+{
+ struct Scsi_Host *shost;
+ struct virtio_scsi *vscsi;
+ int err;
+ u32 sg_elems;
+ u32 cmd_per_lun;
+
+ /* We need to know how many segments before we allocate.
+ * We need an extra sg elements at head and tail.
+ */
+ sg_elems = virtscsi_config_get(vdev, seg_max) ?: 1;
+
+ /* Allocate memory and link the structs together. */
+ shost = scsi_host_alloc(&virtscsi_host_template,
+ sizeof(*vscsi) + sizeof(vscsi->sg[0]) * (sg_elems + 2));
+
+ if (!shost)
+ return -ENOMEM;
+
+ shost->sg_tablesize = sg_elems;
+ vscsi = shost_priv(shost);
+ vscsi->vdev = vdev;
+ vdev->priv = shost;
+
+ /* Random initializations. */
+ spin_lock_init(&vscsi->vq_lock);
+ sg_init_table(vscsi->sg, sg_elems + 2);
+
+ err = virtscsi_init(vdev, vscsi);
+ if (err)
+ goto virtscsi_init_failed;
+
+ cmd_per_lun = virtscsi_config_get(vdev, cmd_per_lun) ?: 1;
+ shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue);
+ shost->max_sectors = virtscsi_config_get(vdev, max_sectors) ?: 0xFFFF;
+ shost->max_lun = virtscsi_config_get(vdev, max_lun) + 1;
+ shost->max_id = virtscsi_config_get(vdev, max_target) + 1;
+ shost->max_channel = 0;
+ shost->max_cmd_len = VIRTIO_SCSI_CDB_SIZE;
+ err = scsi_add_host(shost, &vdev->dev);
+ if (err)
+ goto scsi_add_host_failed;
+
+ scsi_scan_host(shost);
+
+ return 0;
+
+scsi_add_host_failed:
+ vdev->config->del_vqs(vdev);
+virtscsi_init_failed:
+ scsi_host_put(shost);
+ return err;
+}
+
+static void __devexit virtscsi_remove_vqs(struct virtio_device *vdev)
+{
+ /* Stop all the virtqueues. */
+ vdev->config->reset(vdev);
+
+ vdev->config->del_vqs(vdev);
+}
+
+static void __devexit virtscsi_remove(struct virtio_device *vdev)
+{
+ struct Scsi_Host *shost = virtio_scsi_host(vdev);
+
+ scsi_remove_host(shost);
+
+ virtscsi_remove_vqs(vdev);
+ scsi_host_put(shost);
+}
+
+static struct virtio_device_id id_table[] = {
+ { VIRTIO_ID_SCSI, VIRTIO_DEV_ANY_ID },
+ { 0 },
+};
+
+static struct virtio_driver virtio_scsi_driver = {
+ .driver.name = KBUILD_MODNAME,
+ .driver.owner = THIS_MODULE,
+ .id_table = id_table,
+ .probe = virtscsi_probe,
+ .remove = __devexit_p(virtscsi_remove),
+};
+
+static int __init init(void)
+{
+ int ret = -ENOMEM;
+
+ virtscsi_cmd_cache = KMEM_CACHE(virtio_scsi_cmd, 0);
+ if (!virtscsi_cmd_cache) {
+ printk(KERN_ERR "kmem_cache_create() for "
+ "virtscsi_cmd_cache failed\n");
+ goto error;
+ }
+
+
+ virtscsi_cmd_pool =
+ mempool_create_slab_pool(VIRTIO_SCSI_MEMPOOL_SZ,
+ virtscsi_cmd_cache);
+ if (!virtscsi_cmd_pool) {
+ printk(KERN_ERR "mempool_create() for"
+ "virtscsi_cmd_pool failed\n");
+ goto error;
+ }
+ ret = register_virtio_driver(&virtio_scsi_driver);
+ if (ret < 0)
+ goto error;
+
+ return 0;
+
+error:
+ if (virtscsi_cmd_pool) {
+ mempool_destroy(virtscsi_cmd_pool);
+ virtscsi_cmd_pool = NULL;
+ }
+ if (virtscsi_cmd_cache) {
+ kmem_cache_destroy(virtscsi_cmd_cache);
+ virtscsi_cmd_cache = NULL;
+ }
+ return ret;
+}
+
+static void __exit fini(void)
+{
+ unregister_virtio_driver(&virtio_scsi_driver);
+ mempool_destroy(virtscsi_cmd_pool);
+ kmem_cache_destroy(virtscsi_cmd_cache);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio SCSI HBA driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/virtio_ids.h b/include/linux/virtio_ids.h
index 85bb0bb..d83ae52 100644
--- a/include/linux/virtio_ids.h
+++ b/include/linux/virtio_ids.h
@@ -34,6 +34,7 @@
#define VIRTIO_ID_CONSOLE 3 /* virtio console */
#define VIRTIO_ID_RNG 4 /* virtio ring */
#define VIRTIO_ID_BALLOON 5 /* virtio balloon */
+#define VIRTIO_ID_SCSI 8 /* virtio scsi */
#define VIRTIO_ID_9P 9 /* 9p virtio console */
#endif /* _LINUX_VIRTIO_IDS_H */
diff --git a/include/linux/virtio_scsi.h b/include/linux/virtio_scsi.h
new file mode 100644
index 0000000..8ddeafd
--- /dev/null
+++ b/include/linux/virtio_scsi.h
@@ -0,0 +1,114 @@
+#ifndef _LINUX_VIRTIO_SCSI_H
+#define _LINUX_VIRTIO_SCSI_H
+/* This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers. */
+
+#define VIRTIO_SCSI_CDB_SIZE 32
+#define VIRTIO_SCSI_SENSE_SIZE 96
+
+/* SCSI command request, followed by data-out */
+struct virtio_scsi_cmd_req {
+ u8 lun[8]; /* Logical Unit Number */
+ u64 tag; /* Command identifier */
+ u8 task_attr; /* Task attribute */
+ u8 prio;
+ u8 crn;
+ u8 cdb[VIRTIO_SCSI_CDB_SIZE];
+} __packed;
+
+/* Response, followed by sense data and data-in */
+struct virtio_scsi_cmd_resp {
+ u32 sense_len; /* Sense data length */
+ u32 resid; /* Residual bytes in data buffer */
+ u16 status_qualifier; /* Status qualifier */
+ u8 status; /* Command completion status */
+ u8 response; /* Response values */
+ u8 sense[VIRTIO_SCSI_SENSE_SIZE];
+} __packed;
+
+/* Task Management Request */
+struct virtio_scsi_ctrl_tmf_req {
+ u32 type;
+ u32 subtype;
+ u8 lun[8];
+ u64 tag;
+} __packed;
+
+struct virtio_scsi_ctrl_tmf_resp {
+ u8 response;
+} __packed;
+
+/* Asynchronous notification query/subscription */
+struct virtio_scsi_ctrl_an_req {
+ u32 type;
+ u8 lun[8];
+ u32 event_requested;
+} __packed;
+
+struct virtio_scsi_ctrl_an_resp {
+ u32 event_actual;
+ u8 response;
+} __packed;
+
+struct virtio_scsi_event {
+ u32 event;
+ u8 lun[8];
+ u32 reason;
+} __packed;
+
+struct virtio_scsi_config {
+ u32 num_queues;
+ u32 seg_max;
+ u32 max_sectors;
+ u32 cmd_per_lun;
+ u32 event_info_size;
+ u32 sense_size;
+ u32 cdb_size;
+ u16 max_channel;
+ u16 max_target;
+ u32 max_lun;
+} __packed;
+
+/* Response codes */
+#define VIRTIO_SCSI_S_OK 0
+#define VIRTIO_SCSI_S_OVERRUN 1
+#define VIRTIO_SCSI_S_ABORTED 2
+#define VIRTIO_SCSI_S_BAD_TARGET 3
+#define VIRTIO_SCSI_S_RESET 4
+#define VIRTIO_SCSI_S_BUSY 5
+#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6
+#define VIRTIO_SCSI_S_TARGET_FAILURE 7
+#define VIRTIO_SCSI_S_NEXUS_FAILURE 8
+#define VIRTIO_SCSI_S_FAILURE 9
+#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10
+#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11
+#define VIRTIO_SCSI_S_INCORRECT_LUN 12
+
+/* Controlq type codes. */
+#define VIRTIO_SCSI_T_TMF 0
+#define VIRTIO_SCSI_T_AN_QUERY 1
+#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2
+
+/* Valid TMF subtypes. */
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1
+#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2
+#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3
+#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4
+#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7
+
+/* Events. */
+#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000
+#define VIRTIO_SCSI_T_NO_EVENT 0
+#define VIRTIO_SCSI_T_TRANSPORT_RESET 1
+#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2
+
+#define VIRTIO_SCSI_S_SIMPLE 0
+#define VIRTIO_SCSI_S_ORDERED 1
+#define VIRTIO_SCSI_S_HEAD 2
+#define VIRTIO_SCSI_S_ACA 3
+
+
+#endif /* _LINUX_VIRTIO_SCSI_H */
--
1.7.1
From 3c0e8846ac0fc2175dd0e06f495b16a30b549762 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 29 Nov 2011 16:33:28 +0100
Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>, Mike Christie <michaelc@cs.wisc.edu>, Pekka Enberg <penberg@kernel.org>
Subject: [PATCH v5 2/3] virtio-scsi: add error handling
This commit adds basic error handling to the virtio-scsi
HBA device. Task management functions are sent synchronously
via the control virtqueue.
Cc: linux-scsi <linux-scsi@vger.kernel.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: kvm@vger.kernel.org
Acked-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
v3->v4: fixed 32-bit compilation; adjusted call to virtscsi_kick_cmd
v2->v3: added mempool, used GFP_NOIO instead of GFP_ATOMIC,
formatting fixes
v1->v2: use scmd_printk
drivers/scsi/virtio_scsi.c | 73 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 72 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 3f87ae0..68104cd 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -29,6 +29,7 @@
/* Command queue element */
struct virtio_scsi_cmd {
struct scsi_cmnd *sc;
+ struct completion *comp;
union {
struct virtio_scsi_cmd_req cmd;
struct virtio_scsi_ctrl_tmf_req tmf;
@@ -168,11 +169,12 @@ static void virtscsi_req_done(struct virtqueue *vq)
virtscsi_vq_done(vq, virtscsi_complete_cmd);
};
-/* These are still stubs. */
static void virtscsi_complete_free(void *buf)
{
struct virtio_scsi_cmd *cmd = buf;
+ if (cmd->comp)
+ complete_all(cmd->comp);
mempool_free(cmd, virtscsi_cmd_pool);
}
@@ -306,12 +308,81 @@ out:
return ret;
}
+static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
+{
+ DECLARE_COMPLETION_ONSTACK(comp);
+ int ret;
+
+ cmd->comp = &comp;
+ ret = virtscsi_kick_cmd(vscsi, vscsi->ctrl_vq, cmd,
+ sizeof cmd->req.tmf, sizeof cmd->resp.tmf,
+ GFP_NOIO);
+ if (ret < 0)
+ return FAILED;
+
+ wait_for_completion(&comp);
+ if (cmd->resp.tmf.response != VIRTIO_SCSI_S_OK &&
+ cmd->resp.tmf.response != VIRTIO_SCSI_S_FUNCTION_SUCCEEDED)
+ return FAILED;
+
+ return SUCCESS;
+}
+
+static int virtscsi_device_reset(struct scsi_cmnd *sc)
+{
+ struct virtio_scsi *vscsi = shost_priv(sc->device->host);
+ struct virtio_scsi_cmd *cmd;
+
+ sdev_printk(KERN_INFO, sc->device, "device reset\n");
+ cmd = mempool_alloc(virtscsi_cmd_pool, GFP_NOIO);
+ if (!cmd)
+ return FAILED;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->sc = sc;
+ cmd->req.tmf = (struct virtio_scsi_ctrl_tmf_req){
+ .type = VIRTIO_SCSI_T_TMF,
+ .subtype = VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET,
+ .lun[0] = 1,
+ .lun[1] = sc->device->id,
+ .lun[2] = (sc->device->lun >> 8) | 0x40,
+ .lun[3] = sc->device->lun & 0xff,
+ };
+ return virtscsi_tmf(vscsi, cmd);
+}
+
+static int virtscsi_abort(struct scsi_cmnd *sc)
+{
+ struct virtio_scsi *vscsi = shost_priv(sc->device->host);
+ struct virtio_scsi_cmd *cmd;
+
+ scmd_printk(KERN_INFO, sc, "abort\n");
+ cmd = mempool_alloc(virtscsi_cmd_pool, GFP_NOIO);
+ if (!cmd)
+ return FAILED;
+
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->sc = sc;
+ cmd->req.tmf = (struct virtio_scsi_ctrl_tmf_req){
+ .type = VIRTIO_SCSI_T_TMF,
+ .subtype = VIRTIO_SCSI_T_TMF_ABORT_TASK,
+ .lun[0] = 1,
+ .lun[1] = sc->device->id,
+ .lun[2] = (sc->device->lun >> 8) | 0x40,
+ .lun[3] = sc->device->lun & 0xff,
+ .tag = (unsigned long)sc,
+ };
+ return virtscsi_tmf(vscsi, cmd);
+}
+
static struct scsi_host_template virtscsi_host_template = {
.module = THIS_MODULE,
.name = "Virtio SCSI HBA",
.proc_name = "virtio_scsi",
.queuecommand = virtscsi_queuecommand,
.this_id = -1,
+ .eh_abort_handler = virtscsi_abort,
+ .eh_device_reset_handler = virtscsi_device_reset,
.can_queue = 1024,
.dma_boundary = UINT_MAX,
--
1.7.1
From 43cf1b6a4ee31e69581042a0c85d1398f83dcedc Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 13 Jan 2012 15:30:08 +0100
Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>, Mike Christie <michaelc@cs.wisc.edu>, Pekka Enberg <penberg@kernel.org>
Subject: [PATCH v5 3/3] virtio-scsi: add power management support
This patch adds freeze/restore handlers for the HBA. Block queues
are managed independently by the disk devices.
Cc: linux-scsi <linux-scsi@vger.kernel.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: kvm@vger.kernel.org
Acked-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
The feature has been merged in the virtio core for 3.3, so the patch
is new in v4.
drivers/scsi/virtio_scsi.c | 26 +++++++++++++++++++++++---
1 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 68104cd..efccd72 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -406,8 +406,8 @@ static struct scsi_host_template virtscsi_host_template = {
&__val, sizeof(__val)); \
})
-static int __devinit virtscsi_init(struct virtio_device *vdev,
- struct virtio_scsi *vscsi)
+static int virtscsi_init(struct virtio_device *vdev,
+ struct virtio_scsi *vscsi)
{
int err;
struct virtqueue *vqs[3];
@@ -491,7 +491,7 @@ virtscsi_init_failed:
return err;
}
-static void __devexit virtscsi_remove_vqs(struct virtio_device *vdev)
+static void virtscsi_remove_vqs(struct virtio_device *vdev)
{
/* Stop all the virtqueues. */
vdev->config->reset(vdev);
@@ -509,6 +509,22 @@ static void __devexit virtscsi_remove(struct virtio_device *vdev)
scsi_host_put(shost);
}
+#ifdef CONFIG_PM
+static int virtscsi_freeze(struct virtio_device *vdev)
+{
+ virtscsi_remove_vqs(vdev);
+ return 0;
+}
+
+static int virtscsi_restore(struct virtio_device *vdev)
+{
+ struct Scsi_Host *sh = virtio_scsi_host(vdev);
+ struct virtio_scsi *vscsi = shost_priv(sh);
+
+ return virtscsi_init(vdev, vscsi);
+}
+#endif
+
static struct virtio_device_id id_table[] = {
{ VIRTIO_ID_SCSI, VIRTIO_DEV_ANY_ID },
{ 0 },
@@ -519,6 +535,10 @@ static struct virtio_driver virtio_scsi_driver = {
.driver.owner = THIS_MODULE,
.id_table = id_table,
.probe = virtscsi_probe,
+#ifdef CONFIG_PM
+ .freeze = virtscsi_freeze,
+ .restore = virtscsi_restore,
+#endif
.remove = __devexit_p(virtscsi_remove),
};
--
1.7.1

View File

@ -1,15 +0,0 @@
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index f22a9f7..f525f99 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -191,7 +191,7 @@ static void drain_mcelog_buffer(void)
{
unsigned int next, i, prev = 0;
- next = rcu_dereference_check_mce(mcelog.next);
+ next = ACCESS_ONCE(mcelog.next);
do {
struct mce *m;

View File

@ -1,301 +0,0 @@
From 917ee75a59160fe3518c1672feb4562f11a18fbc Mon Sep 17 00:00:00 2001
From: Seth Forshee <seth.forshee@canonical.com>
Date: Fri, 16 Mar 2012 14:41:22 -0500
Subject: [PATCH] platform/x86: Add driver for Apple gmux device
Apple laptops with hybrid graphics have a device named gmux that
controls the muxing of the LVDS panel between the GPUs as well as screen
brightness. This driver adds support for the gmux device. Only backlight
control is supported initially.
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Tested-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/platform/x86/Kconfig | 10 ++
drivers/platform/x86/Makefile | 1 +
drivers/platform/x86/apple-gmux.c | 244 +++++++++++++++++++++++++++++++++++++
3 files changed, 255 insertions(+), 0 deletions(-)
create mode 100644 drivers/platform/x86/apple-gmux.c
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index ce10f03..c5b4bfe 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -752,4 +752,14 @@ config SAMSUNG_Q10
This driver provides support for backlight control on Samsung Q10
and related laptops, including Dell Latitude X200.
+config APPLE_GMUX
+ tristate "Apple Gmux Driver"
+ depends on PNP
+ select BACKLIGHT_CLASS_DEVICE
+ ---help---
+ This driver provides support for the gmux device found on many
+ Apple laptops, which controls the display mux for the hybrid
+ graphics as well as the backlight. Currently only backlight
+ control is supported by the driver.
+
endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index dcfee6b..bf7e4f9 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -49,3 +49,4 @@ obj-$(CONFIG_MXM_WMI) += mxm-wmi.o
obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o
obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
+obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c
new file mode 100644
index 0000000..8a582bd
--- /dev/null
+++ b/drivers/platform/x86/apple-gmux.c
@@ -0,0 +1,244 @@
+/*
+ * Gmux driver for Apple laptops
+ *
+ * Copyright (C) Canonical Ltd. <seth.forshee@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/backlight.h>
+#include <linux/acpi.h>
+#include <linux/pnp.h>
+#include <linux/apple_bl.h>
+#include <linux/slab.h>
+#include <acpi/video.h>
+#include <asm/io.h>
+
+struct apple_gmux_data {
+ unsigned long iostart;
+ unsigned long iolen;
+
+ struct backlight_device *bdev;
+};
+
+/*
+ * gmux port offsets. Many of these are not yet used, but may be in the
+ * future, and it's useful to have them documented here anyhow.
+ */
+#define GMUX_PORT_VERSION_MAJOR 0x04
+#define GMUX_PORT_VERSION_MINOR 0x05
+#define GMUX_PORT_VERSION_RELEASE 0x06
+#define GMUX_PORT_SWITCH_DISPLAY 0x10
+#define GMUX_PORT_SWITCH_GET_DISPLAY 0x11
+#define GMUX_PORT_INTERRUPT_ENABLE 0x14
+#define GMUX_PORT_INTERRUPT_STATUS 0x16
+#define GMUX_PORT_SWITCH_DDC 0x28
+#define GMUX_PORT_SWITCH_EXTERNAL 0x40
+#define GMUX_PORT_SWITCH_GET_EXTERNAL 0x41
+#define GMUX_PORT_DISCRETE_POWER 0x50
+#define GMUX_PORT_MAX_BRIGHTNESS 0x70
+#define GMUX_PORT_BRIGHTNESS 0x74
+
+#define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4)
+
+#define GMUX_INTERRUPT_ENABLE 0xff
+#define GMUX_INTERRUPT_DISABLE 0x00
+
+#define GMUX_INTERRUPT_STATUS_ACTIVE 0
+#define GMUX_INTERRUPT_STATUS_DISPLAY (1 << 0)
+#define GMUX_INTERRUPT_STATUS_POWER (1 << 2)
+#define GMUX_INTERRUPT_STATUS_HOTPLUG (1 << 3)
+
+#define GMUX_BRIGHTNESS_MASK 0x00ffffff
+#define GMUX_MAX_BRIGHTNESS GMUX_BRIGHTNESS_MASK
+
+static inline u8 gmux_read8(struct apple_gmux_data *gmux_data, int port)
+{
+ return inb(gmux_data->iostart + port);
+}
+
+static inline void gmux_write8(struct apple_gmux_data *gmux_data, int port,
+ u8 val)
+{
+ outb(val, gmux_data->iostart + port);
+}
+
+static inline u32 gmux_read32(struct apple_gmux_data *gmux_data, int port)
+{
+ return inl(gmux_data->iostart + port);
+}
+
+static int gmux_get_brightness(struct backlight_device *bd)
+{
+ struct apple_gmux_data *gmux_data = bl_get_data(bd);
+ return gmux_read32(gmux_data, GMUX_PORT_BRIGHTNESS) &
+ GMUX_BRIGHTNESS_MASK;
+}
+
+static int gmux_update_status(struct backlight_device *bd)
+{
+ struct apple_gmux_data *gmux_data = bl_get_data(bd);
+ u32 brightness = bd->props.brightness;
+
+ /*
+ * Older gmux versions require writing out lower bytes first then
+ * setting the upper byte to 0 to flush the values. Newer versions
+ * accept a single u32 write, but the old method also works, so we
+ * just use the old method for all gmux versions.
+ */
+ gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS, brightness);
+ gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 1, brightness >> 8);
+ gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 2, brightness >> 16);
+ gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 3, 0);
+
+ return 0;
+}
+
+static const struct backlight_ops gmux_bl_ops = {
+ .get_brightness = gmux_get_brightness,
+ .update_status = gmux_update_status,
+};
+
+static int __devinit gmux_probe(struct pnp_dev *pnp,
+ const struct pnp_device_id *id)
+{
+ struct apple_gmux_data *gmux_data;
+ struct resource *res;
+ struct backlight_properties props;
+ struct backlight_device *bdev;
+ u8 ver_major, ver_minor, ver_release;
+ int ret = -ENXIO;
+
+ gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL);
+ if (!gmux_data)
+ return -ENOMEM;
+ pnp_set_drvdata(pnp, gmux_data);
+
+ res = pnp_get_resource(pnp, IORESOURCE_IO, 0);
+ if (!res) {
+ pr_err("Failed to find gmux I/O resource\n");
+ goto err_free;
+ }
+
+ gmux_data->iostart = res->start;
+ gmux_data->iolen = res->end - res->start;
+
+ if (gmux_data->iolen < GMUX_MIN_IO_LEN) {
+ pr_err("gmux I/O region too small (%lu < %u)\n",
+ gmux_data->iolen, GMUX_MIN_IO_LEN);
+ goto err_free;
+ }
+
+ if (!request_region(gmux_data->iostart, gmux_data->iolen,
+ "Apple gmux")) {
+ pr_err("gmux I/O already in use\n");
+ goto err_free;
+ }
+
+ /*
+ * On some machines the gmux is in ACPI even thought the machine
+ * doesn't really have a gmux. Check for invalid version information
+ * to detect this.
+ */
+ ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR);
+ ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR);
+ ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);
+ if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
+ pr_info("gmux device not present\n");
+ ret = -ENODEV;
+ goto err_release;
+ }
+
+ pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor,
+ ver_release);
+
+ memset(&props, 0, sizeof(props));
+ props.type = BACKLIGHT_PLATFORM;
+ props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS);
+
+ /*
+ * Currently it's assumed that the maximum brightness is less than
+ * 2^24 for compatibility with old gmux versions. Cap the max
+ * brightness at this value, but print a warning if the hardware
+ * reports something higher so that it can be fixed.
+ */
+ if (WARN_ON(props.max_brightness > GMUX_MAX_BRIGHTNESS))
+ props.max_brightness = GMUX_MAX_BRIGHTNESS;
+
+ bdev = backlight_device_register("gmux_backlight", &pnp->dev,
+ gmux_data, &gmux_bl_ops, &props);
+ if (IS_ERR(bdev)) {
+ ret = PTR_ERR(bdev);
+ goto err_release;
+ }
+
+ gmux_data->bdev = bdev;
+ bdev->props.brightness = gmux_get_brightness(bdev);
+ backlight_update_status(bdev);
+
+ /*
+ * The backlight situation on Macs is complicated. If the gmux is
+ * present it's the best choice, because it always works for
+ * backlight control and supports more levels than other options.
+ * Disable the other backlight choices.
+ */
+ acpi_video_unregister();
+ apple_bl_unregister();
+
+ return 0;
+
+err_release:
+ release_region(gmux_data->iostart, gmux_data->iolen);
+err_free:
+ kfree(gmux_data);
+ return ret;
+}
+
+static void __devexit gmux_remove(struct pnp_dev *pnp)
+{
+ struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
+
+ backlight_device_unregister(gmux_data->bdev);
+ release_region(gmux_data->iostart, gmux_data->iolen);
+ kfree(gmux_data);
+
+ acpi_video_register();
+ apple_bl_register();
+}
+
+static const struct pnp_device_id gmux_device_ids[] = {
+ {"APP000B", 0},
+ {"", 0}
+};
+
+static struct pnp_driver gmux_pnp_driver = {
+ .name = "apple-gmux",
+ .probe = gmux_probe,
+ .remove = __devexit_p(gmux_remove),
+ .id_table = gmux_device_ids,
+};
+
+static int __init apple_gmux_init(void)
+{
+ return pnp_register_driver(&gmux_pnp_driver);
+}
+
+static void __exit apple_gmux_exit(void)
+{
+ pnp_unregister_driver(&gmux_pnp_driver);
+}
+
+module_init(apple_gmux_init);
+module_exit(apple_gmux_exit);
+
+MODULE_AUTHOR("Seth Forshee <seth.forshee@canonical.com>");
+MODULE_DESCRIPTION("Apple Gmux Driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pnp, gmux_device_ids);
--
1.7.7.6

View File

@ -1,136 +0,0 @@
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 2571a2f..822f9e5 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1627,6 +1627,7 @@ struct mac_iveiv_entry {
/*
* H2M_MAILBOX_CSR: Host-to-MCU Mailbox.
+ * CMD_TOKEN: Command id, 0xff disable status reporting
*/
#define H2M_MAILBOX_CSR 0x7010
#define H2M_MAILBOX_CSR_ARG0 FIELD32(0x000000ff)
@@ -1636,6 +1637,8 @@ struct mac_iveiv_entry {
/*
* H2M_MAILBOX_CID:
+ * Free slots contain 0xff. MCU will store command's token to lowest free slot.
+ * If all slots are occupied status will be dropped.
*/
#define H2M_MAILBOX_CID 0x7014
#define H2M_MAILBOX_CID_CMD0 FIELD32(0x000000ff)
@@ -1645,6 +1648,7 @@ struct mac_iveiv_entry {
/*
* H2M_MAILBOX_STATUS:
+ * Command status will be saved to same slot as command id.
*/
#define H2M_MAILBOX_STATUS 0x701c
@@ -2259,6 +2263,12 @@ struct mac_iveiv_entry {
/*
* MCU mailbox commands.
+ * MCU_SLEEP - go to power-save mode.
+ * arg1: 1: save as much power as possible, 0: save less power
+ * status: 1: success, 2: already asleep,
+ * 3: maybe MAC is busy so can't finish this task
+ * MCU_RADIO_OFF
+ * arg0: 0: do power-saving, NOT turn off radio
*/
#define MCU_SLEEP 0x30
#define MCU_WAKEUP 0x31
@@ -2279,7 +2289,9 @@ struct mac_iveiv_entry {
/*
* MCU mailbox tokens
*/
-#define TOKEN_WAKUP 3
+#define TOKEN_SLEEP 1
+#define TOKEN_RADIO_OFF 2
+#define TOKEN_WAKEUP 3
/*
* DMA descriptor defines.
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index dc88bae..9ac3017 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -517,23 +517,6 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
}
}
-static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
- enum dev_state state)
-{
- if (state == STATE_AWAKE) {
- rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02);
- rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP);
- } else if (state == STATE_SLEEP) {
- rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
- 0xffffffff);
- rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID,
- 0xffffffff);
- rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01);
- }
-
- return 0;
-}
-
static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
enum dev_state state)
{
@@ -541,14 +524,20 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
switch (state) {
case STATE_RADIO_ON:
- /*
- * Before the radio can be enabled, the device first has
- * to be woken up. After that it needs a bit of time
- * to be fully awake and then the radio can be enabled.
- */
- rt2800pci_set_state(rt2x00dev, STATE_AWAKE);
- msleep(1);
+ /* Initialise all registers and send MCU_BOOT_SIGNAL. */
retval = rt2800pci_enable_radio(rt2x00dev);
+
+ /* After resume MCU_BOOT_SIGNAL will trash those. */
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+
+ /* Finish initialization procedure. */
+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF,
+ 0xff, 0x02);
+ rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF);
+
+ rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP, 0, 0);
+ rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
break;
case STATE_RADIO_OFF:
/*
@@ -556,7 +545,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
* be put to sleep for powersaving.
*/
rt2800pci_disable_radio(rt2x00dev);
- rt2800pci_set_state(rt2x00dev, STATE_SLEEP);
+ rt2800pci_set_device_state(rt2x00dev, STATE_SLEEP);
break;
case STATE_RADIO_IRQ_ON:
case STATE_RADIO_IRQ_OFF:
@@ -565,8 +554,16 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
case STATE_STANDBY:
+ /* PCIe devices won't report status after SLEEP request. */
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP,
+ 0xff, 0x01);
+ break;
case STATE_AWAKE:
- retval = rt2800pci_set_state(rt2x00dev, state);
+ rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP,
+ 0, 0x02);
+ rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
break;
default:
retval = -ENOTSUPP;

View File

@ -1,86 +0,0 @@
From 574e02abaf816b582685805f0c1150ca9f1f18ee Mon Sep 17 00:00:00 2001
From: Larry Finger <Larry.Finger@lwfinger.net>
Date: Fri, 4 May 2012 08:27:43 -0500
Subject: [PATCH] rtlwifi: fix for race condition when firmware is cached
In commit b0302ab, the rtlwifi family of drivers was converted to use
asynchronous firmware loading. Unfortumately, the implementation was
racy, and the ieee80211 routines could be started before rtl_init_core()
was called to setup the data.
This patch fixes the bug noted in https://bugzilla.kernel.org/show_bug.cgi?id=43187.
Reported-by: Joshua Roys <Joshua.Roys@gtri.gatech.edu>
Tested-by: Neptune Ning <frostyplanet@gmail.com>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Stable <stable@vger.kernel.org> [3.3]
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
drivers/net/wireless/rtlwifi/pci.c | 16 ++++++++--------
drivers/net/wireless/rtlwifi/usb.c | 10 +++++-----
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index b588ca8..03c400e 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1865,14 +1865,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
/*like read eeprom and so on */
rtlpriv->cfg->ops->read_eeprom_info(hw);
- if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- ("Can't init_sw_vars.\n"));
- goto fail3;
- }
-
- rtlpriv->cfg->ops->init_sw_leds(hw);
-
/*aspm */
rtl_pci_init_aspm(hw);
@@ -1892,6 +1884,14 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
goto fail3;
}
+ if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Can't init_sw_vars.\n"));
+ goto fail3;
+ }
+
+ rtlpriv->cfg->ops->init_sw_leds(hw);
+
err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 049e207..20b53ae 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -970,12 +970,6 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
rtlpriv->cfg->ops->read_chip_version(hw);
/*like read eeprom and so on */
rtlpriv->cfg->ops->read_eeprom_info(hw);
- if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- ("Can't init_sw_vars.\n"));
- goto error_out;
- }
- rtlpriv->cfg->ops->init_sw_leds(hw);
err = _rtl_usb_init(hw);
err = _rtl_usb_init_sw(hw);
/* Init mac80211 sw */
@@ -985,6 +979,12 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
("Can't allocate sw for mac80211.\n"));
goto error_out;
}
+ if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Can't init_sw_vars.\n"));
+ goto error_out;
+ }
+ rtlpriv->cfg->ops->init_sw_leds(hw);
return 0;
error_out:

View File

@ -1,2 +1 @@
7133f5a2086a7d7ef97abac610c094f5 linux-3.3.tar.xz
622a3b43238559aeb778279969631260 patch-3.3.7.xz
967f72983655e2479f951195953e8480 linux-3.4.tar.xz

View File

@ -1,135 +0,0 @@
From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Xen dom0 needs to paravirtualize IO operations to the IO APIC, so add
a io_apic_ops for it to intercept. Do this as ops structure because
there's at least some chance that another paravirtualized environment
may want to intercept these.
[ Impact: indirect IO APIC access via io_apic_ops ]
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
arch/x86/include/asm/io_apic.h | 9 +++++++
arch/x86/kernel/apic/io_apic.c | 50 +++++++++++++++++++++++++++++++++++++--
2 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 690d1cc..190d8c2 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -21,6 +21,15 @@
#define IO_APIC_REDIR_LEVEL_TRIGGER (1 << 15)
#define IO_APIC_REDIR_MASKED (1 << 16)
+struct io_apic_ops {
+ void (*init)(void);
+ unsigned int (*read)(unsigned int apic, unsigned int reg);
+ void (*write)(unsigned int apic, unsigned int reg, unsigned int value);
+ void (*modify)(unsigned int apic, unsigned int reg, unsigned int value);
+};
+
+void __init set_io_apic_ops(const struct io_apic_ops *);
+
/*
* The structure of the IO-APIC:
*/
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index fb07275..bf120234 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -67,6 +67,25 @@
#define for_each_irq_pin(entry, head) \
for (entry = head; entry; entry = entry->next)
+static void __init __ioapic_init_mappings(void);
+static unsigned int __io_apic_read(unsigned int apic, unsigned int reg);
+static void __io_apic_write(unsigned int apic, unsigned int reg,
+ unsigned int val);
+static void __io_apic_modify(unsigned int apic, unsigned int reg,
+ unsigned int val);
+
+static struct io_apic_ops io_apic_ops = {
+ .init = __ioapic_init_mappings,
+ .read = __io_apic_read,
+ .write = __io_apic_write,
+ .modify = __io_apic_modify,
+};
+
+void __init set_io_apic_ops(const struct io_apic_ops *ops)
+{
+ io_apic_ops = *ops;
+}
+
/*
* Is the SiS APIC rmw bug present ?
* -1 = don't know, 0 = no, 1 = yes
@@ -294,6 +313,24 @@ static void free_irq_at(unsigned int at, struct irq_cfg *cfg)
irq_free_desc(at);
}
+static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+{
+ return io_apic_ops.read(apic, reg);
+}
+
+static inline void io_apic_write(unsigned int apic, unsigned int reg,
+ unsigned int value)
+{
+ io_apic_ops.write(apic, reg, value);
+}
+
+static inline void io_apic_modify(unsigned int apic, unsigned int reg,
+ unsigned int value)
+{
+ io_apic_ops.modify(apic, reg, value);
+}
+
+
struct io_apic {
unsigned int index;
unsigned int unused[3];
@@ -314,14 +351,15 @@ static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
writel(vector, &io_apic->eoi);
}
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+static unsigned int __io_apic_read(unsigned int apic, unsigned int reg)
{
struct io_apic __iomem *io_apic = io_apic_base(apic);
writel(reg, &io_apic->index);
return readl(&io_apic->data);
}
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+static void __io_apic_write(unsigned int apic, unsigned int reg,
+ unsigned int value)
{
struct io_apic __iomem *io_apic = io_apic_base(apic);
writel(reg, &io_apic->index);
@@ -334,7 +372,8 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i
*
* Older SiS APIC requires we rewrite the index register
*/
-static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
+static void __io_apic_modify(unsigned int apic, unsigned int reg,
+ unsigned int value)
{
struct io_apic __iomem *io_apic = io_apic_base(apic);
@@ -3873,6 +3912,11 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics)
void __init ioapic_and_gsi_init(void)
{
+ io_apic_ops.init();
+}
+
+static void __init __ioapic_init_mappings(void)
+{
unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
struct resource *ioapic_res;
int i;
--
1.7.7.5

View File

@ -1,258 +0,0 @@
. which makes the code fit within the rest of the x86_ops functions.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[v1: Changed x86_apic -> x86_ioapic per Yinghai Lu <yinghai@kernel.org> suggestion]
Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
arch/x86/include/asm/io_apic.h | 40 +++++++++++++++++++++--------
arch/x86/include/asm/x86_init.h | 8 ++++++
arch/x86/kernel/apic/io_apic.c | 54 ++++----------------------------------
arch/x86/kernel/setup.c | 2 +-
arch/x86/kernel/x86_init.c | 8 ++++++
5 files changed, 52 insertions(+), 60 deletions(-)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 190d8c2..ba1b11a 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -5,6 +5,7 @@
#include <asm/mpspec.h>
#include <asm/apicdef.h>
#include <asm/irq_vectors.h>
+#include <asm/x86_init.h>
/*
* Intel IO-APIC support for SMP and UP systems.
@@ -21,15 +22,6 @@
#define IO_APIC_REDIR_LEVEL_TRIGGER (1 << 15)
#define IO_APIC_REDIR_MASKED (1 << 16)
-struct io_apic_ops {
- void (*init)(void);
- unsigned int (*read)(unsigned int apic, unsigned int reg);
- void (*write)(unsigned int apic, unsigned int reg, unsigned int value);
- void (*modify)(unsigned int apic, unsigned int reg, unsigned int value);
-};
-
-void __init set_io_apic_ops(const struct io_apic_ops *);
-
/*
* The structure of the IO-APIC:
*/
@@ -156,7 +148,6 @@ struct io_apic_irq_attr;
extern int io_apic_set_pci_routing(struct device *dev, int irq,
struct io_apic_irq_attr *irq_attr);
void setup_IO_APIC_irq_extra(u32 gsi);
-extern void ioapic_and_gsi_init(void);
extern void ioapic_insert_resources(void);
int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr);
@@ -185,12 +176,35 @@ extern void mp_save_irq(struct mpc_intsrc *m);
extern void disable_ioapic_support(void);
+
+void __init native_ioapic_init_mappings(void);
+unsigned int native_ioapic_read(unsigned int apic, unsigned int reg);
+void native_ioapic_write(unsigned int apic, unsigned int reg,
+ unsigned int val);
+void native_ioapic_modify(unsigned int apic, unsigned int reg,
+ unsigned int val);
+
+static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+{
+ return x86_ioapic.read(apic, reg);
+}
+
+static inline void io_apic_write(unsigned int apic, unsigned int reg,
+ unsigned int value)
+{
+ x86_ioapic.write(apic, reg, value);
+}
+
+static inline void io_apic_modify(unsigned int apic, unsigned int reg,
+ unsigned int value)
+{
+ x86_ioapic.modify(apic, reg, value);
+}
#else /* !CONFIG_X86_IO_APIC */
#define io_apic_assign_pci_irqs 0
#define setup_ioapic_ids_from_mpc x86_init_noop
static const int timer_through_8259 = 0;
-static inline void ioapic_and_gsi_init(void) { }
static inline void ioapic_insert_resources(void) { }
#define gsi_top (NR_IRQS_LEGACY)
static inline int mp_find_ioapic(u32 gsi) { return 0; }
@@ -212,6 +226,10 @@ static inline int restore_ioapic_entries(void)
static inline void mp_save_irq(struct mpc_intsrc *m) { };
static inline void disable_ioapic_support(void) { }
+#define native_ioapic_init_mappings NULL
+#define native_ioapic_read NULL
+#define native_ioapic_write NULL
+#define native_ioapic_modify NULL
#endif
#endif /* _ASM_X86_IO_APIC_H */
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 517d476..a3730cc 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -182,10 +182,18 @@ struct x86_msi_ops {
void (*restore_msi_irqs)(struct pci_dev *dev, int irq);
};
+struct x86_ioapic_ops {
+ void (*init)(void);
+ unsigned int (*read)(unsigned int apic, unsigned int reg);
+ void (*write)(unsigned int apic, unsigned int reg, unsigned int value);
+ void (*modify)(unsigned int apic, unsigned int reg, unsigned int value);
+};
+
extern struct x86_init_ops x86_init;
extern struct x86_cpuinit_ops x86_cpuinit;
extern struct x86_platform_ops x86_platform;
extern struct x86_msi_ops x86_msi;
+extern struct x86_ioapic_ops x86_ioapic;
extern void x86_init_noop(void);
extern void x86_init_uint_noop(unsigned int unused);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index bf120234..9a15d4b 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -67,25 +67,6 @@
#define for_each_irq_pin(entry, head) \
for (entry = head; entry; entry = entry->next)
-static void __init __ioapic_init_mappings(void);
-static unsigned int __io_apic_read(unsigned int apic, unsigned int reg);
-static void __io_apic_write(unsigned int apic, unsigned int reg,
- unsigned int val);
-static void __io_apic_modify(unsigned int apic, unsigned int reg,
- unsigned int val);
-
-static struct io_apic_ops io_apic_ops = {
- .init = __ioapic_init_mappings,
- .read = __io_apic_read,
- .write = __io_apic_write,
- .modify = __io_apic_modify,
-};
-
-void __init set_io_apic_ops(const struct io_apic_ops *ops)
-{
- io_apic_ops = *ops;
-}
-
/*
* Is the SiS APIC rmw bug present ?
* -1 = don't know, 0 = no, 1 = yes
@@ -313,24 +294,6 @@ static void free_irq_at(unsigned int at, struct irq_cfg *cfg)
irq_free_desc(at);
}
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
- return io_apic_ops.read(apic, reg);
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg,
- unsigned int value)
-{
- io_apic_ops.write(apic, reg, value);
-}
-
-static inline void io_apic_modify(unsigned int apic, unsigned int reg,
- unsigned int value)
-{
- io_apic_ops.modify(apic, reg, value);
-}
-
-
struct io_apic {
unsigned int index;
unsigned int unused[3];
@@ -351,15 +314,15 @@ static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
writel(vector, &io_apic->eoi);
}
-static unsigned int __io_apic_read(unsigned int apic, unsigned int reg)
+unsigned int native_ioapic_read(unsigned int apic, unsigned int reg)
{
struct io_apic __iomem *io_apic = io_apic_base(apic);
writel(reg, &io_apic->index);
return readl(&io_apic->data);
}
-static void __io_apic_write(unsigned int apic, unsigned int reg,
- unsigned int value)
+void native_ioapic_write(unsigned int apic, unsigned int reg,
+ unsigned int value)
{
struct io_apic __iomem *io_apic = io_apic_base(apic);
writel(reg, &io_apic->index);
@@ -372,8 +335,8 @@ static void __io_apic_write(unsigned int apic, unsigned int reg,
*
* Older SiS APIC requires we rewrite the index register
*/
-static void __io_apic_modify(unsigned int apic, unsigned int reg,
- unsigned int value)
+void native_ioapic_modify(unsigned int apic, unsigned int reg,
+ unsigned int value)
{
struct io_apic __iomem *io_apic = io_apic_base(apic);
@@ -3910,12 +3873,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics)
return res;
}
-void __init ioapic_and_gsi_init(void)
-{
- io_apic_ops.init();
-}
-
-static void __init __ioapic_init_mappings(void)
+void __init native_ioapic_init_mappings(void)
{
unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
struct resource *ioapic_res;
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d7d5099..7eaef1a 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1016,7 +1016,7 @@ void __init setup_arch(char **cmdline_p)
init_cpu_to_node();
init_apic_mappings();
- ioapic_and_gsi_init();
+ x86_ioapic.init();
kvm_guest_init();
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 947a06c..df870d3 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -18,6 +18,7 @@
#include <asm/e820.h>
#include <asm/time.h>
#include <asm/irq.h>
+#include <asm/io_apic.h>
#include <asm/pat.h>
#include <asm/tsc.h>
#include <asm/iommu.h>
@@ -117,3 +118,10 @@ struct x86_msi_ops x86_msi = {
.teardown_msi_irqs = default_teardown_msi_irqs,
.restore_msi_irqs = default_restore_msi_irqs,
};
+
+struct x86_ioapic_ops x86_ioapic = {
+ .init = native_ioapic_init_mappings,
+ .read = native_ioapic_read,
+ .write = native_ioapic_write,
+ .modify = native_ioapic_modify,
+};
--
1.7.7.5

View File

@ -1,85 +0,0 @@
Or rather just implement one different function as opposed
to the native one : the read function.
We synthesize the values.
Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
arch/x86/xen/Makefile | 2 +-
arch/x86/xen/apic.c | 17 +++++++++++++++++
arch/x86/xen/enlighten.c | 2 ++
arch/x86/xen/xen-ops.h | 4 ++++
4 files changed, 24 insertions(+), 1 deletions(-)
create mode 100644 arch/x86/xen/apic.c
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
index add2c2d..96ab2c0 100644
--- a/arch/x86/xen/Makefile
+++ b/arch/x86/xen/Makefile
@@ -20,5 +20,5 @@ obj-$(CONFIG_EVENT_TRACING) += trace.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o
-obj-$(CONFIG_XEN_DOM0) += vga.o
+obj-$(CONFIG_XEN_DOM0) += apic.o vga.o
obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o
diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c
new file mode 100644
index 0000000..71ed91c
--- /dev/null
+++ b/arch/x86/xen/apic.c
@@ -0,0 +1,17 @@
+#include <linux/init.h>
+#include <asm/x86_init.h>
+
+unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
+{
+ if (reg == 0x1)
+ return 0x00170020;
+ else if (reg == 0x0)
+ return apic << 24;
+
+ return 0xff;
+}
+
+void __init xen_init_apic(void)
+{
+ x86_ioapic.read = xen_io_apic_read;
+}
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 0732326..93a03195 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1377,6 +1377,8 @@ asmlinkage void __init xen_start_kernel(void)
xen_start_info->console.domU.mfn = 0;
xen_start_info->console.domU.evtchn = 0;
+ xen_init_apic();
+
/* Make sure ACS will be enabled */
pci_request_acs();
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index b095739..45c0c06 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -92,11 +92,15 @@ struct dom0_vga_console_info;
#ifdef CONFIG_XEN_DOM0
void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size);
+void __init xen_init_apic(void);
#else
static inline void __init xen_init_vga(const struct dom0_vga_console_info *info,
size_t size)
{
}
+static inline void __init xen_init_apic(void)
+{
+}
#endif
/* Declare an asm function, along with symbols needed to make it
--
1.7.7.5