24 changes: 9 additions & 15 deletions arch/powerpc/sysdev/fsl_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,14 @@ static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
return indirect_read_config(bus, devfn, offset, len, val);
}

static struct pci_ops fsl_indirect_pci_ops =
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)

static struct pci_ops fsl_indirect_pcie_ops =
{
.read = fsl_indirect_read_config,
.write = indirect_write_config,
};

static void __init fsl_setup_indirect_pci(struct pci_controller* hose,
resource_size_t cfg_addr,
resource_size_t cfg_data, u32 flags)
{
setup_indirect_pci(hose, cfg_addr, cfg_data, flags);
hose->ops = &fsl_indirect_pci_ops;
}

#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)

#define MAX_PHYS_ADDR_BITS 40
static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;

Expand Down Expand Up @@ -504,13 +496,15 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
if (!hose->private_data)
goto no_bridge;

fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
PPC_INDIRECT_TYPE_BIG_ENDIAN);
setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
PPC_INDIRECT_TYPE_BIG_ENDIAN);

if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0)
hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK;

if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
/* use fsl_indirect_read_config for PCIe */
hose->ops = &fsl_indirect_pcie_ops;
/* For PCIE read HEADER_TYPE to identify controler mode */
early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
Expand Down Expand Up @@ -814,8 +808,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
if (ret)
goto err0;
} else {
fsl_setup_indirect_pci(hose, rsrc_cfg.start,
rsrc_cfg.start + 4, 0);
setup_indirect_pci(hose, rsrc_cfg.start,
rsrc_cfg.start + 4, 0);
}

printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
Expand Down
3 changes: 2 additions & 1 deletion arch/s390/include/asm/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);

debug_dma_mapping_error(dev, dma_addr);
if (dma_ops->mapping_error)
return dma_ops->mapping_error(dev, dma_addr);
return (dma_addr == 0UL);
return (dma_addr == DMA_ERROR_CODE);
}

static inline void *dma_alloc_coherent(struct device *dev, size_t size,
Expand Down
8 changes: 4 additions & 4 deletions arch/s390/kernel/ipl.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,9 +754,9 @@ static struct bin_attribute sys_reipl_fcp_scp_data_attr = {
.write = reipl_fcp_scpdata_write,
};

DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n",
DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n",
reipl_block_fcp->ipl_info.fcp.wwpn);
DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n",
DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n",
reipl_block_fcp->ipl_info.fcp.lun);
DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
reipl_block_fcp->ipl_info.fcp.bootprog);
Expand Down Expand Up @@ -1323,9 +1323,9 @@ static struct shutdown_action __refdata reipl_action = {

/* FCP dump device attributes */

DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n",
dump_block_fcp->ipl_info.fcp.wwpn);
DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n",
dump_block_fcp->ipl_info.fcp.lun);
DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
dump_block_fcp->ipl_info.fcp.bootprog);
Expand Down
2 changes: 2 additions & 0 deletions arch/s390/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ void measurement_alert_subclass_unregister(void)
}
EXPORT_SYMBOL(measurement_alert_subclass_unregister);

#ifdef CONFIG_SMP
void synchronize_irq(unsigned int irq)
{
/*
Expand All @@ -320,6 +321,7 @@ void synchronize_irq(unsigned int irq)
*/
}
EXPORT_SYMBOL_GPL(synchronize_irq);
#endif

#ifndef CONFIG_PCI

Expand Down
3 changes: 2 additions & 1 deletion arch/s390/mm/mem_detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr,
continue;
} else if ((addr <= chunk->addr) &&
(addr + size >= chunk->addr + chunk->size)) {
memset(chunk, 0 , sizeof(*chunk));
memmove(chunk, chunk + 1, (MEMORY_CHUNKS-i-1) * sizeof(*chunk));
memset(&mem_chunk[MEMORY_CHUNKS-1], 0, sizeof(*chunk));
} else if (addr + size < chunk->addr + chunk->size) {
chunk->size = chunk->addr + chunk->size - addr - size;
chunk->addr = addr + size;
Expand Down
14 changes: 10 additions & 4 deletions arch/x86/kernel/kprobes/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,14 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src)
return insn.length;
}

static void __kprobes arch_copy_kprobe(struct kprobe *p)
static int __kprobes arch_copy_kprobe(struct kprobe *p)
{
int ret;

/* Copy an instruction with recovering if other optprobe modifies it.*/
__copy_instruction(p->ainsn.insn, p->addr);
ret = __copy_instruction(p->ainsn.insn, p->addr);
if (!ret)
return -EINVAL;

/*
* __copy_instruction can modify the displacement of the instruction,
Expand All @@ -384,6 +388,8 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p)

/* Also, displacement change doesn't affect the first byte */
p->opcode = p->ainsn.insn[0];

return 0;
}

int __kprobes arch_prepare_kprobe(struct kprobe *p)
Expand All @@ -397,8 +403,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
p->ainsn.insn = get_insn_slot();
if (!p->ainsn.insn)
return -ENOMEM;
arch_copy_kprobe(p);
return 0;

return arch_copy_kprobe(p);
}

void __kprobes arch_arm_kprobe(struct kprobe *p)
Expand Down
15 changes: 8 additions & 7 deletions crypto/algboss.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ struct cryptomgr_param {
} nu32;
} attrs[CRYPTO_MAX_ATTRS];

char larval[CRYPTO_MAX_ALG_NAME];
char template[CRYPTO_MAX_ALG_NAME];

struct completion *completion;
struct crypto_larval *larval;

u32 otype;
u32 omask;
Expand Down Expand Up @@ -87,7 +86,8 @@ static int cryptomgr_probe(void *data)
crypto_tmpl_put(tmpl);

out:
complete_all(param->completion);
complete_all(&param->larval->completion);
crypto_alg_put(&param->larval->alg);
kfree(param);
module_put_and_exit(0);
}
Expand Down Expand Up @@ -187,18 +187,19 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
param->otype = larval->alg.cra_flags;
param->omask = larval->mask;

memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);

param->completion = &larval->completion;
crypto_alg_get(&larval->alg);
param->larval = larval;

thread = kthread_run(cryptomgr_probe, param, "cryptomgr_probe");
if (IS_ERR(thread))
goto err_free_param;
goto err_put_larval;

wait_for_completion_interruptible(&larval->completion);

return NOTIFY_STOP;

err_put_larval:
crypto_alg_put(&larval->alg);
err_free_param:
kfree(param);
err_put_module:
Expand Down
6 changes: 0 additions & 6 deletions crypto/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem);
BLOCKING_NOTIFIER_HEAD(crypto_chain);
EXPORT_SYMBOL_GPL(crypto_chain);

static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
{
atomic_inc(&alg->cra_refcnt);
return alg;
}

struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
{
return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL;
Expand Down
6 changes: 6 additions & 0 deletions crypto/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ int crypto_register_notifier(struct notifier_block *nb);
int crypto_unregister_notifier(struct notifier_block *nb);
int crypto_probing_notify(unsigned long val, void *v);

static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
{
atomic_inc(&alg->cra_refcnt);
return alg;
}

static inline void crypto_alg_put(struct crypto_alg *alg)
{
if (atomic_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy)
Expand Down
179 changes: 96 additions & 83 deletions drivers/acpi/dock.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,21 @@ struct dock_station {
spinlock_t dd_lock;
struct mutex hp_lock;
struct list_head dependent_devices;
struct list_head hotplug_devices;

struct list_head sibling;
struct platform_device *dock_device;
};
static LIST_HEAD(dock_stations);
static int dock_station_count;
static DEFINE_MUTEX(hotplug_lock);

struct dock_dependent_device {
struct list_head list;
struct list_head hotplug_list;
acpi_handle handle;
const struct acpi_dock_ops *ops;
void *context;
const struct acpi_dock_ops *hp_ops;
void *hp_context;
unsigned int hp_refcount;
void (*hp_release)(void *);
};

#define DOCK_DOCKING 0x00000001
Expand Down Expand Up @@ -111,7 +112,6 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)

dd->handle = handle;
INIT_LIST_HEAD(&dd->list);
INIT_LIST_HEAD(&dd->hotplug_list);

spin_lock(&ds->dd_lock);
list_add_tail(&dd->list, &ds->dependent_devices);
Expand All @@ -121,35 +121,90 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
}

/**
* dock_add_hotplug_device - associate a hotplug handler with the dock station
* @ds: The dock station
* @dd: The dependent device struct
*
* Add the dependent device to the dock's hotplug device list
* dock_init_hotplug - Initialize a hotplug device on a docking station.
* @dd: Dock-dependent device.
* @ops: Dock operations to attach to the dependent device.
* @context: Data to pass to the @ops callbacks and @release.
* @init: Optional initialization routine to run after setting up context.
* @release: Optional release routine to run on removal.
*/
static void
dock_add_hotplug_device(struct dock_station *ds,
struct dock_dependent_device *dd)
static int dock_init_hotplug(struct dock_dependent_device *dd,
const struct acpi_dock_ops *ops, void *context,
void (*init)(void *), void (*release)(void *))
{
mutex_lock(&ds->hp_lock);
list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
mutex_unlock(&ds->hp_lock);
int ret = 0;

mutex_lock(&hotplug_lock);

if (dd->hp_context) {
ret = -EEXIST;
} else {
dd->hp_refcount = 1;
dd->hp_ops = ops;
dd->hp_context = context;
dd->hp_release = release;
}

if (!WARN_ON(ret) && init)
init(context);

mutex_unlock(&hotplug_lock);
return ret;
}

/**
* dock_del_hotplug_device - remove a hotplug handler from the dock station
* @ds: The dock station
* @dd: the dependent device struct
* dock_release_hotplug - Decrement hotplug reference counter of dock device.
* @dd: Dock-dependent device.
*
* Delete the dependent device from the dock's hotplug device list
* Decrement the reference counter of @dd and if 0, detach its hotplug
* operations from it, reset its context pointer and run the optional release
* routine if present.
*/
static void
dock_del_hotplug_device(struct dock_station *ds,
struct dock_dependent_device *dd)
static void dock_release_hotplug(struct dock_dependent_device *dd)
{
mutex_lock(&ds->hp_lock);
list_del(&dd->hotplug_list);
mutex_unlock(&ds->hp_lock);
void (*release)(void *) = NULL;
void *context = NULL;

mutex_lock(&hotplug_lock);

if (dd->hp_context && !--dd->hp_refcount) {
dd->hp_ops = NULL;
context = dd->hp_context;
dd->hp_context = NULL;
release = dd->hp_release;
dd->hp_release = NULL;
}

if (release && context)
release(context);

mutex_unlock(&hotplug_lock);
}

static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event,
bool uevent)
{
acpi_notify_handler cb = NULL;
bool run = false;

mutex_lock(&hotplug_lock);

if (dd->hp_context) {
run = true;
dd->hp_refcount++;
if (dd->hp_ops)
cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler;
}

mutex_unlock(&hotplug_lock);

if (!run)
return;

if (cb)
cb(dd->handle, event, dd->hp_context);

dock_release_hotplug(dd);
}

/**
Expand Down Expand Up @@ -360,9 +415,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
/*
* First call driver specific hotplug functions
*/
list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
if (dd->ops && dd->ops->handler)
dd->ops->handler(dd->handle, event, dd->context);
list_for_each_entry(dd, &ds->dependent_devices, list)
dock_hotplug_event(dd, event, false);

/*
* Now make sure that an acpi_device is created for each
Expand Down Expand Up @@ -398,9 +452,8 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
if (num == DOCK_EVENT)
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);

list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
if (dd->ops && dd->ops->uevent)
dd->ops->uevent(dd->handle, event, dd->context);
list_for_each_entry(dd, &ds->dependent_devices, list)
dock_hotplug_event(dd, event, true);

if (num != DOCK_EVENT)
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
Expand Down Expand Up @@ -570,19 +623,24 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
* @handle: the handle of the device
* @ops: handlers to call after docking
* @context: device specific data
* @init: Optional initialization routine to run after registration
* @release: Optional release routine to run on unregistration
*
* If a driver would like to perform a hotplug operation after a dock
* event, they can register an acpi_notifiy_handler to be called by
* the dock driver after _DCK is executed.
*/
int
register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops,
void *context)
int register_hotplug_dock_device(acpi_handle handle,
const struct acpi_dock_ops *ops, void *context,
void (*init)(void *), void (*release)(void *))
{
struct dock_dependent_device *dd;
struct dock_station *dock_station;
int ret = -EINVAL;

if (WARN_ON(!context))
return -EINVAL;

if (!dock_station_count)
return -ENODEV;

Expand All @@ -597,12 +655,8 @@ register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops
* ops
*/
dd = find_dock_dependent_device(dock_station, handle);
if (dd) {
dd->ops = ops;
dd->context = context;
dock_add_hotplug_device(dock_station, dd);
if (dd && !dock_init_hotplug(dd, ops, context, init, release))
ret = 0;
}
}

return ret;
Expand All @@ -624,7 +678,7 @@ void unregister_hotplug_dock_device(acpi_handle handle)
list_for_each_entry(dock_station, &dock_stations, sibling) {
dd = find_dock_dependent_device(dock_station, handle);
if (dd)
dock_del_hotplug_device(dock_station, dd);
dock_release_hotplug(dd);
}
}
EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
Expand Down Expand Up @@ -953,7 +1007,6 @@ static int __init dock_add(acpi_handle handle)
mutex_init(&dock_station->hp_lock);
spin_lock_init(&dock_station->dd_lock);
INIT_LIST_HEAD(&dock_station->sibling);
INIT_LIST_HEAD(&dock_station->hotplug_devices);
ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
INIT_LIST_HEAD(&dock_station->dependent_devices);

Expand Down Expand Up @@ -993,30 +1046,6 @@ static int __init dock_add(acpi_handle handle)
return ret;
}

/**
* dock_remove - free up resources related to the dock station
*/
static int dock_remove(struct dock_station *ds)
{
struct dock_dependent_device *dd, *tmp;
struct platform_device *dock_device = ds->dock_device;

if (!dock_station_count)
return 0;

/* remove dependent devices */
list_for_each_entry_safe(dd, tmp, &ds->dependent_devices, list)
kfree(dd);

list_del(&ds->sibling);

/* cleanup sysfs */
sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group);
platform_device_unregister(dock_device);

return 0;
}

/**
* find_dock_and_bay - look for dock stations and bays
* @handle: acpi handle of a device
Expand All @@ -1035,7 +1064,7 @@ find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK;
}

static int __init dock_init(void)
int __init acpi_dock_init(void)
{
if (acpi_disabled)
return 0;
Expand All @@ -1054,19 +1083,3 @@ static int __init dock_init(void)
ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
return 0;
}

static void __exit dock_exit(void)
{
struct dock_station *tmp, *dock_station;

unregister_acpi_bus_notifier(&dock_acpi_notifier);
list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling)
dock_remove(dock_station);
}

/*
* Must be called before drivers of devices in dock, otherwise we can't know
* which devices are in a dock
*/
subsys_initcall(dock_init);
module_exit(dock_exit);
5 changes: 5 additions & 0 deletions drivers/acpi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ void acpi_container_init(void);
#else
static inline void acpi_container_init(void) {}
#endif
#ifdef CONFIG_ACPI_DOCK
void acpi_dock_init(void);
#else
static inline void acpi_dock_init(void) {}
#endif
#ifdef CONFIG_ACPI_HOTPLUG_MEMORY
void acpi_memory_hotplug_init(void);
#else
Expand Down
1 change: 1 addition & 0 deletions drivers/acpi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -2042,6 +2042,7 @@ int __init acpi_scan_init(void)
acpi_lpss_init();
acpi_container_init();
acpi_memory_hotplug_init();
acpi_dock_init();

mutex_lock(&acpi_scan_lock);
/*
Expand Down
37 changes: 36 additions & 1 deletion drivers/ata/libata-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,10 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,

spin_unlock_irqrestore(ap->lock, flags);

if (wait)
if (wait) {
ata_port_wait_eh(ap);
flush_work(&ap->hotplug_task.work);
}
}

static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
Expand Down Expand Up @@ -214,6 +216,39 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
.uevent = ata_acpi_ap_uevent,
};

void ata_acpi_hotplug_init(struct ata_host *host)
{
int i;

for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
acpi_handle handle;
struct ata_device *dev;

if (!ap)
continue;

handle = ata_ap_acpi_handle(ap);
if (handle) {
/* we might be on a docking station */
register_hotplug_dock_device(handle,
&ata_acpi_ap_dock_ops, ap,
NULL, NULL);
}

ata_for_each_dev(dev, &ap->link, ALL) {
handle = ata_dev_acpi_handle(dev);
if (!handle)
continue;

/* we might be on a docking station */
register_hotplug_dock_device(handle,
&ata_acpi_dev_dock_ops,
dev, NULL, NULL);
}
}
}

/**
* ata_acpi_dissociate - dissociate ATA host from ACPI objects
* @host: target ATA host
Expand Down
2 changes: 2 additions & 0 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -6148,6 +6148,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
if (rc)
goto err_tadd;

ata_acpi_hotplug_init(host);

/* set cable, sata_spd_limit and report */
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
Expand Down
2 changes: 2 additions & 0 deletions drivers/ata/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ extern int ata_acpi_register(void);
extern void ata_acpi_unregister(void);
extern void ata_acpi_bind(struct ata_device *dev);
extern void ata_acpi_unbind(struct ata_device *dev);
extern void ata_acpi_hotplug_init(struct ata_host *host);
#else
static inline void ata_acpi_dissociate(struct ata_host *host) { }
static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
Expand All @@ -134,6 +135,7 @@ static inline int ata_acpi_register(void) { return 0; }
static inline void ata_acpi_unregister(void) { }
static inline void ata_acpi_bind(struct ata_device *dev) { }
static inline void ata_acpi_unbind(struct ata_device *dev) { }
static inline void ata_acpi_hotplug_init(struct ata_host *host) {}
#endif

/* libata-scsi.c */
Expand Down
14 changes: 9 additions & 5 deletions drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2252,13 +2252,17 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
obj_request->pages, length,
offset & ~PAGE_MASK, false, false);

/*
* set obj_request->img_request before formatting
* the osd_request so that it gets the right snapc
*/
rbd_img_obj_request_add(img_request, obj_request);
if (write_request)
rbd_osd_req_format_write(obj_request);
else
rbd_osd_req_format_read(obj_request);

obj_request->img_offset = img_offset;
rbd_img_obj_request_add(img_request, obj_request);

img_offset += length;
resid -= length;
Expand Down Expand Up @@ -4243,6 +4247,10 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)

down_write(&rbd_dev->header_rwsem);

ret = rbd_dev_v2_image_size(rbd_dev);
if (ret)
goto out;

if (first_time) {
ret = rbd_dev_v2_header_onetime(rbd_dev);
if (ret)
Expand Down Expand Up @@ -4276,10 +4284,6 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
"is EXPERIMENTAL!");
}

ret = rbd_dev_v2_image_size(rbd_dev);
if (ret)
goto out;

if (rbd_dev->spec->snap_id == CEPH_NOSNAP)
if (rbd_dev->mapping.size != rbd_dev->header.image_size)
rbd_dev->mapping.size = rbd_dev->header.image_size;
Expand Down
9 changes: 4 additions & 5 deletions drivers/bluetooth/btmrvl_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,10 @@ static int btmrvl_service_main_thread(void *data)
add_wait_queue(&thread->wait_q, &wait);

set_current_state(TASK_INTERRUPTIBLE);
if (kthread_should_stop()) {
BT_DBG("main_thread: break from main thread");
break;
}

if (adapter->wakeup_tries ||
((!adapter->int_count) &&
Expand All @@ -513,11 +517,6 @@ static int btmrvl_service_main_thread(void *data)

BT_DBG("main_thread woke up");

if (kthread_should_stop()) {
BT_DBG("main_thread: break from main thread");
break;
}

spin_lock_irqsave(&priv->driver_lock, flags);
if (adapter->int_count) {
adapter->int_count = 0;
Expand Down
17 changes: 13 additions & 4 deletions drivers/cpufreq/cpufreq_ondemand.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ static struct od_ops od_ops;
static struct cpufreq_governor cpufreq_gov_ondemand;
#endif

static unsigned int default_powersave_bias;

static void ondemand_powersave_bias_init_cpu(int cpu)
{
struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
Expand Down Expand Up @@ -543,7 +545,7 @@ static int od_init(struct dbs_data *dbs_data)

tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
tuners->ignore_nice = 0;
tuners->powersave_bias = 0;
tuners->powersave_bias = default_powersave_bias;
tuners->io_is_busy = should_io_be_busy();

dbs_data->tuners = tuners;
Expand Down Expand Up @@ -585,6 +587,7 @@ static void od_set_powersave_bias(unsigned int powersave_bias)
unsigned int cpu;
cpumask_t done;

default_powersave_bias = powersave_bias;
cpumask_clear(&done);

get_online_cpus();
Expand All @@ -593,11 +596,17 @@ static void od_set_powersave_bias(unsigned int powersave_bias)
continue;

policy = per_cpu(od_cpu_dbs_info, cpu).cdbs.cur_policy;
dbs_data = policy->governor_data;
od_tuners = dbs_data->tuners;
od_tuners->powersave_bias = powersave_bias;
if (!policy)
continue;

cpumask_or(&done, &done, policy->cpus);

if (policy->governor != &cpufreq_gov_ondemand)
continue;

dbs_data = policy->governor_data;
od_tuners = dbs_data->tuners;
od_tuners->powersave_bias = default_powersave_bias;
}
put_online_cpus();
}
Expand Down
22 changes: 21 additions & 1 deletion drivers/gpio/gpio-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,9 @@ static int omap_gpio_probe(struct platform_device *pdev)
const struct omap_gpio_platform_data *pdata;
struct resource *res;
struct gpio_bank *bank;
#ifdef CONFIG_ARCH_OMAP1
int irq_base;
#endif

match = of_match_device(of_match_ptr(omap_gpio_match), dev);

Expand Down Expand Up @@ -1135,11 +1138,28 @@ static int omap_gpio_probe(struct platform_device *pdev)
pdata->get_context_loss_count;
}

#ifdef CONFIG_ARCH_OMAP1
/*
* REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
* irq_alloc_descs() and irq_domain_add_legacy() and just use a
* linear IRQ domain mapping for all OMAP platforms.
*/
irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
if (irq_base < 0) {
dev_err(dev, "Couldn't allocate IRQ numbers\n");
return -ENODEV;
}

bank->domain = irq_domain_add_legacy(node, bank->width, irq_base,
0, &irq_domain_simple_ops, NULL);
#else
bank->domain = irq_domain_add_linear(node, bank->width,
&irq_domain_simple_ops, NULL);
if (!bank->domain)
#endif
if (!bank->domain) {
dev_err(dev, "Couldn't register an IRQ domain\n");
return -ENODEV;
}

if (bank->regs->set_dataout && bank->regs->clr_dataout)
bank->set_dataout = _set_gpio_dataout_reg;
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1697,6 +1697,8 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *gem_obj, int flags);

void i915_gem_restore_fences(struct drm_device *dev);

/* i915_gem_context.c */
void i915_gem_context_init(struct drm_device *dev);
void i915_gem_context_fini(struct drm_device *dev);
Expand Down
37 changes: 17 additions & 20 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1801,7 +1801,14 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
gfp &= ~(__GFP_IO | __GFP_WAIT);
}

#ifdef CONFIG_SWIOTLB
if (swiotlb_nr_tbl()) {
st->nents++;
sg_set_page(sg, page, PAGE_SIZE, 0);
sg = sg_next(sg);
continue;
}
#endif
if (!i || page_to_pfn(page) != last_pfn + 1) {
if (i)
sg = sg_next(sg);
Expand All @@ -1812,8 +1819,10 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
}
last_pfn = page_to_pfn(page);
}

sg_mark_end(sg);
#ifdef CONFIG_SWIOTLB
if (!swiotlb_nr_tbl())
#endif
sg_mark_end(sg);
obj->pages = st;

if (i915_gem_object_needs_bit17_swizzle(obj))
Expand Down Expand Up @@ -2117,25 +2126,15 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
}
}

static void i915_gem_reset_fences(struct drm_device *dev)
void i915_gem_restore_fences(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i;

for (i = 0; i < dev_priv->num_fence_regs; i++) {
struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];

if (reg->obj)
i915_gem_object_fence_lost(reg->obj);

i915_gem_write_fence(dev, i, NULL);

reg->pin_count = 0;
reg->obj = NULL;
INIT_LIST_HEAD(&reg->lru_list);
i915_gem_write_fence(dev, i, reg->obj);
}

INIT_LIST_HEAD(&dev_priv->mm.fence_list);
}

void i915_gem_reset(struct drm_device *dev)
Expand All @@ -2158,8 +2157,7 @@ void i915_gem_reset(struct drm_device *dev)
obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS;
}

/* The fence registers are invalidated so clear them out */
i915_gem_reset_fences(dev);
i915_gem_restore_fences(dev);
}

/**
Expand Down Expand Up @@ -3865,8 +3863,6 @@ i915_gem_idle(struct drm_device *dev)
if (!drm_core_check_feature(dev, DRIVER_MODESET))
i915_gem_evict_everything(dev);

i915_gem_reset_fences(dev);

/* Hack! Don't let anybody do execbuf while we don't control the chip.
* We need to replace this with a semaphore, or something.
* And not confound mm.suspended!
Expand Down Expand Up @@ -4193,7 +4189,8 @@ i915_gem_load(struct drm_device *dev)
dev_priv->num_fence_regs = 8;

/* Initialize fence registers to zero */
i915_gem_reset_fences(dev);
INIT_LIST_HEAD(&dev_priv->mm.fence_list);
i915_gem_restore_fences(dev);

i915_gem_detect_bit_6_swizzle(dev);
init_waitqueue_head(&dev_priv->pending_flip_queue);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ int i915_restore_state(struct drm_device *dev)

mutex_lock(&dev->struct_mutex);

i915_gem_restore_fences(dev);
i915_restore_display(dev);

if (!drm_core_check_feature(dev, DRIVER_MODESET)) {
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/qxl/qxl_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data,
if (user_cmd.command_size > PAGE_SIZE - sizeof(union qxl_release_info))
return -EINVAL;

if (!access_ok(VERIFY_READ,
(void *)(unsigned long)user_cmd.command,
user_cmd.command_size))
return -EFAULT;

ret = qxl_alloc_release_reserved(qdev,
sizeof(union qxl_release_info) +
user_cmd.command_size,
Expand Down
2 changes: 1 addition & 1 deletion drivers/mfd/tps6586x.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static struct mfd_cell tps6586x_cell[] = {
.name = "tps6586x-gpio",
},
{
.name = "tps6586x-pmic",
.name = "tps6586x-regulator",
},
{
.name = "tps6586x-rtc",
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2413,7 +2413,8 @@ static void bond_miimon_commit(struct bonding *bond)

pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
bond->dev->name, slave->dev->name,
slave->speed, slave->duplex ? "full" : "half");
slave->speed == SPEED_UNKNOWN ? 0 : slave->speed,
slave->duplex ? "full" : "half");

/* notify ad that the link status has changed */
if (bond->params.mode == BOND_MODE_8023AD)
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/can/usb/usb_8dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
err = usb_8dev_cmd_version(priv, &version);
if (err) {
netdev_err(netdev, "can't get firmware version\n");
goto cleanup_cmd_msg_buffer;
goto cleanup_unregister_candev;
} else {
netdev_info(netdev,
"firmware: %d.%d, hardware: %d.%d\n",
Expand All @@ -989,6 +989,9 @@ static int usb_8dev_probe(struct usb_interface *intf,

return 0;

cleanup_unregister_candev:
unregister_netdev(priv->netdev);

cleanup_cmd_msg_buffer:
kfree(priv->cmd_msg_buffer);

Expand Down
18 changes: 18 additions & 0 deletions drivers/net/ethernet/atheros/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,22 @@ config ATL1C
To compile this driver as a module, choose M here. The module
will be called atl1c.

config ALX
tristate "Qualcomm Atheros AR816x/AR817x support"
depends on PCI
select CRC32
select NET_CORE
select MDIO
help
This driver supports the Qualcomm Atheros L1F ethernet adapter,
i.e. the following chipsets:

1969:1091 - AR8161 Gigabit Ethernet
1969:1090 - AR8162 Fast Ethernet
1969:10A1 - AR8171 Gigabit Ethernet
1969:10A0 - AR8172 Fast Ethernet

To compile this driver as a module, choose M here. The module
will be called alx.

endif # NET_VENDOR_ATHEROS
1 change: 1 addition & 0 deletions drivers/net/ethernet/atheros/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ obj-$(CONFIG_ATL1) += atlx/
obj-$(CONFIG_ATL2) += atlx/
obj-$(CONFIG_ATL1E) += atl1e/
obj-$(CONFIG_ATL1C) += atl1c/
obj-$(CONFIG_ALX) += alx/
3 changes: 3 additions & 0 deletions drivers/net/ethernet/atheros/alx/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
obj-$(CONFIG_ALX) += alx.o
alx-objs := main.o ethtool.o hw.o
ccflags-y += -D__CHECK_ENDIAN__
114 changes: 114 additions & 0 deletions drivers/net/ethernet/atheros/alx/alx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net>
*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright (c) 2012 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef _ALX_H_
#define _ALX_H_

#include <linux/types.h>
#include <linux/etherdevice.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
#include "hw.h"

#define ALX_WATCHDOG_TIME (5 * HZ)

struct alx_buffer {
struct sk_buff *skb;
DEFINE_DMA_UNMAP_ADDR(dma);
DEFINE_DMA_UNMAP_LEN(size);
};

struct alx_rx_queue {
struct alx_rrd *rrd;
dma_addr_t rrd_dma;

struct alx_rfd *rfd;
dma_addr_t rfd_dma;

struct alx_buffer *bufs;

u16 write_idx, read_idx;
u16 rrd_read_idx;
};
#define ALX_RX_ALLOC_THRESH 32

struct alx_tx_queue {
struct alx_txd *tpd;
dma_addr_t tpd_dma;
struct alx_buffer *bufs;
u16 write_idx, read_idx;
};

#define ALX_DEFAULT_TX_WORK 128

enum alx_device_quirks {
ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG = BIT(0),
};

struct alx_priv {
struct net_device *dev;

struct alx_hw hw;

/* all descriptor memory */
struct {
dma_addr_t dma;
void *virt;
int size;
} descmem;

/* protect int_mask updates */
spinlock_t irq_lock;
u32 int_mask;

int tx_ringsz;
int rx_ringsz;
int rxbuf_size;

struct napi_struct napi;
struct alx_tx_queue txq;
struct alx_rx_queue rxq;

struct work_struct link_check_wk;
struct work_struct reset_wk;

u16 msg_enable;

bool msi;
};

extern const struct ethtool_ops alx_ethtool_ops;
extern const char alx_drv_name[];

#endif
272 changes: 272 additions & 0 deletions drivers/net/ethernet/atheros/alx/ethtool.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
/*
* Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net>
*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright (c) 2012 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <linux/pci.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/mdio.h>
#include <linux/interrupt.h>
#include <asm/byteorder.h>

#include "alx.h"
#include "reg.h"
#include "hw.h"


static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct alx_priv *alx = netdev_priv(netdev);
struct alx_hw *hw = &alx->hw;

ecmd->supported = SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP |
SUPPORTED_Pause;
if (alx_hw_giga(hw))
ecmd->supported |= SUPPORTED_1000baseT_Full;

ecmd->advertising = ADVERTISED_TP;
if (hw->adv_cfg & ADVERTISED_Autoneg)
ecmd->advertising |= hw->adv_cfg;

ecmd->port = PORT_TP;
ecmd->phy_address = 0;
if (hw->adv_cfg & ADVERTISED_Autoneg)
ecmd->autoneg = AUTONEG_ENABLE;
else
ecmd->autoneg = AUTONEG_DISABLE;
ecmd->transceiver = XCVR_INTERNAL;

if (hw->flowctrl & ALX_FC_ANEG && hw->adv_cfg & ADVERTISED_Autoneg) {
if (hw->flowctrl & ALX_FC_RX) {
ecmd->advertising |= ADVERTISED_Pause;

if (!(hw->flowctrl & ALX_FC_TX))
ecmd->advertising |= ADVERTISED_Asym_Pause;
} else if (hw->flowctrl & ALX_FC_TX) {
ecmd->advertising |= ADVERTISED_Asym_Pause;
}
}

if (hw->link_speed != SPEED_UNKNOWN) {
ethtool_cmd_speed_set(ecmd,
hw->link_speed - hw->link_speed % 10);
ecmd->duplex = hw->link_speed % 10;
} else {
ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
ecmd->duplex = DUPLEX_UNKNOWN;
}

return 0;
}

static int alx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct alx_priv *alx = netdev_priv(netdev);
struct alx_hw *hw = &alx->hw;
u32 adv_cfg;

ASSERT_RTNL();

if (ecmd->autoneg == AUTONEG_ENABLE) {
if (ecmd->advertising & ADVERTISED_1000baseT_Half)
return -EINVAL;
adv_cfg = ecmd->advertising | ADVERTISED_Autoneg;
} else {
int speed = ethtool_cmd_speed(ecmd);

switch (speed + ecmd->duplex) {
case SPEED_10 + DUPLEX_HALF:
adv_cfg = ADVERTISED_10baseT_Half;
break;
case SPEED_10 + DUPLEX_FULL:
adv_cfg = ADVERTISED_10baseT_Full;
break;
case SPEED_100 + DUPLEX_HALF:
adv_cfg = ADVERTISED_100baseT_Half;
break;
case SPEED_100 + DUPLEX_FULL:
adv_cfg = ADVERTISED_100baseT_Full;
break;
default:
return -EINVAL;
}
}

hw->adv_cfg = adv_cfg;
return alx_setup_speed_duplex(hw, adv_cfg, hw->flowctrl);
}

static void alx_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct alx_priv *alx = netdev_priv(netdev);
struct alx_hw *hw = &alx->hw;

if (hw->flowctrl & ALX_FC_ANEG &&
hw->adv_cfg & ADVERTISED_Autoneg)
pause->autoneg = AUTONEG_ENABLE;
else
pause->autoneg = AUTONEG_DISABLE;

if (hw->flowctrl & ALX_FC_TX)
pause->tx_pause = 1;
else
pause->tx_pause = 0;

if (hw->flowctrl & ALX_FC_RX)
pause->rx_pause = 1;
else
pause->rx_pause = 0;
}


static int alx_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct alx_priv *alx = netdev_priv(netdev);
struct alx_hw *hw = &alx->hw;
int err = 0;
bool reconfig_phy = false;
u8 fc = 0;

if (pause->tx_pause)
fc |= ALX_FC_TX;
if (pause->rx_pause)
fc |= ALX_FC_RX;
if (pause->autoneg)
fc |= ALX_FC_ANEG;

ASSERT_RTNL();

/* restart auto-neg for auto-mode */
if (hw->adv_cfg & ADVERTISED_Autoneg) {
if (!((fc ^ hw->flowctrl) & ALX_FC_ANEG))
reconfig_phy = true;
if (fc & hw->flowctrl & ALX_FC_ANEG &&
(fc ^ hw->flowctrl) & (ALX_FC_RX | ALX_FC_TX))
reconfig_phy = true;
}

if (reconfig_phy) {
err = alx_setup_speed_duplex(hw, hw->adv_cfg, fc);
return err;
}

/* flow control on mac */
if ((fc ^ hw->flowctrl) & (ALX_FC_RX | ALX_FC_TX))
alx_cfg_mac_flowcontrol(hw, fc);

hw->flowctrl = fc;

return 0;
}

static u32 alx_get_msglevel(struct net_device *netdev)
{
struct alx_priv *alx = netdev_priv(netdev);

return alx->msg_enable;
}

static void alx_set_msglevel(struct net_device *netdev, u32 data)
{
struct alx_priv *alx = netdev_priv(netdev);

alx->msg_enable = data;
}

static void alx_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct alx_priv *alx = netdev_priv(netdev);
struct alx_hw *hw = &alx->hw;

wol->supported = WAKE_MAGIC | WAKE_PHY;
wol->wolopts = 0;

if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC)
wol->wolopts |= WAKE_MAGIC;
if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY)
wol->wolopts |= WAKE_PHY;
}

static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct alx_priv *alx = netdev_priv(netdev);
struct alx_hw *hw = &alx->hw;

if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
return -EOPNOTSUPP;

hw->sleep_ctrl = 0;

if (wol->wolopts & WAKE_MAGIC)
hw->sleep_ctrl |= ALX_SLEEP_WOL_MAGIC;
if (wol->wolopts & WAKE_PHY)
hw->sleep_ctrl |= ALX_SLEEP_WOL_PHY;

device_set_wakeup_enable(&alx->hw.pdev->dev, hw->sleep_ctrl);

return 0;
}

static void alx_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct alx_priv *alx = netdev_priv(netdev);

strlcpy(drvinfo->driver, alx_drv_name, sizeof(drvinfo->driver));
strlcpy(drvinfo->bus_info, pci_name(alx->hw.pdev),
sizeof(drvinfo->bus_info));
}

const struct ethtool_ops alx_ethtool_ops = {
.get_settings = alx_get_settings,
.set_settings = alx_set_settings,
.get_pauseparam = alx_get_pauseparam,
.set_pauseparam = alx_set_pauseparam,
.get_drvinfo = alx_get_drvinfo,
.get_msglevel = alx_get_msglevel,
.set_msglevel = alx_set_msglevel,
.get_wol = alx_get_wol,
.set_wol = alx_set_wol,
.get_link = ethtool_op_get_link,
};
1,226 changes: 1,226 additions & 0 deletions drivers/net/ethernet/atheros/alx/hw.c

Large diffs are not rendered by default.

499 changes: 499 additions & 0 deletions drivers/net/ethernet/atheros/alx/hw.h

Large diffs are not rendered by default.

1,625 changes: 1,625 additions & 0 deletions drivers/net/ethernet/atheros/alx/main.c

Large diffs are not rendered by default.

810 changes: 810 additions & 0 deletions drivers/net/ethernet/atheros/alx/reg.h

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,9 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
status = tg3_ape_read32(tp, gnt + off);
if (status == bit)
break;
if (pci_channel_offline(tp->pdev))
break;

udelay(10);
}

Expand Down Expand Up @@ -1635,6 +1638,9 @@ static void tg3_wait_for_event_ack(struct tg3 *tp)
for (i = 0; i < delay_cnt; i++) {
if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
break;
if (pci_channel_offline(tp->pdev))
break;

udelay(8);
}
}
Expand Down Expand Up @@ -1813,6 +1819,9 @@ static int tg3_poll_fw(struct tg3 *tp)
for (i = 0; i < 200; i++) {
if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE)
return 0;
if (pci_channel_offline(tp->pdev))
return -ENODEV;

udelay(100);
}
return -ENODEV;
Expand All @@ -1823,6 +1832,15 @@ static int tg3_poll_fw(struct tg3 *tp)
tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
break;
if (pci_channel_offline(tp->pdev)) {
if (!tg3_flag(tp, NO_FWARE_REPORTED)) {
tg3_flag_set(tp, NO_FWARE_REPORTED);
netdev_info(tp->dev, "No firmware running\n");
}

break;
}

udelay(10);
}

Expand Down Expand Up @@ -3520,6 +3538,8 @@ static int tg3_pause_cpu(struct tg3 *tp, u32 cpu_base)
tw32(cpu_base + CPU_MODE, CPU_MODE_HALT);
if (tr32(cpu_base + CPU_MODE) & CPU_MODE_HALT)
break;
if (pci_channel_offline(tp->pdev))
return -EBUSY;
}

return (i == iters) ? -EBUSY : 0;
Expand Down Expand Up @@ -8589,6 +8609,14 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, boo
tw32_f(ofs, val);

for (i = 0; i < MAX_WAIT_CNT; i++) {
if (pci_channel_offline(tp->pdev)) {
dev_err(&tp->pdev->dev,
"tg3_stop_block device offline, "
"ofs=%lx enable_bit=%x\n",
ofs, enable_bit);
return -ENODEV;
}

udelay(100);
val = tr32(ofs);
if ((val & enable_bit) == 0)
Expand All @@ -8612,6 +8640,13 @@ static int tg3_abort_hw(struct tg3 *tp, bool silent)

tg3_disable_ints(tp);

if (pci_channel_offline(tp->pdev)) {
tp->rx_mode &= ~(RX_MODE_ENABLE | TX_MODE_ENABLE);
tp->mac_mode &= ~MAC_MODE_TDE_ENABLE;
err = -ENODEV;
goto err_no_dev;
}

tp->rx_mode &= ~RX_MODE_ENABLE;
tw32_f(MAC_RX_MODE, tp->rx_mode);
udelay(10);
Expand Down Expand Up @@ -8660,6 +8695,7 @@ static int tg3_abort_hw(struct tg3 *tp, bool silent)
err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent);
err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent);

err_no_dev:
for (i = 0; i < tp->irq_cnt; i++) {
struct tg3_napi *tnapi = &tp->napi[i];
if (tnapi->hw_status)
Expand Down
14 changes: 14 additions & 0 deletions drivers/net/ethernet/freescale/fec_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,13 +516,15 @@ fec_restart(struct net_device *ndev, int duplex)
/* Set MII speed */
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);

#if !defined(CONFIG_M5272)
/* set RX checksum */
val = readl(fep->hwp + FEC_RACC);
if (fep->csum_flags & FLAG_RX_CSUM_ENABLED)
val |= FEC_RACC_OPTIONS;
else
val &= ~FEC_RACC_OPTIONS;
writel(val, fep->hwp + FEC_RACC);
#endif

/*
* The phy interface and speed need to get configured
Expand Down Expand Up @@ -575,6 +577,7 @@ fec_restart(struct net_device *ndev, int duplex)
#endif
}

#if !defined(CONFIG_M5272)
/* enable pause frame*/
if ((fep->pause_flag & FEC_PAUSE_FLAG_ENABLE) ||
((fep->pause_flag & FEC_PAUSE_FLAG_AUTONEG) &&
Expand All @@ -592,6 +595,7 @@ fec_restart(struct net_device *ndev, int duplex)
} else {
rcntl &= ~FEC_ENET_FCE;
}
#endif /* !defined(CONFIG_M5272) */

writel(rcntl, fep->hwp + FEC_R_CNTRL);

Expand Down Expand Up @@ -1205,7 +1209,9 @@ static int fec_enet_mii_probe(struct net_device *ndev)
/* mask with MAC supported features */
if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) {
phy_dev->supported &= PHY_GBIT_FEATURES;
#if !defined(CONFIG_M5272)
phy_dev->supported |= SUPPORTED_Pause;
#endif
}
else
phy_dev->supported &= PHY_BASIC_FEATURES;
Expand Down Expand Up @@ -1390,6 +1396,8 @@ static int fec_enet_get_ts_info(struct net_device *ndev,
}
}

#if !defined(CONFIG_M5272)

static void fec_enet_get_pauseparam(struct net_device *ndev,
struct ethtool_pauseparam *pause)
{
Expand Down Expand Up @@ -1436,9 +1444,13 @@ static int fec_enet_set_pauseparam(struct net_device *ndev,
return 0;
}

#endif /* !defined(CONFIG_M5272) */

static const struct ethtool_ops fec_enet_ethtool_ops = {
#if !defined(CONFIG_M5272)
.get_pauseparam = fec_enet_get_pauseparam,
.set_pauseparam = fec_enet_set_pauseparam,
#endif
.get_settings = fec_enet_get_settings,
.set_settings = fec_enet_set_settings,
.get_drvinfo = fec_enet_get_drvinfo,
Expand Down Expand Up @@ -1874,10 +1886,12 @@ fec_probe(struct platform_device *pdev)
/* setup board info structure */
fep = netdev_priv(ndev);

#if !defined(CONFIG_M5272)
/* default enable pause frame auto negotiation */
if (pdev->id_entry &&
(pdev->id_entry->driver_data & FEC_QUIRK_HAS_GBIT))
fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG;
#endif

fep->hwp = devm_request_and_ioremap(&pdev->dev, r);
fep->pdev = pdev;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/mv643xx_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1757,7 +1757,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index)
memset(rxq->rx_desc_area, 0, size);

rxq->rx_desc_area_size = size;
rxq->rx_skb = kmalloc_array(rxq->rx_ring_size, sizeof(*rxq->rx_skb),
rxq->rx_skb = kcalloc(rxq->rx_ring_size, sizeof(*rxq->rx_skb),
GFP_KERNEL);
if (rxq->rx_skb == NULL)
goto out_free;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/marvell/pxa168_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1015,7 +1015,7 @@ static int rxq_init(struct net_device *dev)
int rx_desc_num = pep->rx_ring_size;

/* Allocate RX skb rings */
pep->rx_skb = kmalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size,
pep->rx_skb = kzalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size,
GFP_KERNEL);
if (!pep->rx_skb)
return -ENOMEM;
Expand Down Expand Up @@ -1076,7 +1076,7 @@ static int txq_init(struct net_device *dev)
int size = 0, i = 0;
int tx_desc_num = pep->tx_ring_size;

pep->tx_skb = kmalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size,
pep->tx_skb = kzalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size,
GFP_KERNEL);
if (!pep->tx_skb)
return -ENOMEM;
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/mellanox/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,9 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
dev->caps.cqe_size = 32;
}

dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS;
mlx4_warn(dev, "Timestamping is not supported in slave mode.\n");

slave_adjust_steering_mode(dev, &dev_cap, &hca_param);

return 0;
Expand Down
31 changes: 21 additions & 10 deletions drivers/net/ethernet/octeon/octeon_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,25 @@
union mgmt_port_ring_entry {
u64 d64;
struct {
u64 reserved_62_63:2;
#define RING_ENTRY_CODE_DONE 0xf
#define RING_ENTRY_CODE_MORE 0x10
#ifdef __BIG_ENDIAN_BITFIELD
u64 reserved_62_63:2;
/* Length of the buffer/packet in bytes */
u64 len:14;
u64 len:14;
/* For TX, signals that the packet should be timestamped */
u64 tstamp:1;
u64 tstamp:1;
/* The RX error code */
u64 code:7;
#define RING_ENTRY_CODE_DONE 0xf
#define RING_ENTRY_CODE_MORE 0x10
u64 code:7;
/* Physical address of the buffer */
u64 addr:40;
u64 addr:40;
#else
u64 addr:40;
u64 code:7;
u64 tstamp:1;
u64 len:14;
u64 reserved_62_63:2;
#endif
} s;
};

Expand Down Expand Up @@ -1141,10 +1149,13 @@ static int octeon_mgmt_open(struct net_device *netdev)
/* For compensation state to lock. */
ndelay(1040 * NS_PER_PHY_CLK);

/* Some Ethernet switches cannot handle standard
* Interframe Gap, increase to 16 bytes.
/* Default Interframe Gaps are too small. Recommended
* workaround is.
*
* AGL_GMX_TX_IFG[IFG1]=14
* AGL_GMX_TX_IFG[IFG2]=10
*/
cvmx_write_csr(CVMX_AGL_GMX_TX_IFG, 0x88);
cvmx_write_csr(CVMX_AGL_GMX_TX_IFG, 0xae);
}

octeon_mgmt_rx_fill_ring(netdev);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)
qlcnic_83xx_config_intrpt(adapter, 0);
}
/* Allow dma queues to drain after context reset */
msleep(20);
mdelay(20);
}
}

Expand Down
38 changes: 21 additions & 17 deletions drivers/net/ethernet/renesas/sh_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.eesipr_value = 0x01ff009f,

.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
EESR_ECI,
.tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,

.apr = 1,
Expand Down Expand Up @@ -427,8 +428,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x01ff009f,

.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
EESR_ECI,
.tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,

.apr = 1,
Expand Down Expand Up @@ -478,8 +480,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.rmcr_value = 0x00000001,

.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
EESR_ECI,
.tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,

.apr = 1,
Expand Down Expand Up @@ -592,9 +595,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
.eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,

.tx_check = EESR_TC1 | EESR_FTC,
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
EESR_ECI,
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
EESR_TDE | EESR_ECI,
.tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
EESR_TFE,
.fdr_value = 0x0000072f,
Expand Down Expand Up @@ -674,9 +677,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,

.tx_check = EESR_TC1 | EESR_FTC,
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
EESR_ECI,
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
EESR_TDE | EESR_ECI,
.tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
EESR_TFE,

Expand Down Expand Up @@ -811,9 +814,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,

.tx_check = EESR_TC1 | EESR_FTC,
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
EESR_ECI,
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
EESR_TDE | EESR_ECI,
.tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
EESR_TFE,

Expand Down Expand Up @@ -1549,11 +1552,12 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)

ignore_link:
if (intr_status & EESR_TWB) {
/* Write buck end. unused write back interrupt */
if (intr_status & EESR_TABT) /* Transmit Abort int */
/* Unused write back interrupt */
if (intr_status & EESR_TABT) { /* Transmit Abort int */
ndev->stats.tx_aborted_errors++;
if (netif_msg_tx_err(mdp))
dev_err(&ndev->dev, "Transmit Abort\n");
}
}

if (intr_status & EESR_RABT) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/renesas/sh_eth.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ enum EESR_BIT {

#define DEFAULT_TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \
EESR_RTO)
#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | \
#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | \
EESR_RDE | EESR_RFRMER | EESR_ADE | \
EESR_TFE | EESR_TDE | EESR_ECI)
#define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2139,7 +2139,7 @@ show_phy_type(struct device *dev, struct device_attribute *attr, char *buf)
struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
return sprintf(buf, "%d\n", efx->phy_type);
}
static DEVICE_ATTR(phy_type, 0644, show_phy_type, NULL);
static DEVICE_ATTR(phy_type, 0444, show_phy_type, NULL);

static int efx_register_netdev(struct efx_nic *efx)
{
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/stmicro/stmmac/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ struct dma_features {
#define MAC_RNABLE_RX 0x00000004 /* Receiver Enable */

/* Default LPI timers */
#define STMMAC_DEFAULT_LIT_LS_TIMER 0x3E8
#define STMMAC_DEFAULT_TWT_LS_TIMER 0x0
#define STMMAC_DEFAULT_LIT_LS 0x3E8
#define STMMAC_DEFAULT_TWT_LS 0x0

#define STMMAC_CHAIN_MODE 0x1
#define STMMAC_RING_MODE 0x2
Expand Down
66 changes: 31 additions & 35 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
static int eee_timer = STMMAC_DEFAULT_LPI_TIMER;
module_param(eee_timer, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
#define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x))
#define STMMAC_LPI_T(x) (jiffies + msecs_to_jiffies(x))

/* By default the driver will use the ring mode to manage tx and rx descriptors
* but passing this value so user can force to use the chain instead of the ring
Expand Down Expand Up @@ -288,7 +288,7 @@ static void stmmac_eee_ctrl_timer(unsigned long arg)
struct stmmac_priv *priv = (struct stmmac_priv *)arg;

stmmac_enable_eee_mode(priv);
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
}

/**
Expand All @@ -304,22 +304,34 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
{
bool ret = false;

/* Using PCS we cannot dial with the phy registers at this stage
* so we do not support extra feature like EEE.
*/
if ((priv->pcs == STMMAC_PCS_RGMII) || (priv->pcs == STMMAC_PCS_TBI) ||
(priv->pcs == STMMAC_PCS_RTBI))
goto out;

/* MAC core supports the EEE feature. */
if (priv->dma_cap.eee) {
/* Check if the PHY supports EEE */
if (phy_init_eee(priv->phydev, 1))
goto out;

priv->eee_active = 1;
init_timer(&priv->eee_ctrl_timer);
priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer;
priv->eee_ctrl_timer.data = (unsigned long)priv;
priv->eee_ctrl_timer.expires = STMMAC_LPI_TIMER(eee_timer);
add_timer(&priv->eee_ctrl_timer);

priv->hw->mac->set_eee_timer(priv->ioaddr,
STMMAC_DEFAULT_LIT_LS_TIMER,
priv->tx_lpi_timer);
if (!priv->eee_active) {
priv->eee_active = 1;
init_timer(&priv->eee_ctrl_timer);
priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer;
priv->eee_ctrl_timer.data = (unsigned long)priv;
priv->eee_ctrl_timer.expires = STMMAC_LPI_T(eee_timer);
add_timer(&priv->eee_ctrl_timer);

priv->hw->mac->set_eee_timer(priv->ioaddr,
STMMAC_DEFAULT_LIT_LS,
priv->tx_lpi_timer);
} else
/* Set HW EEE according to the speed */
priv->hw->mac->set_eee_pls(priv->ioaddr,
priv->phydev->link);

pr_info("stmmac: Energy-Efficient Ethernet initialized\n");

Expand All @@ -329,20 +341,6 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
return ret;
}

/**
* stmmac_eee_adjust: adjust HW EEE according to the speed
* @priv: driver private structure
* Description:
* When the EEE has been already initialised we have to
* modify the PLS bit in the LPI ctrl & status reg according
* to the PHY link status. For this reason.
*/
static void stmmac_eee_adjust(struct stmmac_priv *priv)
{
if (priv->eee_enabled)
priv->hw->mac->set_eee_pls(priv->ioaddr, priv->phydev->link);
}

/* stmmac_get_tx_hwtstamp: get HW TX timestamps
* @priv: driver private structure
* @entry : descriptor index to be used.
Expand Down Expand Up @@ -769,7 +767,10 @@ static void stmmac_adjust_link(struct net_device *dev)
if (new_state && netif_msg_link(priv))
phy_print_status(phydev);

stmmac_eee_adjust(priv);
/* At this stage, it could be needed to setup the EEE or adjust some
* MAC related HW registers.
*/
priv->eee_enabled = stmmac_eee_init(priv);

spin_unlock_irqrestore(&priv->lock, flags);

Expand Down Expand Up @@ -1277,7 +1278,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)

if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
stmmac_enable_eee_mode(priv);
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
}
spin_unlock(&priv->tx_lock);
}
Expand Down Expand Up @@ -1671,14 +1672,9 @@ static int stmmac_open(struct net_device *dev)
if (priv->phydev)
phy_start(priv->phydev);

priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER;
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;

/* Using PCS we cannot dial with the phy registers at this stage
* so we do not support extra feature like EEE.
*/
if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
priv->pcs != STMMAC_PCS_RTBI)
priv->eee_enabled = stmmac_eee_init(priv);
priv->eee_enabled = stmmac_eee_init(priv);

stmmac_init_tx_coalesce(priv);

Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/ti/cpsw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1679,7 +1679,7 @@ static int cpsw_probe(struct platform_device *pdev)
priv->rx_packet_max = max(rx_packet_max, 128);
priv->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts), GFP_KERNEL);
priv->irq_enabled = true;
if (!ndev) {
if (!priv->cpts) {
pr_err("error allocating cpts\n");
goto clean_ndev_ret;
}
Expand Down Expand Up @@ -1973,9 +1973,12 @@ static int cpsw_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = platform_get_drvdata(pdev);
struct cpsw_priv *priv = netdev_priv(ndev);

if (netif_running(ndev))
cpsw_ndo_stop(ndev);
soft_reset("sliver 0", &priv->slaves[0].sliver->soft_reset);
soft_reset("sliver 1", &priv->slaves[1].sliver->soft_reset);
pm_runtime_put_sync(&pdev->dev);

return 0;
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/ethernet/ti/davinci_cpdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,13 @@ int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data,
}

buffer = dma_map_single(ctlr->dev, data, len, chan->dir);
ret = dma_mapping_error(ctlr->dev, buffer);
if (ret) {
cpdma_desc_free(ctlr->pool, desc, 1);
ret = -EINVAL;
goto unlock_ret;
}

mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP;
cpdma_desc_to_port(chan, mode, directed);

Expand Down
4 changes: 3 additions & 1 deletion drivers/net/hyperv/netvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,9 @@ int netvsc_recv_callback(struct hv_device *device_obj,

skb->protocol = eth_type_trans(skb, net);
skb->ip_summed = CHECKSUM_NONE;
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), packet->vlan_tci);
if (packet->vlan_tci & VLAN_TAG_PRESENT)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
packet->vlan_tci);

net->stats.rx_packets++;
net->stats.rx_bytes += packet->total_data_buflen;
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/macvtap.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,8 +524,10 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
return -EMSGSIZE;
num_pages = get_user_pages_fast(base, size, 0, &page[i]);
if (num_pages != size) {
for (i = 0; i < num_pages; i++)
put_page(page[i]);
int j;

for (j = 0; j < num_pages; j++)
put_page(page[i + j]);
return -EFAULT;
}
truesize = size * PAGE_SIZE;
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -1010,8 +1010,10 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
return -EMSGSIZE;
num_pages = get_user_pages_fast(base, size, 0, &page[i]);
if (num_pages != size) {
for (i = 0; i < num_pages; i++)
put_page(page[i]);
int j;

for (j = 0; j < num_pages; j++)
put_page(page[i + j]);
return -EFAULT;
}
truesize = size * PAGE_SIZE;
Expand Down
8 changes: 7 additions & 1 deletion drivers/net/usb/qmi_wwan.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,13 @@ static const struct usb_device_id products[] = {
{QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
{QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel/Verizon USB-1000 */
{QMI_GOBI1K_DEVICE(0x1410, 0xa002)}, /* Novatel Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x1410, 0xa003)}, /* Novatel Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x1410, 0xa004)}, /* Novatel Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x1410, 0xa005)}, /* Novatel Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x1410, 0xa006)}, /* Novatel Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x1410, 0xa007)}, /* Novatel Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */
Expand Down
40 changes: 26 additions & 14 deletions drivers/net/vxlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,18 +565,22 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,

/* Watch incoming packets to learn mapping between Ethernet address
* and Tunnel endpoint.
* Return true if packet is bogus and should be droppped.
*/
static void vxlan_snoop(struct net_device *dev,
static bool vxlan_snoop(struct net_device *dev,
__be32 src_ip, const u8 *src_mac)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_fdb *f;
int err;

f = vxlan_find_mac(vxlan, src_mac);
if (likely(f)) {
if (likely(f->remote.remote_ip == src_ip))
return;
return false;

/* Don't migrate static entries, drop packets */
if (f->state & NUD_NOARP)
return true;

if (net_ratelimit())
netdev_info(dev,
Expand All @@ -588,14 +592,19 @@ static void vxlan_snoop(struct net_device *dev,
} else {
/* learned new entry */
spin_lock(&vxlan->hash_lock);
err = vxlan_fdb_create(vxlan, src_mac, src_ip,
NUD_REACHABLE,
NLM_F_EXCL|NLM_F_CREATE,
vxlan->dst_port,
vxlan->default_dst.remote_vni,
0, NTF_SELF);

/* close off race between vxlan_flush and incoming packets */
if (netif_running(dev))
vxlan_fdb_create(vxlan, src_mac, src_ip,
NUD_REACHABLE,
NLM_F_EXCL|NLM_F_CREATE,
vxlan->dst_port,
vxlan->default_dst.remote_vni,
0, NTF_SELF);
spin_unlock(&vxlan->hash_lock);
}

return false;
}


Expand Down Expand Up @@ -727,8 +736,9 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
vxlan->dev->dev_addr) == 0)
goto drop;

if (vxlan->flags & VXLAN_F_LEARN)
vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source);
if ((vxlan->flags & VXLAN_F_LEARN) &&
vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source))
goto drop;

__skb_tunnel_rx(skb, vxlan->dev);
skb_reset_network_header(skb);
Expand Down Expand Up @@ -1151,9 +1161,11 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
struct sk_buff *skb1;

skb1 = skb_clone(skb, GFP_ATOMIC);
rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc);
if (rc == NETDEV_TX_OK)
rc = rc1;
if (skb1) {
rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc);
if (rc == NETDEV_TX_OK)
rc = rc1;
}
}

rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc);
Expand Down
26 changes: 21 additions & 5 deletions drivers/net/wan/dlci.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,21 +384,37 @@ static int dlci_del(struct dlci_add *dlci)
struct frad_local *flp;
struct net_device *master, *slave;
int err;
bool found = false;

rtnl_lock();

/* validate slave device */
master = __dev_get_by_name(&init_net, dlci->devname);
if (!master)
return -ENODEV;
if (!master) {
err = -ENODEV;
goto out;
}

list_for_each_entry(dlp, &dlci_devs, list) {
if (dlp->master == master) {
found = true;
break;
}
}
if (!found) {
err = -ENODEV;
goto out;
}

if (netif_running(master)) {
return -EBUSY;
err = -EBUSY;
goto out;
}

dlp = netdev_priv(master);
slave = dlp->slave;
flp = netdev_priv(slave);

rtnl_lock();
err = (*flp->deassoc)(slave, master);
if (!err) {
list_del(&dlp->list);
Expand All @@ -407,8 +423,8 @@ static int dlci_del(struct dlci_add *dlci)

dev_put(slave);
}
out:
rtnl_unlock();

return err;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath9k/htc_drv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&priv->htc_pm_lock);

priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
if (priv->ps_idle)
if (!priv->ps_idle)
chip_reset = true;

mutex_unlock(&priv->htc_pm_lock);
Expand Down
6 changes: 5 additions & 1 deletion drivers/net/wireless/ath/ath9k/xmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1570,6 +1570,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
return;

rcu_read_lock();

ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);

Expand Down Expand Up @@ -1608,8 +1610,10 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)

if (ac == last_ac ||
txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
return;
break;
}

rcu_read_unlock();
}

/***********/
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,10 @@ int brcmf_bus_start(struct device *dev)
brcmf_fws_del_interface(ifp);
brcmf_fws_deinit(drvr);
}
if (drvr->iflist[0]) {
free_netdev(ifp->ndev);
drvr->iflist[0] = NULL;
}
if (p2p_ifp) {
free_netdev(p2p_ifp->ndev);
drvr->iflist[1] = NULL;
Expand Down
17 changes: 2 additions & 15 deletions drivers/net/wireless/brcm80211/brcmsmac/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3074,21 +3074,8 @@ static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
*/
static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
{
/* disallow PS when one of the following global conditions meets */
if (!wlc->pub->associated)
return false;

/* disallow PS when one of these meets when not scanning */
if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
return false;

if (wlc->bsscfg->type == BRCMS_TYPE_AP)
return false;

if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
return false;

return true;
/* not supporting PS so always return false for now */
return false;
}

static void brcms_c_statsupd(struct brcms_c_info *wlc)
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlegacy/3945-rs.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,7 @@ il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta,
rs_sta->last_txrate_idx = idx;
info->control.rates[0].idx = rs_sta->last_txrate_idx;
}
info->control.rates[0].count = 1;

D_RATE("leave: %d\n", idx);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlegacy/4965-rs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2268,7 +2268,7 @@ il4965_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta,
info->control.rates[0].flags = 0;
}
info->control.rates[0].idx = rate_idx;

info->control.rates[0].count = 1;
}

static void *
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/dvm/rs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2799,7 +2799,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
info->control.rates[0].flags = 0;
}
info->control.rates[0].idx = rate_idx;

info->control.rates[0].count = 1;
}

static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/dvm/rxon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1378,7 +1378,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
struct iwl_chain_noise_data *data = &priv->chain_noise_data;
int ret;

if (!(priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED))
if (priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED)
return;

if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1000,10 +1000,12 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
*/
if (load_module) {
err = request_module("%s", op->name);
#ifdef CONFIG_IWLWIFI_OPMODE_MODULAR
if (err)
IWL_ERR(drv,
"failed to load module %s (error %d), is dynamic loading enabled?\n",
op->name, err);
#endif
}
return;

Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/mvm/rs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2546,6 +2546,7 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
info->control.rates[0].flags = 0;
}
info->control.rates[0].idx = rate_idx;
info->control.rates[0].count = 1;
}

static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/wireless/iwlwifi/mvm/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
return;
} else if (ieee80211_is_back_req(fc)) {
tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
tx_cmd->tx_flags |=
cpu_to_le32(TX_CMD_FLG_ACK | TX_CMD_FLG_BAR);
}

/* HT rate doesn't make sense for a non data frame */
Expand Down
29 changes: 18 additions & 11 deletions drivers/net/wireless/rt2x00/rt2800lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3027,19 +3027,26 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
* TODO: we do not use +6 dBm option to do not increase power beyond
* regulatory limit, however this could be utilized for devices with
* CAPABILITY_POWER_LIMIT.
*
* TODO: add different temperature compensation code for RT3290 & RT5390
* to allow to use BBP_R1 for those chips.
*/
rt2800_bbp_read(rt2x00dev, 1, &r1);
if (delta <= -12) {
power_ctrl = 2;
delta += 12;
} else if (delta <= -6) {
power_ctrl = 1;
delta += 6;
} else {
power_ctrl = 0;
if (!rt2x00_rt(rt2x00dev, RT3290) &&
!rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_bbp_read(rt2x00dev, 1, &r1);
if (delta <= -12) {
power_ctrl = 2;
delta += 12;
} else if (delta <= -6) {
power_ctrl = 1;
delta += 6;
} else {
power_ctrl = 0;
}
rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl);
rt2800_bbp_write(rt2x00dev, 1, r1);
}
rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl);
rt2800_bbp_write(rt2x00dev, 1, r1);

offset = TX_PWR_CFG_0;

for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) {
Expand Down
53 changes: 37 additions & 16 deletions drivers/pci/hotplug/acpiphp_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ static DEFINE_MUTEX(bridge_mutex);
static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
static void acpiphp_sanitize_bus(struct pci_bus *bus);
static void acpiphp_set_hpp_values(struct pci_bus *bus);
static void hotplug_event_func(acpi_handle handle, u32 type, void *context);
static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context);
static void free_bridge(struct kref *kref);

Expand Down Expand Up @@ -147,7 +148,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,


static const struct acpi_dock_ops acpiphp_dock_ops = {
.handler = handle_hotplug_event_func,
.handler = hotplug_event_func,
};

/* Check whether the PCI device is managed by native PCIe hotplug driver */
Expand Down Expand Up @@ -179,6 +180,20 @@ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev)
return true;
}

static void acpiphp_dock_init(void *data)
{
struct acpiphp_func *func = data;

get_bridge(func->slot->bridge);
}

static void acpiphp_dock_release(void *data)
{
struct acpiphp_func *func = data;

put_bridge(func->slot->bridge);
}

/* callback routine to register each ACPI PCI slot object */
static acpi_status
register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
Expand Down Expand Up @@ -298,7 +313,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
*/
newfunc->flags &= ~FUNC_HAS_EJ0;
if (register_hotplug_dock_device(handle,
&acpiphp_dock_ops, newfunc))
&acpiphp_dock_ops, newfunc,
acpiphp_dock_init, acpiphp_dock_release))
dbg("failed to register dock device\n");

/* we need to be notified when dock events happen
Expand Down Expand Up @@ -670,6 +686,7 @@ static int __ref enable_device(struct acpiphp_slot *slot)
struct pci_bus *bus = slot->bridge->pci_bus;
struct acpiphp_func *func;
int num, max, pass;
LIST_HEAD(add_list);

if (slot->flags & SLOT_ENABLED)
goto err_exit;
Expand All @@ -694,13 +711,15 @@ static int __ref enable_device(struct acpiphp_slot *slot)
max = pci_scan_bridge(bus, dev, max, pass);
if (pass && dev->subordinate) {
check_hotplug_bridge(slot, dev);
pci_bus_size_bridges(dev->subordinate);
pcibios_resource_survey_bus(dev->subordinate);
__pci_bus_size_bridges(dev->subordinate,
&add_list);
}
}
}
}

pci_bus_assign_resources(bus);
__pci_bus_assign_resources(bus, &add_list, NULL);
acpiphp_sanitize_bus(bus);
acpiphp_set_hpp_values(bus);
acpiphp_set_acpi_region(slot);
Expand Down Expand Up @@ -1065,22 +1084,12 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type,
alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge);
}

static void _handle_hotplug_event_func(struct work_struct *work)
static void hotplug_event_func(acpi_handle handle, u32 type, void *context)
{
struct acpiphp_func *func;
struct acpiphp_func *func = context;
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
struct acpi_hp_work *hp_work;
acpi_handle handle;
u32 type;

hp_work = container_of(work, struct acpi_hp_work, work);
handle = hp_work->handle;
type = hp_work->type;
func = (struct acpiphp_func *)hp_work->context;

acpi_scan_lock_acquire();

acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);

Expand Down Expand Up @@ -1113,6 +1122,18 @@ static void _handle_hotplug_event_func(struct work_struct *work)
warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
break;
}
}

static void _handle_hotplug_event_func(struct work_struct *work)
{
struct acpi_hp_work *hp_work;
struct acpiphp_func *func;

hp_work = container_of(work, struct acpi_hp_work, work);
func = hp_work->context;
acpi_scan_lock_acquire();

hotplug_event_func(hp_work->handle, hp_work->type, func);

acpi_scan_lock_release();
kfree(hp_work); /* allocated in handle_hotplug_event_func */
Expand Down
5 changes: 5 additions & 0 deletions drivers/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
struct resource *res, unsigned int reg);
int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type);
void pci_configure_ari(struct pci_dev *dev);
void __ref __pci_bus_size_bridges(struct pci_bus *bus,
struct list_head *realloc_head);
void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
struct list_head *realloc_head,
struct list_head *fail_head);

/**
* pci_ari_enabled - query ARI forwarding status
Expand Down
8 changes: 4 additions & 4 deletions drivers/pci/setup-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,7 @@ static void pci_bus_size_cardbus(struct pci_bus *bus,
;
}

static void __ref __pci_bus_size_bridges(struct pci_bus *bus,
void __ref __pci_bus_size_bridges(struct pci_bus *bus,
struct list_head *realloc_head)
{
struct pci_dev *dev;
Expand Down Expand Up @@ -1115,9 +1115,9 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
}
EXPORT_SYMBOL(pci_bus_size_bridges);

static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
struct list_head *realloc_head,
struct list_head *fail_head)
void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
struct list_head *realloc_head,
struct list_head *fail_head)
{
struct pci_bus *b;
struct pci_dev *dev;
Expand Down
2 changes: 1 addition & 1 deletion drivers/regulator/tps6586x-regulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ static int tps6586x_regulator_remove(struct platform_device *pdev)

static struct platform_driver tps6586x_regulator_driver = {
.driver = {
.name = "tps6586x-pmic",
.name = "tps6586x-regulator",
.owner = THIS_MODULE,
},
.probe = tps6586x_regulator_probe,
Expand Down
7 changes: 5 additions & 2 deletions drivers/scsi/fcoe/fcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1656,9 +1656,12 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)

if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN &&
fcoe->realdev->features & NETIF_F_HW_VLAN_CTAG_TX) {
skb->vlan_tci = VLAN_TAG_PRESENT |
vlan_dev_vlan_id(fcoe->netdev);
/* must set skb->dev before calling vlan_put_tag */
skb->dev = fcoe->realdev;
skb = __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
vlan_dev_vlan_id(fcoe->netdev));
if (!skb)
return -ENOMEM;
} else
skb->dev = fcoe->netdev;

Expand Down
15 changes: 5 additions & 10 deletions drivers/scsi/fcoe/fcoe_ctlr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1548,9 +1548,6 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
{
struct fcoe_fcf *fcf;
struct fcoe_fcf *best = fip->sel_fcf;
struct fcoe_fcf *first;

first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list);

list_for_each_entry(fcf, &fip->fcfs, list) {
LIBFCOE_FIP_DBG(fip, "consider FCF fab %16.16llx "
Expand All @@ -1568,17 +1565,15 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
"" : "un");
continue;
}
if (fcf->fabric_name != first->fabric_name ||
fcf->vfid != first->vfid ||
fcf->fc_map != first->fc_map) {
if (!best || fcf->pri < best->pri || best->flogi_sent)
best = fcf;
if (fcf->fabric_name != best->fabric_name ||
fcf->vfid != best->vfid ||
fcf->fc_map != best->fc_map) {
LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
"or FC-MAP\n");
return NULL;
}
if (fcf->flogi_sent)
continue;
if (!best || fcf->pri < best->pri || best->flogi_sent)
best = fcf;
}
fip->sel_fcf = best;
if (best) {
Expand Down
16 changes: 0 additions & 16 deletions drivers/scsi/ipr.c
Original file line number Diff line number Diff line change
Expand Up @@ -8980,19 +8980,6 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
if (!ioa_cfg->res_entries)
goto out;

if (ioa_cfg->sis64) {
ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) *
BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) *
BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) *
BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);

if (!ioa_cfg->target_ids || !ioa_cfg->array_ids
|| !ioa_cfg->vset_ids)
goto out_free_res_entries;
}

for (i = 0; i < ioa_cfg->max_devs_supported; i++) {
list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q);
ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
Expand Down Expand Up @@ -9089,9 +9076,6 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
out_free_res_entries:
kfree(ioa_cfg->res_entries);
kfree(ioa_cfg->target_ids);
kfree(ioa_cfg->array_ids);
kfree(ioa_cfg->vset_ids);
goto out;
}

Expand Down
6 changes: 3 additions & 3 deletions drivers/scsi/ipr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1440,9 +1440,9 @@ struct ipr_ioa_cfg {
/*
* Bitmaps for SIS64 generated target values
*/
unsigned long *target_ids;
unsigned long *array_ids;
unsigned long *vset_ids;
unsigned long target_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)];
unsigned long array_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)];
unsigned long vset_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)];

u16 type; /* CCIN of the card */

Expand Down
37 changes: 24 additions & 13 deletions drivers/scsi/libfc/fc_exch.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,13 +463,7 @@ static void fc_exch_delete(struct fc_exch *ep)
fc_exch_release(ep); /* drop hold for exch in mp */
}

/**
* fc_seq_send() - Send a frame using existing sequence/exchange pair
* @lport: The local port that the exchange will be sent on
* @sp: The sequence to be sent
* @fp: The frame to be sent on the exchange
*/
static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
static int fc_seq_send_locked(struct fc_lport *lport, struct fc_seq *sp,
struct fc_frame *fp)
{
struct fc_exch *ep;
Expand All @@ -479,7 +473,7 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
u8 fh_type = fh->fh_type;

ep = fc_seq_exch(sp);
WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT));

f_ctl = ntoh24(fh->fh_f_ctl);
fc_exch_setup_hdr(ep, fp, f_ctl);
Expand All @@ -502,17 +496,34 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
error = lport->tt.frame_send(lport, fp);

if (fh_type == FC_TYPE_BLS)
return error;
goto out;

/*
* Update the exchange and sequence flags,
* assuming all frames for the sequence have been sent.
* We can only be called to send once for each sequence.
*/
spin_lock_bh(&ep->ex_lock);
ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */
if (f_ctl & FC_FC_SEQ_INIT)
ep->esb_stat &= ~ESB_ST_SEQ_INIT;
out:
return error;
}

/**
* fc_seq_send() - Send a frame using existing sequence/exchange pair
* @lport: The local port that the exchange will be sent on
* @sp: The sequence to be sent
* @fp: The frame to be sent on the exchange
*/
static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
struct fc_frame *fp)
{
struct fc_exch *ep;
int error;
ep = fc_seq_exch(sp);
spin_lock_bh(&ep->ex_lock);
error = fc_seq_send_locked(lport, sp, fp);
spin_unlock_bh(&ep->ex_lock);
return error;
}
Expand Down Expand Up @@ -629,7 +640,7 @@ static int fc_exch_abort_locked(struct fc_exch *ep,
if (fp) {
fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
FC_TYPE_BLS, FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
error = fc_seq_send(ep->lp, sp, fp);
error = fc_seq_send_locked(ep->lp, sp, fp);
} else
error = -ENOBUFS;
return error;
Expand Down Expand Up @@ -1132,7 +1143,7 @@ static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp,
f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
f_ctl |= ep->f_ctl;
fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0);
fc_seq_send(ep->lp, sp, fp);
fc_seq_send_locked(ep->lp, sp, fp);
}

/**
Expand Down Expand Up @@ -1307,8 +1318,8 @@ static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
ap->ba_low_seq_cnt = htons(sp->cnt);
}
sp = fc_seq_start_next_locked(sp);
spin_unlock_bh(&ep->ex_lock);
fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS);
spin_unlock_bh(&ep->ex_lock);
fc_frame_free(rx_fp);
return;

Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/libfc/fc_rport.c
Original file line number Diff line number Diff line change
Expand Up @@ -1962,7 +1962,7 @@ static int fc_rport_fcp_prli(struct fc_rport_priv *rdata, u32 spp_len,
rdata->flags |= FC_RP_FLAGS_RETRY;
rdata->supported_classes = FC_COS_CLASS3;

if (!(lport->service_params & FC_RPORT_ROLE_FCP_INITIATOR))
if (!(lport->service_params & FCP_SPPF_INIT_FCN))
return 0;

spp->spp_flags |= rspp->spp_flags & FC_SPP_EST_IMG_PAIR;
Expand Down
11 changes: 11 additions & 0 deletions drivers/scsi/qla2xxx/qla_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,14 @@ qla2x00_do_host_ramp_up(scsi_qla_host_t *vha)

set_bit(HOST_RAMP_UP_QUEUE_DEPTH, &vha->dpc_flags);
}

static inline void
qla2x00_handle_mbx_completion(struct qla_hw_data *ha, int status)
{
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
complete(&ha->mbx_intr_comp);
}
}
27 changes: 4 additions & 23 deletions drivers/scsi/qla2xxx/qla_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,9 @@ qla2100_intr_handler(int irq, void *dev_id)
RD_REG_WORD(&reg->hccr);
}
}
qla2x00_handle_mbx_completion(ha, status);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
complete(&ha->mbx_intr_comp);
}

return (IRQ_HANDLED);
}

Expand Down Expand Up @@ -221,14 +216,9 @@ qla2300_intr_handler(int irq, void *dev_id)
WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
RD_REG_WORD_RELAXED(&reg->hccr);
}
qla2x00_handle_mbx_completion(ha, status);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
complete(&ha->mbx_intr_comp);
}

return (IRQ_HANDLED);
}

Expand Down Expand Up @@ -2613,14 +2603,9 @@ qla24xx_intr_handler(int irq, void *dev_id)
if (unlikely(IS_QLA83XX(ha) && (ha->pdev->revision == 1)))
ndelay(3500);
}
qla2x00_handle_mbx_completion(ha, status);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
complete(&ha->mbx_intr_comp);
}

return IRQ_HANDLED;
}

Expand Down Expand Up @@ -2763,13 +2748,9 @@ qla24xx_msix_default(int irq, void *dev_id)
}
WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
} while (0);
qla2x00_handle_mbx_completion(ha, status);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
complete(&ha->mbx_intr_comp);
}
return IRQ_HANDLED;
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/scsi/qla2xxx/qla_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)

wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);

clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);

} else {
ql_dbg(ql_dbg_mbx, vha, 0x1011,
"Cmd=%x Polling Mode.\n", command);
Expand Down
10 changes: 2 additions & 8 deletions drivers/scsi/qla2xxx/qla_mr.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ qlafx00_mailbox_command(scsi_qla_host_t *vha, struct mbx_cmd_32 *mcp)
spin_unlock_irqrestore(&ha->hardware_lock, flags);

wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);

clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);

} else {
ql_dbg(ql_dbg_mbx, vha, 0x112c,
"Cmd=%x Polling Mode.\n", command);
Expand Down Expand Up @@ -2934,13 +2931,10 @@ qlafx00_intr_handler(int irq, void *dev_id)
QLAFX00_CLR_INTR_REG(ha, clr_intr);
QLAFX00_RD_INTR_REG(ha);
}

qla2x00_handle_mbx_completion(ha, status);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
complete(&ha->mbx_intr_comp);
}
return IRQ_HANDLED;
}

Expand Down
26 changes: 10 additions & 16 deletions drivers/scsi/qla2xxx/qla_nx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2074,9 +2074,6 @@ qla82xx_intr_handler(int irq, void *dev_id)
}
WRT_REG_DWORD(&reg->host_int, 0);
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (!ha->flags.msi_enabled)
qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);

#ifdef QL_DEBUG_LEVEL_17
if (!irq && ha->flags.eeh_busy)
Expand All @@ -2085,11 +2082,12 @@ qla82xx_intr_handler(int irq, void *dev_id)
status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat);
#endif

if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
complete(&ha->mbx_intr_comp);
}
qla2x00_handle_mbx_completion(ha, status);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

if (!ha->flags.msi_enabled)
qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);

return IRQ_HANDLED;
}

Expand Down Expand Up @@ -2149,20 +2147,16 @@ qla82xx_msix_default(int irq, void *dev_id)
WRT_REG_DWORD(&reg->host_int, 0);
} while (0);

spin_unlock_irqrestore(&ha->hardware_lock, flags);

#ifdef QL_DEBUG_LEVEL_17
if (!irq && ha->flags.eeh_busy)
ql_log(ql_log_warn, vha, 0x5044,
"isr:status %x, cmd_flags %lx, mbox_int %x, stat %x.\n",
status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat);
#endif

if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
complete(&ha->mbx_intr_comp);
}
qla2x00_handle_mbx_completion(ha, status);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

return IRQ_HANDLED;
}

Expand Down Expand Up @@ -3345,7 +3339,7 @@ void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha)
ha->flags.mbox_busy = 0;
ql_log(ql_log_warn, vha, 0x6010,
"Doing premature completion of mbx command.\n");
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags))
if (test_and_clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags))
complete(&ha->mbx_intr_comp);
}
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi-pxa2xx-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data,
int ret;

sg_free_table(sgt);
ret = sg_alloc_table(sgt, nents, GFP_KERNEL);
ret = sg_alloc_table(sgt, nents, GFP_ATOMIC);
if (ret)
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi-pxa2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)
acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev))
return NULL;

pdata = devm_kzalloc(&pdev->dev, sizeof(*ssp), GFP_KERNEL);
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
dev_err(&pdev->dev,
"failed to allocate memory for platform data\n");
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi-s3c64xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
}

ret = pm_runtime_get_sync(&sdd->pdev->dev);
if (ret != 0) {
if (ret < 0) {
dev_err(dev, "Failed to enable device: %d\n", ret);
goto out_tx;
}
Expand Down
16 changes: 9 additions & 7 deletions fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1135,13 +1135,6 @@ void setup_new_exec(struct linux_binprm * bprm)
set_dumpable(current->mm, suid_dumpable);
}

/*
* Flush performance counters when crossing a
* security domain:
*/
if (!get_dumpable(current->mm))
perf_event_exit_task(current);

/* An exec changes our domain. We are no longer part of the thread
group */

Expand Down Expand Up @@ -1205,6 +1198,15 @@ void install_exec_creds(struct linux_binprm *bprm)

commit_creds(bprm->cred);
bprm->cred = NULL;

/*
* Disable monitoring for regular users
* when executing setuid binaries. Must
* wait until new credentials are committed
* by commit_creds() above
*/
if (get_dumpable(current->mm) != SUID_DUMP_USER)
perf_event_exit_task(current);
/*
* cred_guard_mutex must be held at least to this point to prevent
* ptrace_attach() from altering our determination of the task's
Expand Down
12 changes: 8 additions & 4 deletions fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2470,13 +2470,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
.mode = mode
};
int err;
bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) ||
(mode & FALLOC_FL_PUNCH_HOLE);

if (fc->no_fallocate)
return -EOPNOTSUPP;

if (mode & FALLOC_FL_PUNCH_HOLE) {
if (lock_inode) {
mutex_lock(&inode->i_mutex);
fuse_set_nowrite(inode);
if (mode & FALLOC_FL_PUNCH_HOLE)
fuse_set_nowrite(inode);
}

req = fuse_get_req_nopages(fc);
Expand Down Expand Up @@ -2511,8 +2514,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
fuse_invalidate_attr(inode);

out:
if (mode & FALLOC_FL_PUNCH_HOLE) {
fuse_release_nowrite(inode);
if (lock_inode) {
if (mode & FALLOC_FL_PUNCH_HOLE)
fuse_release_nowrite(inode);
mutex_unlock(&inode->i_mutex);
}

Expand Down
54 changes: 39 additions & 15 deletions fs/ubifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,31 +349,50 @@ static unsigned int vfs_dent_type(uint8_t type)
static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
int err, over = 0;
loff_t pos = file->f_pos;
struct qstr nm;
union ubifs_key key;
struct ubifs_dent_node *dent;
struct inode *dir = file_inode(file);
struct ubifs_info *c = dir->i_sb->s_fs_info;

dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos);
dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos);

if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2)
if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2)
/*
* The directory was seek'ed to a senseless position or there
* are no more entries.
*/
return 0;

if (file->f_version == 0) {
/*
* The file was seek'ed, which means that @file->private_data
* is now invalid. This may also be just the first
* 'ubifs_readdir()' invocation, in which case
* @file->private_data is NULL, and the below code is
* basically a no-op.
*/
kfree(file->private_data);
file->private_data = NULL;
}

/*
* 'generic_file_llseek()' unconditionally sets @file->f_version to
* zero, and we use this for detecting whether the file was seek'ed.
*/
file->f_version = 1;

/* File positions 0 and 1 correspond to "." and ".." */
if (file->f_pos == 0) {
if (pos == 0) {
ubifs_assert(!file->private_data);
over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR);
if (over)
return 0;
file->f_pos = 1;
file->f_pos = pos = 1;
}

if (file->f_pos == 1) {
if (pos == 1) {
ubifs_assert(!file->private_data);
over = filldir(dirent, "..", 2, 1,
parent_ino(file->f_path.dentry), DT_DIR);
Expand All @@ -389,25 +408,24 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
goto out;
}

file->f_pos = key_hash_flash(c, &dent->key);
file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
}

dent = file->private_data;
if (!dent) {
/*
* The directory was seek'ed to and is now readdir'ed.
* Find the entry corresponding to @file->f_pos or the
* closest one.
* Find the entry corresponding to @pos or the closest one.
*/
dent_key_init_hash(c, &key, dir->i_ino, file->f_pos);
dent_key_init_hash(c, &key, dir->i_ino, pos);
nm.name = NULL;
dent = ubifs_tnc_next_ent(c, &key, &nm);
if (IS_ERR(dent)) {
err = PTR_ERR(dent);
goto out;
}
file->f_pos = key_hash_flash(c, &dent->key);
file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
}

Expand All @@ -419,7 +437,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
ubifs_inode(dir)->creat_sqnum);

nm.len = le16_to_cpu(dent->nlen);
over = filldir(dirent, dent->name, nm.len, file->f_pos,
over = filldir(dirent, dent->name, nm.len, pos,
le64_to_cpu(dent->inum),
vfs_dent_type(dent->type));
if (over)
Expand All @@ -435,9 +453,17 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
}

kfree(file->private_data);
file->f_pos = key_hash_flash(c, &dent->key);
file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
cond_resched();

if (file->f_version == 0)
/*
* The file was seek'ed meanwhile, lets return and start
* reading direntries from the new position on the next
* invocation.
*/
return 0;
}

out:
Expand All @@ -448,15 +474,13 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)

kfree(file->private_data);
file->private_data = NULL;
/* 2 is a special value indicating that there are no more direntries */
file->f_pos = 2;
return 0;
}

/* If a directory is seeked, we have to free saved readdir() state */
static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence)
{
kfree(file->private_data);
file->private_data = NULL;
return generic_file_llseek(file, offset, whence);
}

Expand Down
8 changes: 6 additions & 2 deletions include/acpi/acpi_drivers.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ extern int register_dock_notifier(struct notifier_block *nb);
extern void unregister_dock_notifier(struct notifier_block *nb);
extern int register_hotplug_dock_device(acpi_handle handle,
const struct acpi_dock_ops *ops,
void *context);
void *context,
void (*init)(void *),
void (*release)(void *));
extern void unregister_hotplug_dock_device(acpi_handle handle);
#else
static inline int is_dock_device(acpi_handle handle)
Expand All @@ -139,7 +141,9 @@ static inline void unregister_dock_notifier(struct notifier_block *nb)
}
static inline int register_hotplug_dock_device(acpi_handle handle,
const struct acpi_dock_ops *ops,
void *context)
void *context,
void (*init)(void *),
void (*release)(void *))
{
return -ENODEV;
}
Expand Down
Loading