diff options
author | David S. Miller <davem@davemloft.net> | 2013-08-26 16:37:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-26 16:37:08 -0400 |
commit | b05930f5d1c7d5873cb050261d21789a99de9d48 (patch) | |
tree | 2d374846712b0bdacc5dd0a36b3c2f754886e560 /drivers | |
parent | b65f63ee845136940db985f3072335d8cdb6fd6c (diff) | |
parent | 41a00f7950a6bc0aa956f6d6b423f0fbf34d431a (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/wireless/iwlwifi/pcie/trans.c
include/linux/inetdevice.h
The inetdevice.h conflict involves moving the IPV4_DEVCONF values
into a UAPI header, overlapping additions of some new entries.
The iwlwifi conflict is a context overlap.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
31 files changed, 342 insertions, 162 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index dc53a527126b..9e6578330801 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c | |||
@@ -85,9 +85,17 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, | |||
85 | struct sg_table *sg, | 85 | struct sg_table *sg, |
86 | enum dma_data_direction dir) | 86 | enum dma_data_direction dir) |
87 | { | 87 | { |
88 | struct drm_i915_gem_object *obj = attachment->dmabuf->priv; | ||
89 | |||
90 | mutex_lock(&obj->base.dev->struct_mutex); | ||
91 | |||
88 | dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir); | 92 | dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir); |
89 | sg_free_table(sg); | 93 | sg_free_table(sg); |
90 | kfree(sg); | 94 | kfree(sg); |
95 | |||
96 | i915_gem_object_unpin_pages(obj); | ||
97 | |||
98 | mutex_unlock(&obj->base.dev->struct_mutex); | ||
91 | } | 99 | } |
92 | 100 | ||
93 | static void i915_gem_dmabuf_release(struct dma_buf *dma_buf) | 101 | static void i915_gem_dmabuf_release(struct dma_buf *dma_buf) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e38b45786653..be79f477a38f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -10042,6 +10042,8 @@ struct intel_display_error_state { | |||
10042 | 10042 | ||
10043 | u32 power_well_driver; | 10043 | u32 power_well_driver; |
10044 | 10044 | ||
10045 | int num_transcoders; | ||
10046 | |||
10045 | struct intel_cursor_error_state { | 10047 | struct intel_cursor_error_state { |
10046 | u32 control; | 10048 | u32 control; |
10047 | u32 position; | 10049 | u32 position; |
@@ -10050,16 +10052,7 @@ struct intel_display_error_state { | |||
10050 | } cursor[I915_MAX_PIPES]; | 10052 | } cursor[I915_MAX_PIPES]; |
10051 | 10053 | ||
10052 | struct intel_pipe_error_state { | 10054 | struct intel_pipe_error_state { |
10053 | enum transcoder cpu_transcoder; | ||
10054 | u32 conf; | ||
10055 | u32 source; | 10055 | u32 source; |
10056 | |||
10057 | u32 htotal; | ||
10058 | u32 hblank; | ||
10059 | u32 hsync; | ||
10060 | u32 vtotal; | ||
10061 | u32 vblank; | ||
10062 | u32 vsync; | ||
10063 | } pipe[I915_MAX_PIPES]; | 10056 | } pipe[I915_MAX_PIPES]; |
10064 | 10057 | ||
10065 | struct intel_plane_error_state { | 10058 | struct intel_plane_error_state { |
@@ -10071,6 +10064,19 @@ struct intel_display_error_state { | |||
10071 | u32 surface; | 10064 | u32 surface; |
10072 | u32 tile_offset; | 10065 | u32 tile_offset; |
10073 | } plane[I915_MAX_PIPES]; | 10066 | } plane[I915_MAX_PIPES]; |
10067 | |||
10068 | struct intel_transcoder_error_state { | ||
10069 | enum transcoder cpu_transcoder; | ||
10070 | |||
10071 | u32 conf; | ||
10072 | |||
10073 | u32 htotal; | ||
10074 | u32 hblank; | ||
10075 | u32 hsync; | ||
10076 | u32 vtotal; | ||
10077 | u32 vblank; | ||
10078 | u32 vsync; | ||
10079 | } transcoder[4]; | ||
10074 | }; | 10080 | }; |
10075 | 10081 | ||
10076 | struct intel_display_error_state * | 10082 | struct intel_display_error_state * |
@@ -10078,9 +10084,17 @@ intel_display_capture_error_state(struct drm_device *dev) | |||
10078 | { | 10084 | { |
10079 | drm_i915_private_t *dev_priv = dev->dev_private; | 10085 | drm_i915_private_t *dev_priv = dev->dev_private; |
10080 | struct intel_display_error_state *error; | 10086 | struct intel_display_error_state *error; |
10081 | enum transcoder cpu_transcoder; | 10087 | int transcoders[] = { |
10088 | TRANSCODER_A, | ||
10089 | TRANSCODER_B, | ||
10090 | TRANSCODER_C, | ||
10091 | TRANSCODER_EDP, | ||
10092 | }; | ||
10082 | int i; | 10093 | int i; |
10083 | 10094 | ||
10095 | if (INTEL_INFO(dev)->num_pipes == 0) | ||
10096 | return NULL; | ||
10097 | |||
10084 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | 10098 | error = kmalloc(sizeof(*error), GFP_ATOMIC); |
10085 | if (error == NULL) | 10099 | if (error == NULL) |
10086 | return NULL; | 10100 | return NULL; |
@@ -10089,9 +10103,6 @@ intel_display_capture_error_state(struct drm_device *dev) | |||
10089 | error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER); | 10103 | error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER); |
10090 | 10104 | ||
10091 | for_each_pipe(i) { | 10105 | for_each_pipe(i) { |
10092 | cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i); | ||
10093 | error->pipe[i].cpu_transcoder = cpu_transcoder; | ||
10094 | |||
10095 | if (INTEL_INFO(dev)->gen <= 6 || IS_VALLEYVIEW(dev)) { | 10106 | if (INTEL_INFO(dev)->gen <= 6 || IS_VALLEYVIEW(dev)) { |
10096 | error->cursor[i].control = I915_READ(CURCNTR(i)); | 10107 | error->cursor[i].control = I915_READ(CURCNTR(i)); |
10097 | error->cursor[i].position = I915_READ(CURPOS(i)); | 10108 | error->cursor[i].position = I915_READ(CURPOS(i)); |
@@ -10115,14 +10126,25 @@ intel_display_capture_error_state(struct drm_device *dev) | |||
10115 | error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i)); | 10126 | error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i)); |
10116 | } | 10127 | } |
10117 | 10128 | ||
10118 | error->pipe[i].conf = I915_READ(PIPECONF(cpu_transcoder)); | ||
10119 | error->pipe[i].source = I915_READ(PIPESRC(i)); | 10129 | error->pipe[i].source = I915_READ(PIPESRC(i)); |
10120 | error->pipe[i].htotal = I915_READ(HTOTAL(cpu_transcoder)); | 10130 | } |
10121 | error->pipe[i].hblank = I915_READ(HBLANK(cpu_transcoder)); | 10131 | |
10122 | error->pipe[i].hsync = I915_READ(HSYNC(cpu_transcoder)); | 10132 | error->num_transcoders = INTEL_INFO(dev)->num_pipes; |
10123 | error->pipe[i].vtotal = I915_READ(VTOTAL(cpu_transcoder)); | 10133 | if (HAS_DDI(dev_priv->dev)) |
10124 | error->pipe[i].vblank = I915_READ(VBLANK(cpu_transcoder)); | 10134 | error->num_transcoders++; /* Account for eDP. */ |
10125 | error->pipe[i].vsync = I915_READ(VSYNC(cpu_transcoder)); | 10135 | |
10136 | for (i = 0; i < error->num_transcoders; i++) { | ||
10137 | enum transcoder cpu_transcoder = transcoders[i]; | ||
10138 | |||
10139 | error->transcoder[i].cpu_transcoder = cpu_transcoder; | ||
10140 | |||
10141 | error->transcoder[i].conf = I915_READ(PIPECONF(cpu_transcoder)); | ||
10142 | error->transcoder[i].htotal = I915_READ(HTOTAL(cpu_transcoder)); | ||
10143 | error->transcoder[i].hblank = I915_READ(HBLANK(cpu_transcoder)); | ||
10144 | error->transcoder[i].hsync = I915_READ(HSYNC(cpu_transcoder)); | ||
10145 | error->transcoder[i].vtotal = I915_READ(VTOTAL(cpu_transcoder)); | ||
10146 | error->transcoder[i].vblank = I915_READ(VBLANK(cpu_transcoder)); | ||
10147 | error->transcoder[i].vsync = I915_READ(VSYNC(cpu_transcoder)); | ||
10126 | } | 10148 | } |
10127 | 10149 | ||
10128 | /* In the code above we read the registers without checking if the power | 10150 | /* In the code above we read the registers without checking if the power |
@@ -10144,22 +10166,16 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, | |||
10144 | { | 10166 | { |
10145 | int i; | 10167 | int i; |
10146 | 10168 | ||
10169 | if (!error) | ||
10170 | return; | ||
10171 | |||
10147 | err_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes); | 10172 | err_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes); |
10148 | if (HAS_POWER_WELL(dev)) | 10173 | if (HAS_POWER_WELL(dev)) |
10149 | err_printf(m, "PWR_WELL_CTL2: %08x\n", | 10174 | err_printf(m, "PWR_WELL_CTL2: %08x\n", |
10150 | error->power_well_driver); | 10175 | error->power_well_driver); |
10151 | for_each_pipe(i) { | 10176 | for_each_pipe(i) { |
10152 | err_printf(m, "Pipe [%d]:\n", i); | 10177 | err_printf(m, "Pipe [%d]:\n", i); |
10153 | err_printf(m, " CPU transcoder: %c\n", | ||
10154 | transcoder_name(error->pipe[i].cpu_transcoder)); | ||
10155 | err_printf(m, " CONF: %08x\n", error->pipe[i].conf); | ||
10156 | err_printf(m, " SRC: %08x\n", error->pipe[i].source); | 10178 | err_printf(m, " SRC: %08x\n", error->pipe[i].source); |
10157 | err_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); | ||
10158 | err_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); | ||
10159 | err_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); | ||
10160 | err_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); | ||
10161 | err_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); | ||
10162 | err_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); | ||
10163 | 10179 | ||
10164 | err_printf(m, "Plane [%d]:\n", i); | 10180 | err_printf(m, "Plane [%d]:\n", i); |
10165 | err_printf(m, " CNTR: %08x\n", error->plane[i].control); | 10181 | err_printf(m, " CNTR: %08x\n", error->plane[i].control); |
@@ -10180,5 +10196,17 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, | |||
10180 | err_printf(m, " POS: %08x\n", error->cursor[i].position); | 10196 | err_printf(m, " POS: %08x\n", error->cursor[i].position); |
10181 | err_printf(m, " BASE: %08x\n", error->cursor[i].base); | 10197 | err_printf(m, " BASE: %08x\n", error->cursor[i].base); |
10182 | } | 10198 | } |
10199 | |||
10200 | for (i = 0; i < error->num_transcoders; i++) { | ||
10201 | err_printf(m, " CPU transcoder: %c\n", | ||
10202 | transcoder_name(error->transcoder[i].cpu_transcoder)); | ||
10203 | err_printf(m, " CONF: %08x\n", error->transcoder[i].conf); | ||
10204 | err_printf(m, " HTOTAL: %08x\n", error->transcoder[i].htotal); | ||
10205 | err_printf(m, " HBLANK: %08x\n", error->transcoder[i].hblank); | ||
10206 | err_printf(m, " HSYNC: %08x\n", error->transcoder[i].hsync); | ||
10207 | err_printf(m, " VTOTAL: %08x\n", error->transcoder[i].vtotal); | ||
10208 | err_printf(m, " VBLANK: %08x\n", error->transcoder[i].vblank); | ||
10209 | err_printf(m, " VSYNC: %08x\n", error->transcoder[i].vsync); | ||
10210 | } | ||
10183 | } | 10211 | } |
10184 | #endif | 10212 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 274b8e1b889f..9f19259667df 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -2163,7 +2163,7 @@ void cik_mm_wdoorbell(struct radeon_device *rdev, u32 offset, u32 v); | |||
2163 | WREG32(reg, tmp_); \ | 2163 | WREG32(reg, tmp_); \ |
2164 | } while (0) | 2164 | } while (0) |
2165 | #define WREG32_AND(reg, and) WREG32_P(reg, 0, and) | 2165 | #define WREG32_AND(reg, and) WREG32_P(reg, 0, and) |
2166 | #define WREG32_OR(reg, or) WREG32_P(reg, or, ~or) | 2166 | #define WREG32_OR(reg, or) WREG32_P(reg, or, ~(or)) |
2167 | #define WREG32_PLL_P(reg, val, mask) \ | 2167 | #define WREG32_PLL_P(reg, val, mask) \ |
2168 | do { \ | 2168 | do { \ |
2169 | uint32_t tmp_ = RREG32_PLL(reg); \ | 2169 | uint32_t tmp_ = RREG32_PLL(reg); \ |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index f1c15754e73c..b79f4f5cdd62 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -356,6 +356,14 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
356 | return -EINVAL; | 356 | return -EINVAL; |
357 | } | 357 | } |
358 | 358 | ||
359 | if (bo->tbo.sync_obj) { | ||
360 | r = radeon_fence_wait(bo->tbo.sync_obj, false); | ||
361 | if (r) { | ||
362 | DRM_ERROR("Failed waiting for UVD message (%d)!\n", r); | ||
363 | return r; | ||
364 | } | ||
365 | } | ||
366 | |||
359 | r = radeon_bo_kmap(bo, &ptr); | 367 | r = radeon_bo_kmap(bo, &ptr); |
360 | if (r) { | 368 | if (r) { |
361 | DRM_ERROR("Failed mapping the UVD message (%d)!\n", r); | 369 | DRM_ERROR("Failed mapping the UVD message (%d)!\n", r); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index bcc68ec204ad..f5e92cfcc140 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -744,10 +744,10 @@ static void rv770_init_golden_registers(struct radeon_device *rdev) | |||
744 | (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers)); | 744 | (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers)); |
745 | radeon_program_register_sequence(rdev, | 745 | radeon_program_register_sequence(rdev, |
746 | rv730_golden_registers, | 746 | rv730_golden_registers, |
747 | (const u32)ARRAY_SIZE(rv770_golden_registers)); | 747 | (const u32)ARRAY_SIZE(rv730_golden_registers)); |
748 | radeon_program_register_sequence(rdev, | 748 | radeon_program_register_sequence(rdev, |
749 | rv730_mgcg_init, | 749 | rv730_mgcg_init, |
750 | (const u32)ARRAY_SIZE(rv770_mgcg_init)); | 750 | (const u32)ARRAY_SIZE(rv730_mgcg_init)); |
751 | break; | 751 | break; |
752 | case CHIP_RV710: | 752 | case CHIP_RV710: |
753 | radeon_program_register_sequence(rdev, | 753 | radeon_program_register_sequence(rdev, |
@@ -758,18 +758,18 @@ static void rv770_init_golden_registers(struct radeon_device *rdev) | |||
758 | (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers)); | 758 | (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers)); |
759 | radeon_program_register_sequence(rdev, | 759 | radeon_program_register_sequence(rdev, |
760 | rv710_golden_registers, | 760 | rv710_golden_registers, |
761 | (const u32)ARRAY_SIZE(rv770_golden_registers)); | 761 | (const u32)ARRAY_SIZE(rv710_golden_registers)); |
762 | radeon_program_register_sequence(rdev, | 762 | radeon_program_register_sequence(rdev, |
763 | rv710_mgcg_init, | 763 | rv710_mgcg_init, |
764 | (const u32)ARRAY_SIZE(rv770_mgcg_init)); | 764 | (const u32)ARRAY_SIZE(rv710_mgcg_init)); |
765 | break; | 765 | break; |
766 | case CHIP_RV740: | 766 | case CHIP_RV740: |
767 | radeon_program_register_sequence(rdev, | 767 | radeon_program_register_sequence(rdev, |
768 | rv740_golden_registers, | 768 | rv740_golden_registers, |
769 | (const u32)ARRAY_SIZE(rv770_golden_registers)); | 769 | (const u32)ARRAY_SIZE(rv740_golden_registers)); |
770 | radeon_program_register_sequence(rdev, | 770 | radeon_program_register_sequence(rdev, |
771 | rv740_mgcg_init, | 771 | rv740_mgcg_init, |
772 | (const u32)ARRAY_SIZE(rv770_mgcg_init)); | 772 | (const u32)ARRAY_SIZE(rv740_mgcg_init)); |
773 | break; | 773 | break; |
774 | default: | 774 | default: |
775 | break; | 775 | break; |
diff --git a/drivers/md/dm-cache-policy-mq.c b/drivers/md/dm-cache-policy-mq.c index dc112a7137fe..4296155090b2 100644 --- a/drivers/md/dm-cache-policy-mq.c +++ b/drivers/md/dm-cache-policy-mq.c | |||
@@ -959,23 +959,21 @@ out: | |||
959 | return r; | 959 | return r; |
960 | } | 960 | } |
961 | 961 | ||
962 | static void remove_mapping(struct mq_policy *mq, dm_oblock_t oblock) | 962 | static void mq_remove_mapping(struct dm_cache_policy *p, dm_oblock_t oblock) |
963 | { | 963 | { |
964 | struct entry *e = hash_lookup(mq, oblock); | 964 | struct mq_policy *mq = to_mq_policy(p); |
965 | struct entry *e; | ||
966 | |||
967 | mutex_lock(&mq->lock); | ||
968 | |||
969 | e = hash_lookup(mq, oblock); | ||
965 | 970 | ||
966 | BUG_ON(!e || !e->in_cache); | 971 | BUG_ON(!e || !e->in_cache); |
967 | 972 | ||
968 | del(mq, e); | 973 | del(mq, e); |
969 | e->in_cache = false; | 974 | e->in_cache = false; |
970 | push(mq, e); | 975 | push(mq, e); |
971 | } | ||
972 | 976 | ||
973 | static void mq_remove_mapping(struct dm_cache_policy *p, dm_oblock_t oblock) | ||
974 | { | ||
975 | struct mq_policy *mq = to_mq_policy(p); | ||
976 | |||
977 | mutex_lock(&mq->lock); | ||
978 | remove_mapping(mq, oblock); | ||
979 | mutex_unlock(&mq->lock); | 977 | mutex_unlock(&mq->lock); |
980 | } | 978 | } |
981 | 979 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 126dec4342e6..12202f81735c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -1333,6 +1333,8 @@ enum { | |||
1333 | BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN, | 1333 | BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN, |
1334 | BNX2X_SP_RTNL_RX_MODE, | 1334 | BNX2X_SP_RTNL_RX_MODE, |
1335 | BNX2X_SP_RTNL_HYPERVISOR_VLAN, | 1335 | BNX2X_SP_RTNL_HYPERVISOR_VLAN, |
1336 | BNX2X_SP_RTNL_TX_STOP, | ||
1337 | BNX2X_SP_RTNL_TX_RESUME, | ||
1336 | }; | 1338 | }; |
1337 | 1339 | ||
1338 | struct bnx2x_prev_path_list { | 1340 | struct bnx2x_prev_path_list { |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index f9122f2d6b65..fcf2761d8828 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c | |||
@@ -30,10 +30,8 @@ | |||
30 | #include "bnx2x_dcb.h" | 30 | #include "bnx2x_dcb.h" |
31 | 31 | ||
32 | /* forward declarations of dcbx related functions */ | 32 | /* forward declarations of dcbx related functions */ |
33 | static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); | ||
34 | static void bnx2x_pfc_set_pfc(struct bnx2x *bp); | 33 | static void bnx2x_pfc_set_pfc(struct bnx2x *bp); |
35 | static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp); | 34 | static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp); |
36 | static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp); | ||
37 | static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, | 35 | static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, |
38 | u32 *set_configuration_ets_pg, | 36 | u32 *set_configuration_ets_pg, |
39 | u32 *pri_pg_tbl); | 37 | u32 *pri_pg_tbl); |
@@ -425,30 +423,52 @@ static void bnx2x_pfc_set_pfc(struct bnx2x *bp) | |||
425 | bnx2x_pfc_clear(bp); | 423 | bnx2x_pfc_clear(bp); |
426 | } | 424 | } |
427 | 425 | ||
428 | static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) | 426 | int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) |
429 | { | 427 | { |
430 | struct bnx2x_func_state_params func_params = {NULL}; | 428 | struct bnx2x_func_state_params func_params = {NULL}; |
429 | int rc; | ||
431 | 430 | ||
432 | func_params.f_obj = &bp->func_obj; | 431 | func_params.f_obj = &bp->func_obj; |
433 | func_params.cmd = BNX2X_F_CMD_TX_STOP; | 432 | func_params.cmd = BNX2X_F_CMD_TX_STOP; |
434 | 433 | ||
434 | __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); | ||
435 | __set_bit(RAMROD_RETRY, &func_params.ramrod_flags); | ||
436 | |||
435 | DP(BNX2X_MSG_DCB, "STOP TRAFFIC\n"); | 437 | DP(BNX2X_MSG_DCB, "STOP TRAFFIC\n"); |
436 | return bnx2x_func_state_change(bp, &func_params); | 438 | |
439 | rc = bnx2x_func_state_change(bp, &func_params); | ||
440 | if (rc) { | ||
441 | BNX2X_ERR("Unable to hold traffic for HW configuration\n"); | ||
442 | bnx2x_panic(); | ||
443 | } | ||
444 | |||
445 | return rc; | ||
437 | } | 446 | } |
438 | 447 | ||
439 | static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) | 448 | int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) |
440 | { | 449 | { |
441 | struct bnx2x_func_state_params func_params = {NULL}; | 450 | struct bnx2x_func_state_params func_params = {NULL}; |
442 | struct bnx2x_func_tx_start_params *tx_params = | 451 | struct bnx2x_func_tx_start_params *tx_params = |
443 | &func_params.params.tx_start; | 452 | &func_params.params.tx_start; |
453 | int rc; | ||
444 | 454 | ||
445 | func_params.f_obj = &bp->func_obj; | 455 | func_params.f_obj = &bp->func_obj; |
446 | func_params.cmd = BNX2X_F_CMD_TX_START; | 456 | func_params.cmd = BNX2X_F_CMD_TX_START; |
447 | 457 | ||
458 | __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); | ||
459 | __set_bit(RAMROD_RETRY, &func_params.ramrod_flags); | ||
460 | |||
448 | bnx2x_dcbx_fw_struct(bp, tx_params); | 461 | bnx2x_dcbx_fw_struct(bp, tx_params); |
449 | 462 | ||
450 | DP(BNX2X_MSG_DCB, "START TRAFFIC\n"); | 463 | DP(BNX2X_MSG_DCB, "START TRAFFIC\n"); |
451 | return bnx2x_func_state_change(bp, &func_params); | 464 | |
465 | rc = bnx2x_func_state_change(bp, &func_params); | ||
466 | if (rc) { | ||
467 | BNX2X_ERR("Unable to resume traffic after HW configuration\n"); | ||
468 | bnx2x_panic(); | ||
469 | } | ||
470 | |||
471 | return rc; | ||
452 | } | 472 | } |
453 | 473 | ||
454 | static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp) | 474 | static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp) |
@@ -744,7 +764,9 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) | |||
744 | if (IS_MF(bp)) | 764 | if (IS_MF(bp)) |
745 | bnx2x_link_sync_notify(bp); | 765 | bnx2x_link_sync_notify(bp); |
746 | 766 | ||
747 | bnx2x_dcbx_stop_hw_tx(bp); | 767 | set_bit(BNX2X_SP_RTNL_TX_STOP, &bp->sp_rtnl_state); |
768 | |||
769 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
748 | 770 | ||
749 | return; | 771 | return; |
750 | } | 772 | } |
@@ -757,7 +779,9 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) | |||
757 | /* ets may affect cmng configuration: reinit it in hw */ | 779 | /* ets may affect cmng configuration: reinit it in hw */ |
758 | bnx2x_set_local_cmng(bp); | 780 | bnx2x_set_local_cmng(bp); |
759 | 781 | ||
760 | bnx2x_dcbx_resume_hw_tx(bp); | 782 | set_bit(BNX2X_SP_RTNL_TX_RESUME, &bp->sp_rtnl_state); |
783 | |||
784 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
761 | 785 | ||
762 | return; | 786 | return; |
763 | case BNX2X_DCBX_STATE_TX_RELEASED: | 787 | case BNX2X_DCBX_STATE_TX_RELEASED: |
@@ -2367,21 +2391,24 @@ static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid, | |||
2367 | case DCB_FEATCFG_ATTR_PG: | 2391 | case DCB_FEATCFG_ATTR_PG: |
2368 | if (bp->dcbx_local_feat.ets.enabled) | 2392 | if (bp->dcbx_local_feat.ets.enabled) |
2369 | *flags |= DCB_FEATCFG_ENABLE; | 2393 | *flags |= DCB_FEATCFG_ENABLE; |
2370 | if (bp->dcbx_error & DCBX_LOCAL_ETS_ERROR) | 2394 | if (bp->dcbx_error & (DCBX_LOCAL_ETS_ERROR | |
2395 | DCBX_REMOTE_MIB_ERROR)) | ||
2371 | *flags |= DCB_FEATCFG_ERROR; | 2396 | *flags |= DCB_FEATCFG_ERROR; |
2372 | break; | 2397 | break; |
2373 | case DCB_FEATCFG_ATTR_PFC: | 2398 | case DCB_FEATCFG_ATTR_PFC: |
2374 | if (bp->dcbx_local_feat.pfc.enabled) | 2399 | if (bp->dcbx_local_feat.pfc.enabled) |
2375 | *flags |= DCB_FEATCFG_ENABLE; | 2400 | *flags |= DCB_FEATCFG_ENABLE; |
2376 | if (bp->dcbx_error & (DCBX_LOCAL_PFC_ERROR | | 2401 | if (bp->dcbx_error & (DCBX_LOCAL_PFC_ERROR | |
2377 | DCBX_LOCAL_PFC_MISMATCH)) | 2402 | DCBX_LOCAL_PFC_MISMATCH | |
2403 | DCBX_REMOTE_MIB_ERROR)) | ||
2378 | *flags |= DCB_FEATCFG_ERROR; | 2404 | *flags |= DCB_FEATCFG_ERROR; |
2379 | break; | 2405 | break; |
2380 | case DCB_FEATCFG_ATTR_APP: | 2406 | case DCB_FEATCFG_ATTR_APP: |
2381 | if (bp->dcbx_local_feat.app.enabled) | 2407 | if (bp->dcbx_local_feat.app.enabled) |
2382 | *flags |= DCB_FEATCFG_ENABLE; | 2408 | *flags |= DCB_FEATCFG_ENABLE; |
2383 | if (bp->dcbx_error & (DCBX_LOCAL_APP_ERROR | | 2409 | if (bp->dcbx_error & (DCBX_LOCAL_APP_ERROR | |
2384 | DCBX_LOCAL_APP_MISMATCH)) | 2410 | DCBX_LOCAL_APP_MISMATCH | |
2411 | DCBX_REMOTE_MIB_ERROR)) | ||
2385 | *flags |= DCB_FEATCFG_ERROR; | 2412 | *flags |= DCB_FEATCFG_ERROR; |
2386 | break; | 2413 | break; |
2387 | default: | 2414 | default: |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h index 125bd1b6586f..804b8f64463e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h | |||
@@ -199,4 +199,7 @@ extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops; | |||
199 | int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall); | 199 | int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall); |
200 | #endif /* BCM_DCBNL */ | 200 | #endif /* BCM_DCBNL */ |
201 | 201 | ||
202 | int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); | ||
203 | int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp); | ||
204 | |||
202 | #endif /* BNX2X_DCB_H */ | 205 | #endif /* BNX2X_DCB_H */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 7f4ec80f0cb3..17f117c1d8d2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -2261,6 +2261,23 @@ static void bnx2x_set_requested_fc(struct bnx2x *bp) | |||
2261 | bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH; | 2261 | bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH; |
2262 | } | 2262 | } |
2263 | 2263 | ||
2264 | static void bnx2x_init_dropless_fc(struct bnx2x *bp) | ||
2265 | { | ||
2266 | u32 pause_enabled = 0; | ||
2267 | |||
2268 | if (!CHIP_IS_E1(bp) && bp->dropless_fc && bp->link_vars.link_up) { | ||
2269 | if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) | ||
2270 | pause_enabled = 1; | ||
2271 | |||
2272 | REG_WR(bp, BAR_USTRORM_INTMEM + | ||
2273 | USTORM_ETH_PAUSE_ENABLED_OFFSET(BP_PORT(bp)), | ||
2274 | pause_enabled); | ||
2275 | } | ||
2276 | |||
2277 | DP(NETIF_MSG_IFUP | NETIF_MSG_LINK, "dropless_fc is %s\n", | ||
2278 | pause_enabled ? "enabled" : "disabled"); | ||
2279 | } | ||
2280 | |||
2264 | int bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) | 2281 | int bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) |
2265 | { | 2282 | { |
2266 | int rc, cfx_idx = bnx2x_get_link_cfg_idx(bp); | 2283 | int rc, cfx_idx = bnx2x_get_link_cfg_idx(bp); |
@@ -2294,6 +2311,8 @@ int bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) | |||
2294 | 2311 | ||
2295 | bnx2x_release_phy_lock(bp); | 2312 | bnx2x_release_phy_lock(bp); |
2296 | 2313 | ||
2314 | bnx2x_init_dropless_fc(bp); | ||
2315 | |||
2297 | bnx2x_calc_fc_adv(bp); | 2316 | bnx2x_calc_fc_adv(bp); |
2298 | 2317 | ||
2299 | if (bp->link_vars.link_up) { | 2318 | if (bp->link_vars.link_up) { |
@@ -2315,6 +2334,8 @@ void bnx2x_link_set(struct bnx2x *bp) | |||
2315 | bnx2x_phy_init(&bp->link_params, &bp->link_vars); | 2334 | bnx2x_phy_init(&bp->link_params, &bp->link_vars); |
2316 | bnx2x_release_phy_lock(bp); | 2335 | bnx2x_release_phy_lock(bp); |
2317 | 2336 | ||
2337 | bnx2x_init_dropless_fc(bp); | ||
2338 | |||
2318 | bnx2x_calc_fc_adv(bp); | 2339 | bnx2x_calc_fc_adv(bp); |
2319 | } else | 2340 | } else |
2320 | BNX2X_ERR("Bootcode is missing - can not set link\n"); | 2341 | BNX2X_ERR("Bootcode is missing - can not set link\n"); |
@@ -2556,20 +2577,9 @@ static void bnx2x_link_attn(struct bnx2x *bp) | |||
2556 | 2577 | ||
2557 | bnx2x_link_update(&bp->link_params, &bp->link_vars); | 2578 | bnx2x_link_update(&bp->link_params, &bp->link_vars); |
2558 | 2579 | ||
2559 | if (bp->link_vars.link_up) { | 2580 | bnx2x_init_dropless_fc(bp); |
2560 | 2581 | ||
2561 | /* dropless flow control */ | 2582 | if (bp->link_vars.link_up) { |
2562 | if (!CHIP_IS_E1(bp) && bp->dropless_fc) { | ||
2563 | int port = BP_PORT(bp); | ||
2564 | u32 pause_enabled = 0; | ||
2565 | |||
2566 | if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) | ||
2567 | pause_enabled = 1; | ||
2568 | |||
2569 | REG_WR(bp, BAR_USTRORM_INTMEM + | ||
2570 | USTORM_ETH_PAUSE_ENABLED_OFFSET(port), | ||
2571 | pause_enabled); | ||
2572 | } | ||
2573 | 2583 | ||
2574 | if (bp->link_vars.mac_type != MAC_TYPE_EMAC) { | 2584 | if (bp->link_vars.mac_type != MAC_TYPE_EMAC) { |
2575 | struct host_port_stats *pstats; | 2585 | struct host_port_stats *pstats; |
@@ -9643,6 +9653,12 @@ sp_rtnl_not_reset: | |||
9643 | &bp->sp_rtnl_state)) | 9653 | &bp->sp_rtnl_state)) |
9644 | bnx2x_pf_set_vfs_vlan(bp); | 9654 | bnx2x_pf_set_vfs_vlan(bp); |
9645 | 9655 | ||
9656 | if (test_and_clear_bit(BNX2X_SP_RTNL_TX_STOP, &bp->sp_rtnl_state)) | ||
9657 | bnx2x_dcbx_stop_hw_tx(bp); | ||
9658 | |||
9659 | if (test_and_clear_bit(BNX2X_SP_RTNL_TX_RESUME, &bp->sp_rtnl_state)) | ||
9660 | bnx2x_dcbx_resume_hw_tx(bp); | ||
9661 | |||
9646 | /* work which needs rtnl lock not-taken (as it takes the lock itself and | 9662 | /* work which needs rtnl lock not-taken (as it takes the lock itself and |
9647 | * can be called from other contexts as well) | 9663 | * can be called from other contexts as well) |
9648 | */ | 9664 | */ |
@@ -11145,6 +11161,9 @@ static bool bnx2x_get_dropless_info(struct bnx2x *bp) | |||
11145 | int tmp; | 11161 | int tmp; |
11146 | u32 cfg; | 11162 | u32 cfg; |
11147 | 11163 | ||
11164 | if (IS_VF(bp)) | ||
11165 | return 0; | ||
11166 | |||
11148 | if (IS_MF(bp) && !CHIP_IS_E1x(bp)) { | 11167 | if (IS_MF(bp) && !CHIP_IS_E1x(bp)) { |
11149 | /* Take function: tmp = func */ | 11168 | /* Take function: tmp = func */ |
11150 | tmp = BP_ABS_FUNC(bp); | 11169 | tmp = BP_ABS_FUNC(bp); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 1d925fd9cdc6..fbc026c4cab2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | |||
@@ -1755,11 +1755,8 @@ void bnx2x_iov_init_dq(struct bnx2x *bp) | |||
1755 | 1755 | ||
1756 | void bnx2x_iov_init_dmae(struct bnx2x *bp) | 1756 | void bnx2x_iov_init_dmae(struct bnx2x *bp) |
1757 | { | 1757 | { |
1758 | DP(BNX2X_MSG_IOV, "SRIOV is %s\n", IS_SRIOV(bp) ? "ON" : "OFF"); | 1758 | if (pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV)) |
1759 | if (!IS_SRIOV(bp)) | 1759 | REG_WR(bp, DMAE_REG_BACKWARD_COMP_EN, 0); |
1760 | return; | ||
1761 | |||
1762 | REG_WR(bp, DMAE_REG_BACKWARD_COMP_EN, 0); | ||
1763 | } | 1760 | } |
1764 | 1761 | ||
1765 | static int bnx2x_vf_bus(struct bnx2x *bp, int vfid) | 1762 | static int bnx2x_vf_bus(struct bnx2x *bp, int vfid) |
@@ -3092,8 +3089,9 @@ void bnx2x_disable_sriov(struct bnx2x *bp) | |||
3092 | pci_disable_sriov(bp->pdev); | 3089 | pci_disable_sriov(bp->pdev); |
3093 | } | 3090 | } |
3094 | 3091 | ||
3095 | static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx, | 3092 | static int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx, |
3096 | struct bnx2x_virtf *vf) | 3093 | struct bnx2x_virtf **vf, |
3094 | struct pf_vf_bulletin_content **bulletin) | ||
3097 | { | 3095 | { |
3098 | if (bp->state != BNX2X_STATE_OPEN) { | 3096 | if (bp->state != BNX2X_STATE_OPEN) { |
3099 | BNX2X_ERR("vf ndo called though PF is down\n"); | 3097 | BNX2X_ERR("vf ndo called though PF is down\n"); |
@@ -3111,12 +3109,22 @@ static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx, | |||
3111 | return -EINVAL; | 3109 | return -EINVAL; |
3112 | } | 3110 | } |
3113 | 3111 | ||
3114 | if (!vf) { | 3112 | /* init members */ |
3113 | *vf = BP_VF(bp, vfidx); | ||
3114 | *bulletin = BP_VF_BULLETIN(bp, vfidx); | ||
3115 | |||
3116 | if (!*vf) { | ||
3115 | BNX2X_ERR("vf ndo called but vf was null. vfidx was %d\n", | 3117 | BNX2X_ERR("vf ndo called but vf was null. vfidx was %d\n", |
3116 | vfidx); | 3118 | vfidx); |
3117 | return -EINVAL; | 3119 | return -EINVAL; |
3118 | } | 3120 | } |
3119 | 3121 | ||
3122 | if (!*bulletin) { | ||
3123 | BNX2X_ERR("vf ndo called but Bulletin Board struct is null. vfidx was %d\n", | ||
3124 | vfidx); | ||
3125 | return -EINVAL; | ||
3126 | } | ||
3127 | |||
3120 | return 0; | 3128 | return 0; |
3121 | } | 3129 | } |
3122 | 3130 | ||
@@ -3124,17 +3132,19 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx, | |||
3124 | struct ifla_vf_info *ivi) | 3132 | struct ifla_vf_info *ivi) |
3125 | { | 3133 | { |
3126 | struct bnx2x *bp = netdev_priv(dev); | 3134 | struct bnx2x *bp = netdev_priv(dev); |
3127 | struct bnx2x_virtf *vf = BP_VF(bp, vfidx); | 3135 | struct bnx2x_virtf *vf = NULL; |
3128 | struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj); | 3136 | struct pf_vf_bulletin_content *bulletin = NULL; |
3129 | struct bnx2x_vlan_mac_obj *vlan_obj = &bnx2x_vfq(vf, 0, vlan_obj); | 3137 | struct bnx2x_vlan_mac_obj *mac_obj; |
3130 | struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx); | 3138 | struct bnx2x_vlan_mac_obj *vlan_obj; |
3131 | int rc; | 3139 | int rc; |
3132 | 3140 | ||
3133 | /* sanity */ | 3141 | /* sanity and init */ |
3134 | rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf); | 3142 | rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin); |
3135 | if (rc) | 3143 | if (rc) |
3136 | return rc; | 3144 | return rc; |
3137 | if (!mac_obj || !vlan_obj || !bulletin) { | 3145 | mac_obj = &bnx2x_vfq(vf, 0, mac_obj); |
3146 | vlan_obj = &bnx2x_vfq(vf, 0, vlan_obj); | ||
3147 | if (!mac_obj || !vlan_obj) { | ||
3138 | BNX2X_ERR("VF partially initialized\n"); | 3148 | BNX2X_ERR("VF partially initialized\n"); |
3139 | return -EINVAL; | 3149 | return -EINVAL; |
3140 | } | 3150 | } |
@@ -3191,11 +3201,11 @@ int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac) | |||
3191 | { | 3201 | { |
3192 | struct bnx2x *bp = netdev_priv(dev); | 3202 | struct bnx2x *bp = netdev_priv(dev); |
3193 | int rc, q_logical_state; | 3203 | int rc, q_logical_state; |
3194 | struct bnx2x_virtf *vf = BP_VF(bp, vfidx); | 3204 | struct bnx2x_virtf *vf = NULL; |
3195 | struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx); | 3205 | struct pf_vf_bulletin_content *bulletin = NULL; |
3196 | 3206 | ||
3197 | /* sanity */ | 3207 | /* sanity and init */ |
3198 | rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf); | 3208 | rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin); |
3199 | if (rc) | 3209 | if (rc) |
3200 | return rc; | 3210 | return rc; |
3201 | if (!is_valid_ether_addr(mac)) { | 3211 | if (!is_valid_ether_addr(mac)) { |
@@ -3257,11 +3267,11 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos) | |||
3257 | { | 3267 | { |
3258 | struct bnx2x *bp = netdev_priv(dev); | 3268 | struct bnx2x *bp = netdev_priv(dev); |
3259 | int rc, q_logical_state; | 3269 | int rc, q_logical_state; |
3260 | struct bnx2x_virtf *vf = BP_VF(bp, vfidx); | 3270 | struct bnx2x_virtf *vf = NULL; |
3261 | struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx); | 3271 | struct pf_vf_bulletin_content *bulletin = NULL; |
3262 | 3272 | ||
3263 | /* sanity */ | 3273 | /* sanity and init */ |
3264 | rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf); | 3274 | rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin); |
3265 | if (rc) | 3275 | if (rc) |
3266 | return rc; | 3276 | return rc; |
3267 | 3277 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index ff2b40db38ba..08f64178c7a1 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -2556,8 +2556,8 @@ static int be_close(struct net_device *netdev) | |||
2556 | /* Wait for all pending tx completions to arrive so that | 2556 | /* Wait for all pending tx completions to arrive so that |
2557 | * all tx skbs are freed. | 2557 | * all tx skbs are freed. |
2558 | */ | 2558 | */ |
2559 | be_tx_compl_clean(adapter); | ||
2560 | netif_tx_disable(netdev); | 2559 | netif_tx_disable(netdev); |
2560 | be_tx_compl_clean(adapter); | ||
2561 | 2561 | ||
2562 | be_rx_qs_destroy(adapter); | 2562 | be_rx_qs_destroy(adapter); |
2563 | 2563 | ||
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index c0c9e145fd3b..6f87f2cde647 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -7089,7 +7089,7 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
7089 | 7089 | ||
7090 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 7090 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
7091 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); | 7091 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); |
7092 | RTL_W8(Config5, RTL_R8(Config5) & PMEStatus); | 7092 | RTL_W8(Config5, RTL_R8(Config5) & (BWF | MWF | UWF | LanWake | PMEStatus)); |
7093 | if ((RTL_R8(Config3) & (LinkUp | MagicPacket)) != 0) | 7093 | if ((RTL_R8(Config3) & (LinkUp | MagicPacket)) != 0) |
7094 | tp->features |= RTL_FEATURE_WOL; | 7094 | tp->features |= RTL_FEATURE_WOL; |
7095 | if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) | 7095 | if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) |
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 51f2bc376101..2dcc60fb37f1 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c | |||
@@ -210,8 +210,7 @@ static int via_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) | |||
210 | pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0)); | 210 | pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0)); |
211 | pci_write_config_byte(pcidev,0x5a,0xc0); | 211 | pci_write_config_byte(pcidev,0x5a,0xc0); |
212 | WriteLPCReg(0x28, 0x70 ); | 212 | WriteLPCReg(0x28, 0x70 ); |
213 | if (via_ircc_open(pcidev, &info, 0x3076) == 0) | 213 | rc = via_ircc_open(pcidev, &info, 0x3076); |
214 | rc=0; | ||
215 | } else | 214 | } else |
216 | rc = -ENODEV; //IR not turn on | 215 | rc = -ENODEV; //IR not turn on |
217 | } else { //Not VT1211 | 216 | } else { //Not VT1211 |
@@ -249,8 +248,7 @@ static int via_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) | |||
249 | info.irq=FirIRQ; | 248 | info.irq=FirIRQ; |
250 | info.dma=FirDRQ1; | 249 | info.dma=FirDRQ1; |
251 | info.dma2=FirDRQ0; | 250 | info.dma2=FirDRQ0; |
252 | if (via_ircc_open(pcidev, &info, 0x3096) == 0) | 251 | rc = via_ircc_open(pcidev, &info, 0x3096); |
253 | rc=0; | ||
254 | } else | 252 | } else |
255 | rc = -ENODEV; //IR not turn on !!!!! | 253 | rc = -ENODEV; //IR not turn on !!!!! |
256 | }//Not VT1211 | 254 | }//Not VT1211 |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 1c6e1116eb0a..9dccb1edfd2a 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -68,6 +68,8 @@ static const struct proto_ops macvtap_socket_ops; | |||
68 | #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ | 68 | #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ |
69 | NETIF_F_TSO6 | NETIF_F_UFO) | 69 | NETIF_F_TSO6 | NETIF_F_UFO) |
70 | #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO) | 70 | #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO) |
71 | #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG) | ||
72 | |||
71 | /* | 73 | /* |
72 | * RCU usage: | 74 | * RCU usage: |
73 | * The macvtap_queue and the macvlan_dev are loosely coupled, the | 75 | * The macvtap_queue and the macvlan_dev are loosely coupled, the |
@@ -278,7 +280,8 @@ static int macvtap_forward(struct net_device *dev, struct sk_buff *skb) | |||
278 | { | 280 | { |
279 | struct macvlan_dev *vlan = netdev_priv(dev); | 281 | struct macvlan_dev *vlan = netdev_priv(dev); |
280 | struct macvtap_queue *q = macvtap_get_queue(dev, skb); | 282 | struct macvtap_queue *q = macvtap_get_queue(dev, skb); |
281 | netdev_features_t features; | 283 | netdev_features_t features = TAP_FEATURES; |
284 | |||
282 | if (!q) | 285 | if (!q) |
283 | goto drop; | 286 | goto drop; |
284 | 287 | ||
@@ -287,9 +290,11 @@ static int macvtap_forward(struct net_device *dev, struct sk_buff *skb) | |||
287 | 290 | ||
288 | skb->dev = dev; | 291 | skb->dev = dev; |
289 | /* Apply the forward feature mask so that we perform segmentation | 292 | /* Apply the forward feature mask so that we perform segmentation |
290 | * according to users wishes. | 293 | * according to users wishes. This only works if VNET_HDR is |
294 | * enabled. | ||
291 | */ | 295 | */ |
292 | features = netif_skb_features(skb) & vlan->tap_features; | 296 | if (q->flags & IFF_VNET_HDR) |
297 | features |= vlan->tap_features; | ||
293 | if (netif_needs_gso(skb, features)) { | 298 | if (netif_needs_gso(skb, features)) { |
294 | struct sk_buff *segs = __skb_gso_segment(skb, features, false); | 299 | struct sk_buff *segs = __skb_gso_segment(skb, features, false); |
295 | 300 | ||
@@ -961,8 +966,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg) | |||
961 | /* tap_features are the same as features on tun/tap and | 966 | /* tap_features are the same as features on tun/tap and |
962 | * reflect user expectations. | 967 | * reflect user expectations. |
963 | */ | 968 | */ |
964 | vlan->tap_features = vlan->dev->features & | 969 | vlan->tap_features = feature_mask; |
965 | (feature_mask | ~TUN_OFFLOADS); | ||
966 | vlan->set_features = features; | 970 | vlan->set_features = features; |
967 | netdev_update_features(vlan->dev); | 971 | netdev_update_features(vlan->dev); |
968 | 972 | ||
@@ -1058,10 +1062,6 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, | |||
1058 | TUN_F_TSO_ECN | TUN_F_UFO)) | 1062 | TUN_F_TSO_ECN | TUN_F_UFO)) |
1059 | return -EINVAL; | 1063 | return -EINVAL; |
1060 | 1064 | ||
1061 | /* TODO: only accept frames with the features that | ||
1062 | got enabled for forwarded frames */ | ||
1063 | if (!(q->flags & IFF_VNET_HDR)) | ||
1064 | return -EINVAL; | ||
1065 | rtnl_lock(); | 1065 | rtnl_lock(); |
1066 | ret = set_offload(q, arg); | 1066 | ret = set_offload(q, arg); |
1067 | rtnl_unlock(); | 1067 | rtnl_unlock(); |
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 8e7af8354342..138de837977f 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #define RTL821x_INER_INIT 0x6400 | 23 | #define RTL821x_INER_INIT 0x6400 |
24 | #define RTL821x_INSR 0x13 | 24 | #define RTL821x_INSR 0x13 |
25 | 25 | ||
26 | #define RTL8211E_INER_LINK_STAT 0x10 | 26 | #define RTL8211E_INER_LINK_STATUS 0x400 |
27 | 27 | ||
28 | MODULE_DESCRIPTION("Realtek PHY driver"); | 28 | MODULE_DESCRIPTION("Realtek PHY driver"); |
29 | MODULE_AUTHOR("Johnson Leung"); | 29 | MODULE_AUTHOR("Johnson Leung"); |
@@ -57,7 +57,7 @@ static int rtl8211e_config_intr(struct phy_device *phydev) | |||
57 | 57 | ||
58 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | 58 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) |
59 | err = phy_write(phydev, RTL821x_INER, | 59 | err = phy_write(phydev, RTL821x_INER, |
60 | RTL8211E_INER_LINK_STAT); | 60 | RTL8211E_INER_LINK_STATUS); |
61 | else | 61 | else |
62 | err = phy_write(phydev, RTL821x_INER, 0); | 62 | err = phy_write(phydev, RTL821x_INER, 0); |
63 | 63 | ||
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index cba1d46e672e..86292e6aaf49 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -2816,13 +2816,16 @@ exit: | |||
2816 | static int hso_get_config_data(struct usb_interface *interface) | 2816 | static int hso_get_config_data(struct usb_interface *interface) |
2817 | { | 2817 | { |
2818 | struct usb_device *usbdev = interface_to_usbdev(interface); | 2818 | struct usb_device *usbdev = interface_to_usbdev(interface); |
2819 | u8 config_data[17]; | 2819 | u8 *config_data = kmalloc(17, GFP_KERNEL); |
2820 | u32 if_num = interface->altsetting->desc.bInterfaceNumber; | 2820 | u32 if_num = interface->altsetting->desc.bInterfaceNumber; |
2821 | s32 result; | 2821 | s32 result; |
2822 | 2822 | ||
2823 | if (!config_data) | ||
2824 | return -ENOMEM; | ||
2823 | if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), | 2825 | if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), |
2824 | 0x86, 0xC0, 0, 0, config_data, 17, | 2826 | 0x86, 0xC0, 0, 0, config_data, 17, |
2825 | USB_CTRL_SET_TIMEOUT) != 0x11) { | 2827 | USB_CTRL_SET_TIMEOUT) != 0x11) { |
2828 | kfree(config_data); | ||
2826 | return -EIO; | 2829 | return -EIO; |
2827 | } | 2830 | } |
2828 | 2831 | ||
@@ -2873,6 +2876,7 @@ static int hso_get_config_data(struct usb_interface *interface) | |||
2873 | if (config_data[16] & 0x1) | 2876 | if (config_data[16] & 0x1) |
2874 | result |= HSO_INFO_CRC_BUG; | 2877 | result |= HSO_INFO_CRC_BUG; |
2875 | 2878 | ||
2879 | kfree(config_data); | ||
2876 | return result; | 2880 | return result; |
2877 | } | 2881 | } |
2878 | 2882 | ||
@@ -2886,6 +2890,11 @@ static int hso_probe(struct usb_interface *interface, | |||
2886 | struct hso_shared_int *shared_int; | 2890 | struct hso_shared_int *shared_int; |
2887 | struct hso_device *tmp_dev = NULL; | 2891 | struct hso_device *tmp_dev = NULL; |
2888 | 2892 | ||
2893 | if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) { | ||
2894 | dev_err(&interface->dev, "Not our interface\n"); | ||
2895 | return -ENODEV; | ||
2896 | } | ||
2897 | |||
2889 | if_num = interface->altsetting->desc.bInterfaceNumber; | 2898 | if_num = interface->altsetting->desc.bInterfaceNumber; |
2890 | 2899 | ||
2891 | /* Get the interface/port specification from either driver_info or from | 2900 | /* Get the interface/port specification from either driver_info or from |
@@ -2895,10 +2904,6 @@ static int hso_probe(struct usb_interface *interface, | |||
2895 | else | 2904 | else |
2896 | port_spec = hso_get_config_data(interface); | 2905 | port_spec = hso_get_config_data(interface); |
2897 | 2906 | ||
2898 | if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) { | ||
2899 | dev_err(&interface->dev, "Not our interface\n"); | ||
2900 | return -ENODEV; | ||
2901 | } | ||
2902 | /* Check if we need to switch to alt interfaces prior to port | 2907 | /* Check if we need to switch to alt interfaces prior to port |
2903 | * configuration */ | 2908 | * configuration */ |
2904 | if (interface->num_altsetting > 1) | 2909 | if (interface->num_altsetting > 1) |
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index ac074731335a..e5090309824e 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c | |||
@@ -523,9 +523,9 @@ static int prism2_ioctl_giwaplist(struct net_device *dev, | |||
523 | 523 | ||
524 | data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1); | 524 | data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1); |
525 | 525 | ||
526 | memcpy(extra, &addr, sizeof(struct sockaddr) * data->length); | 526 | memcpy(extra, addr, sizeof(struct sockaddr) * data->length); |
527 | data->flags = 1; /* has quality information */ | 527 | data->flags = 1; /* has quality information */ |
528 | memcpy(extra + sizeof(struct sockaddr) * data->length, &qual, | 528 | memcpy(extra + sizeof(struct sockaddr) * data->length, qual, |
529 | sizeof(struct iw_quality) * data->length); | 529 | sizeof(struct iw_quality) * data->length); |
530 | 530 | ||
531 | kfree(addr); | 531 | kfree(addr); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index f0a2c957d503..cae4d3182e33 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -1024,7 +1024,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) | |||
1024 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 1024 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1025 | return; | 1025 | return; |
1026 | 1026 | ||
1027 | if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) | 1027 | if (!test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
1028 | return; | ||
1029 | |||
1030 | if (ctx->vif) | ||
1028 | ieee80211_chswitch_done(ctx->vif, is_success); | 1031 | ieee80211_chswitch_done(ctx->vif, is_success); |
1029 | } | 1032 | } |
1030 | 1033 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index a70c7b9d9bad..ff8cc75c189d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -97,8 +97,6 @@ | |||
97 | 97 | ||
98 | #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) | 98 | #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) |
99 | 99 | ||
100 | #define APMG_RTC_INT_STT_RFKILL (0x10000000) | ||
101 | |||
102 | /* Device system time */ | 100 | /* Device system time */ |
103 | #define DEVICE_SYSTEM_TIME_REG 0xA0206C | 101 | #define DEVICE_SYSTEM_TIME_REG 0xA0206C |
104 | 102 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index ad9bbca99213..7fd6fbfbc1b3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
@@ -138,6 +138,20 @@ static void iwl_mvm_roc_finished(struct iwl_mvm *mvm) | |||
138 | schedule_work(&mvm->roc_done_wk); | 138 | schedule_work(&mvm->roc_done_wk); |
139 | } | 139 | } |
140 | 140 | ||
141 | static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm, | ||
142 | struct ieee80211_vif *vif, | ||
143 | const char *errmsg) | ||
144 | { | ||
145 | if (vif->type != NL80211_IFTYPE_STATION) | ||
146 | return false; | ||
147 | if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) | ||
148 | return false; | ||
149 | if (errmsg) | ||
150 | IWL_ERR(mvm, "%s\n", errmsg); | ||
151 | ieee80211_connection_loss(vif); | ||
152 | return true; | ||
153 | } | ||
154 | |||
141 | /* | 155 | /* |
142 | * Handles a FW notification for an event that is known to the driver. | 156 | * Handles a FW notification for an event that is known to the driver. |
143 | * | 157 | * |
@@ -163,8 +177,13 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
163 | * P2P Device discoveribility, while there are other higher priority | 177 | * P2P Device discoveribility, while there are other higher priority |
164 | * events in the system). | 178 | * events in the system). |
165 | */ | 179 | */ |
166 | WARN_ONCE(!le32_to_cpu(notif->status), | 180 | if (WARN_ONCE(!le32_to_cpu(notif->status), |
167 | "Failed to schedule time event\n"); | 181 | "Failed to schedule time event\n")) { |
182 | if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, NULL)) { | ||
183 | iwl_mvm_te_clear_data(mvm, te_data); | ||
184 | return; | ||
185 | } | ||
186 | } | ||
168 | 187 | ||
169 | if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) { | 188 | if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) { |
170 | IWL_DEBUG_TE(mvm, | 189 | IWL_DEBUG_TE(mvm, |
@@ -180,14 +199,8 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
180 | * By now, we should have finished association | 199 | * By now, we should have finished association |
181 | * and know the dtim period. | 200 | * and know the dtim period. |
182 | */ | 201 | */ |
183 | if (te_data->vif->type == NL80211_IFTYPE_STATION && | 202 | iwl_mvm_te_check_disconnect(mvm, te_data->vif, |
184 | (!te_data->vif->bss_conf.assoc || | 203 | "No assocation and the time event is over already..."); |
185 | !te_data->vif->bss_conf.dtim_period)) { | ||
186 | IWL_ERR(mvm, | ||
187 | "No assocation and the time event is over already...\n"); | ||
188 | ieee80211_connection_loss(te_data->vif); | ||
189 | } | ||
190 | |||
191 | iwl_mvm_te_clear_data(mvm, te_data); | 204 | iwl_mvm_te_clear_data(mvm, te_data); |
192 | } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) { | 205 | } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) { |
193 | te_data->running = true; | 206 | te_data->running = true; |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 68837d4e9fa0..5fdb4eea146d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -888,14 +888,6 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) | |||
888 | 888 | ||
889 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 889 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
890 | if (hw_rfkill) { | 890 | if (hw_rfkill) { |
891 | /* | ||
892 | * Clear the interrupt in APMG if the NIC is going down. | ||
893 | * Note that when the NIC exits RFkill (else branch), we | ||
894 | * can't access prph and the NIC will be reset in | ||
895 | * start_hw anyway. | ||
896 | */ | ||
897 | iwl_write_prph(trans, APMG_RTC_INT_STT_REG, | ||
898 | APMG_RTC_INT_STT_RFKILL); | ||
899 | set_bit(STATUS_RFKILL, &trans_pcie->status); | 891 | set_bit(STATUS_RFKILL, &trans_pcie->status); |
900 | if (test_and_clear_bit(STATUS_HCMD_ACTIVE, | 892 | if (test_and_clear_bit(STATUS_HCMD_ACTIVE, |
901 | &trans_pcie->status)) | 893 | &trans_pcie->status)) |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index e52d1ce1501c..eca44299c512 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -1416,6 +1416,11 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1416 | goto out_no_pci; | 1416 | goto out_no_pci; |
1417 | } | 1417 | } |
1418 | 1418 | ||
1419 | /* W/A - seems to solve weird behavior. We need to remove this if we | ||
1420 | * don't want to stay in L1 all the time. This wastes a lot of power */ | ||
1421 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | | ||
1422 | PCIE_LINK_STATE_CLKPM); | ||
1423 | |||
1419 | pci_set_master(pdev); | 1424 | pci_set_master(pdev); |
1420 | 1425 | ||
1421 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); | 1426 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); |
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 4941f201d6c8..b8ba1f925e75 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c | |||
@@ -98,10 +98,12 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw) | |||
98 | goto exit; | 98 | goto exit; |
99 | 99 | ||
100 | err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4, | 100 | err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4, |
101 | USB_DIR_IN | 0x40, 0,0, &ret, sizeof(ret), ZD1201_FW_TIMEOUT); | 101 | USB_DIR_IN | 0x40, 0, 0, buf, sizeof(ret), ZD1201_FW_TIMEOUT); |
102 | if (err < 0) | 102 | if (err < 0) |
103 | goto exit; | 103 | goto exit; |
104 | 104 | ||
105 | memcpy(&ret, buf, sizeof(ret)); | ||
106 | |||
105 | if (ret & 0x80) { | 107 | if (ret & 0x80) { |
106 | err = -EIO; | 108 | err = -EIO; |
107 | goto exit; | 109 | goto exit; |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 6bb7cf2de556..b10ba00cc3e6 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -392,6 +392,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob, | |||
392 | mem = (unsigned long) | 392 | mem = (unsigned long) |
393 | dt_alloc(size + 4, __alignof__(struct device_node)); | 393 | dt_alloc(size + 4, __alignof__(struct device_node)); |
394 | 394 | ||
395 | memset((void *)mem, 0, size); | ||
396 | |||
395 | ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); | 397 | ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); |
396 | 398 | ||
397 | pr_debug(" unflattening %lx...\n", mem); | 399 | pr_debug(" unflattening %lx...\n", mem); |
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c index c47fd1e5450b..94716c779800 100644 --- a/drivers/pinctrl/pinctrl-sunxi.c +++ b/drivers/pinctrl/pinctrl-sunxi.c | |||
@@ -278,6 +278,7 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, | |||
278 | { | 278 | { |
279 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | 279 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
280 | struct sunxi_pinctrl_group *g = &pctl->groups[group]; | 280 | struct sunxi_pinctrl_group *g = &pctl->groups[group]; |
281 | unsigned long flags; | ||
281 | u32 val, mask; | 282 | u32 val, mask; |
282 | u16 strength; | 283 | u16 strength; |
283 | u8 dlevel; | 284 | u8 dlevel; |
@@ -295,22 +296,35 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, | |||
295 | * 3: 40mA | 296 | * 3: 40mA |
296 | */ | 297 | */ |
297 | dlevel = strength / 10 - 1; | 298 | dlevel = strength / 10 - 1; |
299 | |||
300 | spin_lock_irqsave(&pctl->lock, flags); | ||
301 | |||
298 | val = readl(pctl->membase + sunxi_dlevel_reg(g->pin)); | 302 | val = readl(pctl->membase + sunxi_dlevel_reg(g->pin)); |
299 | mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin); | 303 | mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin); |
300 | writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin), | 304 | writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin), |
301 | pctl->membase + sunxi_dlevel_reg(g->pin)); | 305 | pctl->membase + sunxi_dlevel_reg(g->pin)); |
306 | |||
307 | spin_unlock_irqrestore(&pctl->lock, flags); | ||
302 | break; | 308 | break; |
303 | case PIN_CONFIG_BIAS_PULL_UP: | 309 | case PIN_CONFIG_BIAS_PULL_UP: |
310 | spin_lock_irqsave(&pctl->lock, flags); | ||
311 | |||
304 | val = readl(pctl->membase + sunxi_pull_reg(g->pin)); | 312 | val = readl(pctl->membase + sunxi_pull_reg(g->pin)); |
305 | mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); | 313 | mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); |
306 | writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin), | 314 | writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin), |
307 | pctl->membase + sunxi_pull_reg(g->pin)); | 315 | pctl->membase + sunxi_pull_reg(g->pin)); |
316 | |||
317 | spin_unlock_irqrestore(&pctl->lock, flags); | ||
308 | break; | 318 | break; |
309 | case PIN_CONFIG_BIAS_PULL_DOWN: | 319 | case PIN_CONFIG_BIAS_PULL_DOWN: |
320 | spin_lock_irqsave(&pctl->lock, flags); | ||
321 | |||
310 | val = readl(pctl->membase + sunxi_pull_reg(g->pin)); | 322 | val = readl(pctl->membase + sunxi_pull_reg(g->pin)); |
311 | mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); | 323 | mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); |
312 | writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin), | 324 | writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin), |
313 | pctl->membase + sunxi_pull_reg(g->pin)); | 325 | pctl->membase + sunxi_pull_reg(g->pin)); |
326 | |||
327 | spin_unlock_irqrestore(&pctl->lock, flags); | ||
314 | break; | 328 | break; |
315 | default: | 329 | default: |
316 | break; | 330 | break; |
@@ -360,11 +374,17 @@ static void sunxi_pmx_set(struct pinctrl_dev *pctldev, | |||
360 | u8 config) | 374 | u8 config) |
361 | { | 375 | { |
362 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | 376 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
377 | unsigned long flags; | ||
378 | u32 val, mask; | ||
379 | |||
380 | spin_lock_irqsave(&pctl->lock, flags); | ||
363 | 381 | ||
364 | u32 val = readl(pctl->membase + sunxi_mux_reg(pin)); | 382 | val = readl(pctl->membase + sunxi_mux_reg(pin)); |
365 | u32 mask = MUX_PINS_MASK << sunxi_mux_offset(pin); | 383 | mask = MUX_PINS_MASK << sunxi_mux_offset(pin); |
366 | writel((val & ~mask) | config << sunxi_mux_offset(pin), | 384 | writel((val & ~mask) | config << sunxi_mux_offset(pin), |
367 | pctl->membase + sunxi_mux_reg(pin)); | 385 | pctl->membase + sunxi_mux_reg(pin)); |
386 | |||
387 | spin_unlock_irqrestore(&pctl->lock, flags); | ||
368 | } | 388 | } |
369 | 389 | ||
370 | static int sunxi_pmx_enable(struct pinctrl_dev *pctldev, | 390 | static int sunxi_pmx_enable(struct pinctrl_dev *pctldev, |
@@ -464,8 +484,21 @@ static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip, | |||
464 | struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev); | 484 | struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev); |
465 | u32 reg = sunxi_data_reg(offset); | 485 | u32 reg = sunxi_data_reg(offset); |
466 | u8 index = sunxi_data_offset(offset); | 486 | u8 index = sunxi_data_offset(offset); |
487 | unsigned long flags; | ||
488 | u32 regval; | ||
489 | |||
490 | spin_lock_irqsave(&pctl->lock, flags); | ||
491 | |||
492 | regval = readl(pctl->membase + reg); | ||
467 | 493 | ||
468 | writel((value & DATA_PINS_MASK) << index, pctl->membase + reg); | 494 | if (value) |
495 | regval |= BIT(index); | ||
496 | else | ||
497 | regval &= ~(BIT(index)); | ||
498 | |||
499 | writel(regval, pctl->membase + reg); | ||
500 | |||
501 | spin_unlock_irqrestore(&pctl->lock, flags); | ||
469 | } | 502 | } |
470 | 503 | ||
471 | static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc, | 504 | static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc, |
@@ -526,6 +559,8 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, | |||
526 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); | 559 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); |
527 | u32 reg = sunxi_irq_cfg_reg(d->hwirq); | 560 | u32 reg = sunxi_irq_cfg_reg(d->hwirq); |
528 | u8 index = sunxi_irq_cfg_offset(d->hwirq); | 561 | u8 index = sunxi_irq_cfg_offset(d->hwirq); |
562 | unsigned long flags; | ||
563 | u32 regval; | ||
529 | u8 mode; | 564 | u8 mode; |
530 | 565 | ||
531 | switch (type) { | 566 | switch (type) { |
@@ -548,7 +583,13 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, | |||
548 | return -EINVAL; | 583 | return -EINVAL; |
549 | } | 584 | } |
550 | 585 | ||
551 | writel((mode & IRQ_CFG_IRQ_MASK) << index, pctl->membase + reg); | 586 | spin_lock_irqsave(&pctl->lock, flags); |
587 | |||
588 | regval = readl(pctl->membase + reg); | ||
589 | regval &= ~IRQ_CFG_IRQ_MASK; | ||
590 | writel(regval | (mode << index), pctl->membase + reg); | ||
591 | |||
592 | spin_unlock_irqrestore(&pctl->lock, flags); | ||
552 | 593 | ||
553 | return 0; | 594 | return 0; |
554 | } | 595 | } |
@@ -560,14 +601,19 @@ static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d) | |||
560 | u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq); | 601 | u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq); |
561 | u32 status_reg = sunxi_irq_status_reg(d->hwirq); | 602 | u32 status_reg = sunxi_irq_status_reg(d->hwirq); |
562 | u8 status_idx = sunxi_irq_status_offset(d->hwirq); | 603 | u8 status_idx = sunxi_irq_status_offset(d->hwirq); |
604 | unsigned long flags; | ||
563 | u32 val; | 605 | u32 val; |
564 | 606 | ||
607 | spin_lock_irqsave(&pctl->lock, flags); | ||
608 | |||
565 | /* Mask the IRQ */ | 609 | /* Mask the IRQ */ |
566 | val = readl(pctl->membase + ctrl_reg); | 610 | val = readl(pctl->membase + ctrl_reg); |
567 | writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg); | 611 | writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg); |
568 | 612 | ||
569 | /* Clear the IRQ */ | 613 | /* Clear the IRQ */ |
570 | writel(1 << status_idx, pctl->membase + status_reg); | 614 | writel(1 << status_idx, pctl->membase + status_reg); |
615 | |||
616 | spin_unlock_irqrestore(&pctl->lock, flags); | ||
571 | } | 617 | } |
572 | 618 | ||
573 | static void sunxi_pinctrl_irq_mask(struct irq_data *d) | 619 | static void sunxi_pinctrl_irq_mask(struct irq_data *d) |
@@ -575,11 +621,16 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d) | |||
575 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); | 621 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); |
576 | u32 reg = sunxi_irq_ctrl_reg(d->hwirq); | 622 | u32 reg = sunxi_irq_ctrl_reg(d->hwirq); |
577 | u8 idx = sunxi_irq_ctrl_offset(d->hwirq); | 623 | u8 idx = sunxi_irq_ctrl_offset(d->hwirq); |
624 | unsigned long flags; | ||
578 | u32 val; | 625 | u32 val; |
579 | 626 | ||
627 | spin_lock_irqsave(&pctl->lock, flags); | ||
628 | |||
580 | /* Mask the IRQ */ | 629 | /* Mask the IRQ */ |
581 | val = readl(pctl->membase + reg); | 630 | val = readl(pctl->membase + reg); |
582 | writel(val & ~(1 << idx), pctl->membase + reg); | 631 | writel(val & ~(1 << idx), pctl->membase + reg); |
632 | |||
633 | spin_unlock_irqrestore(&pctl->lock, flags); | ||
583 | } | 634 | } |
584 | 635 | ||
585 | static void sunxi_pinctrl_irq_unmask(struct irq_data *d) | 636 | static void sunxi_pinctrl_irq_unmask(struct irq_data *d) |
@@ -588,6 +639,7 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d) | |||
588 | struct sunxi_desc_function *func; | 639 | struct sunxi_desc_function *func; |
589 | u32 reg = sunxi_irq_ctrl_reg(d->hwirq); | 640 | u32 reg = sunxi_irq_ctrl_reg(d->hwirq); |
590 | u8 idx = sunxi_irq_ctrl_offset(d->hwirq); | 641 | u8 idx = sunxi_irq_ctrl_offset(d->hwirq); |
642 | unsigned long flags; | ||
591 | u32 val; | 643 | u32 val; |
592 | 644 | ||
593 | func = sunxi_pinctrl_desc_find_function_by_pin(pctl, | 645 | func = sunxi_pinctrl_desc_find_function_by_pin(pctl, |
@@ -597,9 +649,13 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d) | |||
597 | /* Change muxing to INT mode */ | 649 | /* Change muxing to INT mode */ |
598 | sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval); | 650 | sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval); |
599 | 651 | ||
652 | spin_lock_irqsave(&pctl->lock, flags); | ||
653 | |||
600 | /* Unmask the IRQ */ | 654 | /* Unmask the IRQ */ |
601 | val = readl(pctl->membase + reg); | 655 | val = readl(pctl->membase + reg); |
602 | writel(val | (1 << idx), pctl->membase + reg); | 656 | writel(val | (1 << idx), pctl->membase + reg); |
657 | |||
658 | spin_unlock_irqrestore(&pctl->lock, flags); | ||
603 | } | 659 | } |
604 | 660 | ||
605 | static struct irq_chip sunxi_pinctrl_irq_chip = { | 661 | static struct irq_chip sunxi_pinctrl_irq_chip = { |
@@ -752,6 +808,8 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev) | |||
752 | return -ENOMEM; | 808 | return -ENOMEM; |
753 | platform_set_drvdata(pdev, pctl); | 809 | platform_set_drvdata(pdev, pctl); |
754 | 810 | ||
811 | spin_lock_init(&pctl->lock); | ||
812 | |||
755 | pctl->membase = of_iomap(node, 0); | 813 | pctl->membase = of_iomap(node, 0); |
756 | if (!pctl->membase) | 814 | if (!pctl->membase) |
757 | return -ENOMEM; | 815 | return -ENOMEM; |
diff --git a/drivers/pinctrl/pinctrl-sunxi.h b/drivers/pinctrl/pinctrl-sunxi.h index d68047d8f699..01c494f8a14f 100644 --- a/drivers/pinctrl/pinctrl-sunxi.h +++ b/drivers/pinctrl/pinctrl-sunxi.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #define __PINCTRL_SUNXI_H | 14 | #define __PINCTRL_SUNXI_H |
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/spinlock.h> | ||
17 | 18 | ||
18 | #define PA_BASE 0 | 19 | #define PA_BASE 0 |
19 | #define PB_BASE 32 | 20 | #define PB_BASE 32 |
@@ -407,6 +408,7 @@ struct sunxi_pinctrl { | |||
407 | unsigned ngroups; | 408 | unsigned ngroups; |
408 | int irq; | 409 | int irq; |
409 | int irq_array[SUNXI_IRQ_NUMBER]; | 410 | int irq_array[SUNXI_IRQ_NUMBER]; |
411 | spinlock_t lock; | ||
410 | struct pinctrl_dev *pctl_dev; | 412 | struct pinctrl_dev *pctl_dev; |
411 | }; | 413 | }; |
412 | 414 | ||
diff --git a/drivers/platform/olpc/olpc-ec.c b/drivers/platform/olpc/olpc-ec.c index 0f9f8596b300..f9119525f557 100644 --- a/drivers/platform/olpc/olpc-ec.c +++ b/drivers/platform/olpc/olpc-ec.c | |||
@@ -330,7 +330,7 @@ static int __init olpc_ec_init_module(void) | |||
330 | return platform_driver_register(&olpc_ec_plat_driver); | 330 | return platform_driver_register(&olpc_ec_plat_driver); |
331 | } | 331 | } |
332 | 332 | ||
333 | module_init(olpc_ec_init_module); | 333 | arch_initcall(olpc_ec_init_module); |
334 | 334 | ||
335 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | 335 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); |
336 | MODULE_LICENSE("GPL"); | 336 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 97bb05edcb5a..d6970f47ae72 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -53,7 +53,6 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); | |||
53 | #define HPWMI_ALS_QUERY 0x3 | 53 | #define HPWMI_ALS_QUERY 0x3 |
54 | #define HPWMI_HARDWARE_QUERY 0x4 | 54 | #define HPWMI_HARDWARE_QUERY 0x4 |
55 | #define HPWMI_WIRELESS_QUERY 0x5 | 55 | #define HPWMI_WIRELESS_QUERY 0x5 |
56 | #define HPWMI_BIOS_QUERY 0x9 | ||
57 | #define HPWMI_HOTKEY_QUERY 0xc | 56 | #define HPWMI_HOTKEY_QUERY 0xc |
58 | #define HPWMI_WIRELESS2_QUERY 0x1b | 57 | #define HPWMI_WIRELESS2_QUERY 0x1b |
59 | #define HPWMI_POSTCODEERROR_QUERY 0x2a | 58 | #define HPWMI_POSTCODEERROR_QUERY 0x2a |
@@ -293,19 +292,6 @@ static int hp_wmi_tablet_state(void) | |||
293 | return (state & 0x4) ? 1 : 0; | 292 | return (state & 0x4) ? 1 : 0; |
294 | } | 293 | } |
295 | 294 | ||
296 | static int hp_wmi_enable_hotkeys(void) | ||
297 | { | ||
298 | int ret; | ||
299 | int query = 0x6e; | ||
300 | |||
301 | ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, 1, &query, sizeof(query), | ||
302 | 0); | ||
303 | |||
304 | if (ret) | ||
305 | return -EINVAL; | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static int hp_wmi_set_block(void *data, bool blocked) | 295 | static int hp_wmi_set_block(void *data, bool blocked) |
310 | { | 296 | { |
311 | enum hp_wmi_radio r = (enum hp_wmi_radio) data; | 297 | enum hp_wmi_radio r = (enum hp_wmi_radio) data; |
@@ -1009,8 +995,6 @@ static int __init hp_wmi_init(void) | |||
1009 | err = hp_wmi_input_setup(); | 995 | err = hp_wmi_input_setup(); |
1010 | if (err) | 996 | if (err) |
1011 | return err; | 997 | return err; |
1012 | |||
1013 | hp_wmi_enable_hotkeys(); | ||
1014 | } | 998 | } |
1015 | 999 | ||
1016 | if (bios_capable) { | 1000 | if (bios_capable) { |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 2ac045f27f10..3a1b6bf326a8 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -2440,7 +2440,10 @@ static ssize_t sony_nc_gfx_switch_status_show(struct device *dev, | |||
2440 | if (pos < 0) | 2440 | if (pos < 0) |
2441 | return pos; | 2441 | return pos; |
2442 | 2442 | ||
2443 | return snprintf(buffer, PAGE_SIZE, "%s\n", pos ? "speed" : "stamina"); | 2443 | return snprintf(buffer, PAGE_SIZE, "%s\n", |
2444 | pos == SPEED ? "speed" : | ||
2445 | pos == STAMINA ? "stamina" : | ||
2446 | pos == AUTO ? "auto" : "unknown"); | ||
2444 | } | 2447 | } |
2445 | 2448 | ||
2446 | static int sony_nc_gfx_switch_setup(struct platform_device *pd, | 2449 | static int sony_nc_gfx_switch_setup(struct platform_device *pd, |
@@ -4320,7 +4323,8 @@ static int sony_pic_add(struct acpi_device *device) | |||
4320 | goto err_free_resources; | 4323 | goto err_free_resources; |
4321 | } | 4324 | } |
4322 | 4325 | ||
4323 | if (sonypi_compat_init()) | 4326 | result = sonypi_compat_init(); |
4327 | if (result) | ||
4324 | goto err_remove_input; | 4328 | goto err_remove_input; |
4325 | 4329 | ||
4326 | /* request io port */ | 4330 | /* request io port */ |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index a58ac435a9a4..5e8be462aed5 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -348,7 +348,7 @@ static void init_evtchn_cpu_bindings(void) | |||
348 | 348 | ||
349 | for_each_possible_cpu(i) | 349 | for_each_possible_cpu(i) |
350 | memset(per_cpu(cpu_evtchn_mask, i), | 350 | memset(per_cpu(cpu_evtchn_mask, i), |
351 | (i == 0) ? ~0 : 0, sizeof(*per_cpu(cpu_evtchn_mask, i))); | 351 | (i == 0) ? ~0 : 0, NR_EVENT_CHANNELS/8); |
352 | } | 352 | } |
353 | 353 | ||
354 | static inline void clear_evtchn(int port) | 354 | static inline void clear_evtchn(int port) |
@@ -1493,8 +1493,10 @@ void rebind_evtchn_irq(int evtchn, int irq) | |||
1493 | /* Rebind an evtchn so that it gets delivered to a specific cpu */ | 1493 | /* Rebind an evtchn so that it gets delivered to a specific cpu */ |
1494 | static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) | 1494 | static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) |
1495 | { | 1495 | { |
1496 | struct shared_info *s = HYPERVISOR_shared_info; | ||
1496 | struct evtchn_bind_vcpu bind_vcpu; | 1497 | struct evtchn_bind_vcpu bind_vcpu; |
1497 | int evtchn = evtchn_from_irq(irq); | 1498 | int evtchn = evtchn_from_irq(irq); |
1499 | int masked; | ||
1498 | 1500 | ||
1499 | if (!VALID_EVTCHN(evtchn)) | 1501 | if (!VALID_EVTCHN(evtchn)) |
1500 | return -1; | 1502 | return -1; |
@@ -1511,6 +1513,12 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) | |||
1511 | bind_vcpu.vcpu = tcpu; | 1513 | bind_vcpu.vcpu = tcpu; |
1512 | 1514 | ||
1513 | /* | 1515 | /* |
1516 | * Mask the event while changing the VCPU binding to prevent | ||
1517 | * it being delivered on an unexpected VCPU. | ||
1518 | */ | ||
1519 | masked = sync_test_and_set_bit(evtchn, BM(s->evtchn_mask)); | ||
1520 | |||
1521 | /* | ||
1514 | * If this fails, it usually just indicates that we're dealing with a | 1522 | * If this fails, it usually just indicates that we're dealing with a |
1515 | * virq or IPI channel, which don't actually need to be rebound. Ignore | 1523 | * virq or IPI channel, which don't actually need to be rebound. Ignore |
1516 | * it, but don't do the xenlinux-level rebind in that case. | 1524 | * it, but don't do the xenlinux-level rebind in that case. |
@@ -1518,6 +1526,9 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) | |||
1518 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) | 1526 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) |
1519 | bind_evtchn_to_cpu(evtchn, tcpu); | 1527 | bind_evtchn_to_cpu(evtchn, tcpu); |
1520 | 1528 | ||
1529 | if (!masked) | ||
1530 | unmask_evtchn(evtchn); | ||
1531 | |||
1521 | return 0; | 1532 | return 0; |
1522 | } | 1533 | } |
1523 | 1534 | ||