VIEWING EXECUTING AND QUEUED ITEMS
==================================
-If CONFIG_SLOW_WORK_PROC is enabled, a proc file is made available:
+If CONFIG_SLOW_WORK_DEBUG is enabled, a debugfs file is made available:
- /proc/slow_work_rq
+ /sys/kernel/debug/slow_work/runqueue
through which the list of work items being executed and the queues of items to
be executed may be viewed. The owner of a work item is given the chance to
F: fs/autofs4/
KERNEL BUILD
-M: Sam Ravnborg <sam@ravnborg.org>
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes.git
L: linux-kbuild@vger.kernel.org
-S: Maintained
+S: Orphan
F: Documentation/kbuild/
F: Makefile
F: scripts/Makefile.*
/*
* Thread information flags:
* - these are process state flags and used from assembly
- * - pending work-to-be-done flags come first to fit in and immediate operand.
+ * - pending work-to-be-done flags come first and must be assigned to be
+ * within bits 0 to 7 to fit in and immediate operand.
+ * - ALPHA_UAC_SHIFT below must be kept consistent with the unaligned
+ * control flags.
*
* TIF_SYSCALL_TRACE is known to be 0 via blbs.
*/
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
-#define TIF_SIGPENDING 1 /* signal pending */
-#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG 3 /* poll_idle is polling NEED_RESCHED */
-#define TIF_DIE_IF_KERNEL 4 /* dik recursion lock */
-#define TIF_UAC_NOPRINT 5 /* see sysinfo.h */
-#define TIF_UAC_NOFIX 6
-#define TIF_UAC_SIGBUS 7
-#define TIF_MEMDIE 8
-#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */
-#define TIF_NOTIFY_RESUME 10 /* callback before returning to user */
+#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
+#define TIF_SIGPENDING 2 /* signal pending */
+#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+#define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */
+#define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */
+#define TIF_UAC_NOPRINT 10 /* see sysinfo.h */
+#define TIF_UAC_NOFIX 11
+#define TIF_UAC_SIGBUS 12
+#define TIF_MEMDIE 13
+#define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */
#define TIF_FREEZE 16 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \
| _TIF_SYSCALL_TRACE)
-#define ALPHA_UAC_SHIFT 6
+#define ALPHA_UAC_SHIFT 10
#define ALPHA_UAC_MASK (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \
1 << TIF_UAC_SIGBUS)
* Allocate the info structure.
*/
agp = kmalloc(sizeof(*agp), GFP_KERNEL);
+ if (!agp)
+ return NULL;
/*
* Fill it in.
* Allocate the info structure.
*/
agp = kmalloc(sizeof(*agp), GFP_KERNEL);
+ if (!agp)
+ return NULL;
/*
* Fill it in.
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
#endif
- seq_printf(p, " %14s", irq_desc[irq].chip->typename);
+ seq_printf(p, " %14s", irq_desc[irq].chip->name);
seq_printf(p, " %c%s",
(action->flags & IRQF_DISABLED)?'+':' ',
action->name);
};
static struct irq_chip rtc_irq_type = {
- .typename = "RTC",
+ .name = "RTC",
.startup = rtc_startup,
.shutdown = rtc_enable_disable,
.enable = rtc_enable_disable,
}
struct irq_chip i8259a_irq_type = {
- .typename = "XT-PIC",
+ .name = "XT-PIC",
.startup = i8259a_startup_irq,
.shutdown = i8259a_disable_irq,
.enable = i8259a_enable_irq,
}
static struct irq_chip pyxis_irq_type = {
- .typename = "PYXIS",
+ .name = "PYXIS",
.startup = pyxis_startup_irq,
.shutdown = pyxis_disable_irq,
.enable = pyxis_enable_irq,
/* Handle interrupts from the SRM, assuming no additional weirdness. */
static struct irq_chip srm_irq_type = {
- .typename = "SRM",
+ .name = "SRM",
.startup = srm_startup_irq,
.shutdown = srm_disable_irq,
.enable = srm_enable_irq,
}
static struct irq_chip alcor_irq_type = {
- .typename = "ALCOR",
+ .name = "ALCOR",
.startup = alcor_startup_irq,
.shutdown = alcor_disable_irq,
.enable = alcor_enable_irq,
}
static struct irq_chip cabriolet_irq_type = {
- .typename = "CABRIOLET",
+ .name = "CABRIOLET",
.startup = cabriolet_startup_irq,
.shutdown = cabriolet_disable_irq,
.enable = cabriolet_enable_irq,
}
static struct irq_chip dp264_irq_type = {
- .typename = "DP264",
+ .name = "DP264",
.startup = dp264_startup_irq,
.shutdown = dp264_disable_irq,
.enable = dp264_enable_irq,
};
static struct irq_chip clipper_irq_type = {
- .typename = "CLIPPER",
+ .name = "CLIPPER",
.startup = clipper_startup_irq,
.shutdown = clipper_disable_irq,
.enable = clipper_enable_irq,
}
static struct irq_chip eb64p_irq_type = {
- .typename = "EB64P",
+ .name = "EB64P",
.startup = eb64p_startup_irq,
.shutdown = eb64p_disable_irq,
.enable = eb64p_enable_irq,
}
static struct irq_chip eiger_irq_type = {
- .typename = "EIGER",
+ .name = "EIGER",
.startup = eiger_startup_irq,
.shutdown = eiger_disable_irq,
.enable = eiger_enable_irq,
}
static struct irq_chip jensen_local_irq_type = {
- .typename = "LOCAL",
+ .name = "LOCAL",
.startup = jensen_local_startup,
.shutdown = jensen_local_shutdown,
.enable = jensen_local_enable,
}
static struct irq_chip marvel_legacy_irq_type = {
- .typename = "LEGACY",
+ .name = "LEGACY",
.startup = marvel_irq_noop_return,
.shutdown = marvel_irq_noop,
.enable = marvel_irq_noop,
};
static struct irq_chip io7_lsi_irq_type = {
- .typename = "LSI",
+ .name = "LSI",
.startup = io7_startup_irq,
.shutdown = io7_disable_irq,
.enable = io7_enable_irq,
};
static struct irq_chip io7_msi_irq_type = {
- .typename = "MSI",
+ .name = "MSI",
.startup = io7_startup_irq,
.shutdown = io7_disable_irq,
.enable = io7_enable_irq,
}
static struct irq_chip mikasa_irq_type = {
- .typename = "MIKASA",
+ .name = "MIKASA",
.startup = mikasa_startup_irq,
.shutdown = mikasa_disable_irq,
.enable = mikasa_enable_irq,
}
static struct irq_chip noritake_irq_type = {
- .typename = "NORITAKE",
+ .name = "NORITAKE",
.startup = noritake_startup_irq,
.shutdown = noritake_disable_irq,
.enable = noritake_enable_irq,
}
static struct irq_chip rawhide_irq_type = {
- .typename = "RAWHIDE",
+ .name = "RAWHIDE",
.startup = rawhide_startup_irq,
.shutdown = rawhide_disable_irq,
.enable = rawhide_enable_irq,
common_init_isa_dma();
}
-#define RUFFIAN_LATCH ((PIT_TICK_RATE + HZ / 2) / HZ)
+#define RUFFIAN_LATCH DIV_ROUND_CLOSEST(PIT_TICK_RATE, HZ)
static void __init
ruffian_init_rtc(void)
}
static struct irq_chip rx164_irq_type = {
- .typename = "RX164",
+ .name = "RX164",
.startup = rx164_startup_irq,
.shutdown = rx164_disable_irq,
.enable = rx164_enable_irq,
}
static struct irq_chip sable_lynx_irq_type = {
- .typename = "SABLE/LYNX",
+ .name = "SABLE/LYNX",
.startup = sable_lynx_startup_irq,
.shutdown = sable_lynx_disable_irq,
.enable = sable_lynx_enable_irq,
}
static struct irq_chip takara_irq_type = {
- .typename = "TAKARA",
+ .name = "TAKARA",
.startup = takara_startup_irq,
.shutdown = takara_disable_irq,
.enable = takara_enable_irq,
}
static struct irq_chip titan_irq_type = {
- .typename = "TITAN",
+ .name = "TITAN",
.startup = titan_startup_irq,
.shutdown = titan_disable_irq,
.enable = titan_enable_irq,
}
static struct irq_chip wildfire_irq_type = {
- .typename = "WILDFIRE",
+ .name = "WILDFIRE",
.startup = wildfire_startup_irq,
.shutdown = wildfire_disable_irq,
.enable = wildfire_enable_irq,
select SWAP_IO_SPACE
select SYS_HAS_CPU_R4X00
select SYS_HAS_CPU_R5000
- select SYS_HAS_EARLY_PRINTK
+ #
+ # Disable EARLY_PRINTK for now since it leads to overwritten prom
+ # memory during early boot on some machines.
+ #
+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+ # for a more details discussion
+ #
+ # select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SGI_HAS_ZILOG
select SWAP_IO_SPACE
select SYS_HAS_CPU_R10000
- select SYS_HAS_EARLY_PRINTK
+ #
+ # Disable EARLY_PRINTK for now since it leads to overwritten prom
+ # memory during early boot on some machines.
+ #
+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+ # for a more details discussion
+ #
+ # select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
help
config PAGE_SIZE_4KB
bool "4kB"
+ depends on !CPU_LOONGSON2
help
This option select the standard 4kB Linux page size. On some
R3000-family processors this is the only available page size. Using
config ARCH_FLATMEM_ENABLE
def_bool y
- depends on !NUMA
+ depends on !NUMA && !CPU_LOONGSON2
config ARCH_DISCONTIGMEM_ENABLE
bool
#define MADV_MERGEABLE 12 /* KSM may merge identical pages */
#define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */
+#define MADV_HWPOISON 100 /* poison a page for testing */
/* compatibility flags */
#define MAP_FILE 0
#ifndef _ASM_SYSTEM_H
#define _ASM_SYSTEM_H
+#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/irqflags.h>
#define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels
#endif
-/* This function doesn't exist, so you'll get a linker error
- if something tries to do an invalid xchg(). */
-extern void __xchg_called_with_bad_pointer(void);
-
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
switch (size) {
case 8:
return __xchg_u64(ptr, x);
}
- __xchg_called_with_bad_pointer();
+
return x;
}
-#define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+#define xchg(ptr, x) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) & ~0xc); \
+ \
+ ((__typeof__(*(ptr))) \
+ __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))); \
+})
extern void set_handler(unsigned long offset, void *addr, unsigned long len);
extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__ (
+ " .set mips3 \n"
" li %[err], 0 \n"
"1: ll %[old], (%[addr]) \n"
" move %[tmp], %[new] \n"
" "STR(PTR)" 1b, 4b \n"
" "STR(PTR)" 2b, 4b \n"
" .previous \n"
+ " .set mips0 \n"
: [old] "=&r" (old),
[err] "=&r" (err),
[tmp] "=&r" (tmp)
: "memory");
} else if (cpu_has_llsc) {
__asm__ __volatile__ (
+ " .set mips3 \n"
" li %[err], 0 \n"
"1: ll %[old], (%[addr]) \n"
" move %[tmp], %[new] \n"
" "STR(PTR)" 1b, 5b \n"
" "STR(PTR)" 2b, 5b \n"
" .previous \n"
+ " .set mips0 \n"
: [old] "=&r" (old),
[err] "=&r" (err),
[tmp] "=&r" (tmp)
static struct platform_device korina_dev0 = {
.id = -1,
.name = "korina",
- .dev.driver_data = &korina_dev0_data,
.resource = korina_dev0_res,
.num_resources = ARRAY_SIZE(korina_dev0_res),
};
/* set the uart clock to the current cpu frequency */
rb532_uart_res[0].uartclk = idt_cpu_freq;
+ dev_set_drvdata(&korina_dev0.dev, &korina_dev0_data);
+
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
}
part_stat_unlock();
}
+/*
+ * Ensure we don't create aliases in VI caches
+ */
+static inline void
+killalias(struct bio *bio)
+{
+ struct bio_vec *bv;
+ int i;
+
+ if (bio_data_dir(bio) == READ)
+ __bio_for_each_segment(bv, bio, i, 0) {
+ flush_dcache_page(bv->bv_page);
+ }
+}
+
void
aoecmd_ata_rsp(struct sk_buff *skb)
{
if (buf && --buf->nframesout == 0 && buf->resid == 0) {
diskstats(d->gd, buf->bio, jiffies - buf->stime, buf->sector);
- n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
- bio_endio(buf->bio, n);
+ if (buf->flags & BUFFL_FAIL)
+ bio_endio(buf->bio, -EIO);
+ else {
+ killalias(buf->bio);
+ bio_endio(buf->bio, 0);
+ }
mempool_free(buf, d->bufpool);
}
/* if non-blocking mode is set we can pass directly to open unless
the port has just hung up or is in another error state */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
+ if (tty->flags & (1 << TTY_IO_ERROR)) {
+ port->flags |= ASYNC_NORMAL_ACTIVE;
+ return 0;
+ }
+ if (filp->f_flags & O_NONBLOCK) {
/* Indicate we are open */
if (tty->termios->c_cflag & CBAUD)
tty_port_raise_dtr_rts(port);
static void lnw_irq_unmask(unsigned irq)
{
- struct lnw_gpio *lnw = get_irq_chip_data(irq);
- u32 gpio = irq - lnw->irq_base;
- u8 reg = gpio / 32;
- void __iomem *gedr;
-
- gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]);
- writel(BIT(gpio % 32), gedr);
};
static void lnw_irq_mask(unsigned irq)
gedr_v = readl(gedr);
if (!gedr_v)
continue;
- for (gpio = reg*32; gpio < reg*32+32; gpio++) {
- gedr_v = readl(gedr);
+ for (gpio = reg*32; gpio < reg*32+32; gpio++)
if (gedr_v & BIT(gpio % 32)) {
pr_debug("pin %d triggered\n", gpio);
generic_handle_irq(lnw->irq_base + gpio);
}
- }
/* clear the edge detect status bit */
writel(gedr_v, gedr);
}
DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
},
},
+ {
+ .ident = "Dell Vostro 1320",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
+ },
+ },
+ {
+ .ident = "Dell Vostro 1520",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
+ },
+ },
+ {
+ .ident = "Dell Vostro 1720",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
+ },
+ },
{ }
};
r1_bio->sector,
r1_bio->sectors);
unfreeze_array(conf);
- }
+ } else
+ md_error(mddev,
+ conf->mirrors[r1_bio->read_disk].rdev);
bio = r1_bio->bios[r1_bio->read_disk];
- if ((disk=read_balance(conf, r1_bio)) == -1 ||
- disk == r1_bio->read_disk) {
+ if ((disk=read_balance(conf, r1_bio)) == -1) {
printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
" read error for block %llu\n",
bdevname(bio->bi_bdev,b),
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/poll.h>
+#include <linux/semaphore.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/freezer.h>
if (mmc) {
struct pxamci_host *host = mmc_priv(mmc);
+ mmc_remove_host(mmc);
+
if (host->pdata) {
gpio_cd = host->pdata->gpio_card_detect;
gpio_ro = host->pdata->gpio_card_ro;
if (host->pdata && host->pdata->exit)
host->pdata->exit(&pdev->dev, mmc);
- mmc_remove_host(mmc);
-
pxamci_stop_clock(host);
writel(TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
return -ENOMEM;
}
+ isink->wm831x = wm831x;
+
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (res == NULL) {
dev_err(&pdev->dev, "No I/O resource\n");
&pcf50633_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
+ int ret = PTR_ERR(rtc->rtc_dev);
kfree(rtc);
- return PTR_ERR(rtc->rtc_dev);
+ return ret;
}
pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM,
/* year, since the rtc epoch*/
buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
buf[CCR_WDAY] = tm->tm_wday & 0x07;
- buf[CCR_Y2K] = bin2bcd(tm->tm_year / 100);
+ buf[CCR_Y2K] = bin2bcd((tm->tm_year + 1900) / 100);
}
/* If writing alarm registers, set compare bits on registers 0-4 */
int err;
struct rtc_time tm;
- tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+ memset(&tm, 0, sizeof(tm));
- err = x1205_set_datetime(client, &tm, 0, X1205_CCR_BASE, 0);
+ err = x1205_set_datetime(client, &tm, 1, X1205_CCR_BASE, 0);
if (err < 0)
dev_err(&client->dev, "unable to restart the oscillator\n");
* higher than fifo size anyway since we're much faster than
* serial port */
max_count = 32;
- tty = port->info->port.tty;
+ tty = port->state->port.tty;
do {
unsigned int iestat, c, cstat;
char flag;
return;
}
- xmit = &port->info->xmit;
+ xmit = &port->state->xmit;
if (uart_circ_empty(xmit))
goto txq_empty;
static struct of_device_id __devinitdata of_platform_serial_table[] = {
{ .type = "serial", .compatible = "ns8250", .data = (void *)PORT_8250, },
{ .type = "serial", .compatible = "ns16450", .data = (void *)PORT_16450, },
+ { .type = "serial", .compatible = "ns16550a", .data = (void *)PORT_16550A, },
{ .type = "serial", .compatible = "ns16550", .data = (void *)PORT_16550, },
{ .type = "serial", .compatible = "ns16750", .data = (void *)PORT_16750, },
{ .type = "serial", .compatible = "ns16850", .data = (void *)PORT_16850, },
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*
*/
/* Stop callback and cancel the timer asap */
Channel->OnChannelCallback = NULL;
- del_timer(&Channel->poll_timer);
+ del_timer_sync(&Channel->poll_timer);
/* Send a closing message */
info = kmalloc(sizeof(*info) +
{
DumpVmbusChannel(Channel);
ASSERT(Channel->OnChannelCallback);
-#ifdef ENABLE_POLLING
- del_timer(&Channel->poll_timer);
- Channel->OnChannelCallback(Channel->ChannelCallbackContext);
- channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
- add_timer(&channel->poll_timer);
-#else
+
Channel->OnChannelCallback(Channel->ChannelCallbackContext);
-#endif
+
+ mod_timer(&Channel->poll_timer, jiffies + usecs_to_jiffies(100));
}
/**
if (channel->OnChannelCallback) {
channel->OnChannelCallback(channel->ChannelCallbackContext);
-#ifdef ENABLE_POLLING
- channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
- add_timer(&channel->poll_timer);
-#endif
}
}
*/
void FreeVmbusChannel(struct vmbus_channel *Channel)
{
- del_timer(&Channel->poll_timer);
+ del_timer_sync(&Channel->poll_timer);
/*
* We have to release the channel's workqueue/thread in the vmbus's
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*/
#include <linux/kernel.h>
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*
*/
* Now, initiate the vsc/vsp initialization protocol on the open
* channel
*/
- memset(request, sizeof(struct storvsc_request_extension), 0);
+ memset(request, 0, sizeof(struct storvsc_request_extension));
request->WaitEvent = osd_WaitEventCreate();
vstorPacket->Operation = VStorOperationBeginInitialization;
DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION...");
/* reuse the packet for version range supported */
- memset(vstorPacket, sizeof(struct vstor_packet), 0);
+ memset(vstorPacket, 0, sizeof(struct vstor_packet));
vstorPacket->Operation = VStorOperationQueryProtocolVersion;
vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
/* Query channel properties */
DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION...");
- memset(vstorPacket, sizeof(struct vstor_packet), 0);
+ memset(vstorPacket, 0, sizeof(struct vstor_packet));
vstorPacket->Operation = VStorOperationQueryProperties;
vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
vstorPacket->StorageChannelProperties.PortNumber =
DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION...");
- memset(vstorPacket, sizeof(struct vstor_packet), 0);
+ memset(vstorPacket, 0, sizeof(struct vstor_packet));
vstorPacket->Operation = VStorOperationEndInitialization;
vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
int ret;
storDriver = (struct storvsc_driver_object *)Device->Driver;
- memset(&props, sizeof(struct vmstorage_channel_properties), 0);
+ memset(&props, 0, sizeof(struct vmstorage_channel_properties));
/* Open the channel */
ret = Device->Driver->VmbusChannelInterface.Open(Device,
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*/
#include <linux/init.h>
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
+ * Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*/
#include <linux/init.h>
- sparse fixes
- integrate with drivers/net/wireless/rtl818x
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
-Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
- sparse fixes
- integrate with drivers/net/wireless/rtl818x
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
-Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
- sparse fixes
- integrate with drivers/net/wireless
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>,
-Forest Bond <forest@alittletooquiet.net> and Bartlomiej Zolnierkiewicz
-<bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
+and Forest Bond <forest@alittletooquiet.net>.
- sparse fixes
- integrate with drivers/net/wireless
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>,
-Forest Bond <forest@alittletooquiet.net> and Bartlomiej Zolnierkiewicz
-<bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
+and Forest Bond <forest@alittletooquiet.net>.
static inline int
hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
{
- return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
+ return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo,
tt, NULL, 0, 1000);
}
tmp &= AMD_UNMASK_BIT(ep->num);
writel(tmp, &dev->regs->ep_irqmsk);
}
- }
+ } else if (ep->in) {
+ /* enable ep irq */
+ tmp = readl(&dev->regs->ep_irqmsk);
+ tmp &= AMD_UNMASK_BIT(ep->num);
+ writel(tmp, &dev->regs->ep_irqmsk);
+ }
} else if (ep->dma) {
{
int tmp;
- /* empty queues and init hardware */
- udc_basic_init(dev);
- for (tmp = 0; tmp < UDC_EP_NUM; tmp++) {
- empty_req_queue(&dev->ep[tmp]);
- }
-
if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
spin_unlock(&dev->lock);
driver->disconnect(&dev->gadget);
spin_lock(&dev->lock);
}
- /* init */
+
+ /* empty queues and init hardware */
+ udc_basic_init(dev);
+ for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
+ empty_req_queue(&dev->ep[tmp]);
+
udc_setup_endpoints(dev);
}
}
}
+ } else if (!use_dma && ep->in) {
+ /* disable interrupt */
+ tmp = readl(
+ &dev->regs->ep_irqmsk);
+ tmp |= AMD_BIT(ep->num);
+ writel(tmp,
+ &dev->regs->ep_irqmsk);
}
}
/* clear status bits */
goto finished;
}
+ spin_lock_init(&dev->lock);
+ /* udc csr registers base */
+ dev->csr = dev->virt_addr + UDC_CSR_ADDR;
+ /* dev registers base */
+ dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
+ /* ep registers base */
+ dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
+ /* fifo's base */
+ dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
+ dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
+
if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
kfree(dev);
udc_pollstall_timer.data = 0;
/* device struct setup */
- spin_lock_init(&dev->lock);
dev->gadget.ops = &udc_ops;
dev_set_name(&dev->gadget.dev, "gadget");
dev->gadget.name = name;
dev->gadget.is_dualspeed = 1;
- /* udc csr registers base */
- dev->csr = dev->virt_addr + UDC_CSR_ADDR;
- /* dev registers base */
- dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
- /* ep registers base */
- dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
- /* fifo's base */
- dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
- dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
-
/* init registers, interrupts, ... */
startup_registers(dev);
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
+#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
msleep(5);
up_write(&ehci_cf_port_reset_rwsem);
+ ehci->last_periodic_enable = ktime_get_real();
temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
ehci_info (ehci,
switch (pdev->vendor) {
case PCI_VENDOR_ID_INTEL:
ehci->need_io_watchdog = 0;
+ if (pdev->device == 0x27cc) {
+ ehci->broken_periodic = 1;
+ ehci_info(ehci, "using broken periodic workaround\n");
+ }
break;
case PCI_VENDOR_ID_TDI:
if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
* we must clear the TT buffer (11.17.5).
*/
if (unlikely(last_status != -EINPROGRESS &&
- last_status != -EREMOTEIO))
- ehci_clear_tt_buffer(ehci, qh, urb, token);
+ last_status != -EREMOTEIO)) {
+ /* The TT's in some hubs malfunction when they
+ * receive this request following a STALL (they
+ * stop sending isochronous packets). Since a
+ * STALL can't leave the TT buffer in a busy
+ * state (if you believe Figures 11-48 - 11-51
+ * in the USB 2.0 spec), we won't clear the TT
+ * buffer in this case. Strictly speaking this
+ * is a violation of the spec.
+ */
+ if (last_status != -EPIPE)
+ ehci_clear_tt_buffer(ehci, qh, urb,
+ token);
+ }
}
/* if we're removing something not at the queue head,
/* make sure ehci_work scans these */
ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index)
% (ehci->periodic_size << 3);
+ if (unlikely(ehci->broken_periodic))
+ ehci->last_periodic_enable = ktime_get_real();
return 0;
}
if (--ehci->periodic_sched)
return 0;
+ if (unlikely(ehci->broken_periodic)) {
+ /* delay experimentally determined */
+ ktime_t safe = ktime_add_us(ehci->last_periodic_enable, 1000);
+ ktime_t now = ktime_get_real();
+ s64 delay = ktime_us_delta(safe, now);
+
+ if (unlikely(delay > 0))
+ udelay(delay);
+ }
+
/* did setting PSE not take effect yet?
* takes effect only at frame boundaries...
*/
unsigned stamp;
unsigned random_frame;
unsigned long next_statechange;
+ ktime_t last_periodic_enable;
u32 command;
/* SILICON QUIRKS */
unsigned big_endian_desc:1;
unsigned has_amcc_usb23:1;
unsigned need_io_watchdog:1;
+ unsigned broken_periodic:1;
/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
musb_writew(regs, MUSB_TXCSR, value);
musb_writew(regs, MUSB_TXCSR, value);
- /* re-enable interrupt */
- if (enabled)
- musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
- (1 << cppi_ch->index));
-
/* While we scrub the TX state RAM, ensure that we clean
* up any interrupt that's currently asserted:
* 1. Write to completion Ptr value 0x1(bit 0 set)
cppi_reset_tx(tx_ram, 1);
musb_writel(&tx_ram->tx_complete, 0, 0);
+ /* re-enable interrupt */
+ if (enabled)
+ musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
+ (1 << cppi_ch->index));
+
cppi_dump_tx(5, cppi_ch, " (done teardown)");
/* REVISIT tx side _should_ clean up the same way
#endif
if (hw_ep->max_packet_sz_tx) {
- printk(KERN_DEBUG
+ DBG(1,
"%s: hw_ep %d%s, %smax %d\n",
musb_driver_name, i,
hw_ep->is_shared_fifo ? "shared" : "tx",
hw_ep->max_packet_sz_tx);
}
if (hw_ep->max_packet_sz_rx && !hw_ep->is_shared_fifo) {
- printk(KERN_DEBUG
+ DBG(1,
"%s: hw_ep %d%s, %smax %d\n",
musb_driver_name, i,
"rx",
* Copyright 2005 Mentor Graphics Corporation
* Copyright (C) 2005-2006 by Texas Instruments
* Copyright (C) 2006-2007 Nokia Corporation
+ * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
csr |= MUSB_TXCSR_P_WZC_BITS;
csr &= ~MUSB_TXCSR_P_SENTSTALL;
musb_writew(epio, MUSB_TXCSR, csr);
- if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
- dma->status = MUSB_DMA_STATUS_CORE_ABORT;
- musb->dma_controller->channel_abort(dma);
- }
-
- if (request)
- musb_g_giveback(musb_ep, request, -EPIPE);
-
break;
}
*/
static void rxstate(struct musb *musb, struct musb_request *req)
{
- u16 csr = 0;
const u8 epnum = req->epnum;
struct usb_request *request = &req->request;
struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
void __iomem *epio = musb->endpoints[epnum].regs;
unsigned fifo_count = 0;
u16 len = musb_ep->packet_sz;
+ u16 csr = musb_readw(epio, MUSB_RXCSR);
- csr = musb_readw(epio, MUSB_RXCSR);
+ /* We shouldn't get here while DMA is active, but we do... */
+ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
+ DBG(4, "DMA pending...\n");
+ return;
+ }
+
+ if (csr & MUSB_RXCSR_P_SENDSTALL) {
+ DBG(5, "%s stalling, RXCSR %04x\n",
+ musb_ep->end_point.name, csr);
+ return;
+ }
if (is_cppi_enabled() && musb_ep->dma) {
struct dma_controller *c = musb->dma_controller;
csr, dma ? " (dma)" : "", request);
if (csr & MUSB_RXCSR_P_SENTSTALL) {
- if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
- dma->status = MUSB_DMA_STATUS_CORE_ABORT;
- (void) musb->dma_controller->channel_abort(dma);
- request->actual += musb_ep->dma->actual_len;
- }
-
csr |= MUSB_RXCSR_P_WZC_BITS;
csr &= ~MUSB_RXCSR_P_SENTSTALL;
musb_writew(epio, MUSB_RXCSR, csr);
-
- if (request)
- musb_g_giveback(musb_ep, request, -EPIPE);
- goto done;
+ return;
}
if (csr & MUSB_RXCSR_P_OVERRUN) {
DBG((csr & MUSB_RXCSR_DMAENAB) ? 4 : 1,
"%s busy, csr %04x\n",
musb_ep->end_point.name, csr);
- goto done;
+ return;
}
if (dma && (csr & MUSB_RXCSR_DMAENAB)) {
if ((request->actual < request->length)
&& (musb_ep->dma->actual_len
== musb_ep->packet_sz))
- goto done;
+ return;
#endif
musb_g_giveback(musb_ep, request, 0);
request = next_request(musb_ep);
if (!request)
- goto done;
-
- /* don't start more i/o till the stall clears */
- musb_ep_select(mbase, epnum);
- csr = musb_readw(epio, MUSB_RXCSR);
- if (csr & MUSB_RXCSR_P_SENDSTALL)
- goto done;
+ return;
}
-
/* analyze request if the ep is hot */
if (request)
rxstate(musb, to_musb_request(request));
DBG(3, "packet waiting for %s%s request\n",
musb_ep->desc ? "" : "inactive ",
musb_ep->end_point.name);
-
-done:
return;
}
void __iomem *mbase;
unsigned long flags;
u16 csr;
- struct musb_request *request = NULL;
+ struct musb_request *request;
int status = 0;
if (!ep)
musb_ep_select(mbase, epnum);
- /* cannot portably stall with non-empty FIFO */
request = to_musb_request(next_request(musb_ep));
- if (value && musb_ep->is_in) {
- csr = musb_readw(epio, MUSB_TXCSR);
- if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
- DBG(3, "%s fifo busy, cannot halt\n", ep->name);
- spin_unlock_irqrestore(&musb->lock, flags);
- return -EAGAIN;
+ if (value) {
+ if (request) {
+ DBG(3, "request in progress, cannot halt %s\n",
+ ep->name);
+ status = -EAGAIN;
+ goto done;
+ }
+ /* Cannot portably stall with non-empty FIFO */
+ if (musb_ep->is_in) {
+ csr = musb_readw(epio, MUSB_TXCSR);
+ if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
+ DBG(3, "FIFO busy, cannot halt %s\n", ep->name);
+ status = -EAGAIN;
+ goto done;
+ }
}
-
}
/* set/clear the stall and toggle bits */
DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear");
if (musb_ep->is_in) {
csr = musb_readw(epio, MUSB_TXCSR);
- if (csr & MUSB_TXCSR_FIFONOTEMPTY)
- csr |= MUSB_TXCSR_FLUSHFIFO;
csr |= MUSB_TXCSR_P_WZC_BITS
| MUSB_TXCSR_CLRDATATOG;
if (value)
musb_writew(epio, MUSB_RXCSR, csr);
}
-done:
-
/* maybe start the first request in the queue */
if (!musb_ep->busy && !value && request) {
DBG(3, "restarting the request\n");
musb_ep_restart(musb, request);
}
+done:
spin_unlock_irqrestore(&musb->lock, flags);
return status;
}
/* update the flags */
if (fifo_count < MUSB_MAX_END0_PACKET
- || request->actual == request->length) {
+ || (request->actual == request->length
+ && !request->zero)) {
musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT;
csr |= MUSB_CSR0_P_DATAEND;
} else
return;
} else if (usb_pipeisoc(pipe) && dma) {
if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb,
- offset, length))
+ offset, length)) {
+ if (is_cppi_enabled() || tusb_dma_omap())
+ musb_h_tx_dma_start(hw_ep);
return;
+ }
} else if (tx_csr & MUSB_TXCSR_DMAENAB) {
DBG(1, "not complete, but DMA enabled?\n");
return;
return;
}
/* account for transferred data */
- countback = urb->actual_length;
+ countback = urb->transfer_buffer_length;
data_offset = priv->write_offset;
if (data_offset > 0) {
/* Subtract the control bytes */
if (status) {
dbg("nonzero write bulk status received: %d", status);
- return;
}
usb_serial_port_softint(port);
#define AIRPLUS_VENDOR_ID 0x1011
#define AIRPLUS_PRODUCT_MCD650 0x3198
+/* 4G Systems products */
+#define FOUR_G_SYSTEMS_VENDOR_ID 0x1c9e
+#define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603
+
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
+ { USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
var->transp.length = 0;
break;
case 16: /* RGB 565 */
- var->red.offset = 0;
+ var->red.offset = 11;
var->red.length = 5;
var->green.offset = 5;
var->green.length = 6;
- var->blue.offset = 11;
+ var->blue.offset = 0;
var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
- info->screen_base,
+ info->screen_base - PAGE_SIZE,
info->fix.smem_start);
free_irq(par->irq, par);
clk_disable(par->lcdc_clk);
(PAGE_SIZE - par->palette_sz);
/* the rest of the frame buffer is pixel data */
+ da8xx_fb_info->screen_base = par->v_palette_base + par->palette_sz;
da8xx_fb_fix.smem_start = par->p_palette_base + par->palette_sz;
da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz;
da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8;
da8xx_fb_info->var = da8xx_fb_var;
da8xx_fb_info->fbops = &da8xx_fb_ops;
da8xx_fb_info->pseudo_palette = par->pseudo_palette;
+ da8xx_fb_info->fix.visual = (da8xx_fb_info->var.bits_per_pixel <= 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
if (ret)
err_release_fb_mem:
dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
- da8xx_fb_info->screen_base,
+ da8xx_fb_info->screen_base - PAGE_SIZE,
da8xx_fb_info->fix.smem_start);
err_release_fb:
static int timeout = WATCHDOG_TIMEOUT;
module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout, "Watchdog timeout value, in seconds (default="
- WATCHDOG_TIMEOUT ")");
+ __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
return -ENODEV;
}
- wdt_reg = ioremap_nocache(r->start, r->end - r->start);
+ wdt_reg = ioremap_nocache(r->start, resource_size(r));
if (!wdt_reg) {
printk(KERN_ERR PFX "failed to remap I/O resources\n");
return -ENXIO;
BUG_ON(!vcookie->fscache);
- return fscache_maybe_release_page(vnode->cache, page, gfp);
+ return fscache_maybe_release_page(vcookie->fscache, page, gfp);
}
void __v9fs_fscache_invalidate_page(struct page *page)
#include <linux/mount.h>
#include <linux/file.h>
+#include <linux/ima.h>
#include "internal.h"
/*
if (IS_ERR(file)) {
ret = PTR_ERR(file);
} else {
+ ima_counts_get(file);
ret = -EIO;
if (file->f_op->write) {
pos = (loff_t) page->index << PAGE_SHIFT;
#include <linux/timer.h>
struct slow_work;
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
struct seq_file;
#endif
/* execute a work item */
void (*execute)(struct slow_work *work);
-#ifdef CONFIG_SLOW_WORK_PROC
- /* describe a work item for /proc */
+#ifdef CONFIG_SLOW_WORK_DEBUG
+ /* describe a work item for debugfs */
void (*desc)(struct slow_work *work, struct seq_file *m);
#endif
};
#define SLOW_WORK_DELAYED 5 /* item is struct delayed_slow_work with active timer */
const struct slow_work_ops *ops; /* operations table for this item */
struct list_head link; /* link in queue */
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
struct timespec mark; /* jiffies at which queued or exec begun */
#endif
};
bool
config SYSFS_DEPRECATED_V2
- bool "remove sysfs features which may confuse old userspace tools"
+ bool "enable deprecated sysfs features which may confuse old userspace tools"
depends on SYSFS
default n
select SYSFS_DEPRECATED
See Documentation/slow-work.txt.
-config SLOW_WORK_PROC
- bool "Slow work debugging through /proc"
+config SLOW_WORK_DEBUG
+ bool "Slow work debugging through debugfs"
default n
- depends on SLOW_WORK && PROC_FS
+ depends on SLOW_WORK && DEBUG_FS
help
- Display the contents of the slow work run queue through /proc,
+ Display the contents of the slow work run queue through debugfs,
including items currently executing.
See Documentation/slow-work.txt.
/*
* Unknown boot options get handed to init, unless they look like
- * failed parameters
+ * unused parameters (modprobe will find them in /proc/cmdline).
*/
static int __init unknown_bootoption(char *param, char *val)
{
if (obsolete_checksetup(param))
return 0;
- /*
- * Preemptive maintenance for "why didn't my misspelled command
- * line work?"
- */
- if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
- printk(KERN_ERR "Unknown boot option `%s': ignoring\n", param);
+ /* Unused module parameter. */
+ if (strchr(param, '.') && (!val || strchr(param, '.') < val))
return 0;
- }
if (panic_later)
return 0;
obj-$(CONFIG_RING_BUFFER) += trace/
obj-$(CONFIG_SMP) += sched_cpupri.o
obj-$(CONFIG_SLOW_WORK) += slow-work.o
-obj-$(CONFIG_SLOW_WORK_PROC) += slow-work-proc.o
+obj-$(CONFIG_SLOW_WORK_DEBUG) += slow-work-debugfs.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
/* Count loaded sections and allocate structures */
for (i = 0; i < nsect; i++)
- if (sechdrs[i].sh_flags & SHF_ALLOC)
+ if (sechdrs[i].sh_flags & SHF_ALLOC
+ && sechdrs[i].sh_size)
nloaded++;
size[0] = ALIGN(sizeof(*sect_attrs)
+ nloaded * sizeof(sect_attrs->attrs[0]),
for (i = 0; i < nsect; i++) {
if (! (sechdrs[i].sh_flags & SHF_ALLOC))
continue;
+ if (!sechdrs[i].sh_size)
+ continue;
sattr->address = sechdrs[i].sh_addr;
sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
GFP_KERNEL);
}
/*
- * Describe a slow work item for /proc
+ * Describe a slow work item for debugfs
*/
static int slow_work_runqueue_show(struct seq_file *m, void *v)
{
};
/*
- * open "/proc/slow_work_rq" to list queue contents
+ * open "/sys/kernel/debug/slow_work/runqueue" to list queue contents
*/
static int slow_work_runqueue_open(struct inode *inode, struct file *file)
{
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/wait.h>
-#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
#include "slow-work.h"
static void slow_work_cull_timeout(unsigned long);
static struct slow_work *slow_work_unreg_work_item;
static DECLARE_WAIT_QUEUE_HEAD(slow_work_unreg_wq);
static DEFINE_MUTEX(slow_work_unreg_sync_lock);
+
+static void slow_work_set_thread_processing(int id, struct slow_work *work)
+{
+ if (work)
+ slow_work_thread_processing[id] = work->owner;
+}
+static void slow_work_done_thread_processing(int id, struct slow_work *work)
+{
+ struct module *module = slow_work_thread_processing[id];
+
+ slow_work_thread_processing[id] = NULL;
+ smp_mb();
+ if (slow_work_unreg_work_item == work ||
+ slow_work_unreg_module == module)
+ wake_up_all(&slow_work_unreg_wq);
+}
+static void slow_work_clear_thread_processing(int id)
+{
+ slow_work_thread_processing[id] = NULL;
+}
+#else
+static void slow_work_set_thread_processing(int id, struct slow_work *work) {}
+static void slow_work_done_thread_processing(int id, struct slow_work *work) {}
+static void slow_work_clear_thread_processing(int id) {}
#endif
/*
* Data for tracking currently executing items for indication through /proc
*/
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
struct slow_work *slow_work_execs[SLOW_WORK_THREAD_LIMIT];
pid_t slow_work_pids[SLOW_WORK_THREAD_LIMIT];
DEFINE_RWLOCK(slow_work_execs_lock);
*/
static noinline bool slow_work_execute(int id)
{
-#ifdef CONFIG_MODULES
- struct module *module;
-#endif
struct slow_work *work = NULL;
unsigned vsmax;
bool very_slow;
very_slow = false; /* avoid the compiler warning */
}
-#ifdef CONFIG_MODULES
- if (work)
- slow_work_thread_processing[id] = work->owner;
-#endif
+ slow_work_set_thread_processing(id, work);
if (work) {
slow_work_mark_time(work);
slow_work_begin_exec(id, work);
/* sort out the race between module unloading and put_ref() */
slow_work_put_ref(work);
-
-#ifdef CONFIG_MODULES
- module = slow_work_thread_processing[id];
- slow_work_thread_processing[id] = NULL;
- smp_mb();
- if (slow_work_unreg_work_item == work ||
- slow_work_unreg_module == module)
- wake_up_all(&slow_work_unreg_wq);
-#endif
+ slow_work_done_thread_processing(id, work);
return true;
else
list_add_tail(&work->link, &slow_work_queue);
spin_unlock_irq(&slow_work_queue_lock);
- slow_work_thread_processing[id] = NULL;
+ slow_work_clear_thread_processing(id);
return true;
}
static const struct slow_work_ops slow_work_new_thread_ops = {
.owner = THIS_MODULE,
.execute = slow_work_new_thread_execute,
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
.desc = slow_work_new_thread_desc,
#endif
};
*/
static void slow_work_wait_for_items(struct module *module)
{
+#ifdef CONFIG_MODULES
DECLARE_WAITQUEUE(myself, current);
struct slow_work *work;
int loop;
remove_wait_queue(&slow_work_unreg_wq, &myself);
mutex_unlock(&slow_work_unreg_sync_lock);
+#endif /* CONFIG_MODULES */
}
/**
if (slow_work_max_max_threads < nr_cpus * 2)
slow_work_max_max_threads = nr_cpus * 2;
#endif
-#ifdef CONFIG_SLOW_WORK_PROC
- proc_create("slow_work_rq", S_IFREG | 0400, NULL,
- &slow_work_runqueue_fops);
+#ifdef CONFIG_SLOW_WORK_DEBUG
+ {
+ struct dentry *dbdir;
+
+ dbdir = debugfs_create_dir("slow_work", NULL);
+ if (dbdir && !IS_ERR(dbdir))
+ debugfs_create_file("runqueue", S_IFREG | 0400, dbdir,
+ NULL, &slow_work_runqueue_fops);
+ }
#endif
return 0;
}
/*
* slow-work.c
*/
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
extern struct slow_work *slow_work_execs[];
extern pid_t slow_work_pids[];
extern rwlock_t slow_work_execs_lock;
extern spinlock_t slow_work_queue_lock;
/*
- * slow-work-proc.c
+ * slow-work-debugfs.c
*/
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
extern const struct file_operations slow_work_runqueue_fops;
extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *);