diff options
Diffstat (limited to 'drivers')
74 files changed, 632 insertions, 297 deletions
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 54784bb42ce..edc25867ad9 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -416,10 +416,15 @@ struct acpi_gpe_handler_info {  	u8 originally_enabled;  /* True if GPE was originally enabled */  }; +struct acpi_gpe_notify_object { +	struct acpi_namespace_node *node; +	struct acpi_gpe_notify_object *next; +}; +  union acpi_gpe_dispatch_info {  	struct acpi_namespace_node *method_node;	/* Method node for this GPE level */  	struct acpi_gpe_handler_info *handler;  /* Installed GPE handler */ -	struct acpi_namespace_node *device_node;        /* Parent _PRW device for implicit notify */ +	struct acpi_gpe_notify_object device;   /* List of _PRW devices for implicit notify */  };  /* diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 14988a86066..f4725212eb4 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -457,6 +457,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)  	acpi_status status;  	struct acpi_gpe_event_info *local_gpe_event_info;  	struct acpi_evaluate_info *info; +	struct acpi_gpe_notify_object *notify_object;  	ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); @@ -508,10 +509,18 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)  		 * from this thread -- because handlers may in turn run other  		 * control methods.  		 */ -		status = -		    acpi_ev_queue_notify_request(local_gpe_event_info->dispatch. -						 device_node, -						 ACPI_NOTIFY_DEVICE_WAKE); +		status = acpi_ev_queue_notify_request( +				local_gpe_event_info->dispatch.device.node, +				ACPI_NOTIFY_DEVICE_WAKE); + +		notify_object = local_gpe_event_info->dispatch.device.next; +		while (ACPI_SUCCESS(status) && notify_object) { +			status = acpi_ev_queue_notify_request( +					notify_object->node, +					ACPI_NOTIFY_DEVICE_WAKE); +			notify_object = notify_object->next; +		} +  		break;  	case ACPI_GPE_DISPATCH_METHOD: diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 3b20a3401b6..52aaff3df56 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -198,7 +198,9 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,  	acpi_status status = AE_BAD_PARAMETER;  	struct acpi_gpe_event_info *gpe_event_info;  	struct acpi_namespace_node *device_node; +	struct acpi_gpe_notify_object *notify_object;  	acpi_cpu_flags flags; +	u8 gpe_dispatch_mask;  	ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); @@ -221,27 +223,49 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,  		goto unlock_and_exit;  	} +	if (wake_device == ACPI_ROOT_OBJECT) { +		goto out; +	} +  	/*  	 * If there is no method or handler for this GPE, then the  	 * wake_device will be notified whenever this GPE fires (aka  	 * "implicit notify") Note: The GPE is assumed to be  	 * level-triggered (for windows compatibility).  	 */ -	if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == -	      ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) { +	gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK; +	if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE +	    && gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) { +		goto out; +	} -		/* Validate wake_device is of type Device */ +	/* Validate wake_device is of type Device */ -		device_node = ACPI_CAST_PTR(struct acpi_namespace_node, -					    wake_device); -		if (device_node->type != ACPI_TYPE_DEVICE) { -			goto unlock_and_exit; -		} +	device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); +	if (device_node->type != ACPI_TYPE_DEVICE) { +		goto unlock_and_exit; +	} + +	if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) {  		gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY |  					 ACPI_GPE_LEVEL_TRIGGERED); -		gpe_event_info->dispatch.device_node = device_node; +		gpe_event_info->dispatch.device.node = device_node; +		gpe_event_info->dispatch.device.next = NULL; +	} else { +		/* There are multiple devices to notify implicitly. */ + +		notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object)); +		if (!notify_object) { +			status = AE_NO_MEMORY; +			goto unlock_and_exit; +		} + +		notify_object->node = device_node; +		notify_object->next = gpe_event_info->dispatch.device.next; +		gpe_event_info->dispatch.device.next = notify_object;  	} + out:  	gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;  	status = AE_OK; diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 5df67f1d6c6..384f7abcff7 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -26,7 +26,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,  			size_t count, loff_t *ppos)  {  	static char *buf; -	static int uncopied_bytes; +	static u32 max_size; +	static u32 uncopied_bytes; +  	struct acpi_table_header table;  	acpi_status status; @@ -37,19 +39,24 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,  		if (copy_from_user(&table, user_buf,  				   sizeof(struct acpi_table_header)))  			return -EFAULT; -		uncopied_bytes = table.length; -		buf = kzalloc(uncopied_bytes, GFP_KERNEL); +		uncopied_bytes = max_size = table.length; +		buf = kzalloc(max_size, GFP_KERNEL);  		if (!buf)  			return -ENOMEM;  	} -	if (uncopied_bytes < count) { -		kfree(buf); +	if (buf == NULL) +		return -EINVAL; + +	if ((*ppos > max_size) || +	    (*ppos + count > max_size) || +	    (*ppos + count < count) || +	    (count > uncopied_bytes))  		return -EINVAL; -	}  	if (copy_from_user(buf + (*ppos), user_buf, count)) {  		kfree(buf); +		buf = NULL;  		return -EFAULT;  	} @@ -59,6 +66,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,  	if (!uncopied_bytes) {  		status = acpi_install_method(buf);  		kfree(buf); +		buf = NULL;  		if (ACPI_FAILURE(status))  			return -EINVAL;  		add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 49e6a545eb6..dbf31ec9114 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -78,7 +78,6 @@  #include <asm/uaccess.h> -static DEFINE_MUTEX(loop_mutex);  static LIST_HEAD(loop_devices);  static DEFINE_MUTEX(loop_devices_mutex); @@ -1501,11 +1500,9 @@ static int lo_open(struct block_device *bdev, fmode_t mode)  {  	struct loop_device *lo = bdev->bd_disk->private_data; -	mutex_lock(&loop_mutex);  	mutex_lock(&lo->lo_ctl_mutex);  	lo->lo_refcnt++;  	mutex_unlock(&lo->lo_ctl_mutex); -	mutex_unlock(&loop_mutex);  	return 0;  } @@ -1515,7 +1512,6 @@ static int lo_release(struct gendisk *disk, fmode_t mode)  	struct loop_device *lo = disk->private_data;  	int err; -	mutex_lock(&loop_mutex);  	mutex_lock(&lo->lo_ctl_mutex);  	if (--lo->lo_refcnt) @@ -1540,7 +1536,6 @@ static int lo_release(struct gendisk *disk, fmode_t mode)  out:  	mutex_unlock(&lo->lo_ctl_mutex);  out_unlocked: -	mutex_unlock(&loop_mutex);  	return 0;  } diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 49039318633..84b164d1eb2 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -388,6 +388,10 @@ static void discard_port_data(struct port *port)  	unsigned int len;  	int ret; +	if (!port->portdev) { +		/* Device has been unplugged.  vqs are already gone. */ +		return; +	}  	vq = port->in_vq;  	if (port->inbuf)  		buf = port->inbuf; @@ -470,6 +474,10 @@ static void reclaim_consumed_buffers(struct port *port)  	void *buf;  	unsigned int len; +	if (!port->portdev) { +		/* Device has been unplugged.  vqs are already gone. */ +		return; +	}  	while ((buf = virtqueue_get_buf(port->out_vq, &len))) {  		kfree(buf);  		port->outvq_full = false; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1109f6848a4..5cb4d09919d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1919,8 +1919,10 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)  	ret = sysdev_driver_register(&cpu_sysdev_class,  					&cpufreq_sysdev_driver); +	if (ret) +		goto err_null_driver; -	if ((!ret) && !(cpufreq_driver->flags & CPUFREQ_STICKY)) { +	if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {  		int i;  		ret = -ENODEV; @@ -1935,21 +1937,22 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)  		if (ret) {  			dprintk("no CPU initialized for driver %s\n",  							driver_data->name); -			sysdev_driver_unregister(&cpu_sysdev_class, -						&cpufreq_sysdev_driver); - -			spin_lock_irqsave(&cpufreq_driver_lock, flags); -			cpufreq_driver = NULL; -			spin_unlock_irqrestore(&cpufreq_driver_lock, flags); +			goto err_sysdev_unreg;  		}  	} -	if (!ret) { -		register_hotcpu_notifier(&cpufreq_cpu_notifier); -		dprintk("driver %s up and running\n", driver_data->name); -		cpufreq_debug_enable_ratelimit(); -	} +	register_hotcpu_notifier(&cpufreq_cpu_notifier); +	dprintk("driver %s up and running\n", driver_data->name); +	cpufreq_debug_enable_ratelimit(); +	return 0; +err_sysdev_unreg: +	sysdev_driver_unregister(&cpu_sysdev_class, +			&cpufreq_sysdev_driver); +err_null_driver: +	spin_lock_irqsave(&cpufreq_driver_lock, flags); +	cpufreq_driver = NULL; +	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);  	return ret;  }  EXPORT_SYMBOL_GPL(cpufreq_register_driver); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 6977a1ce9d9..f73ef4390db 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -672,7 +672,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)  	struct drm_crtc_helper_funcs *crtc_funcs;  	u16 *red, *green, *blue, *transp;  	struct drm_crtc *crtc; -	int i, rc = 0; +	int i, j, rc = 0;  	int start;  	for (i = 0; i < fb_helper->crtc_count; i++) { @@ -685,7 +685,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)  		transp = cmap->transp;  		start = cmap->start; -		for (i = 0; i < cmap->len; i++) { +		for (j = 0; j < cmap->len; j++) {  			u16 hred, hgreen, hblue, htransp = 0xffff;  			hred = *red++; diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3601466c550..4ff9b6cc973 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -865,7 +865,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)  		int max_freq;  		/* RPSTAT1 is in the GT power well */ -		__gen6_force_wake_get(dev_priv); +		__gen6_gt_force_wake_get(dev_priv);  		seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);  		seq_printf(m, "RPSTAT1: 0x%08x\n", I915_READ(GEN6_RPSTAT1)); @@ -888,7 +888,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)  		seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",  			   max_freq * 100); -		__gen6_force_wake_put(dev_priv); +		__gen6_gt_force_wake_put(dev_priv);  	} else {  		seq_printf(m, "no P-state info available\n");  	} diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 17bd766f208..e33d9be7df3 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1895,6 +1895,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)  	if (IS_GEN2(dev))  		dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); +	/* 965GM sometimes incorrectly writes to hardware status page (HWS) +	 * using 32bit addressing, overwriting memory if HWS is located +	 * above 4GB. +	 * +	 * The documentation also mentions an issue with undefined +	 * behaviour if any general state is accessed within a page above 4GB, +	 * which also needs to be handled carefully. +	 */ +	if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) +		dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); +  	mmio_bar = IS_GEN2(dev) ? 1 : 0;  	dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0);  	if (!dev_priv->regs) { diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0ad533f06af..22ec066adae 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -46,6 +46,9 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);  unsigned int i915_powersave = 1;  module_param_named(powersave, i915_powersave, int, 0600); +unsigned int i915_semaphores = 0; +module_param_named(semaphores, i915_semaphores, int, 0600); +  unsigned int i915_enable_rc6 = 0;  module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); @@ -254,7 +257,7 @@ void intel_detect_pch (struct drm_device *dev)  	}  } -void __gen6_force_wake_get(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)  {  	int count; @@ -270,12 +273,22 @@ void __gen6_force_wake_get(struct drm_i915_private *dev_priv)  		udelay(10);  } -void __gen6_force_wake_put(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)  {  	I915_WRITE_NOTRACE(FORCEWAKE, 0);  	POSTING_READ(FORCEWAKE);  } +void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) +{ +	int loop = 500; +	u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); +	while (fifo < 20 && loop--) { +		udelay(10); +		fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); +	} +} +  static int i915_drm_freeze(struct drm_device *dev)  {  	struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 65dfe81d003..456f4048483 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -956,6 +956,7 @@ extern struct drm_ioctl_desc i915_ioctls[];  extern int i915_max_ioctl;  extern unsigned int i915_fbpercrtc;  extern unsigned int i915_powersave; +extern unsigned int i915_semaphores;  extern unsigned int i915_lvds_downclock;  extern unsigned int i915_panel_use_ssc;  extern unsigned int i915_enable_rc6; @@ -1177,6 +1178,9 @@ void i915_gem_detach_phys_object(struct drm_device *dev,  void i915_gem_free_all_phys_object(struct drm_device *dev);  void i915_gem_release(struct drm_device *dev, struct drm_file *file); +uint32_t +i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj); +  /* i915_gem_gtt.c */  void i915_gem_restore_gtt_mappings(struct drm_device *dev);  int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); @@ -1353,22 +1357,32 @@ __i915_write(64, q)   * must be set to prevent GT core from power down and stale values being   * returned.   */ -void __gen6_force_wake_get(struct drm_i915_private *dev_priv); -void __gen6_force_wake_put (struct drm_i915_private *dev_priv); -static inline u32 i915_safe_read(struct drm_i915_private *dev_priv, u32 reg) +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); +void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); + +static inline u32 i915_gt_read(struct drm_i915_private *dev_priv, u32 reg)  {  	u32 val;  	if (dev_priv->info->gen >= 6) { -		__gen6_force_wake_get(dev_priv); +		__gen6_gt_force_wake_get(dev_priv);  		val = I915_READ(reg); -		__gen6_force_wake_put(dev_priv); +		__gen6_gt_force_wake_put(dev_priv);  	} else  		val = I915_READ(reg);  	return val;  } +static inline void i915_gt_write(struct drm_i915_private *dev_priv, +				u32 reg, u32 val) +{ +	if (dev_priv->info->gen >= 6) +		__gen6_gt_wait_for_fifo(dev_priv); +	I915_WRITE(reg, val); +} +  static inline void  i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len)  { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cf4f74c7c6f..36e66cc5225 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1398,7 +1398,7 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj)   * Return the required GTT alignment for an object, only taking into account   * unfenced tiled surface requirements.   */ -static uint32_t +uint32_t  i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj)  {  	struct drm_device *dev = obj->base.dev; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index d2f445e825f..50ab1614571 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -772,8 +772,8 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj,  	if (from == NULL || to == from)  		return 0; -	/* XXX gpu semaphores are currently causing hard hangs on SNB mobile */ -	if (INTEL_INFO(obj->base.dev)->gen < 6 || IS_MOBILE(obj->base.dev)) +	/* XXX gpu semaphores are implicated in various hard hangs on SNB */ +	if (INTEL_INFO(obj->base.dev)->gen < 6 || !i915_semaphores)  		return i915_gem_object_wait_rendering(obj, true);  	idx = intel_ring_sync_index(from, to); diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 79a04fde69b..d64843e18df 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -184,7 +184,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)  static bool  i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)  { -	int tile_width, tile_height; +	int tile_width;  	/* Linear is always fine */  	if (tiling_mode == I915_TILING_NONE) @@ -215,20 +215,6 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)  		}  	} -	if (IS_GEN2(dev) || -	    (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) -		tile_height = 32; -	else -		tile_height = 8; -	/* i8xx is strange: It has 2 interleaved rows of tiles, so needs an even -	 * number of tile rows. */ -	if (IS_GEN2(dev)) -		tile_height *= 2; - -	/* Size needs to be aligned to a full tile row */ -	if (size & (tile_height * stride - 1)) -		return false; -  	/* 965+ just needs multiples of tile width */  	if (INTEL_INFO(dev)->gen >= 4) {  		if (stride & (tile_width - 1)) @@ -363,14 +349,27 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,  			(obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end &&  			 i915_gem_object_fence_ok(obj, args->tiling_mode)); -		obj->tiling_changed = true; -		obj->tiling_mode = args->tiling_mode; -		obj->stride = args->stride; +		/* Rebind if we need a change of alignment */ +		if (!obj->map_and_fenceable) { +			u32 unfenced_alignment = +				i915_gem_get_unfenced_gtt_alignment(obj); +			if (obj->gtt_offset & (unfenced_alignment - 1)) +				ret = i915_gem_object_unbind(obj); +		} + +		if (ret == 0) { +			obj->tiling_changed = true; +			obj->tiling_mode = args->tiling_mode; +			obj->stride = args->stride; +		}  	} +	/* we have to maintain this existing ABI... */ +	args->stride = obj->stride; +	args->tiling_mode = obj->tiling_mode;  	drm_gem_object_unreference(&obj->base);  	mutex_unlock(&dev->struct_mutex); -	return 0; +	return ret;  }  /** diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 729d4233b76..3e6f486f460 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3261,6 +3261,8 @@  #define  FORCEWAKE				0xA18C  #define  FORCEWAKE_ACK				0x130090 +#define  GT_FIFO_FREE_ENTRIES			0x120008 +  #define GEN6_RPNSWREQ				0xA008  #define   GEN6_TURBO_DISABLE			(1<<31)  #define   GEN6_FREQUENCY(x)			((x)<<25) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e79b25bbee6..49fb54fd9a1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1219,7 +1219,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)  	u32 blt_ecoskpd;  	/* Make sure blitter notifies FBC of writes */ -	__gen6_force_wake_get(dev_priv); +	__gen6_gt_force_wake_get(dev_priv);  	blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);  	blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<  		GEN6_BLITTER_LOCK_SHIFT; @@ -1230,7 +1230,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)  			 GEN6_BLITTER_LOCK_SHIFT);  	I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);  	POSTING_READ(GEN6_BLITTER_ECOSKPD); -	__gen6_force_wake_put(dev_priv); +	__gen6_gt_force_wake_put(dev_priv);  }  static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) @@ -6282,7 +6282,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)  	 * userspace...  	 */  	I915_WRITE(GEN6_RC_STATE, 0); -	__gen6_force_wake_get(dev_priv); +	__gen6_gt_force_wake_get(dev_priv);  	/* disable the counters and set deterministic thresholds */  	I915_WRITE(GEN6_RC_CONTROL, 0); @@ -6380,7 +6380,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)  	/* enable all PM interrupts */  	I915_WRITE(GEN6_PMINTRMSK, 0); -	__gen6_force_wake_put(dev_priv); +	__gen6_gt_force_wake_put(dev_priv);  }  void intel_enable_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 6d6fde85a63..34306865a5d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -14,22 +14,23 @@ struct  intel_hw_status_page {  	struct		drm_i915_gem_object *obj;  }; -#define I915_RING_READ(reg) i915_safe_read(dev_priv, reg) +#define I915_RING_READ(reg) i915_gt_read(dev_priv, reg) +#define I915_RING_WRITE(reg, val) i915_gt_write(dev_priv, reg, val)  #define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL((ring)->mmio_base)) -#define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL((ring)->mmio_base), val) +#define I915_WRITE_TAIL(ring, val) I915_RING_WRITE(RING_TAIL((ring)->mmio_base), val)  #define I915_READ_START(ring) I915_RING_READ(RING_START((ring)->mmio_base)) -#define I915_WRITE_START(ring, val) I915_WRITE(RING_START((ring)->mmio_base), val) +#define I915_WRITE_START(ring, val) I915_RING_WRITE(RING_START((ring)->mmio_base), val)  #define I915_READ_HEAD(ring)  I915_RING_READ(RING_HEAD((ring)->mmio_base)) -#define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD((ring)->mmio_base), val) +#define I915_WRITE_HEAD(ring, val) I915_RING_WRITE(RING_HEAD((ring)->mmio_base), val)  #define I915_READ_CTL(ring) I915_RING_READ(RING_CTL((ring)->mmio_base)) -#define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL((ring)->mmio_base), val) +#define I915_WRITE_CTL(ring, val) I915_RING_WRITE(RING_CTL((ring)->mmio_base), val) -#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val)  #define I915_READ_IMR(ring) I915_RING_READ(RING_IMR((ring)->mmio_base)) +#define I915_WRITE_IMR(ring, val) I915_RING_WRITE(RING_IMR((ring)->mmio_base), val)  #define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID((ring)->mmio_base))  #define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0((ring)->mmio_base)) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 65699bfaaae..b368ed74aad 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -83,7 +83,8 @@ nouveau_dma_init(struct nouveau_channel *chan)  		return ret;  	/* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ -	ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); +	ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000, +				     &chan->m2mf_ntfy);  	if (ret)  		return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9821fcacc3d..982d70b1272 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -852,7 +852,8 @@ extern const struct ttm_mem_type_manager_func nouveau_vram_manager;  extern int  nouveau_notifier_init_channel(struct nouveau_channel *);  extern void nouveau_notifier_takedown_channel(struct nouveau_channel *);  extern int  nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, -				   int cout, uint32_t *offset); +				   int cout, uint32_t start, uint32_t end, +				   uint32_t *offset);  extern int  nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *);  extern int  nouveau_ioctl_notifier_alloc(struct drm_device *, void *data,  					 struct drm_file *); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 26347b7cd87..b0fb9bdcddb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -725,8 +725,10 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,  	ret = vram->get(dev, mem->num_pages << PAGE_SHIFT,  			mem->page_alignment << PAGE_SHIFT, size_nc,  			(nvbo->tile_flags >> 8) & 0xff, &node); -	if (ret) -		return ret; +	if (ret) { +		mem->mm_node = NULL; +		return (ret == -ENOSPC) ? 0 : ret; +	}  	node->page_shift = 12;  	if (nvbo->vma.node) diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/nouveau_mm.c index 8844b50c3e5..7609756b6fa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mm.c +++ b/drivers/gpu/drm/nouveau/nouveau_mm.c @@ -123,7 +123,7 @@ nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc,  		return 0;  	} -	return -ENOMEM; +	return -ENOSPC;  }  int diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index fe29d604b82..5ea167623a8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c @@ -96,7 +96,8 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev,  int  nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, -		       int size, uint32_t *b_offset) +		       int size, uint32_t start, uint32_t end, +		       uint32_t *b_offset)  {  	struct drm_device *dev = chan->dev;  	struct nouveau_gpuobj *nobj = NULL; @@ -104,9 +105,10 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,  	uint32_t offset;  	int target, ret; -	mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0); +	mem = drm_mm_search_free_in_range(&chan->notifier_heap, size, 0, +					  start, end, 0);  	if (mem) -		mem = drm_mm_get_block(mem, size, 0); +		mem = drm_mm_get_block_range(mem, size, 0, start, end);  	if (!mem) {  		NV_ERROR(dev, "Channel %d notifier block full\n", chan->id);  		return -ENOMEM; @@ -177,7 +179,8 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data,  	if (IS_ERR(chan))  		return PTR_ERR(chan); -	ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); +	ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000, +				     &na->offset);  	nouveau_channel_put(&chan);  	return ret;  } diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index ea0041810ae..e57caa2a00e 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -403,16 +403,24 @@ nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj)  void  nv50_instmem_flush(struct drm_device *dev)  { +	struct drm_nouveau_private *dev_priv = dev->dev_private; + +	spin_lock(&dev_priv->ramin_lock);  	nv_wr32(dev, 0x00330c, 0x00000001);  	if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000))  		NV_ERROR(dev, "PRAMIN flush timeout\n"); +	spin_unlock(&dev_priv->ramin_lock);  }  void  nv84_instmem_flush(struct drm_device *dev)  { +	struct drm_nouveau_private *dev_priv = dev->dev_private; + +	spin_lock(&dev_priv->ramin_lock);  	nv_wr32(dev, 0x070000, 0x00000001);  	if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000))  		NV_ERROR(dev, "PRAMIN flush timeout\n"); +	spin_unlock(&dev_priv->ramin_lock);  } diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index 459ff08241e..6144156f255 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -169,7 +169,11 @@ nv50_vm_flush(struct nouveau_vm *vm)  void  nv50_vm_flush_engine(struct drm_device *dev, int engine)  { +	struct drm_nouveau_private *dev_priv = dev->dev_private; + +	spin_lock(&dev_priv->ramin_lock);  	nv_wr32(dev, 0x100c80, (engine << 16) | 1);  	if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000))  		NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); +	spin_unlock(&dev_priv->ramin_lock);  } diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 1fa091e0569..4a5c4a44ffb 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -62,6 +62,7 @@  #include <linux/notifier.h>  #include <linux/cpu.h>  #include <asm/mwait.h> +#include <asm/msr.h>  #define INTEL_IDLE_VERSION "0.4"  #define PREFIX "intel_idle: " @@ -85,6 +86,12 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state);  static struct cpuidle_state *cpuidle_state_table;  /* + * Hardware C-state auto-demotion may not always be optimal. + * Indicate which enable bits to clear here. + */ +static unsigned long long auto_demotion_disable_flags; + +/*   * Set this flag for states where the HW flushes the TLB for us   * and so we don't need cross-calls to keep it consistent.   * If this flag is set, SW flushes the TLB, so even if the @@ -281,6 +288,15 @@ static struct notifier_block setup_broadcast_notifier = {  	.notifier_call = setup_broadcast_cpuhp_notify,  }; +static void auto_demotion_disable(void *dummy) +{ +	unsigned long long msr_bits; + +	rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); +	msr_bits &= ~auto_demotion_disable_flags; +	wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); +} +  /*   * intel_idle_probe()   */ @@ -324,11 +340,17 @@ static int intel_idle_probe(void)  	case 0x25:	/* Westmere */  	case 0x2C:	/* Westmere */  		cpuidle_state_table = nehalem_cstates; +		auto_demotion_disable_flags = +			(NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE);  		break;  	case 0x1C:	/* 28 - Atom Processor */ +		cpuidle_state_table = atom_cstates; +		break; +  	case 0x26:	/* 38 - Lincroft Atom Processor */  		cpuidle_state_table = atom_cstates; +		auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE;  		break;  	case 0x2A:	/* SNB */ @@ -436,6 +458,8 @@ static int intel_idle_cpuidle_devices_init(void)  			return -EIO;  		}  	} +	if (auto_demotion_disable_flags) +		smp_call_function(auto_demotion_disable, NULL, 1);  	return 0;  } diff --git a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c index 18f8798442f..7bd5baa547b 100644 --- a/drivers/isdn/hardware/eicon/istream.c +++ b/drivers/isdn/hardware/eicon/istream.c @@ -62,7 +62,7 @@ void diva_xdi_provide_istream_info (ADAPTER* a,    stream interface.    If synchronous service was requested, then function    does return amount of data written to stream. -  'final' does indicate that pice of data to be written is +  'final' does indicate that piece of data to be written is    final part of frame (necessary only by structured datatransfer)    return  0 if zero lengh packet was written    return -1 if stream is full diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 6a1f9404261..c45e6305b26 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -143,9 +143,9 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)  	unsigned long flags;  	struct asic3 *asic; -	desc->chip->ack(irq); +	desc->irq_data.chip->irq_ack(&desc->irq_data); -	asic = desc->handler_data; +	asic = get_irq_data(irq);  	for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) {  		u32 status; diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 33c923d215c..fdd8a1b8bc6 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c @@ -118,12 +118,12 @@ static int __init davinci_vc_probe(struct platform_device *pdev)  	/* Voice codec interface client */  	cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; -	cell->name = "davinci_vcif"; +	cell->name = "davinci-vcif";  	cell->driver_data = davinci_vc;  	/* Voice codec CQ93VC client */  	cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; -	cell->name = "cq93vc"; +	cell->name = "cq93vc-codec";  	cell->driver_data = davinci_vc;  	ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 627cf577b16..e9018d1394e 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -150,12 +150,12 @@ static inline int __tps6586x_write(struct i2c_client *client,  static inline int __tps6586x_writes(struct i2c_client *client, int reg,  				  int len, uint8_t *val)  { -	int ret; +	int ret, i; -	ret = i2c_smbus_write_i2c_block_data(client, reg, len, val); -	if (ret < 0) { -		dev_err(&client->dev, "failed writings to 0x%02x\n", reg); -		return ret; +	for (i = 0; i < len; i++) { +		ret = __tps6586x_write(client, reg + i, *(val + i)); +		if (ret < 0) +			return ret;  	}  	return 0; diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 000cb414a78..92b85e28a15 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c @@ -385,12 +385,18 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)  	idev->close      = ucb1x00_ts_close;  	__set_bit(EV_ABS, idev->evbit); -	__set_bit(ABS_X, idev->absbit); -	__set_bit(ABS_Y, idev->absbit); -	__set_bit(ABS_PRESSURE, idev->absbit);  	input_set_drvdata(idev, ts); +	ucb1x00_adc_enable(ts->ucb); +	ts->x_res = ucb1x00_ts_read_xres(ts); +	ts->y_res = ucb1x00_ts_read_yres(ts); +	ucb1x00_adc_disable(ts->ucb); + +	input_set_abs_params(idev, ABS_X, 0, ts->x_res, 0, 0); +	input_set_abs_params(idev, ABS_Y, 0, ts->y_res, 0, 0); +	input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); +  	err = input_register_device(idev);  	if (err)  		goto fail; diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 41233c7fa58..f4016a075fd 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -246,6 +246,16 @@ static int wm8994_suspend(struct device *dev)  	struct wm8994 *wm8994 = dev_get_drvdata(dev);  	int ret; +	/* Don't actually go through with the suspend if the CODEC is +	 * still active (eg, for audio passthrough from CP. */ +	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1); +	if (ret < 0) { +		dev_err(dev, "Failed to read power status: %d\n", ret); +	} else if (ret & WM8994_VMID_SEL_MASK) { +		dev_dbg(dev, "CODEC still active, ignoring suspend\n"); +		return 0; +	} +  	/* GPIO configuration state is saved here since we may be configuring  	 * the GPIO alternate functions even if we're not using the gpiolib  	 * driver for them. @@ -261,6 +271,8 @@ static int wm8994_suspend(struct device *dev)  	if (ret < 0)  		dev_err(dev, "Failed to save LDO registers: %d\n", ret); +	wm8994->suspended = true; +  	ret = regulator_bulk_disable(wm8994->num_supplies,  				     wm8994->supplies);  	if (ret != 0) { @@ -276,6 +288,10 @@ static int wm8994_resume(struct device *dev)  	struct wm8994 *wm8994 = dev_get_drvdata(dev);  	int ret; +	/* We may have lied to the PM core about suspending */ +	if (!wm8994->suspended) +		return 0; +  	ret = regulator_bulk_enable(wm8994->num_supplies,  				    wm8994->supplies);  	if (ret != 0) { @@ -298,6 +314,8 @@ static int wm8994_resume(struct device *dev)  	if (ret < 0)  		dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); +	wm8994->suspended = false; +  	return 0;  }  #endif diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c index 63ee4c1a531..b6e1c9a6679 100644 --- a/drivers/misc/bmp085.c +++ b/drivers/misc/bmp085.c @@ -449,6 +449,7 @@ static const struct i2c_device_id bmp085_id[] = {  	{ "bmp085", 0 },  	{ }  }; +MODULE_DEVICE_TABLE(i2c, bmp085_id);  static struct i2c_driver bmp085_driver = {  	.driver = { diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 5c4a54d9b6a..ebc62ad4cc5 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -792,7 +792,6 @@ int mmc_attach_sdio(struct mmc_host *host)  	 */  	mmc_release_host(host);  	err = mmc_add_card(host->card); -	mmc_claim_host(host);  	if (err)  		goto remove_added; @@ -805,12 +804,12 @@ int mmc_attach_sdio(struct mmc_host *host)  			goto remove_added;  	} +	mmc_claim_host(host);  	return 0;  remove_added:  	/* Remove without lock if the device has been added. */ -	mmc_release_host(host);  	mmc_sdio_remove(host);  	mmc_claim_host(host);  remove: diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 653c62475cb..7897d114b29 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -22,7 +22,7 @@   * (you will need to reboot afterwards) */  /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION      "1.62.00-5" +#define DRV_MODULE_VERSION      "1.62.00-6"  #define DRV_MODULE_RELDATE      "2011/01/30"  #define BNX2X_BC_VER            0x040200 @@ -1613,19 +1613,23 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,  #define BNX2X_BTR			4  #define MAX_SPQ_PENDING			8 - -/* CMNG constants -   derived from lab experiments, and not from system spec calculations !!! */ -#define DEF_MIN_RATE			100 +/* CMNG constants, as derived from system spec calculations */ +/* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */ +#define DEF_MIN_RATE					100  /* resolution of the rate shaping timer - 100 usec */ -#define RS_PERIODIC_TIMEOUT_USEC	100 -/* resolution of fairness algorithm in usecs - -   coefficient for calculating the actual t fair */ -#define T_FAIR_COEF			10000000 +#define RS_PERIODIC_TIMEOUT_USEC			100  /* number of bytes in single QM arbitration cycle - -   coefficient for calculating the fairness timer */ -#define QM_ARB_BYTES			40000 -#define FAIR_MEM			2 + * coefficient for calculating the fairness timer */ +#define QM_ARB_BYTES					160000 +/* resolution of Min algorithm 1:100 */ +#define MIN_RES						100 +/* how many bytes above threshold for the minimal credit of Min algorithm*/ +#define MIN_ABOVE_THRESH				32768 +/* Fairness algorithm integration time coefficient - + * for calculating the actual Tfair */ +#define T_FAIR_COEF	((MIN_ABOVE_THRESH +  QM_ARB_BYTES) * 8 * MIN_RES) +/* Memory of fairness algorithm . 2 cycles */ +#define FAIR_MEM					2  #define ATTN_NIG_FOR_FUNC		(1L << 8) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 710ce5d04c5..93798129061 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -259,10 +259,44 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,  #endif  } +/* Timestamp option length allowed for TPA aggregation: + * + *		nop nop kind length echo val + */ +#define TPA_TSTAMP_OPT_LEN	12 +/** + * Calculate the approximate value of the MSS for this + * aggregation using the first packet of it. + * + * @param bp + * @param parsing_flags Parsing flags from the START CQE + * @param len_on_bd Total length of the first packet for the + *		     aggregation. + */ +static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags, +				    u16 len_on_bd) +{ +	/* TPA arrgregation won't have an IP options and TCP options +	 * other than timestamp. +	 */ +	u16 hdrs_len = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr); + + +	/* Check if there was a TCP timestamp, if there is it's will +	 * always be 12 bytes length: nop nop kind length echo val. +	 * +	 * Otherwise FW would close the aggregation. +	 */ +	if (parsing_flags & PARSING_FLAGS_TIME_STAMP_EXIST_FLAG) +		hdrs_len += TPA_TSTAMP_OPT_LEN; + +	return len_on_bd - hdrs_len; +} +  static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,  			       struct sk_buff *skb,  			       struct eth_fast_path_rx_cqe *fp_cqe, -			       u16 cqe_idx) +			       u16 cqe_idx, u16 parsing_flags)  {  	struct sw_rx_page *rx_pg, old_rx_pg;  	u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); @@ -275,8 +309,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,  	/* This is needed in order to enable forwarding support */  	if (frag_size) -		skb_shinfo(skb)->gso_size = min((u32)SGE_PAGE_SIZE, -					       max(frag_size, (u32)len_on_bd)); +		skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp, parsing_flags, +							      len_on_bd);  #ifdef BNX2X_STOP_ON_ERROR  	if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { @@ -344,6 +378,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,  	if (likely(new_skb)) {  		/* fix ip xsum and give it to the stack */  		/* (no need to map the new skb) */ +		u16 parsing_flags = +			le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags);  		prefetch(skb);  		prefetch(((char *)(skb)) + L1_CACHE_BYTES); @@ -373,9 +409,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,  		}  		if (!bnx2x_fill_frag_skb(bp, fp, skb, -					 &cqe->fast_path_cqe, cqe_idx)) { -			if ((le16_to_cpu(cqe->fast_path_cqe. -			    pars_flags.flags) & PARSING_FLAGS_VLAN)) +					 &cqe->fast_path_cqe, cqe_idx, +					 parsing_flags)) { +			if (parsing_flags & PARSING_FLAGS_VLAN)  				__vlan_hwaccel_put_tag(skb,  						 le16_to_cpu(cqe->fast_path_cqe.  							     vlan_tag)); @@ -703,19 +739,20 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp)  {  	u16 line_speed = bp->link_vars.line_speed;  	if (IS_MF(bp)) { -		u16 maxCfg = (bp->mf_config[BP_VN(bp)] & -						FUNC_MF_CFG_MAX_BW_MASK) >> -						FUNC_MF_CFG_MAX_BW_SHIFT; -		/* Calculate the current MAX line speed limit for the DCC -		 * capable devices +		u16 maxCfg = bnx2x_extract_max_cfg(bp, +						   bp->mf_config[BP_VN(bp)]); + +		/* Calculate the current MAX line speed limit for the MF +		 * devices  		 */ -		if (IS_MF_SD(bp)) { +		if (IS_MF_SI(bp)) +			line_speed = (line_speed * maxCfg) / 100; +		else { /* SD mode */  			u16 vn_max_rate = maxCfg * 100;  			if (vn_max_rate < line_speed)  				line_speed = vn_max_rate; -		} else /* IS_MF_SI(bp)) */ -			line_speed = (line_speed * maxCfg) / 100; +		}  	}  	return line_speed; diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 03eb4d68e6b..326ba44b3de 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -1044,4 +1044,24 @@ static inline void storm_memset_cmng(struct bnx2x *bp,  void bnx2x_acquire_phy_lock(struct bnx2x *bp);  void bnx2x_release_phy_lock(struct bnx2x *bp); +/** + * Extracts MAX BW part from MF configuration. + * + * @param bp + * @param mf_cfg + * + * @return u16 + */ +static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg) +{ +	u16 max_cfg = (mf_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> +			      FUNC_MF_CFG_MAX_BW_SHIFT; +	if (!max_cfg) { +		BNX2X_ERR("Illegal configuration detected for Max BW - " +			  "using 100 instead\n"); +		max_cfg = 100; +	} +	return max_cfg; +} +  #endif /* BNX2X_CMN_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 5b44a8b4850..ef2919987a1 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)  	speed |= (cmd->speed_hi << 16);  	if (IS_MF_SI(bp)) { -		u32 param = 0; +		u32 param = 0, part;  		u32 line_speed = bp->link_vars.line_speed;  		/* use 10G if no link detected */ @@ -251,9 +251,11 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)  				       REQ_BC_VER_4_SET_MF_BW);  			return -EINVAL;  		} -		if (line_speed < speed) { -			BNX2X_DEV_INFO("New speed should be less or equal " -				       "to actual line speed\n"); +		part = (speed * 100) / line_speed; +		if (line_speed < speed || !part) { +			BNX2X_DEV_INFO("Speed setting should be in a range " +				       "from 1%% to 100%% " +				       "of actual line speed\n");  			return -EINVAL;  		}  		/* load old values */ @@ -263,8 +265,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)  		param &= FUNC_MF_CFG_MIN_BW_MASK;  		/* set new MAX value */ -		param |= (((speed * 100) / line_speed) -				 << FUNC_MF_CFG_MAX_BW_SHIFT) +		param |= (part << FUNC_MF_CFG_MAX_BW_SHIFT)  				  & FUNC_MF_CFG_MAX_BW_MASK;  		bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); @@ -1781,9 +1782,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp)  		{ 0x100, 0x350 }, /* manuf_info */  		{ 0x450,  0xf0 }, /* feature_info */  		{ 0x640,  0x64 }, /* upgrade_key_info */ -		{ 0x6a4,  0x64 },  		{ 0x708,  0x70 }, /* manuf_key_info */ -		{ 0x778,  0x70 },  		{     0,     0 }  	};  	__be32 buf[0x350 / 4]; @@ -1933,11 +1932,11 @@ static void bnx2x_self_test(struct net_device *dev,  		buf[4] = 1;  		etest->flags |= ETH_TEST_FL_FAILED;  	} -	if (bp->port.pmf) -		if (bnx2x_link_test(bp, is_serdes) != 0) { -			buf[5] = 1; -			etest->flags |= ETH_TEST_FL_FAILED; -		} + +	if (bnx2x_link_test(bp, is_serdes) != 0) { +		buf[5] = 1; +		etest->flags |= ETH_TEST_FL_FAILED; +	}  #ifdef BNX2X_EXTRA_DEBUG  	bnx2x_panic_dump(bp); diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 5a268e9a089..fa6dbe3f205 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -241,7 +241,7 @@ static const struct {  	/* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't  	 * want to handle "system kill" flow at the moment.  	 */ -	BLOCK_PRTY_INFO(PXP, 0x3ffffff, 0x3ffffff, 0x3ffffff, 0x3ffffff), +	BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff),  	BLOCK_PRTY_INFO_0(PXP2,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff),  	BLOCK_PRTY_INFO_1(PXP2,	0x7ff, 0x7f, 0x7f, 0x7ff),  	BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0), diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index d584d32c747..032ae184b60 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1974,13 +1974,22 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn)  		vn_max_rate = 0;  	} else { +		u32 maxCfg = bnx2x_extract_max_cfg(bp, vn_cfg); +  		vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>  				FUNC_MF_CFG_MIN_BW_SHIFT) * 100; -		/* If min rate is zero - set it to 1 */ +		/* If fairness is enabled (not all min rates are zeroes) and +		   if current min rate is zero - set it to 1. +		   This is a requirement of the algorithm. */  		if (bp->vn_weight_sum && (vn_min_rate == 0))  			vn_min_rate = DEF_MIN_RATE; -		vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> -				FUNC_MF_CFG_MAX_BW_SHIFT) * 100; + +		if (IS_MF_SI(bp)) +			/* maxCfg in percents of linkspeed */ +			vn_max_rate = (bp->link_vars.line_speed * maxCfg) / 100; +		else +			/* maxCfg is absolute in 100Mb units */ +			vn_max_rate = maxCfg * 100;  	}  	DP(NETIF_MSG_IFUP, @@ -2006,7 +2015,8 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn)  		m_fair_vn.vn_credit_delta =  			max_t(u32, (vn_min_rate * (T_FAIR_COEF /  						   (8 * bp->vn_weight_sum))), -			      (bp->cmng.fair_vars.fair_threshold * 2)); +			      (bp->cmng.fair_vars.fair_threshold + +							MIN_ABOVE_THRESH));  		DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta %d\n",  		   m_fair_vn.vn_credit_delta);  	} diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index bda60d590fa..3445ded6674 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -1239,14 +1239,14 @@ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)  	if (unlikely(bp->panic))  		return; +	bnx2x_stats_stm[bp->stats_state][event].action(bp); +  	/* Protect a state change flow */  	spin_lock_bh(&bp->stats_lock);  	state = bp->stats_state;  	bp->stats_state = bnx2x_stats_stm[state][event].next_state;  	spin_unlock_bh(&bp->stats_lock); -	bnx2x_stats_stm[state][event].action(bp); -  	if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp))  		DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",  		   state, event, bp->stats_state); diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index 5157e15e96e..aeea9f9ff6e 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -633,6 +633,7 @@ static const struct net_device_ops softing_netdev_ops = {  };  static const struct can_bittiming_const softing_btr_const = { +	.name = "softing",  	.tseg1_min = 1,  	.tseg1_max = 16,  	.tseg2_min = 1, diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 7ff170cbc7d..302be4aa69d 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2760,6 +2760,8 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev)  	u32 status_idx = (u16) *cp->kcq1.status_idx_ptr;  	int kcqe_cnt; +	/* status block index must be read before reading other fields */ +	rmb();  	cp->kwq_con_idx = *cp->kwq_con_idx_ptr;  	while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) { @@ -2770,6 +2772,8 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev)  		barrier();  		if (status_idx != *cp->kcq1.status_idx_ptr) {  			status_idx = (u16) *cp->kcq1.status_idx_ptr; +			/* status block index must be read first */ +			rmb();  			cp->kwq_con_idx = *cp->kwq_con_idx_ptr;  		} else  			break; @@ -2888,6 +2892,8 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info)  	u32 last_status = *info->status_idx_ptr;  	int kcqe_cnt; +	/* status block index must be read before reading the KCQ */ +	rmb();  	while ((kcqe_cnt = cnic_get_kcqes(dev, info))) {  		service_kcqes(dev, kcqe_cnt); @@ -2898,6 +2904,8 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info)  			break;  		last_status = *info->status_idx_ptr; +		/* status block index must be read before reading the KCQ */ +		rmb();  	}  	return last_status;  } @@ -2906,26 +2914,35 @@ static void cnic_service_bnx2x_bh(unsigned long data)  {  	struct cnic_dev *dev = (struct cnic_dev *) data;  	struct cnic_local *cp = dev->cnic_priv; -	u32 status_idx; +	u32 status_idx, new_status_idx;  	if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))  		return; -	status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); +	while (1) { +		status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); -	CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); +		CNIC_WR16(dev, cp->kcq1.io_addr, +			  cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); -	if (BNX2X_CHIP_IS_E2(cp->chip_id)) { -		status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); +		if (!BNX2X_CHIP_IS_E2(cp->chip_id)) { +			cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, +					   status_idx, IGU_INT_ENABLE, 1); +			break; +		} + +		new_status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); + +		if (new_status_idx != status_idx) +			continue;  		CNIC_WR16(dev, cp->kcq2.io_addr, cp->kcq2.sw_prod_idx +  			  MAX_KCQ_IDX);  		cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF,  				status_idx, IGU_INT_ENABLE, 1); -	} else { -		cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, -				   status_idx, IGU_INT_ENABLE, 1); + +		break;  	}  } diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 2a628d17d17..7018bfe408a 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1008,7 +1008,7 @@ static void emac_rx_handler(void *token, int len, int status)  	int			ret;  	/* free and bail if we are shutting down */ -	if (unlikely(!netif_running(ndev))) { +	if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) {  		dev_kfree_skb_any(skb);  		return;  	} diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c index 9d8a20b72fa..8318ea06cb6 100644 --- a/drivers/net/dnet.c +++ b/drivers/net/dnet.c @@ -337,8 +337,6 @@ static int dnet_mii_init(struct dnet *bp)  	for (i = 0; i < PHY_MAX_ADDR; i++)  		bp->mii_bus->irq[i] = PHY_POLL; -	platform_set_drvdata(bp->dev, bp->mii_bus); -  	if (mdiobus_register(bp->mii_bus)) {  		err = -ENXIO;  		goto err_out_free_mdio_irq; @@ -863,6 +861,7 @@ static int __devinit dnet_probe(struct platform_device *pdev)  	bp = netdev_priv(dev);  	bp->dev = dev; +	platform_set_drvdata(pdev, dev);  	SET_NETDEV_DEV(dev, &pdev->dev);  	spin_lock_init(&bp->lock); diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h index 55c1711f168..33e7c45a4fe 100644 --- a/drivers/net/e1000/e1000_osdep.h +++ b/drivers/net/e1000/e1000_osdep.h @@ -42,7 +42,8 @@  #define GBE_CONFIG_RAM_BASE \  	((unsigned int)(CONFIG_RAM_BASE + GBE_CONFIG_OFFSET)) -#define GBE_CONFIG_BASE_VIRT    phys_to_virt(GBE_CONFIG_RAM_BASE) +#define GBE_CONFIG_BASE_VIRT \ +	((void __iomem *)phys_to_virt(GBE_CONFIG_RAM_BASE))  #define GBE_CONFIG_FLASH_WRITE(base, offset, count, data) \  	(iowrite16_rep(base + offset, data, count)) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3fa110ddb04..2e5022849f1 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5967,7 +5967,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  		/* APME bit in EEPROM is mapped to WUC.APME */  		eeprom_data = er32(WUC);  		eeprom_apme_mask = E1000_WUC_APME; -		if (eeprom_data & E1000_WUC_PHY_WAKE) +		if ((hw->mac.type > e1000_ich10lan) && +		    (eeprom_data & E1000_WUC_PHY_WAKE))  			adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;  	} else if (adapter->flags & FLAG_APME_IN_CTRL3) {  		if (adapter->flags & FLAG_APME_CHECK_PORT_B && diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 2a71373719a..cd0282d5d40 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -74,7 +74,8 @@ static struct platform_device_id fec_devtype[] = {  	}, {  		.name = "imx28-fec",  		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, -	} +	}, +	{ }  };  static unsigned char macaddr[ETH_ALEN]; diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c index 74486a8b009..af3822f9ea9 100644 --- a/drivers/net/igbvf/vf.c +++ b/drivers/net/igbvf/vf.c @@ -220,7 +220,7 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)   *  The parameter rar_count will usually be hw->mac.rar_entry_count   *  unless there are workarounds that change this.   **/ -void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, +static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,                                    u8 *mc_addr_list, u32 mc_addr_count,                                    u32 rar_used_count, u32 rar_count)  { diff --git a/drivers/net/macb.c b/drivers/net/macb.c index f69e73e2191..79ccb54ab00 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -260,7 +260,7 @@ static int macb_mii_init(struct macb *bp)  	for (i = 0; i < PHY_MAX_ADDR; i++)  		bp->mii_bus->irq[i] = PHY_POLL; -	platform_set_drvdata(bp->dev, bp->mii_bus); +	dev_set_drvdata(&bp->dev->dev, bp->mii_bus);  	if (mdiobus_register(bp->mii_bus))  		goto err_out_free_mdio_irq; diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 9226cda4d05..530ab5a10bd 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -691,6 +691,7 @@ static struct pcmcia_device_id fmvj18x_ids[] = {  	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a),  	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0e01),  	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05), +	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0b05),  	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101),  	PCMCIA_DEVICE_NULL,  }; diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ef2133b16f8..7ffdb80adf4 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -25,6 +25,7 @@  #include <linux/dma-mapping.h>  #include <linux/pm_runtime.h>  #include <linux/firmware.h> +#include <linux/pci-aspm.h>  #include <asm/system.h>  #include <asm/io.h> @@ -3020,6 +3021,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  	mii->reg_num_mask = 0x1f;  	mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII); +	/* disable ASPM completely as that cause random device stop working +	 * problems as well as full system hangs for some PCIe devices users */ +	pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | +				     PCIE_LINK_STATE_CLKPM); +  	/* enable device (incl. PCI PM wakeup and hotplug setup) */  	rc = pci_enable_device(pdev);  	if (rc < 0) { diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 42daf98ba73..35b28f42d20 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3856,9 +3856,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,  	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);  	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); -	/* device is off until link detection */ -	netif_carrier_off(dev); -  	return dev;  } diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 5ab3084eb9c..07b1633b7f3 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -219,8 +219,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)  	struct tx_buf *tx_buf = NULL;  	struct sk_buff *nskb = NULL;  	int ret = 0, i; -	u16 *hdr, tx_skb_cnt = 0; +	u16 tx_skb_cnt = 0;  	u8 *buf; +	__le16 *hdr;  	if (hif_dev->tx.tx_skb_cnt == 0)  		return 0; @@ -245,9 +246,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)  		buf = tx_buf->buf;  		buf += tx_buf->offset; -		hdr = (u16 *)buf; -		*hdr++ = nskb->len; -		*hdr++ = ATH_USB_TX_STREAM_MODE_TAG; +		hdr = (__le16 *)buf; +		*hdr++ = cpu_to_le16(nskb->len); +		*hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG);  		buf += 4;  		memcpy(buf, nskb->data, nskb->len);  		tx_buf->len = nskb->len + 4; diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 180170d3ce2..2915b11edef 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -885,7 +885,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)  	struct ath_common *common = ath9k_hw_common(ah);  	if (!(ints & ATH9K_INT_GLOBAL)) -		ath9k_hw_enable_interrupts(ah); +		ath9k_hw_disable_interrupts(ah);  	ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); @@ -963,7 +963,8 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)  			REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);  	} -	ath9k_hw_enable_interrupts(ah); +	if (ints & ATH9K_INT_GLOBAL) +		ath9k_hw_enable_interrupts(ah);  	return;  } diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 537732e5964..f82c400be28 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -118,6 +118,8 @@ static struct usb_device_id carl9170_usb_ids[] = {  	{ USB_DEVICE(0x057c, 0x8402) },  	/* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */  	{ USB_DEVICE(0x1668, 0x1200) }, +	/* Airlive X.USB a/b/g/n */ +	{ USB_DEVICE(0x1b75, 0x9170) },  	/* terminate */  	{} diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 79ab0a6b138..537fb8c84e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -51,7 +51,7 @@  #include "iwl-agn-debugfs.h"  /* Highest firmware API version supported */ -#define IWL5000_UCODE_API_MAX 2 +#define IWL5000_UCODE_API_MAX 5  #define IWL5150_UCODE_API_MAX 2  /* Lowest firmware API version supported */ diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 21713a7638c..9b344a921e7 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -98,6 +98,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {  	{USB_DEVICE(0x1413, 0x5400)},   /* Telsey 802.11g USB2.0 Adapter */  	{USB_DEVICE(0x1435, 0x0427)},	/* Inventel UR054G */  	{USB_DEVICE(0x1668, 0x1050)},	/* Actiontec 802UIG-1 */ +	{USB_DEVICE(0x1740, 0x1000)},	/* Senao NUB-350 */  	{USB_DEVICE(0x2001, 0x3704)},	/* DLink DWL-G122 rev A2 */  	{USB_DEVICE(0x2001, 0x3705)},	/* D-Link DWL-G120 rev C1 */  	{USB_DEVICE(0x413c, 0x5513)},	/* Dell WLA3310 USB Wireless Adapter */ diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 848cc2cce24..518542b4bf9 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2597,6 +2597,9 @@ static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,  	__le32 mode;  	int ret; +	if (priv->device_type != RNDIS_BCM4320B) +		return -ENOTSUPP; +  	netdev_dbg(usbdev->net, "%s(): %s, %d\n", __func__,  				enabled ? "enabled" : "disabled",  				timeout); diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 28295d0a50f..4d87b5dc928 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -36,19 +36,55 @@ unsigned int of_pdt_unique_id __initdata;  	(p)->unique_id = of_pdt_unique_id++; \  } while (0) -static inline const char *of_pdt_node_name(struct device_node *dp) +static char * __init of_pdt_build_full_name(struct device_node *dp)  { -	return dp->path_component_name; +	int len, ourlen, plen; +	char *n; + +	dp->path_component_name = build_path_component(dp); + +	plen = strlen(dp->parent->full_name); +	ourlen = strlen(dp->path_component_name); +	len = ourlen + plen + 2; + +	n = prom_early_alloc(len); +	strcpy(n, dp->parent->full_name); +	if (!of_node_is_root(dp->parent)) { +		strcpy(n + plen, "/"); +		plen++; +	} +	strcpy(n + plen, dp->path_component_name); + +	return n;  } -#else +#else /* CONFIG_SPARC */  static inline void of_pdt_incr_unique_id(void *p) { }  static inline void irq_trans_init(struct device_node *dp) { } -static inline const char *of_pdt_node_name(struct device_node *dp) +static char * __init of_pdt_build_full_name(struct device_node *dp)  { -	return dp->name; +	static int failsafe_id = 0; /* for generating unique names on failure */ +	char *buf; +	int len; + +	if (of_pdt_prom_ops->pkg2path(dp->phandle, NULL, 0, &len)) +		goto failsafe; + +	buf = prom_early_alloc(len + 1); +	if (of_pdt_prom_ops->pkg2path(dp->phandle, buf, len, &len)) +		goto failsafe; +	return buf; + + failsafe: +	buf = prom_early_alloc(strlen(dp->parent->full_name) + +			       strlen(dp->name) + 16); +	sprintf(buf, "%s/%s@unknown%i", +		of_node_is_root(dp->parent) ? "" : dp->parent->full_name, +		dp->name, failsafe_id++); +	pr_err("%s: pkg2path failed; assigning %s\n", __func__, buf); +	return buf;  }  #endif /* !CONFIG_SPARC */ @@ -132,47 +168,6 @@ static char * __init of_pdt_get_one_property(phandle node, const char *name)  	return buf;  } -static char * __init of_pdt_try_pkg2path(phandle node) -{ -	char *res, *buf = NULL; -	int len; - -	if (!of_pdt_prom_ops->pkg2path) -		return NULL; - -	if (of_pdt_prom_ops->pkg2path(node, buf, 0, &len)) -		return NULL; -	buf = prom_early_alloc(len + 1); -	if (of_pdt_prom_ops->pkg2path(node, buf, len, &len)) { -		pr_err("%s: package-to-path failed\n", __func__); -		return NULL; -	} - -	res = strrchr(buf, '/'); -	if (!res) { -		pr_err("%s: couldn't find / in %s\n", __func__, buf); -		return NULL; -	} -	return res+1; -} - -/* - * When fetching the node's name, first try using package-to-path; if - * that fails (either because the arch hasn't supplied a PROM callback, - * or some other random failure), fall back to just looking at the node's - * 'name' property. - */ -static char * __init of_pdt_build_name(phandle node) -{ -	char *buf; - -	buf = of_pdt_try_pkg2path(node); -	if (!buf) -		buf = of_pdt_get_one_property(node, "name"); - -	return buf; -} -  static struct device_node * __init of_pdt_create_node(phandle node,  						    struct device_node *parent)  { @@ -187,7 +182,7 @@ static struct device_node * __init of_pdt_create_node(phandle node,  	kref_init(&dp->kref); -	dp->name = of_pdt_build_name(node); +	dp->name = of_pdt_get_one_property(node, "name");  	dp->type = of_pdt_get_one_property(node, "device_type");  	dp->phandle = node; @@ -198,26 +193,6 @@ static struct device_node * __init of_pdt_create_node(phandle node,  	return dp;  } -static char * __init of_pdt_build_full_name(struct device_node *dp) -{ -	int len, ourlen, plen; -	char *n; - -	plen = strlen(dp->parent->full_name); -	ourlen = strlen(of_pdt_node_name(dp)); -	len = ourlen + plen + 2; - -	n = prom_early_alloc(len); -	strcpy(n, dp->parent->full_name); -	if (!of_node_is_root(dp->parent)) { -		strcpy(n + plen, "/"); -		plen++; -	} -	strcpy(n + plen, of_pdt_node_name(dp)); - -	return n; -} -  static struct device_node * __init of_pdt_build_tree(struct device_node *parent,  						   phandle node,  						   struct device_node ***nextp) @@ -240,9 +215,6 @@ static struct device_node * __init of_pdt_build_tree(struct device_node *parent,  		*(*nextp) = dp;  		*nextp = &dp->allnext; -#if defined(CONFIG_SPARC) -		dp->path_component_name = build_path_component(dp); -#endif  		dp->full_name = of_pdt_build_full_name(dp);  		dp->child = of_pdt_build_tree(dp, diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index c3f72192af6..a52039564e7 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -181,6 +181,9 @@ static int __init colibri_pcmcia_init(void)  {  	int ret; +	if (!machine_is_colibri() && !machine_is_colibri320()) +		return -ENODEV; +  	colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);  	if (!colibri_pcmcia_device)  		return -ENOMEM; diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig index f3a73dd7766..e4c4f3dc072 100644 --- a/drivers/pps/generators/Kconfig +++ b/drivers/pps/generators/Kconfig @@ -6,7 +6,7 @@ comment "PPS generators support"  config PPS_GENERATOR_PARPORT  	tristate "Parallel port PPS signal generator" -	depends on PARPORT +	depends on PARPORT && BROKEN  	help  	  If you say yes here you get support for a PPS signal generator which  	  utilizes STROBE pin of a parallel port to send PPS signals. It uses diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index cf953ecbfca..b80fa288240 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -77,18 +77,20 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id)  }  /* Update control registers */ -static void s3c_rtc_setaie(int to) +static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)  {  	unsigned int tmp; -	pr_debug("%s: aie=%d\n", __func__, to); +	pr_debug("%s: aie=%d\n", __func__, enabled);  	tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; -	if (to) +	if (enabled)  		tmp |= S3C2410_RTCALM_ALMEN;  	writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); + +	return 0;  }  static int s3c_rtc_setpie(struct device *dev, int enabled) @@ -308,7 +310,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)  	writeb(alrm_en, base + S3C2410_RTCALM); -	s3c_rtc_setaie(alrm->enabled); +	s3c_rtc_setaie(dev, alrm->enabled);  	return 0;  } @@ -440,7 +442,7 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)  	rtc_device_unregister(rtc);  	s3c_rtc_setpie(&dev->dev, 0); -	s3c_rtc_setaie(0); +	s3c_rtc_setaie(&dev->dev, 0);  	clk_disable(rtc_clk);  	clk_put(rtc_clk); diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index c881a14fa5d..1f6a4d894e7 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -62,8 +62,8 @@ static int xpram_devs;  /*   * Parameter parsing functions.   */ -static int __initdata devs = XPRAM_DEVS; -static char __initdata *sizes[XPRAM_MAX_DEVS]; +static int devs = XPRAM_DEVS; +static char *sizes[XPRAM_MAX_DEVS];  module_param(devs, int, 0);  module_param_array(sizes, charp, NULL, 0); diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 8cd58e412b5..5ad44daef73 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -460,7 +460,8 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file,  	  unsigned int cmd, unsigned long arg)  {  	void __user *argp; -	int ct, perm; +	unsigned int ct; +	int perm;  	argp = (void __user *)arg; diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 7a242f07363..267b54e8ff5 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -280,6 +280,14 @@ tape_do_io_free(struct tape_device *device, struct tape_request *request)  	return rc;  } +static inline void +tape_do_io_async_free(struct tape_device *device, struct tape_request *request) +{ +	request->callback = (void *) tape_free_request; +	request->callback_data = NULL; +	tape_do_io_async(device, request); +} +  extern int tape_oper_handler(int irq, int status);  extern void tape_noper_handler(int irq, int status);  extern int tape_open(struct tape_device *); diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index c17f35b6136..c26511171ff 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -53,23 +53,11 @@ static void tape_34xx_delete_sbid_from(struct tape_device *, int);   * Medium sense for 34xx tapes. There is no 'real' medium sense call.   * So we just do a normal sense.   */ -static int -tape_34xx_medium_sense(struct tape_device *device) +static void __tape_34xx_medium_sense(struct tape_request *request)  { -	struct tape_request *request; -	unsigned char       *sense; -	int                  rc; - -	request = tape_alloc_request(1, 32); -	if (IS_ERR(request)) { -		DBF_EXCEPTION(6, "MSEN fail\n"); -		return PTR_ERR(request); -	} - -	request->op = TO_MSEN; -	tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); +	struct tape_device *device = request->device; +	unsigned char *sense; -	rc = tape_do_io_interruptible(device, request);  	if (request->rc == 0) {  		sense = request->cpdata; @@ -88,15 +76,47 @@ tape_34xx_medium_sense(struct tape_device *device)  			device->tape_generic_status |= GMT_WR_PROT(~0);  		else  			device->tape_generic_status &= ~GMT_WR_PROT(~0); -	} else { +	} else  		DBF_EVENT(4, "tape_34xx: medium sense failed with rc=%d\n",  			request->rc); -	}  	tape_free_request(request); +} + +static int tape_34xx_medium_sense(struct tape_device *device) +{ +	struct tape_request *request; +	int rc; + +	request = tape_alloc_request(1, 32); +	if (IS_ERR(request)) { +		DBF_EXCEPTION(6, "MSEN fail\n"); +		return PTR_ERR(request); +	} +	request->op = TO_MSEN; +	tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); +	rc = tape_do_io_interruptible(device, request); +	__tape_34xx_medium_sense(request);  	return rc;  } +static void tape_34xx_medium_sense_async(struct tape_device *device) +{ +	struct tape_request *request; + +	request = tape_alloc_request(1, 32); +	if (IS_ERR(request)) { +		DBF_EXCEPTION(6, "MSEN fail\n"); +		return; +	} + +	request->op = TO_MSEN; +	tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); +	request->callback = (void *) __tape_34xx_medium_sense; +	request->callback_data = NULL; +	tape_do_io_async(device, request); +} +  struct tape_34xx_work {  	struct tape_device	*device;  	enum tape_op		 op; @@ -109,6 +129,9 @@ struct tape_34xx_work {   * is inserted but cannot call tape_do_io* from an interrupt context.   * Maybe that's useful for other actions we want to start from the   * interrupt handler. + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq).   */  static void  tape_34xx_work_handler(struct work_struct *work) @@ -119,7 +142,7 @@ tape_34xx_work_handler(struct work_struct *work)  	switch(p->op) {  		case TO_MSEN: -			tape_34xx_medium_sense(device); +			tape_34xx_medium_sense_async(device);  			break;  		default:  			DBF_EVENT(3, "T34XX: internal error: unknown work\n"); diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index fbe361fcd2c..de2e99e0a71 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -329,17 +329,17 @@ out:  /*   * Enable encryption   */ -static int tape_3592_enable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_enable_crypt(struct tape_device *device)  {  	struct tape_request *request;  	char *data;  	DBF_EVENT(6, "tape_3592_enable_crypt\n");  	if (!crypt_supported(device)) -		return -ENOSYS; +		return ERR_PTR(-ENOSYS);  	request = tape_alloc_request(2, 72);  	if (IS_ERR(request)) -		return PTR_ERR(request); +		return request;  	data = request->cpdata;  	memset(data,0,72); @@ -354,23 +354,42 @@ static int tape_3592_enable_crypt(struct tape_device *device)  	request->op = TO_CRYPT_ON;  	tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);  	tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); +	return request; +} + +static int tape_3592_enable_crypt(struct tape_device *device) +{ +	struct tape_request *request; + +	request = __tape_3592_enable_crypt(device); +	if (IS_ERR(request)) +		return PTR_ERR(request);  	return tape_do_io_free(device, request);  } +static void tape_3592_enable_crypt_async(struct tape_device *device) +{ +	struct tape_request *request; + +	request = __tape_3592_enable_crypt(device); +	if (!IS_ERR(request)) +		tape_do_io_async_free(device, request); +} +  /*   * Disable encryption   */ -static int tape_3592_disable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_disable_crypt(struct tape_device *device)  {  	struct tape_request *request;  	char *data;  	DBF_EVENT(6, "tape_3592_disable_crypt\n");  	if (!crypt_supported(device)) -		return -ENOSYS; +		return ERR_PTR(-ENOSYS);  	request = tape_alloc_request(2, 72);  	if (IS_ERR(request)) -		return PTR_ERR(request); +		return request;  	data = request->cpdata;  	memset(data,0,72); @@ -383,9 +402,28 @@ static int tape_3592_disable_crypt(struct tape_device *device)  	tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);  	tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); +	return request; +} + +static int tape_3592_disable_crypt(struct tape_device *device) +{ +	struct tape_request *request; + +	request = __tape_3592_disable_crypt(device); +	if (IS_ERR(request)) +		return PTR_ERR(request);  	return tape_do_io_free(device, request);  } +static void tape_3592_disable_crypt_async(struct tape_device *device) +{ +	struct tape_request *request; + +	request = __tape_3592_disable_crypt(device); +	if (!IS_ERR(request)) +		tape_do_io_async_free(device, request); +} +  /*   * IOCTL: Set encryption status   */ @@ -457,8 +495,7 @@ tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg)  /*   * SENSE Medium: Get Sense data about medium state   */ -static int -tape_3590_sense_medium(struct tape_device *device) +static int tape_3590_sense_medium(struct tape_device *device)  {  	struct tape_request *request; @@ -470,6 +507,18 @@ tape_3590_sense_medium(struct tape_device *device)  	return tape_do_io_free(device, request);  } +static void tape_3590_sense_medium_async(struct tape_device *device) +{ +	struct tape_request *request; + +	request = tape_alloc_request(1, 128); +	if (IS_ERR(request)) +		return; +	request->op = TO_MSEN; +	tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata); +	tape_do_io_async_free(device, request); +} +  /*   * MTTELL: Tell block. Return the number of block relative to current file.   */ @@ -546,15 +595,14 @@ tape_3590_read_opposite(struct tape_device *device,   * 2. The attention msg is written to the "read subsystem data" buffer.   * In this case we probably should print it to the console.   */ -static int -tape_3590_read_attmsg(struct tape_device *device) +static void tape_3590_read_attmsg_async(struct tape_device *device)  {  	struct tape_request *request;  	char *buf;  	request = tape_alloc_request(3, 4096);  	if (IS_ERR(request)) -		return PTR_ERR(request); +		return;  	request->op = TO_READ_ATTMSG;  	buf = request->cpdata;  	buf[0] = PREP_RD_SS_DATA; @@ -562,12 +610,15 @@ tape_3590_read_attmsg(struct tape_device *device)  	tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf);  	tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12);  	tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); -	return tape_do_io_free(device, request); +	tape_do_io_async_free(device, request);  }  /*   * These functions are used to schedule follow-up actions from within an   * interrupt context (like unsolicited interrupts). + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq).   */  struct work_handler_data {  	struct tape_device *device; @@ -583,16 +634,16 @@ tape_3590_work_handler(struct work_struct *work)  	switch (p->op) {  	case TO_MSEN: -		tape_3590_sense_medium(p->device); +		tape_3590_sense_medium_async(p->device);  		break;  	case TO_READ_ATTMSG: -		tape_3590_read_attmsg(p->device); +		tape_3590_read_attmsg_async(p->device);  		break;  	case TO_CRYPT_ON: -		tape_3592_enable_crypt(p->device); +		tape_3592_enable_crypt_async(p->device);  		break;  	case TO_CRYPT_OFF: -		tape_3592_disable_crypt(p->device); +		tape_3592_disable_crypt_async(p->device);  		break;  	default:  		DBF_EVENT(3, "T3590: work handler undefined for " diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9045c52abd2..fb2bb35c62c 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -443,7 +443,7 @@ static void scsi_run_queue(struct request_queue *q)  					&sdev->request_queue->queue_flags);  		if (flagset)  			queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue); -		__blk_run_queue(sdev->request_queue); +		__blk_run_queue(sdev->request_queue, false);  		if (flagset)  			queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue);  		spin_unlock(sdev->request_queue->queue_lock); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 998c01be323..5c3ccfc6b62 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3829,7 +3829,7 @@ fc_bsg_goose_queue(struct fc_rport *rport)  		  !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags);  	if (flagset)  		queue_flag_set(QUEUE_FLAG_REENTER, rport->rqst_q); -	__blk_run_queue(rport->rqst_q); +	__blk_run_queue(rport->rqst_q, false);  	if (flagset)  		queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q);  	spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags); diff --git a/drivers/tty/serial/serial_cs.c b/drivers/tty/serial/serial_cs.c index 93760b2ea17..1ef4df9bf7e 100644 --- a/drivers/tty/serial/serial_cs.c +++ b/drivers/tty/serial/serial_cs.c @@ -712,6 +712,7 @@ static struct pcmcia_device_id serial_ids[] = {  	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),  	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01),  	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), +	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0b05),  	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101),  	PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),  	PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 3c6e1a05874..5e1495097ec 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -346,14 +346,19 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)  		if (unlikely(!skb))  			break; -		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 0, -				req->actual); -		page = NULL; -		if (req->actual < req->length) { /* Last fragment */ +		if (skb->len == 0) { /* First fragment */  			skb->protocol = htons(ETH_P_PHONET);  			skb_reset_mac_header(skb); -			pskb_pull(skb, 1); +			/* Can't use pskb_pull() on page in IRQ */ +			memcpy(skb_put(skb, 1), page_address(page), 1); +		} + +		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, +				skb->len == 0, req->actual); +		page = NULL; + +		if (req->actual < req->length) { /* Last fragment */  			skb->dev = dev;  			dev->stats.rx_packets++;  			dev->stats.rx_bytes += skb->len; diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index e8f4f36fdf0..a6f21b891f6 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -29,6 +29,7 @@  #include <linux/of.h>  #include <linux/of_platform.h> +#include <linux/of_address.h>  /**   * ehci_xilinx_of_setup - Initialize the device for ehci_reset() diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index 8010aaeb5ad..dd0e84a9bd2 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c @@ -239,11 +239,15 @@ static int __devinit ltv350qv_probe(struct spi_device *spi)  	lcd->spi = spi;  	lcd->power = FB_BLANK_POWERDOWN;  	lcd->buffer = kzalloc(8, GFP_KERNEL); +	if (!lcd->buffer) { +		ret = -ENOMEM; +		goto out_free_lcd; +	}  	ld = lcd_device_register("ltv350qv", &spi->dev, lcd, <v_ops);  	if (IS_ERR(ld)) {  		ret = PTR_ERR(ld); -		goto out_free_lcd; +		goto out_free_buffer;  	}  	lcd->ld = ld; @@ -257,6 +261,8 @@ static int __devinit ltv350qv_probe(struct spi_device *spi)  out_unregister:  	lcd_device_unregister(ld); +out_free_buffer: +	kfree(lcd->buffer);  out_free_lcd:  	kfree(lcd);  	return ret; @@ -268,6 +274,7 @@ static int __devexit ltv350qv_remove(struct spi_device *spi)  	ltv350qv_power(lcd, FB_BLANK_POWERDOWN);  	lcd_device_unregister(lcd->ld); +	kfree(lcd->buffer);  	kfree(lcd);  	return 0;  |