mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-22 08:49:45 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Merge 'net' into 'net-next' to get the MSG_CMSG_COMPAT regression fix. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
93a306aef5
58 changed files with 520 additions and 323 deletions
|
@ -33,6 +33,9 @@ When mounting an XFS filesystem, the following options are accepted.
|
|||
removing extended attributes) the on-disk superblock feature
|
||||
bit field will be updated to reflect this format being in use.
|
||||
|
||||
CRC enabled filesystems always use the attr2 format, and so
|
||||
will reject the noattr2 mount option if it is set.
|
||||
|
||||
barrier
|
||||
Enables the use of block layer write barriers for writes into
|
||||
the journal and unwritten extent conversion. This allows for
|
||||
|
|
|
@ -33,18 +33,6 @@
|
|||
#include <asm/pgalloc.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
/*
|
||||
* We need to delay page freeing for SMP as other CPUs can access pages
|
||||
* which have been removed but not yet had their TLB entries invalidated.
|
||||
* Also, as ARMv7 speculative prefetch can drag new entries into the TLB,
|
||||
* we need to apply this same delaying tactic to ensure correct operation.
|
||||
*/
|
||||
#if defined(CONFIG_SMP) || defined(CONFIG_CPU_32v7)
|
||||
#define tlb_fast_mode(tlb) 0
|
||||
#else
|
||||
#define tlb_fast_mode(tlb) 1
|
||||
#endif
|
||||
|
||||
#define MMU_GATHER_BUNDLE 8
|
||||
|
||||
/*
|
||||
|
@ -112,12 +100,10 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb)
|
|||
static inline void tlb_flush_mmu(struct mmu_gather *tlb)
|
||||
{
|
||||
tlb_flush(tlb);
|
||||
if (!tlb_fast_mode(tlb)) {
|
||||
free_pages_and_swap_cache(tlb->pages, tlb->nr);
|
||||
tlb->nr = 0;
|
||||
if (tlb->pages == tlb->local)
|
||||
__tlb_alloc_page(tlb);
|
||||
}
|
||||
free_pages_and_swap_cache(tlb->pages, tlb->nr);
|
||||
tlb->nr = 0;
|
||||
if (tlb->pages == tlb->local)
|
||||
__tlb_alloc_page(tlb);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -178,11 +164,6 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
|
|||
|
||||
static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
|
||||
{
|
||||
if (tlb_fast_mode(tlb)) {
|
||||
free_page_and_swap_cache(page);
|
||||
return 1; /* avoid calling tlb_flush_mmu */
|
||||
}
|
||||
|
||||
tlb->pages[tlb->nr++] = page;
|
||||
VM_BUG_ON(tlb->nr > tlb->max);
|
||||
return tlb->max - tlb->nr;
|
||||
|
|
|
@ -46,12 +46,6 @@
|
|||
#include <asm/tlbflush.h>
|
||||
#include <asm/machvec.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# define tlb_fast_mode(tlb) ((tlb)->nr == ~0U)
|
||||
#else
|
||||
# define tlb_fast_mode(tlb) (1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we can't allocate a page to make a big batch of page pointers
|
||||
* to work on, then just handle a few from the on-stack structure.
|
||||
|
@ -60,7 +54,7 @@
|
|||
|
||||
struct mmu_gather {
|
||||
struct mm_struct *mm;
|
||||
unsigned int nr; /* == ~0U => fast mode */
|
||||
unsigned int nr;
|
||||
unsigned int max;
|
||||
unsigned char fullmm; /* non-zero means full mm flush */
|
||||
unsigned char need_flush; /* really unmapped some PTEs? */
|
||||
|
@ -103,6 +97,7 @@ extern struct ia64_tr_entry *ia64_idtrs[NR_CPUS];
|
|||
static inline void
|
||||
ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned long i;
|
||||
unsigned int nr;
|
||||
|
||||
if (!tlb->need_flush)
|
||||
|
@ -141,13 +136,11 @@ ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long e
|
|||
|
||||
/* lastly, release the freed pages */
|
||||
nr = tlb->nr;
|
||||
if (!tlb_fast_mode(tlb)) {
|
||||
unsigned long i;
|
||||
tlb->nr = 0;
|
||||
tlb->start_addr = ~0UL;
|
||||
for (i = 0; i < nr; ++i)
|
||||
free_page_and_swap_cache(tlb->pages[i]);
|
||||
}
|
||||
|
||||
tlb->nr = 0;
|
||||
tlb->start_addr = ~0UL;
|
||||
for (i = 0; i < nr; ++i)
|
||||
free_page_and_swap_cache(tlb->pages[i]);
|
||||
}
|
||||
|
||||
static inline void __tlb_alloc_page(struct mmu_gather *tlb)
|
||||
|
@ -167,20 +160,7 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_m
|
|||
tlb->mm = mm;
|
||||
tlb->max = ARRAY_SIZE(tlb->local);
|
||||
tlb->pages = tlb->local;
|
||||
/*
|
||||
* Use fast mode if only 1 CPU is online.
|
||||
*
|
||||
* It would be tempting to turn on fast-mode for full_mm_flush as well. But this
|
||||
* doesn't work because of speculative accesses and software prefetching: the page
|
||||
* table of "mm" may (and usually is) the currently active page table and even
|
||||
* though the kernel won't do any user-space accesses during the TLB shoot down, a
|
||||
* compiler might use speculation or lfetch.fault on what happens to be a valid
|
||||
* user-space address. This in turn could trigger a TLB miss fault (or a VHPT
|
||||
* walk) and re-insert a TLB entry we just removed. Slow mode avoids such
|
||||
* problems. (We could make fast-mode work by switching the current task to a
|
||||
* different "mm" during the shootdown.) --davidm 08/02/2002
|
||||
*/
|
||||
tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
|
||||
tlb->nr = 0;
|
||||
tlb->fullmm = full_mm_flush;
|
||||
tlb->start_addr = ~0UL;
|
||||
}
|
||||
|
@ -214,11 +194,6 @@ static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
|
|||
{
|
||||
tlb->need_flush = 1;
|
||||
|
||||
if (tlb_fast_mode(tlb)) {
|
||||
free_page_and_swap_cache(page);
|
||||
return 1; /* avoid calling tlb_flush_mmu */
|
||||
}
|
||||
|
||||
if (!tlb->nr && tlb->pages == tlb->local)
|
||||
__tlb_alloc_page(tlb);
|
||||
|
||||
|
|
|
@ -628,7 +628,9 @@ int pcibios_add_device(struct pci_dev *dev)
|
|||
|
||||
pa_data = boot_params.hdr.setup_data;
|
||||
while (pa_data) {
|
||||
data = phys_to_virt(pa_data);
|
||||
data = ioremap(pa_data, sizeof(*rom));
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
if (data->type == SETUP_PCI) {
|
||||
rom = (struct pci_setup_rom *)data;
|
||||
|
@ -645,6 +647,7 @@ int pcibios_add_device(struct pci_dev *dev)
|
|||
}
|
||||
}
|
||||
pa_data = data->next;
|
||||
iounmap(data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
|
|||
while (chan->indio_dev) {
|
||||
if (chan->indio_dev != indio_dev) {
|
||||
ret = -EINVAL;
|
||||
goto error_release_channels;
|
||||
goto error_free_scan_mask;
|
||||
}
|
||||
set_bit(chan->channel->scan_index,
|
||||
cb_buff->buffer.scan_mask);
|
||||
|
@ -73,6 +73,8 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
|
|||
|
||||
return cb_buff;
|
||||
|
||||
error_free_scan_mask:
|
||||
kfree(cb_buff->buffer.scan_mask);
|
||||
error_release_channels:
|
||||
iio_channel_release_all(cb_buff->channels);
|
||||
error_free_cb_buff:
|
||||
|
@ -100,6 +102,7 @@ EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
|
|||
|
||||
void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
|
||||
{
|
||||
kfree(cb_buff->buffer.scan_mask);
|
||||
iio_channel_release_all(cb_buff->channels);
|
||||
kfree(cb_buff);
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq)
|
|||
(pdata->r2_user_settings & (ADF4350_REG2_PD_POLARITY_POS |
|
||||
ADF4350_REG2_LDP_6ns | ADF4350_REG2_LDF_INT_N |
|
||||
ADF4350_REG2_CHARGE_PUMP_CURR_uA(5000) |
|
||||
ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x9)));
|
||||
ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x3)));
|
||||
|
||||
st->regs[ADF4350_REG3] = pdata->r3_user_settings &
|
||||
(ADF4350_REG3_12BIT_CLKDIV(0xFFF) |
|
||||
|
|
|
@ -124,7 +124,7 @@ static int __of_iio_channel_get(struct iio_channel *channel,
|
|||
channel->indio_dev = indio_dev;
|
||||
index = iiospec.args_count ? iiospec.args[0] : 0;
|
||||
if (index >= indio_dev->num_channels) {
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto err_put;
|
||||
}
|
||||
channel->channel = &indio_dev->channels[index];
|
||||
|
@ -450,7 +450,7 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
|
|||
s64 raw64 = raw;
|
||||
int ret;
|
||||
|
||||
ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE);
|
||||
ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_OFFSET);
|
||||
if (ret == 0)
|
||||
raw64 += offset;
|
||||
|
||||
|
|
|
@ -264,6 +264,8 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
}
|
||||
|
||||
rv = alarm_do_ioctl(file, cmd, &ts);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
|
||||
case ANDROID_ALARM_GET_TIME(0):
|
||||
|
@ -272,7 +274,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
|
@ -295,6 +297,8 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
|
|||
}
|
||||
|
||||
rv = alarm_do_ioctl(file, cmd, &ts);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
|
||||
case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */
|
||||
|
@ -303,7 +307,7 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
|
|||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2804,9 +2804,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
|
|||
|
||||
/* Set device flags indicating whether the HCD supports DMA */
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(31)) < 0)
|
||||
dev_warn(hsotg->dev,
|
||||
"can't enable workaround for >2GB RAM\n");
|
||||
if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0)
|
||||
dev_warn(hsotg->dev, "can't set DMA mask\n");
|
||||
if (dma_set_coherent_mask(hsotg->dev, DMA_BIT_MASK(31)) < 0)
|
||||
dev_warn(hsotg->dev,
|
||||
"can't enable workaround for >2GB RAM\n");
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
#ifndef _ZCACHE_RAMSTER_H_
|
||||
#define _ZCACHE_RAMSTER_H_
|
||||
|
||||
#ifdef CONFIG_RAMSTER_MODULE
|
||||
#define CONFIG_RAMSTER
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RAMSTER
|
||||
#include "ramster/ramster.h"
|
||||
#else
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <linux/atomic.h>
|
||||
#include "debug.h"
|
||||
|
||||
ssize_t ramster_foreign_eph_pages;
|
||||
ssize_t ramster_foreign_pers_pages;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
|
|
|
@ -66,8 +66,6 @@ static int ramster_remote_target_nodenum __read_mostly = -1;
|
|||
|
||||
/* Used by this code. */
|
||||
long ramster_flnodes;
|
||||
ssize_t ramster_foreign_eph_pages;
|
||||
ssize_t ramster_foreign_pers_pages;
|
||||
/* FIXME frontswap selfshrinking knobs in debugfs? */
|
||||
|
||||
static LIST_HEAD(ramster_rem_op_list);
|
||||
|
@ -399,14 +397,18 @@ void ramster_count_foreign_pages(bool eph, int count)
|
|||
inc_ramster_foreign_eph_pages();
|
||||
} else {
|
||||
dec_ramster_foreign_eph_pages();
|
||||
#ifdef CONFIG_RAMSTER_DEBUG
|
||||
WARN_ON_ONCE(ramster_foreign_eph_pages < 0);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (count > 0) {
|
||||
inc_ramster_foreign_pers_pages();
|
||||
} else {
|
||||
dec_ramster_foreign_pers_pages();
|
||||
#ifdef CONFIG_RAMSTER_DEBUG
|
||||
WARN_ON_ONCE(ramster_foreign_pers_pages < 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2755,7 +2755,7 @@ static void __init serial8250_isa_init_ports(void)
|
|||
if (nr_uarts > UART_NR)
|
||||
nr_uarts = UART_NR;
|
||||
|
||||
for (i = 0; i < UART_NR; i++) {
|
||||
for (i = 0; i < nr_uarts; i++) {
|
||||
struct uart_8250_port *up = &serial8250_ports[i];
|
||||
struct uart_port *port = &up->port;
|
||||
|
||||
|
@ -2916,7 +2916,7 @@ static int __init serial8250_console_setup(struct console *co, char *options)
|
|||
* if so, search for the first available port that does have
|
||||
* console support.
|
||||
*/
|
||||
if (co->index >= UART_NR)
|
||||
if (co->index >= nr_uarts)
|
||||
co->index = 0;
|
||||
port = &serial8250_ports[co->index].port;
|
||||
if (!port->iobase && !port->membase)
|
||||
|
@ -2957,7 +2957,7 @@ int serial8250_find_port(struct uart_port *p)
|
|||
int line;
|
||||
struct uart_port *port;
|
||||
|
||||
for (line = 0; line < UART_NR; line++) {
|
||||
for (line = 0; line < nr_uarts; line++) {
|
||||
port = &serial8250_ports[line].port;
|
||||
if (uart_match_port(p, port))
|
||||
return line;
|
||||
|
@ -3110,7 +3110,7 @@ static int serial8250_remove(struct platform_device *dev)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < UART_NR; i++) {
|
||||
for (i = 0; i < nr_uarts; i++) {
|
||||
struct uart_8250_port *up = &serial8250_ports[i];
|
||||
|
||||
if (up->port.dev == &dev->dev)
|
||||
|
@ -3178,7 +3178,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
|
|||
/*
|
||||
* First, find a port entry which matches.
|
||||
*/
|
||||
for (i = 0; i < UART_NR; i++)
|
||||
for (i = 0; i < nr_uarts; i++)
|
||||
if (uart_match_port(&serial8250_ports[i].port, port))
|
||||
return &serial8250_ports[i];
|
||||
|
||||
|
@ -3187,7 +3187,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
|
|||
* free entry. We look for one which hasn't been previously
|
||||
* used (indicated by zero iobase).
|
||||
*/
|
||||
for (i = 0; i < UART_NR; i++)
|
||||
for (i = 0; i < nr_uarts; i++)
|
||||
if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
|
||||
serial8250_ports[i].port.iobase == 0)
|
||||
return &serial8250_ports[i];
|
||||
|
@ -3196,7 +3196,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
|
|||
* That also failed. Last resort is to find any entry which
|
||||
* doesn't have a real port associated with it.
|
||||
*/
|
||||
for (i = 0; i < UART_NR; i++)
|
||||
for (i = 0; i < nr_uarts; i++)
|
||||
if (serial8250_ports[i].port.type == PORT_UNKNOWN)
|
||||
return &serial8250_ports[i];
|
||||
|
||||
|
|
|
@ -761,6 +761,8 @@ static int imx_startup(struct uart_port *port)
|
|||
|
||||
temp = readl(sport->port.membase + UCR2);
|
||||
temp |= (UCR2_RXEN | UCR2_TXEN);
|
||||
if (!sport->have_rtscts)
|
||||
temp |= UCR2_IRTS;
|
||||
writel(temp, sport->port.membase + UCR2);
|
||||
|
||||
if (USE_IRDA(sport)) {
|
||||
|
|
|
@ -1166,6 +1166,18 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
|
|||
ourport->tx_irq = ret;
|
||||
|
||||
ourport->clk = clk_get(&platdev->dev, "uart");
|
||||
if (IS_ERR(ourport->clk)) {
|
||||
pr_err("%s: Controller clock not found\n",
|
||||
dev_name(&platdev->dev));
|
||||
return PTR_ERR(ourport->clk);
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(ourport->clk);
|
||||
if (ret) {
|
||||
pr_err("uart: clock failed to prepare+enable: %d\n", ret);
|
||||
clk_put(ourport->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Keep all interrupts masked and cleared */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port)) {
|
||||
|
@ -1180,6 +1192,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
|
|||
|
||||
/* reset the fifos (and setup the uart) */
|
||||
s3c24xx_serial_resetport(port, cfg);
|
||||
clk_disable_unprepare(ourport->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1287,9 +1287,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
|||
goto error;
|
||||
}
|
||||
for (totlen = u = 0; u < uurb->number_of_packets; u++) {
|
||||
/* arbitrary limit,
|
||||
* sufficient for USB 2.0 high-bandwidth iso */
|
||||
if (isopkt[u].length > 8192) {
|
||||
/*
|
||||
* arbitrary limit need for USB 3.0
|
||||
* bMaxBurst (0~15 allowed, 1~16 packets)
|
||||
* bmAttributes (bit 1:0, mult 0~2, 1~3 packets)
|
||||
* sizemax: 1024 * 16 * 3 = 49152
|
||||
*/
|
||||
if (isopkt[u].length > 49152) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -164,9 +164,9 @@ static int dwc3_exynos_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
|
||||
|
||||
device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
|
||||
platform_device_unregister(exynos->usb2_phy);
|
||||
platform_device_unregister(exynos->usb3_phy);
|
||||
device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
|
||||
|
||||
clk_disable_unprepare(exynos->clk);
|
||||
|
||||
|
|
|
@ -196,9 +196,9 @@ static void dwc3_pci_remove(struct pci_dev *pci)
|
|||
{
|
||||
struct dwc3_pci *glue = pci_get_drvdata(pci);
|
||||
|
||||
platform_device_unregister(glue->dwc3);
|
||||
platform_device_unregister(glue->usb2_phy);
|
||||
platform_device_unregister(glue->usb3_phy);
|
||||
platform_device_unregister(glue->dwc3);
|
||||
pci_set_drvdata(pci, NULL);
|
||||
pci_disable_device(pci);
|
||||
}
|
||||
|
|
|
@ -1706,11 +1706,19 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
|
|||
dep = dwc->eps[epnum];
|
||||
if (!dep)
|
||||
continue;
|
||||
|
||||
dwc3_free_trb_pool(dep);
|
||||
|
||||
if (epnum != 0 && epnum != 1)
|
||||
/*
|
||||
* Physical endpoints 0 and 1 are special; they form the
|
||||
* bi-directional USB endpoint 0.
|
||||
*
|
||||
* For those two physical endpoints, we don't allocate a TRB
|
||||
* pool nor do we add them the endpoints list. Due to that, we
|
||||
* shouldn't do these two operations otherwise we would end up
|
||||
* with all sorts of bugs when removing dwc3.ko.
|
||||
*/
|
||||
if (epnum != 0 && epnum != 1) {
|
||||
dwc3_free_trb_pool(dep);
|
||||
list_del(&dep->endpoint.ep_list);
|
||||
}
|
||||
|
||||
kfree(dep);
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
|
|||
}
|
||||
|
||||
static const unsigned char
|
||||
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };
|
||||
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
|
||||
|
||||
/* carryover low/fullspeed bandwidth that crosses uframe boundries */
|
||||
static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
|
||||
|
@ -646,6 +646,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|||
/* reschedule QH iff another request is queued */
|
||||
if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) {
|
||||
rc = qh_schedule(ehci, qh);
|
||||
if (rc == 0) {
|
||||
qh_refresh(ehci, qh);
|
||||
qh_link_periodic(ehci, qh);
|
||||
}
|
||||
|
||||
/* An error here likely indicates handshake failure
|
||||
* or no space left in the schedule. Neither fault
|
||||
|
@ -653,9 +657,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|||
*
|
||||
* FIXME kill the now-dysfunctional queued urbs
|
||||
*/
|
||||
if (rc != 0)
|
||||
else {
|
||||
ehci_err(ehci, "can't reschedule qh %p, err %d\n",
|
||||
qh, rc);
|
||||
}
|
||||
}
|
||||
|
||||
/* maybe turn off periodic schedule */
|
||||
|
|
|
@ -1827,6 +1827,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
|
|||
}
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
|
||||
if (!xhci->rh_bw)
|
||||
goto no_bw;
|
||||
|
||||
num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
|
||||
for (i = 0; i < num_ports; i++) {
|
||||
struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
|
||||
|
@ -1845,6 +1848,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
|
|||
}
|
||||
}
|
||||
|
||||
no_bw:
|
||||
xhci->num_usb2_ports = 0;
|
||||
xhci->num_usb3_ports = 0;
|
||||
xhci->num_active_eps = 0;
|
||||
|
@ -2256,6 +2260,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
|||
u32 page_size, temp;
|
||||
int i;
|
||||
|
||||
INIT_LIST_HEAD(&xhci->lpm_failed_devs);
|
||||
INIT_LIST_HEAD(&xhci->cancel_cmd_list);
|
||||
|
||||
page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
|
||||
xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
|
||||
for (i = 0; i < 16; i++) {
|
||||
|
@ -2334,7 +2341,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
|||
xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags);
|
||||
if (!xhci->cmd_ring)
|
||||
goto fail;
|
||||
INIT_LIST_HEAD(&xhci->cancel_cmd_list);
|
||||
xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
|
||||
xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
|
||||
(unsigned long long)xhci->cmd_ring->first_seg->dma);
|
||||
|
@ -2445,8 +2451,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
|||
if (xhci_setup_port_arrays(xhci, flags))
|
||||
goto fail;
|
||||
|
||||
INIT_LIST_HEAD(&xhci->lpm_failed_devs);
|
||||
|
||||
/* Enable USB 3.0 device notifications for function remote wake, which
|
||||
* is necessary for allowing USB 3.0 devices to do remote wakeup from
|
||||
* U3 (device suspend).
|
||||
|
|
|
@ -221,6 +221,14 @@ static void xhci_pci_remove(struct pci_dev *dev)
|
|||
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
|
||||
{
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
|
||||
/*
|
||||
* Systems with the TI redriver that loses port status change events
|
||||
* need to have the registers polled during D3, so avoid D3cold.
|
||||
*/
|
||||
if (xhci_compliance_mode_recovery_timer_quirk_check())
|
||||
pdev->no_d3cold = true;
|
||||
|
||||
return xhci_suspend(xhci);
|
||||
}
|
||||
|
|
|
@ -466,7 +466,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
|
|||
* Systems:
|
||||
* Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820
|
||||
*/
|
||||
static bool compliance_mode_recovery_timer_quirk_check(void)
|
||||
bool xhci_compliance_mode_recovery_timer_quirk_check(void)
|
||||
{
|
||||
const char *dmi_product_name, *dmi_sys_vendor;
|
||||
|
||||
|
@ -517,7 +517,7 @@ int xhci_init(struct usb_hcd *hcd)
|
|||
xhci_dbg(xhci, "Finished xhci_init\n");
|
||||
|
||||
/* Initializing Compliance Mode Recovery Data If Needed */
|
||||
if (compliance_mode_recovery_timer_quirk_check()) {
|
||||
if (xhci_compliance_mode_recovery_timer_quirk_check()) {
|
||||
xhci->quirks |= XHCI_COMP_MODE_QUIRK;
|
||||
compliance_mode_recovery_timer_init(xhci);
|
||||
}
|
||||
|
@ -956,6 +956,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|||
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
||||
struct usb_hcd *secondary_hcd;
|
||||
int retval = 0;
|
||||
bool comp_timer_running = false;
|
||||
|
||||
/* Wait a bit if either of the roothubs need to settle from the
|
||||
* transition into bus suspend.
|
||||
|
@ -993,6 +994,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|||
|
||||
/* If restore operation fails, re-initialize the HC during resume */
|
||||
if ((temp & STS_SRE) || hibernated) {
|
||||
|
||||
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
|
||||
!(xhci_all_ports_seen_u0(xhci))) {
|
||||
del_timer_sync(&xhci->comp_mode_recovery_timer);
|
||||
xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n");
|
||||
}
|
||||
|
||||
/* Let the USB core know _both_ roothubs lost power. */
|
||||
usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
|
||||
usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
|
||||
|
@ -1035,6 +1043,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|||
retval = xhci_init(hcd->primary_hcd);
|
||||
if (retval)
|
||||
return retval;
|
||||
comp_timer_running = true;
|
||||
|
||||
xhci_dbg(xhci, "Start the primary HCD\n");
|
||||
retval = xhci_run(hcd->primary_hcd);
|
||||
if (!retval) {
|
||||
|
@ -1076,7 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|||
* to suffer the Compliance Mode issue again. It doesn't matter if
|
||||
* ports have entered previously to U0 before system's suspension.
|
||||
*/
|
||||
if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
|
||||
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
|
||||
compliance_mode_recovery_timer_init(xhci);
|
||||
|
||||
/* Re-enable port polling. */
|
||||
|
|
|
@ -1853,4 +1853,7 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci,
|
|||
struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
|
||||
struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
|
||||
|
||||
/* xHCI quirks */
|
||||
bool xhci_compliance_mode_recovery_timer_quirk_check(void);
|
||||
|
||||
#endif /* __LINUX_XHCI_HCD_H */
|
||||
|
|
|
@ -1232,7 +1232,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
|
|||
void __iomem *mbase = musb->mregs;
|
||||
struct dma_channel *dma;
|
||||
bool transfer_pending = false;
|
||||
static bool use_sg;
|
||||
|
||||
musb_ep_select(mbase, epnum);
|
||||
tx_csr = musb_readw(epio, MUSB_TXCSR);
|
||||
|
@ -1463,9 +1462,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)
|
|||
* NULL.
|
||||
*/
|
||||
if (!urb->transfer_buffer)
|
||||
use_sg = true;
|
||||
qh->use_sg = true;
|
||||
|
||||
if (use_sg) {
|
||||
if (qh->use_sg) {
|
||||
/* sg_miter_start is already done in musb_ep_program */
|
||||
if (!sg_miter_next(&qh->sg_miter)) {
|
||||
dev_err(musb->controller, "error: sg list empty\n");
|
||||
|
@ -1484,9 +1483,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)
|
|||
|
||||
qh->segsize = length;
|
||||
|
||||
if (use_sg) {
|
||||
if (qh->use_sg) {
|
||||
if (offset + length >= urb->transfer_buffer_length)
|
||||
use_sg = false;
|
||||
qh->use_sg = false;
|
||||
}
|
||||
|
||||
musb_ep_select(mbase, epnum);
|
||||
|
@ -1552,7 +1551,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
|
|||
bool done = false;
|
||||
u32 status;
|
||||
struct dma_channel *dma;
|
||||
static bool use_sg;
|
||||
unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;
|
||||
|
||||
musb_ep_select(mbase, epnum);
|
||||
|
@ -1878,12 +1876,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)
|
|||
* NULL.
|
||||
*/
|
||||
if (!urb->transfer_buffer) {
|
||||
use_sg = true;
|
||||
qh->use_sg = true;
|
||||
sg_miter_start(&qh->sg_miter, urb->sg, 1,
|
||||
sg_flags);
|
||||
}
|
||||
|
||||
if (use_sg) {
|
||||
if (qh->use_sg) {
|
||||
if (!sg_miter_next(&qh->sg_miter)) {
|
||||
dev_err(musb->controller, "error: sg list empty\n");
|
||||
sg_miter_stop(&qh->sg_miter);
|
||||
|
@ -1913,8 +1911,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
|
|||
urb->actual_length += xfer_len;
|
||||
qh->offset += xfer_len;
|
||||
if (done) {
|
||||
if (use_sg)
|
||||
use_sg = false;
|
||||
if (qh->use_sg)
|
||||
qh->use_sg = false;
|
||||
|
||||
if (urb->status == -EINPROGRESS)
|
||||
urb->status = status;
|
||||
|
|
|
@ -74,6 +74,7 @@ struct musb_qh {
|
|||
u16 frame; /* for periodic schedule */
|
||||
unsigned iso_idx; /* in urb->iso_frame_desc[] */
|
||||
struct sg_mapping_iter sg_miter; /* for highmem in PIO mode */
|
||||
bool use_sg; /* to track urb using sglist */
|
||||
};
|
||||
|
||||
/* map from control or bulk queue head to the first qh on that ring */
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#define DRIVER_NAME "ark3116"
|
||||
|
||||
/* usb timeout of 1 second */
|
||||
#define ARK_TIMEOUT (1*HZ)
|
||||
#define ARK_TIMEOUT 1000
|
||||
|
||||
static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x6547, 0x0232) },
|
||||
|
|
|
@ -65,6 +65,7 @@ static const struct usb_device_id id_table_earthmate[] = {
|
|||
static const struct usb_device_id id_table_cyphidcomrs232[] = {
|
||||
{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
|
||||
{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
|
||||
{ USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
@ -78,6 +79,7 @@ static const struct usb_device_id id_table_combined[] = {
|
|||
{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
|
||||
{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
|
||||
{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
|
||||
{ USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
|
||||
{ USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
@ -229,6 +231,12 @@ static struct usb_serial_driver * const serial_drivers[] = {
|
|||
* Cypress serial helper functions
|
||||
*****************************************************************************/
|
||||
|
||||
/* FRWD Dongle hidcom needs to skip reset and speed checks */
|
||||
static inline bool is_frwd(struct usb_device *dev)
|
||||
{
|
||||
return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) &&
|
||||
(le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD));
|
||||
}
|
||||
|
||||
static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
|
||||
{
|
||||
|
@ -238,6 +246,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
|
|||
if (unstable_bauds)
|
||||
return new_rate;
|
||||
|
||||
/* FRWD Dongle uses 115200 bps */
|
||||
if (is_frwd(port->serial->dev))
|
||||
return new_rate;
|
||||
|
||||
/*
|
||||
* The general purpose firmware for the Cypress M8 allows for
|
||||
* a maximum speed of 57600bps (I have no idea whether DeLorme
|
||||
|
@ -448,7 +460,11 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
usb_reset_configuration(serial->dev);
|
||||
/* Skip reset for FRWD device. It is a workaound:
|
||||
device hangs if it receives SET_CONFIGURE in Configured
|
||||
state. */
|
||||
if (!is_frwd(serial->dev))
|
||||
usb_reset_configuration(serial->dev);
|
||||
|
||||
priv->cmd_ctrl = 0;
|
||||
priv->line_control = 0;
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#define VENDOR_ID_CYPRESS 0x04b4
|
||||
#define PRODUCT_ID_CYPHIDCOM 0x5500
|
||||
|
||||
/* FRWD Dongle - a GPS sports watch */
|
||||
#define VENDOR_ID_FRWD 0x6737
|
||||
#define PRODUCT_ID_CYPHIDCOM_FRWD 0x0001
|
||||
|
||||
/* Powercom UPS, chip CY7C63723 */
|
||||
#define VENDOR_ID_POWERCOM 0x0d9f
|
||||
#define PRODUCT_ID_UPS 0x0002
|
||||
|
|
|
@ -287,7 +287,7 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
|
|||
usb_bulk_msg(serial->dev,
|
||||
usb_sndbulkpipe(serial->dev,
|
||||
port->bulk_out_endpointAddress), buf,
|
||||
count, &actual, HZ * 1);
|
||||
count, &actual, 1000);
|
||||
|
||||
if (status != IUU_OPERATION_OK)
|
||||
dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
|
||||
|
@ -307,7 +307,7 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
|
|||
usb_bulk_msg(serial->dev,
|
||||
usb_rcvbulkpipe(serial->dev,
|
||||
port->bulk_in_endpointAddress), buf,
|
||||
count, &actual, HZ * 1);
|
||||
count, &actual, 1000);
|
||||
|
||||
if (status != IUU_OPERATION_OK)
|
||||
dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
|
||||
|
|
|
@ -1548,7 +1548,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
|
|||
struct keyspan_serial_private *s_priv;
|
||||
struct keyspan_port_private *p_priv;
|
||||
const struct keyspan_device_details *d_details;
|
||||
int outcont_urb;
|
||||
struct urb *this_urb;
|
||||
int device_port, err;
|
||||
|
||||
|
@ -1559,7 +1558,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
|
|||
d_details = s_priv->device_details;
|
||||
device_port = port->number - port->serial->minor;
|
||||
|
||||
outcont_urb = d_details->outcont_endpoints[port->number];
|
||||
this_urb = p_priv->outcont_urb;
|
||||
|
||||
dev_dbg(&port->dev, "%s - endpoint %d\n", __func__, usb_pipeendpoint(this_urb->pipe));
|
||||
|
@ -1685,14 +1683,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
|
|||
err = usb_submit_urb(this_urb, GFP_ATOMIC);
|
||||
if (err != 0)
|
||||
dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
|
||||
#if 0
|
||||
else {
|
||||
dev_dbg(&port->dev, "%s - usb_submit_urb(%d) OK %d bytes (end %d)\n", __func__
|
||||
outcont_urb, this_urb->transfer_buffer_length,
|
||||
usb_pipeendpoint(this_urb->pipe));
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#define DRIVER_DESC "Moschip USB Serial Driver"
|
||||
|
||||
/* default urb timeout */
|
||||
#define MOS_WDR_TIMEOUT (HZ * 5)
|
||||
#define MOS_WDR_TIMEOUT 5000
|
||||
|
||||
#define MOS_MAX_PORT 0x02
|
||||
#define MOS_WRITE 0x0E
|
||||
|
@ -227,11 +227,22 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum,
|
|||
__u8 requesttype = (__u8)0xc0;
|
||||
__u16 index = get_reg_index(reg);
|
||||
__u16 value = get_reg_value(reg, serial_portnum);
|
||||
int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
|
||||
index, data, 1, MOS_WDR_TIMEOUT);
|
||||
if (status < 0)
|
||||
u8 *buf;
|
||||
int status;
|
||||
|
||||
buf = kmalloc(1, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
status = usb_control_msg(usbdev, pipe, request, requesttype, value,
|
||||
index, buf, 1, MOS_WDR_TIMEOUT);
|
||||
if (status == 1)
|
||||
*data = *buf;
|
||||
else if (status < 0)
|
||||
dev_err(&usbdev->dev,
|
||||
"mos7720: usb_control_msg() failed: %d", status);
|
||||
kfree(buf);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1618,7 +1629,7 @@ static void change_port_settings(struct tty_struct *tty,
|
|||
mos7720_port->shadowMCR |= (UART_MCR_XONANY);
|
||||
/* To set hardware flow control to the specified *
|
||||
* serial port, in SP1/2_CONTROL_REG */
|
||||
if (port->number)
|
||||
if (port_number)
|
||||
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01);
|
||||
else
|
||||
write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02);
|
||||
|
@ -1927,7 +1938,7 @@ static int mos7720_startup(struct usb_serial *serial)
|
|||
|
||||
/* setting configuration feature to one */
|
||||
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||
(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
|
||||
(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);
|
||||
|
||||
/* start the interrupt urb */
|
||||
ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
|
||||
|
@ -1970,7 +1981,7 @@ static void mos7720_release(struct usb_serial *serial)
|
|||
/* wait for synchronous usb calls to return */
|
||||
if (mos_parport->msg_pending)
|
||||
wait_for_completion_timeout(&mos_parport->syncmsg_compl,
|
||||
MOS_WDR_TIMEOUT);
|
||||
msecs_to_jiffies(MOS_WDR_TIMEOUT));
|
||||
|
||||
parport_remove_port(mos_parport->pp);
|
||||
usb_set_serial_data(serial, NULL);
|
||||
|
|
|
@ -2142,13 +2142,21 @@ static int mos7840_ioctl(struct tty_struct *tty,
|
|||
static int mos7810_check(struct usb_serial *serial)
|
||||
{
|
||||
int i, pass_count = 0;
|
||||
u8 *buf;
|
||||
__u16 data = 0, mcr_data = 0;
|
||||
__u16 test_pattern = 0x55AA;
|
||||
int res;
|
||||
|
||||
buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return 0; /* failed to identify 7810 */
|
||||
|
||||
/* Store MCR setting */
|
||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
|
||||
&mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||
buf, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||
if (res == VENDOR_READ_LENGTH)
|
||||
mcr_data = *buf;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
/* Send the 1-bit test pattern out to MCS7810 test pin */
|
||||
|
@ -2158,9 +2166,12 @@ static int mos7810_check(struct usb_serial *serial)
|
|||
MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
|
||||
|
||||
/* Read the test pattern back */
|
||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
|
||||
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||
res = usb_control_msg(serial->dev,
|
||||
usb_rcvctrlpipe(serial->dev, 0), MCS_RDREQ,
|
||||
MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
|
||||
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||
if (res == VENDOR_READ_LENGTH)
|
||||
data = *buf;
|
||||
|
||||
/* If this is a MCS7810 device, both test patterns must match */
|
||||
if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
|
||||
|
@ -2174,6 +2185,8 @@ static int mos7810_check(struct usb_serial *serial)
|
|||
MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
|
||||
0, MOS_WDR_TIMEOUT);
|
||||
|
||||
kfree(buf);
|
||||
|
||||
if (pass_count == 16)
|
||||
return 1;
|
||||
|
||||
|
@ -2183,11 +2196,17 @@ static int mos7810_check(struct usb_serial *serial)
|
|||
static int mos7840_calc_num_ports(struct usb_serial *serial)
|
||||
{
|
||||
__u16 data = 0x00;
|
||||
u8 *buf;
|
||||
int mos7840_num_ports;
|
||||
|
||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
|
||||
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||
buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
|
||||
if (buf) {
|
||||
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
|
||||
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
|
||||
data = *buf;
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
|
||||
serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
|
||||
|
|
|
@ -250,13 +250,7 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define ZTE_PRODUCT_MF622 0x0001
|
||||
#define ZTE_PRODUCT_MF628 0x0015
|
||||
#define ZTE_PRODUCT_MF626 0x0031
|
||||
#define ZTE_PRODUCT_CDMA_TECH 0xfffe
|
||||
#define ZTE_PRODUCT_AC8710 0xfff1
|
||||
#define ZTE_PRODUCT_AC2726 0xfff5
|
||||
#define ZTE_PRODUCT_AC8710T 0xffff
|
||||
#define ZTE_PRODUCT_MC2718 0xffe8
|
||||
#define ZTE_PRODUCT_AD3812 0xffeb
|
||||
#define ZTE_PRODUCT_MC2716 0xffed
|
||||
|
||||
#define BENQ_VENDOR_ID 0x04a5
|
||||
#define BENQ_PRODUCT_H10 0x4068
|
||||
|
@ -495,18 +489,10 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = {
|
|||
.reserved = BIT(4),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info zte_ad3812_z_blacklist = {
|
||||
.sendsetup = BIT(0) | BIT(1) | BIT(2),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info zte_mc2718_z_blacklist = {
|
||||
.sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info zte_mc2716_z_blacklist = {
|
||||
.sendsetup = BIT(1) | BIT(2) | BIT(3),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info huawei_cdc12_blacklist = {
|
||||
.reserved = BIT(1) | BIT(2),
|
||||
};
|
||||
|
@ -593,6 +579,8 @@ static const struct usb_device_id option_ids[] = {
|
|||
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff), /* Huawei E1820 */
|
||||
.driver_info = (kernel_ulong_t) &net_intf1_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) },
|
||||
|
@ -797,7 +785,6 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) },
|
||||
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
|
||||
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
|
||||
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
|
||||
|
@ -1199,16 +1186,9 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
|
||||
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
|
||||
/* NOTE: most ZTE CDMA devices should be driven by zte_ev, not option */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist },
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) },
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) },
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) },
|
||||
|
|
|
@ -118,6 +118,7 @@ static const struct usb_device_id id_table[] = {
|
|||
{USB_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */
|
||||
{USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */
|
||||
{USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */
|
||||
{USB_DEVICE(0x0AF0, 0x8120)}, /* Option GTM681W */
|
||||
|
||||
/* non Gobi Qualcomm serial devices */
|
||||
{USB_DEVICE_INTERFACE_NUMBER(0x0f3d, 0x68a2, 0)}, /* Sierra Wireless MC7700 Device Management */
|
||||
|
|
|
@ -408,7 +408,7 @@ static int serial_ioctl(struct tty_struct *tty,
|
|||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct usb_serial_port *port = tty->driver_data;
|
||||
int retval = -ENODEV;
|
||||
int retval = -ENOIOCTLCMD;
|
||||
|
||||
dev_dbg(tty->dev, "%s - cmd 0x%.4x\n", __func__, cmd);
|
||||
|
||||
|
@ -420,8 +420,6 @@ static int serial_ioctl(struct tty_struct *tty,
|
|||
default:
|
||||
if (port->serial->type->ioctl)
|
||||
retval = port->serial->type->ioctl(tty, cmd, arg);
|
||||
else
|
||||
retval = -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
|
|
@ -560,10 +560,19 @@ static int treo_attach(struct usb_serial *serial)
|
|||
*/
|
||||
#define COPY_PORT(dest, src) \
|
||||
do { \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < ARRAY_SIZE(src->read_urbs); ++i) { \
|
||||
dest->read_urbs[i] = src->read_urbs[i]; \
|
||||
dest->read_urbs[i]->context = dest; \
|
||||
dest->bulk_in_buffers[i] = src->bulk_in_buffers[i]; \
|
||||
} \
|
||||
dest->read_urb = src->read_urb; \
|
||||
dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
|
||||
dest->bulk_in_buffer = src->bulk_in_buffer; \
|
||||
dest->bulk_in_size = src->bulk_in_size; \
|
||||
dest->interrupt_in_urb = src->interrupt_in_urb; \
|
||||
dest->interrupt_in_urb->context = dest; \
|
||||
dest->interrupt_in_endpointAddress = \
|
||||
src->interrupt_in_endpointAddress;\
|
||||
dest->interrupt_in_buffer = src->interrupt_in_buffer; \
|
||||
|
|
|
@ -649,7 +649,7 @@ static void firm_setup_port(struct tty_struct *tty)
|
|||
struct whiteheat_port_settings port_settings;
|
||||
unsigned int cflag = tty->termios.c_cflag;
|
||||
|
||||
port_settings.port = port->number + 1;
|
||||
port_settings.port = port->number - port->serial->minor + 1;
|
||||
|
||||
/* get the byte size */
|
||||
switch (cflag & CSIZE) {
|
||||
|
|
|
@ -41,9 +41,6 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
|||
int len;
|
||||
unsigned char *buf;
|
||||
|
||||
if (port->number != 0)
|
||||
return -ENODEV;
|
||||
|
||||
buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
@ -53,7 +50,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x22, 0x21,
|
||||
0x0001, 0x0000, NULL, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
dev_dbg(dev, "result = %d\n", result);
|
||||
|
||||
/* send 2st cmd and recieve data */
|
||||
|
@ -65,7 +62,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
|||
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||
0x21, 0xa1,
|
||||
0x0000, 0x0000, buf, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
debug_data(dev, __func__, len, buf, result);
|
||||
|
||||
/* send 3 cmd */
|
||||
|
@ -84,7 +81,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x20, 0x21,
|
||||
0x0000, 0x0000, buf, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
debug_data(dev, __func__, len, buf, result);
|
||||
|
||||
/* send 4 cmd */
|
||||
|
@ -95,7 +92,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x22, 0x21,
|
||||
0x0003, 0x0000, NULL, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
dev_dbg(dev, "result = %d\n", result);
|
||||
|
||||
/* send 5 cmd */
|
||||
|
@ -107,7 +104,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
|||
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||
0x21, 0xa1,
|
||||
0x0000, 0x0000, buf, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
debug_data(dev, __func__, len, buf, result);
|
||||
|
||||
/* send 6 cmd */
|
||||
|
@ -126,7 +123,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x20, 0x21,
|
||||
0x0000, 0x0000, buf, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
debug_data(dev, __func__, len, buf, result);
|
||||
kfree(buf);
|
||||
|
||||
|
@ -166,9 +163,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
int len;
|
||||
unsigned char *buf;
|
||||
|
||||
if (port->number != 0)
|
||||
return;
|
||||
|
||||
buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return;
|
||||
|
@ -178,7 +172,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x22, 0x21,
|
||||
0x0002, 0x0000, NULL, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
dev_dbg(dev, "result = %d\n", result);
|
||||
|
||||
/* send 2st ctl cmd(CTL 21 22 03 00 00 00 00 00 ) */
|
||||
|
@ -186,7 +180,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x22, 0x21,
|
||||
0x0003, 0x0000, NULL, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
dev_dbg(dev, "result = %d\n", result);
|
||||
|
||||
/* send 3st cmd and recieve data */
|
||||
|
@ -198,7 +192,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||
0x21, 0xa1,
|
||||
0x0000, 0x0000, buf, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
debug_data(dev, __func__, len, buf, result);
|
||||
|
||||
/* send 4 cmd */
|
||||
|
@ -217,7 +211,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x20, 0x21,
|
||||
0x0000, 0x0000, buf, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
debug_data(dev, __func__, len, buf, result);
|
||||
|
||||
/* send 5 cmd */
|
||||
|
@ -228,7 +222,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x22, 0x21,
|
||||
0x0003, 0x0000, NULL, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
dev_dbg(dev, "result = %d\n", result);
|
||||
|
||||
/* send 6 cmd */
|
||||
|
@ -240,7 +234,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||
0x21, 0xa1,
|
||||
0x0000, 0x0000, buf, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
debug_data(dev, __func__, len, buf, result);
|
||||
|
||||
/* send 7 cmd */
|
||||
|
@ -259,7 +253,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x20, 0x21,
|
||||
0x0000, 0x0000, buf, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
debug_data(dev, __func__, len, buf, result);
|
||||
|
||||
/* send 8 cmd */
|
||||
|
@ -270,7 +264,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0x22, 0x21,
|
||||
0x0003, 0x0000, NULL, len,
|
||||
HZ * USB_CTRL_GET_TIMEOUT);
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
dev_dbg(dev, "result = %d\n", result);
|
||||
|
||||
kfree(buf);
|
||||
|
@ -279,11 +273,29 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
|
|||
}
|
||||
|
||||
static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x19d2, 0xffff) }, /* AC8700 */
|
||||
{ USB_DEVICE(0x19d2, 0xfffe) },
|
||||
{ USB_DEVICE(0x19d2, 0xfffd) }, /* MG880 */
|
||||
/* AC8710, AC8710T */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) },
|
||||
/* AC8700 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfffe, 0xff, 0xff, 0xff) },
|
||||
/* MG880 */
|
||||
{ USB_DEVICE(0x19d2, 0xfffd) },
|
||||
{ USB_DEVICE(0x19d2, 0xfffc) },
|
||||
{ USB_DEVICE(0x19d2, 0xfffb) },
|
||||
/* AC2726, AC8710_V3 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfff1, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE(0x19d2, 0xfff6) },
|
||||
{ USB_DEVICE(0x19d2, 0xfff7) },
|
||||
{ USB_DEVICE(0x19d2, 0xfff8) },
|
||||
{ USB_DEVICE(0x19d2, 0xfff9) },
|
||||
{ USB_DEVICE(0x19d2, 0xffee) },
|
||||
/* AC2716, MC2716 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffed, 0xff, 0xff, 0xff) },
|
||||
/* AD3812 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffeb, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE(0x19d2, 0xffec) },
|
||||
{ USB_DEVICE(0x05C6, 0x3197) },
|
||||
{ USB_DEVICE(0x05C6, 0x6000) },
|
||||
{ USB_DEVICE(0x05C6, 0x9008) },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, id_table);
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_vnodeops.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_trace.h"
|
||||
#include <linux/slab.h>
|
||||
#include <linux/xattr.h>
|
||||
|
@ -34,7 +36,9 @@
|
|||
*/
|
||||
|
||||
STATIC struct posix_acl *
|
||||
xfs_acl_from_disk(struct xfs_acl *aclp)
|
||||
xfs_acl_from_disk(
|
||||
struct xfs_acl *aclp,
|
||||
int max_entries)
|
||||
{
|
||||
struct posix_acl_entry *acl_e;
|
||||
struct posix_acl *acl;
|
||||
|
@ -42,7 +46,7 @@ xfs_acl_from_disk(struct xfs_acl *aclp)
|
|||
unsigned int count, i;
|
||||
|
||||
count = be32_to_cpu(aclp->acl_cnt);
|
||||
if (count > XFS_ACL_MAX_ENTRIES)
|
||||
if (count > max_entries)
|
||||
return ERR_PTR(-EFSCORRUPTED);
|
||||
|
||||
acl = posix_acl_alloc(count, GFP_KERNEL);
|
||||
|
@ -108,9 +112,9 @@ xfs_get_acl(struct inode *inode, int type)
|
|||
struct xfs_inode *ip = XFS_I(inode);
|
||||
struct posix_acl *acl;
|
||||
struct xfs_acl *xfs_acl;
|
||||
int len = sizeof(struct xfs_acl);
|
||||
unsigned char *ea_name;
|
||||
int error;
|
||||
int len;
|
||||
|
||||
acl = get_cached_acl(inode, type);
|
||||
if (acl != ACL_NOT_CACHED)
|
||||
|
@ -133,8 +137,8 @@ xfs_get_acl(struct inode *inode, int type)
|
|||
* If we have a cached ACLs value just return it, not need to
|
||||
* go out to the disk.
|
||||
*/
|
||||
|
||||
xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
|
||||
len = XFS_ACL_MAX_SIZE(ip->i_mount);
|
||||
xfs_acl = kzalloc(len, GFP_KERNEL);
|
||||
if (!xfs_acl)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
@ -153,7 +157,7 @@ xfs_get_acl(struct inode *inode, int type)
|
|||
goto out;
|
||||
}
|
||||
|
||||
acl = xfs_acl_from_disk(xfs_acl);
|
||||
acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount));
|
||||
if (IS_ERR(acl))
|
||||
goto out;
|
||||
|
||||
|
@ -189,16 +193,17 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
|
|||
|
||||
if (acl) {
|
||||
struct xfs_acl *xfs_acl;
|
||||
int len;
|
||||
int len = XFS_ACL_MAX_SIZE(ip->i_mount);
|
||||
|
||||
xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
|
||||
xfs_acl = kzalloc(len, GFP_KERNEL);
|
||||
if (!xfs_acl)
|
||||
return -ENOMEM;
|
||||
|
||||
xfs_acl_to_disk(xfs_acl, acl);
|
||||
len = sizeof(struct xfs_acl) -
|
||||
(sizeof(struct xfs_acl_entry) *
|
||||
(XFS_ACL_MAX_ENTRIES - acl->a_count));
|
||||
|
||||
/* subtract away the unused acl entries */
|
||||
len -= sizeof(struct xfs_acl_entry) *
|
||||
(XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count);
|
||||
|
||||
error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl,
|
||||
len, ATTR_ROOT);
|
||||
|
@ -243,7 +248,7 @@ xfs_set_mode(struct inode *inode, umode_t mode)
|
|||
static int
|
||||
xfs_acl_exists(struct inode *inode, unsigned char *name)
|
||||
{
|
||||
int len = sizeof(struct xfs_acl);
|
||||
int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb));
|
||||
|
||||
return (xfs_attr_get(XFS_I(inode), name, NULL, &len,
|
||||
ATTR_ROOT|ATTR_KERNOVAL) == 0);
|
||||
|
@ -379,7 +384,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
|
|||
goto out_release;
|
||||
|
||||
error = -EINVAL;
|
||||
if (acl->a_count > XFS_ACL_MAX_ENTRIES)
|
||||
if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb)))
|
||||
goto out_release;
|
||||
|
||||
if (type == ACL_TYPE_ACCESS) {
|
||||
|
|
|
@ -22,19 +22,36 @@ struct inode;
|
|||
struct posix_acl;
|
||||
struct xfs_inode;
|
||||
|
||||
#define XFS_ACL_MAX_ENTRIES 25
|
||||
#define XFS_ACL_NOT_PRESENT (-1)
|
||||
|
||||
/* On-disk XFS access control list structure */
|
||||
struct xfs_acl {
|
||||
__be32 acl_cnt;
|
||||
struct xfs_acl_entry {
|
||||
__be32 ae_tag;
|
||||
__be32 ae_id;
|
||||
__be16 ae_perm;
|
||||
} acl_entry[XFS_ACL_MAX_ENTRIES];
|
||||
struct xfs_acl_entry {
|
||||
__be32 ae_tag;
|
||||
__be32 ae_id;
|
||||
__be16 ae_perm;
|
||||
__be16 ae_pad; /* fill the implicit hole in the structure */
|
||||
};
|
||||
|
||||
struct xfs_acl {
|
||||
__be32 acl_cnt;
|
||||
struct xfs_acl_entry acl_entry[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* The number of ACL entries allowed is defined by the on-disk format.
|
||||
* For v4 superblocks, that is limited to 25 entries. For v5 superblocks, it is
|
||||
* limited only by the maximum size of the xattr that stores the information.
|
||||
*/
|
||||
#define XFS_ACL_MAX_ENTRIES(mp) \
|
||||
(xfs_sb_version_hascrc(&mp->m_sb) \
|
||||
? (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
|
||||
sizeof(struct xfs_acl_entry) \
|
||||
: 25)
|
||||
|
||||
#define XFS_ACL_MAX_SIZE(mp) \
|
||||
(sizeof(struct xfs_acl) + \
|
||||
sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp)))
|
||||
|
||||
/* On-disk XFS extended attribute names */
|
||||
#define SGI_ACL_FILE (unsigned char *)"SGI_ACL_FILE"
|
||||
#define SGI_ACL_DEFAULT (unsigned char *)"SGI_ACL_DEFAULT"
|
||||
|
|
|
@ -3258,7 +3258,7 @@ xfs_attr3_leaf_inactive(
|
|||
name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
|
||||
if (name_rmt->valueblk) {
|
||||
lp->valueblk = be32_to_cpu(name_rmt->valueblk);
|
||||
lp->valuelen = XFS_B_TO_FSB(dp->i_mount,
|
||||
lp->valuelen = xfs_attr3_rmt_blocks(dp->i_mount,
|
||||
be32_to_cpu(name_rmt->valuelen));
|
||||
lp++;
|
||||
}
|
||||
|
|
|
@ -249,8 +249,11 @@ xfs_qm_init_dquot_blk(
|
|||
d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
|
||||
d->dd_diskdq.d_id = cpu_to_be32(curid);
|
||||
d->dd_diskdq.d_flags = type;
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb))
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid);
|
||||
xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
|
||||
XFS_DQUOT_CRC_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
xfs_trans_dquot_buf(tp, bp,
|
||||
|
@ -286,23 +289,6 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
|
|||
dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5;
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_dquot_buf_calc_crc(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr;
|
||||
int i;
|
||||
|
||||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||
return;
|
||||
|
||||
for (i = 0; i < mp->m_quotainfo->qi_dqperchunk; i++, d++) {
|
||||
xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
|
||||
offsetof(struct xfs_dqblk, dd_crc));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC bool
|
||||
xfs_dquot_buf_verify_crc(
|
||||
struct xfs_mount *mp,
|
||||
|
@ -328,12 +314,11 @@ xfs_dquot_buf_verify_crc(
|
|||
|
||||
for (i = 0; i < ndquots; i++, d++) {
|
||||
if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
|
||||
offsetof(struct xfs_dqblk, dd_crc)))
|
||||
XFS_DQUOT_CRC_OFF))
|
||||
return false;
|
||||
if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -393,6 +378,11 @@ xfs_dquot_buf_read_verify(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* we don't calculate the CRC here as that is done when the dquot is flushed to
|
||||
* the buffer after the update is done. This ensures that the dquot in the
|
||||
* buffer always has an up-to-date CRC value.
|
||||
*/
|
||||
void
|
||||
xfs_dquot_buf_write_verify(
|
||||
struct xfs_buf *bp)
|
||||
|
@ -404,7 +394,6 @@ xfs_dquot_buf_write_verify(
|
|||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
return;
|
||||
}
|
||||
xfs_dquot_buf_calc_crc(mp, bp);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_dquot_buf_ops = {
|
||||
|
@ -1151,11 +1140,17 @@ xfs_qm_dqflush(
|
|||
* copy the lsn into the on-disk dquot now while we have the in memory
|
||||
* dquot here. This can't be done later in the write verifier as we
|
||||
* can't get access to the log item at that point in time.
|
||||
*
|
||||
* We also calculate the CRC here so that the on-disk dquot in the
|
||||
* buffer always has a valid CRC. This ensures there is no possibility
|
||||
* of a dquot without an up-to-date CRC getting to disk.
|
||||
*/
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
struct xfs_dqblk *dqb = (struct xfs_dqblk *)ddqp;
|
||||
|
||||
dqb->dd_lsn = cpu_to_be64(dqp->q_logitem.qli_item.li_lsn);
|
||||
xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk),
|
||||
XFS_DQUOT_CRC_OFF);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1638,6 +1638,10 @@ xfs_iunlink(
|
|||
dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
|
||||
offset = ip->i_imap.im_boffset +
|
||||
offsetof(xfs_dinode_t, di_next_unlinked);
|
||||
|
||||
/* need to recalc the inode CRC if appropriate */
|
||||
xfs_dinode_calc_crc(mp, dip);
|
||||
|
||||
xfs_trans_inode_buf(tp, ibp);
|
||||
xfs_trans_log_buf(tp, ibp, offset,
|
||||
(offset + sizeof(xfs_agino_t) - 1));
|
||||
|
@ -1723,6 +1727,10 @@ xfs_iunlink_remove(
|
|||
dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
|
||||
offset = ip->i_imap.im_boffset +
|
||||
offsetof(xfs_dinode_t, di_next_unlinked);
|
||||
|
||||
/* need to recalc the inode CRC if appropriate */
|
||||
xfs_dinode_calc_crc(mp, dip);
|
||||
|
||||
xfs_trans_inode_buf(tp, ibp);
|
||||
xfs_trans_log_buf(tp, ibp, offset,
|
||||
(offset + sizeof(xfs_agino_t) - 1));
|
||||
|
@ -1796,6 +1804,10 @@ xfs_iunlink_remove(
|
|||
dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
|
||||
offset = ip->i_imap.im_boffset +
|
||||
offsetof(xfs_dinode_t, di_next_unlinked);
|
||||
|
||||
/* need to recalc the inode CRC if appropriate */
|
||||
xfs_dinode_calc_crc(mp, dip);
|
||||
|
||||
xfs_trans_inode_buf(tp, ibp);
|
||||
xfs_trans_log_buf(tp, ibp, offset,
|
||||
(offset + sizeof(xfs_agino_t) - 1));
|
||||
|
@ -1809,6 +1821,10 @@ xfs_iunlink_remove(
|
|||
last_dip->di_next_unlinked = cpu_to_be32(next_agino);
|
||||
ASSERT(next_agino != 0);
|
||||
offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked);
|
||||
|
||||
/* need to recalc the inode CRC if appropriate */
|
||||
xfs_dinode_calc_crc(mp, last_dip);
|
||||
|
||||
xfs_trans_inode_buf(tp, last_ibp);
|
||||
xfs_trans_log_buf(tp, last_ibp, offset,
|
||||
(offset + sizeof(xfs_agino_t) - 1));
|
||||
|
|
|
@ -1599,10 +1599,43 @@ xlog_recover_add_to_trans(
|
|||
}
|
||||
|
||||
/*
|
||||
* Sort the log items in the transaction. Cancelled buffers need
|
||||
* to be put first so they are processed before any items that might
|
||||
* modify the buffers. If they are cancelled, then the modifications
|
||||
* don't need to be replayed.
|
||||
* Sort the log items in the transaction.
|
||||
*
|
||||
* The ordering constraints are defined by the inode allocation and unlink
|
||||
* behaviour. The rules are:
|
||||
*
|
||||
* 1. Every item is only logged once in a given transaction. Hence it
|
||||
* represents the last logged state of the item. Hence ordering is
|
||||
* dependent on the order in which operations need to be performed so
|
||||
* required initial conditions are always met.
|
||||
*
|
||||
* 2. Cancelled buffers are recorded in pass 1 in a separate table and
|
||||
* there's nothing to replay from them so we can simply cull them
|
||||
* from the transaction. However, we can't do that until after we've
|
||||
* replayed all the other items because they may be dependent on the
|
||||
* cancelled buffer and replaying the cancelled buffer can remove it
|
||||
* form the cancelled buffer table. Hence they have tobe done last.
|
||||
*
|
||||
* 3. Inode allocation buffers must be replayed before inode items that
|
||||
* read the buffer and replay changes into it.
|
||||
*
|
||||
* 4. Inode unlink buffers must be replayed after inode items are replayed.
|
||||
* This ensures that inodes are completely flushed to the inode buffer
|
||||
* in a "free" state before we remove the unlinked inode list pointer.
|
||||
*
|
||||
* Hence the ordering needs to be inode allocation buffers first, inode items
|
||||
* second, inode unlink buffers third and cancelled buffers last.
|
||||
*
|
||||
* But there's a problem with that - we can't tell an inode allocation buffer
|
||||
* apart from a regular buffer, so we can't separate them. We can, however,
|
||||
* tell an inode unlink buffer from the others, and so we can separate them out
|
||||
* from all the other buffers and move them to last.
|
||||
*
|
||||
* Hence, 4 lists, in order from head to tail:
|
||||
* - buffer_list for all buffers except cancelled/inode unlink buffers
|
||||
* - item_list for all non-buffer items
|
||||
* - inode_buffer_list for inode unlink buffers
|
||||
* - cancel_list for the cancelled buffers
|
||||
*/
|
||||
STATIC int
|
||||
xlog_recover_reorder_trans(
|
||||
|
@ -1612,6 +1645,10 @@ xlog_recover_reorder_trans(
|
|||
{
|
||||
xlog_recover_item_t *item, *n;
|
||||
LIST_HEAD(sort_list);
|
||||
LIST_HEAD(cancel_list);
|
||||
LIST_HEAD(buffer_list);
|
||||
LIST_HEAD(inode_buffer_list);
|
||||
LIST_HEAD(inode_list);
|
||||
|
||||
list_splice_init(&trans->r_itemq, &sort_list);
|
||||
list_for_each_entry_safe(item, n, &sort_list, ri_list) {
|
||||
|
@ -1619,12 +1656,18 @@ xlog_recover_reorder_trans(
|
|||
|
||||
switch (ITEM_TYPE(item)) {
|
||||
case XFS_LI_BUF:
|
||||
if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
|
||||
if (buf_f->blf_flags & XFS_BLF_CANCEL) {
|
||||
trace_xfs_log_recover_item_reorder_head(log,
|
||||
trans, item, pass);
|
||||
list_move(&item->ri_list, &trans->r_itemq);
|
||||
list_move(&item->ri_list, &cancel_list);
|
||||
break;
|
||||
}
|
||||
if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
|
||||
list_move(&item->ri_list, &inode_buffer_list);
|
||||
break;
|
||||
}
|
||||
list_move_tail(&item->ri_list, &buffer_list);
|
||||
break;
|
||||
case XFS_LI_INODE:
|
||||
case XFS_LI_DQUOT:
|
||||
case XFS_LI_QUOTAOFF:
|
||||
|
@ -1632,7 +1675,7 @@ xlog_recover_reorder_trans(
|
|||
case XFS_LI_EFI:
|
||||
trace_xfs_log_recover_item_reorder_tail(log,
|
||||
trans, item, pass);
|
||||
list_move_tail(&item->ri_list, &trans->r_itemq);
|
||||
list_move_tail(&item->ri_list, &inode_list);
|
||||
break;
|
||||
default:
|
||||
xfs_warn(log->l_mp,
|
||||
|
@ -1643,6 +1686,14 @@ xlog_recover_reorder_trans(
|
|||
}
|
||||
}
|
||||
ASSERT(list_empty(&sort_list));
|
||||
if (!list_empty(&buffer_list))
|
||||
list_splice(&buffer_list, &trans->r_itemq);
|
||||
if (!list_empty(&inode_list))
|
||||
list_splice_tail(&inode_list, &trans->r_itemq);
|
||||
if (!list_empty(&inode_buffer_list))
|
||||
list_splice_tail(&inode_buffer_list, &trans->r_itemq);
|
||||
if (!list_empty(&cancel_list))
|
||||
list_splice_tail(&cancel_list, &trans->r_itemq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1861,6 +1912,15 @@ xlog_recover_do_inode_buffer(
|
|||
buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
|
||||
next_unlinked_offset);
|
||||
*buffer_nextp = *logged_nextp;
|
||||
|
||||
/*
|
||||
* If necessary, recalculate the CRC in the on-disk inode. We
|
||||
* have to leave the inode in a consistent state for whoever
|
||||
* reads it next....
|
||||
*/
|
||||
xfs_dinode_calc_crc(mp, (struct xfs_dinode *)
|
||||
xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2266,6 +2326,12 @@ xfs_qm_dqcheck(
|
|||
d->dd_diskdq.d_flags = type;
|
||||
d->dd_diskdq.d_id = cpu_to_be32(id);
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid);
|
||||
xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
|
||||
XFS_DQUOT_CRC_OFF);
|
||||
}
|
||||
|
||||
return errs;
|
||||
}
|
||||
|
||||
|
@ -2793,6 +2859,10 @@ xlog_recover_dquot_pass2(
|
|||
}
|
||||
|
||||
memcpy(ddq, recddq, item->ri_buf[1].i_len);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
xfs_update_cksum((char *)ddq, sizeof(struct xfs_dqblk),
|
||||
XFS_DQUOT_CRC_OFF);
|
||||
}
|
||||
|
||||
ASSERT(dq_f->qlf_size == 2);
|
||||
ASSERT(bp->b_target->bt_mount == mp);
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "xfs_qm.h"
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_icache.h"
|
||||
#include "xfs_cksum.h"
|
||||
|
||||
/*
|
||||
* The global quota manager. There is only one of these for the entire
|
||||
|
@ -839,7 +840,7 @@ xfs_qm_reset_dqcounts(
|
|||
xfs_dqid_t id,
|
||||
uint type)
|
||||
{
|
||||
xfs_disk_dquot_t *ddq;
|
||||
struct xfs_dqblk *dqb;
|
||||
int j;
|
||||
|
||||
trace_xfs_reset_dqcounts(bp, _RET_IP_);
|
||||
|
@ -853,8 +854,12 @@ xfs_qm_reset_dqcounts(
|
|||
do_div(j, sizeof(xfs_dqblk_t));
|
||||
ASSERT(mp->m_quotainfo->qi_dqperchunk == j);
|
||||
#endif
|
||||
ddq = bp->b_addr;
|
||||
dqb = bp->b_addr;
|
||||
for (j = 0; j < mp->m_quotainfo->qi_dqperchunk; j++) {
|
||||
struct xfs_disk_dquot *ddq;
|
||||
|
||||
ddq = (struct xfs_disk_dquot *)&dqb[j];
|
||||
|
||||
/*
|
||||
* Do a sanity check, and if needed, repair the dqblk. Don't
|
||||
* output any warnings because it's perfectly possible to
|
||||
|
@ -871,7 +876,12 @@ xfs_qm_reset_dqcounts(
|
|||
ddq->d_bwarns = 0;
|
||||
ddq->d_iwarns = 0;
|
||||
ddq->d_rtbwarns = 0;
|
||||
ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1);
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
xfs_update_cksum((char *)&dqb[j],
|
||||
sizeof(struct xfs_dqblk),
|
||||
XFS_DQUOT_CRC_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -907,19 +917,29 @@ xfs_qm_dqiter_bufs(
|
|||
XFS_FSB_TO_DADDR(mp, bno),
|
||||
mp->m_quotainfo->qi_dqchunklen, 0, &bp,
|
||||
&xfs_dquot_buf_ops);
|
||||
|
||||
/*
|
||||
* CRC and validation errors will return a EFSCORRUPTED here. If
|
||||
* this occurs, re-read without CRC validation so that we can
|
||||
* repair the damage via xfs_qm_reset_dqcounts(). This process
|
||||
* will leave a trace in the log indicating corruption has
|
||||
* been detected.
|
||||
*/
|
||||
if (error == EFSCORRUPTED) {
|
||||
error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
|
||||
XFS_FSB_TO_DADDR(mp, bno),
|
||||
mp->m_quotainfo->qi_dqchunklen, 0, &bp,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (error)
|
||||
break;
|
||||
|
||||
/*
|
||||
* XXX(hch): need to figure out if it makes sense to validate
|
||||
* the CRC here.
|
||||
*/
|
||||
xfs_qm_reset_dqcounts(mp, bp, firstid, type);
|
||||
xfs_buf_delwri_queue(bp, buffer_list);
|
||||
xfs_buf_relse(bp);
|
||||
/*
|
||||
* goto the next block.
|
||||
*/
|
||||
|
||||
/* goto the next block. */
|
||||
bno++;
|
||||
firstid += mp->m_quotainfo->qi_dqperchunk;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,8 @@ typedef struct xfs_dqblk {
|
|||
uuid_t dd_uuid; /* location information */
|
||||
} xfs_dqblk_t;
|
||||
|
||||
#define XFS_DQUOT_CRC_OFF offsetof(struct xfs_dqblk, dd_crc)
|
||||
|
||||
/*
|
||||
* flags for q_flags field in the dquot.
|
||||
*/
|
||||
|
|
|
@ -1372,6 +1372,17 @@ xfs_finish_flags(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* V5 filesystems always use attr2 format for attributes.
|
||||
*/
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
(mp->m_flags & XFS_MOUNT_NOATTR2)) {
|
||||
xfs_warn(mp,
|
||||
"Cannot mount a V5 filesystem as %s. %s is always enabled for V5 filesystems.",
|
||||
MNTOPT_NOATTR2, MNTOPT_ATTR2);
|
||||
return XFS_ERROR(EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* mkfs'ed attr2 will turn on attr2 mount unless explicitly
|
||||
* told by noattr2 to turn it off
|
||||
|
|
|
@ -97,11 +97,9 @@ struct mmu_gather {
|
|||
unsigned long start;
|
||||
unsigned long end;
|
||||
unsigned int need_flush : 1, /* Did free PTEs */
|
||||
fast_mode : 1; /* No batching */
|
||||
|
||||
/* we are in the middle of an operation to clear
|
||||
* a full mm and can make some optimizations */
|
||||
unsigned int fullmm : 1,
|
||||
fullmm : 1,
|
||||
/* we have performed an operation which
|
||||
* requires a complete flush of the tlb */
|
||||
need_flush_all : 1;
|
||||
|
@ -114,19 +112,6 @@ struct mmu_gather {
|
|||
|
||||
#define HAVE_GENERIC_MMU_GATHER
|
||||
|
||||
static inline int tlb_fast_mode(struct mmu_gather *tlb)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
return tlb->fast_mode;
|
||||
#else
|
||||
/*
|
||||
* For UP we don't need to worry about TLB flush
|
||||
* and page free order so much..
|
||||
*/
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm);
|
||||
void tlb_flush_mmu(struct mmu_gather *tlb);
|
||||
void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
|
||||
|
|
|
@ -320,6 +320,9 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
|
|||
|
||||
struct timespec;
|
||||
|
||||
/* The __sys_...msg variants allow MSG_CMSG_COMPAT */
|
||||
extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags);
|
||||
extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
|
||||
extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
|
||||
unsigned int flags, struct timespec *timeout);
|
||||
extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
|
||||
|
|
|
@ -220,7 +220,6 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm)
|
|||
tlb->start = -1UL;
|
||||
tlb->end = 0;
|
||||
tlb->need_flush = 0;
|
||||
tlb->fast_mode = (num_possible_cpus() == 1);
|
||||
tlb->local.next = NULL;
|
||||
tlb->local.nr = 0;
|
||||
tlb->local.max = ARRAY_SIZE(tlb->__pages);
|
||||
|
@ -244,9 +243,6 @@ void tlb_flush_mmu(struct mmu_gather *tlb)
|
|||
tlb_table_flush(tlb);
|
||||
#endif
|
||||
|
||||
if (tlb_fast_mode(tlb))
|
||||
return;
|
||||
|
||||
for (batch = &tlb->local; batch; batch = batch->next) {
|
||||
free_pages_and_swap_cache(batch->pages, batch->nr);
|
||||
batch->nr = 0;
|
||||
|
@ -288,11 +284,6 @@ int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
|
|||
|
||||
VM_BUG_ON(!tlb->need_flush);
|
||||
|
||||
if (tlb_fast_mode(tlb)) {
|
||||
free_page_and_swap_cache(page);
|
||||
return 1; /* avoid calling tlb_flush_mmu() */
|
||||
}
|
||||
|
||||
batch = tlb->active;
|
||||
batch->pages[batch->nr++] = page;
|
||||
if (batch->nr == batch->max) {
|
||||
|
|
13
net/compat.c
13
net/compat.c
|
@ -734,19 +734,25 @@ static unsigned char nas[21] = {
|
|||
|
||||
asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
|
||||
{
|
||||
return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
|
||||
if (flags & MSG_CMSG_COMPAT)
|
||||
return -EINVAL;
|
||||
return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
|
||||
}
|
||||
|
||||
asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
|
||||
unsigned int vlen, unsigned int flags)
|
||||
{
|
||||
if (flags & MSG_CMSG_COMPAT)
|
||||
return -EINVAL;
|
||||
return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
|
||||
flags | MSG_CMSG_COMPAT);
|
||||
}
|
||||
|
||||
asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
|
||||
{
|
||||
return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
|
||||
if (flags & MSG_CMSG_COMPAT)
|
||||
return -EINVAL;
|
||||
return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
|
||||
}
|
||||
|
||||
asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags)
|
||||
|
@ -768,6 +774,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
|
|||
int datagrams;
|
||||
struct timespec ktspec;
|
||||
|
||||
if (flags & MSG_CMSG_COMPAT)
|
||||
return -EINVAL;
|
||||
|
||||
if (COMPAT_USE_64BIT_TIME)
|
||||
return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
|
||||
flags | MSG_CMSG_COMPAT,
|
||||
|
|
72
net/socket.c
72
net/socket.c
|
@ -1956,7 +1956,7 @@ struct used_address {
|
|||
unsigned int name_len;
|
||||
};
|
||||
|
||||
static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
|
||||
static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
|
||||
struct msghdr *msg_sys, unsigned int flags,
|
||||
struct used_address *used_address)
|
||||
{
|
||||
|
@ -2071,26 +2071,30 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
|
|||
* BSD sendmsg interface
|
||||
*/
|
||||
|
||||
SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
|
||||
long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
|
||||
{
|
||||
int fput_needed, err;
|
||||
struct msghdr msg_sys;
|
||||
struct socket *sock;
|
||||
|
||||
if (flags & MSG_CMSG_COMPAT)
|
||||
return -EINVAL;
|
||||
|
||||
sock = sockfd_lookup_light(fd, &err, &fput_needed);
|
||||
if (!sock)
|
||||
goto out;
|
||||
|
||||
err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
|
||||
err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
|
||||
|
||||
fput_light(sock->file, fput_needed);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
|
||||
{
|
||||
if (flags & MSG_CMSG_COMPAT)
|
||||
return -EINVAL;
|
||||
return __sys_sendmsg(fd, msg, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Linux sendmmsg interface
|
||||
*/
|
||||
|
@ -2121,15 +2125,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
|
|||
|
||||
while (datagrams < vlen) {
|
||||
if (MSG_CMSG_COMPAT & flags) {
|
||||
err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
|
||||
&msg_sys, flags, &used_address);
|
||||
err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
|
||||
&msg_sys, flags, &used_address);
|
||||
if (err < 0)
|
||||
break;
|
||||
err = __put_user(err, &compat_entry->msg_len);
|
||||
++compat_entry;
|
||||
} else {
|
||||
err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
|
||||
&msg_sys, flags, &used_address);
|
||||
err = ___sys_sendmsg(sock,
|
||||
(struct msghdr __user *)entry,
|
||||
&msg_sys, flags, &used_address);
|
||||
if (err < 0)
|
||||
break;
|
||||
err = put_user(err, &entry->msg_len);
|
||||
|
@ -2158,7 +2163,7 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
|
|||
return __sys_sendmmsg(fd, mmsg, vlen, flags);
|
||||
}
|
||||
|
||||
static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
|
||||
static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
|
||||
struct msghdr *msg_sys, unsigned int flags, int nosec)
|
||||
{
|
||||
struct compat_msghdr __user *msg_compat =
|
||||
|
@ -2250,27 +2255,31 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
|
|||
* BSD recvmsg interface
|
||||
*/
|
||||
|
||||
SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
|
||||
unsigned int, flags)
|
||||
long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags)
|
||||
{
|
||||
int fput_needed, err;
|
||||
struct msghdr msg_sys;
|
||||
struct socket *sock;
|
||||
|
||||
if (flags & MSG_CMSG_COMPAT)
|
||||
return -EINVAL;
|
||||
|
||||
sock = sockfd_lookup_light(fd, &err, &fput_needed);
|
||||
if (!sock)
|
||||
goto out;
|
||||
|
||||
err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0);
|
||||
err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
|
||||
|
||||
fput_light(sock->file, fput_needed);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
|
||||
unsigned int, flags)
|
||||
{
|
||||
if (flags & MSG_CMSG_COMPAT)
|
||||
return -EINVAL;
|
||||
return __sys_recvmsg(fd, msg, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Linux recvmmsg interface
|
||||
*/
|
||||
|
@ -2308,17 +2317,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
|
|||
* No need to ask LSM for more than the first datagram.
|
||||
*/
|
||||
if (MSG_CMSG_COMPAT & flags) {
|
||||
err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
|
||||
&msg_sys, flags & ~MSG_WAITFORONE,
|
||||
datagrams);
|
||||
err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
|
||||
&msg_sys, flags & ~MSG_WAITFORONE,
|
||||
datagrams);
|
||||
if (err < 0)
|
||||
break;
|
||||
err = __put_user(err, &compat_entry->msg_len);
|
||||
++compat_entry;
|
||||
} else {
|
||||
err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
|
||||
&msg_sys, flags & ~MSG_WAITFORONE,
|
||||
datagrams);
|
||||
err = ___sys_recvmsg(sock,
|
||||
(struct msghdr __user *)entry,
|
||||
&msg_sys, flags & ~MSG_WAITFORONE,
|
||||
datagrams);
|
||||
if (err < 0)
|
||||
break;
|
||||
err = put_user(err, &entry->msg_len);
|
||||
|
@ -2505,31 +2515,15 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
|
|||
(int __user *)a[4]);
|
||||
break;
|
||||
case SYS_SENDMSG:
|
||||
if (a[2] & MSG_CMSG_COMPAT) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]);
|
||||
break;
|
||||
case SYS_SENDMMSG:
|
||||
if (a[3] & MSG_CMSG_COMPAT) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
|
||||
break;
|
||||
case SYS_RECVMSG:
|
||||
if (a[2] & MSG_CMSG_COMPAT) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
|
||||
break;
|
||||
case SYS_RECVMMSG:
|
||||
if (a[3] & MSG_CMSG_COMPAT) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],
|
||||
(struct timespec __user *)a[4]);
|
||||
break;
|
||||
|
|
|
@ -264,7 +264,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb
|
|||
quiet_cmd_dtc = DTC $@
|
||||
cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
|
||||
$(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
|
||||
-i $(srctree)/arch/$(SRCARCH)/boot/dts $(DTC_FLAGS) \
|
||||
-i $(dir $<) $(DTC_FLAGS) \
|
||||
-d $(depfile).dtc $(dtc-tmp) ; \
|
||||
cat $(depfile).pre $(depfile).dtc > $(depfile)
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ while [ "$1" != "" ] ; do
|
|||
;;
|
||||
--refresh)
|
||||
;;
|
||||
--*-after)
|
||||
--*-after|-E|-D|-M)
|
||||
checkarg "$1"
|
||||
A=$ARG
|
||||
checkarg "$2"
|
||||
|
|
|
@ -303,10 +303,11 @@ int dialog_menu(const char *title, const char *prompt,
|
|||
}
|
||||
}
|
||||
|
||||
if (i < max_choice ||
|
||||
key == KEY_UP || key == KEY_DOWN ||
|
||||
key == '-' || key == '+' ||
|
||||
key == KEY_PPAGE || key == KEY_NPAGE) {
|
||||
if (item_count() != 0 &&
|
||||
(i < max_choice ||
|
||||
key == KEY_UP || key == KEY_DOWN ||
|
||||
key == '-' || key == '+' ||
|
||||
key == KEY_PPAGE || key == KEY_NPAGE)) {
|
||||
/* Remove highligt of current item */
|
||||
print_item(scroll + choice, choice, FALSE);
|
||||
|
||||
|
|
|
@ -670,11 +670,12 @@ static void conf(struct menu *menu, struct menu *active_menu)
|
|||
active_menu, &s_scroll);
|
||||
if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
|
||||
break;
|
||||
if (!item_activate_selected())
|
||||
continue;
|
||||
if (!item_tag())
|
||||
continue;
|
||||
|
||||
if (item_count() != 0) {
|
||||
if (!item_activate_selected())
|
||||
continue;
|
||||
if (!item_tag())
|
||||
continue;
|
||||
}
|
||||
submenu = item_data();
|
||||
active_menu = item_data();
|
||||
if (submenu)
|
||||
|
|
|
@ -146,11 +146,24 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
|
|||
struct menu *menu = current_entry;
|
||||
|
||||
while ((menu = menu->parent) != NULL) {
|
||||
struct expr *dup_expr;
|
||||
|
||||
if (!menu->visibility)
|
||||
continue;
|
||||
/*
|
||||
* Do not add a reference to the
|
||||
* menu's visibility expression but
|
||||
* use a copy of it. Otherwise the
|
||||
* expression reduction functions
|
||||
* will modify expressions that have
|
||||
* multiple references which can
|
||||
* cause unwanted side effects.
|
||||
*/
|
||||
dup_expr = expr_copy(menu->visibility);
|
||||
|
||||
prop->visible.expr
|
||||
= expr_alloc_and(prop->visible.expr,
|
||||
menu->visibility);
|
||||
dup_expr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue