From f66834c80391a6fc942ee944b9801cb6577b03e6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 22 Mar 2012 16:08:36 -0700 Subject: [PATCH] 3.3-stable patches added patches: bluetooth-add-ar30xx-device-id-on-asus-laptops.patch drm-i915-only-clear-the-gpu-domains-upon-a-successful-finish.patch drm-radeon-kms-add-connector-quirk-for-fujitsu-d3003-s2-board.patch drm-radeon-kms-fix-analog-load-detection-on-dvi-i-connectors.patch drm-radeon-restrict-offset-for-legacy-hardware-cursor.patch gma500-fix-mmap-frambuffer.patch hid-add-extra-hotkeys-in-asus-aio-keyboards.patch hid-add-more-hotkeys-in-asus-aio-keyboards.patch ib_srpt-fix-srpt_handle_cmd-send_ioctx-ioctx_kref-leak-on-exception.patch md-bitmap-ensure-to-load-bitmap-when-creating-via-sysfs.patch md-don-t-set-md-arrays-to-readonly-on-shutdown.patch md-fix-clearing-of-the-changed-flags-for-the-bad-blocks-list.patch md-raid1-raid10-avoid-deadlock-during-resync-recovery.patch target-don-t-set-wbus16-or-sync-bits-in-inquiry-response.patch target-fix-16-bit-target-ports-for-set-target-port-groups-emulation.patch target-fix-up-handling-of-short-inquiry-buffers.patch target-fix-use-after-free-in-target_report_luns.patch target-prevent-null-pointer-dereference-in-target_report_luns.patch target-set-peripheral-device-type-consistently-in-inquiry-response.patch tcm_fc-fix-fc_exch-memory-leak-in-ft_send_resp_status.patch udlfb-remove-sysfs-framebuffer-device-with-usb-.disconnect.patch --- ...add-ar30xx-device-id-on-asus-laptops.patch | 63 +++ ...gpu-domains-upon-a-successful-finish.patch | 61 +++ ...tor-quirk-for-fujitsu-d3003-s2-board.patch | 45 +++ ...g-load-detection-on-dvi-i-connectors.patch | 37 ++ ...ct-offset-for-legacy-hardware-cursor.patch | 124 ++++++ queue-3.3/gma500-fix-mmap-frambuffer.patch | 35 ++ ...-extra-hotkeys-in-asus-aio-keyboards.patch | 65 ++++ ...d-more-hotkeys-in-asus-aio-keyboards.patch | 32 ++ ...d_ioctx-ioctx_kref-leak-on-exception.patch | 70 ++++ ...-load-bitmap-when-creating-via-sysfs.patch | 34 ++ ...et-md-arrays-to-readonly-on-shutdown.patch | 80 ++++ ...hanged-flags-for-the-bad-blocks-list.patch | 52 +++ ...void-deadlock-during-resync-recovery.patch | 92 +++++ queue-3.3/series | 21 + ...s16-or-sync-bits-in-inquiry-response.patch | 38 ++ ...for-set-target-port-groups-emulation.patch | 51 +++ ...up-handling-of-short-inquiry-buffers.patch | 368 ++++++++++++++++++ ...use-after-free-in-target_report_luns.patch | 35 ++ ...er-dereference-in-target_report_luns.patch | 34 ++ ...ype-consistently-in-inquiry-response.patch | 76 ++++ ...h-memory-leak-in-ft_send_resp_status.patch | 47 +++ ...mebuffer-device-with-usb-.disconnect.patch | 113 ++++++ 22 files changed, 1573 insertions(+) create mode 100644 queue-3.3/bluetooth-add-ar30xx-device-id-on-asus-laptops.patch create mode 100644 queue-3.3/drm-i915-only-clear-the-gpu-domains-upon-a-successful-finish.patch create mode 100644 queue-3.3/drm-radeon-kms-add-connector-quirk-for-fujitsu-d3003-s2-board.patch create mode 100644 queue-3.3/drm-radeon-kms-fix-analog-load-detection-on-dvi-i-connectors.patch create mode 100644 queue-3.3/drm-radeon-restrict-offset-for-legacy-hardware-cursor.patch create mode 100644 queue-3.3/gma500-fix-mmap-frambuffer.patch create mode 100644 queue-3.3/hid-add-extra-hotkeys-in-asus-aio-keyboards.patch create mode 100644 queue-3.3/hid-add-more-hotkeys-in-asus-aio-keyboards.patch create mode 100644 queue-3.3/ib_srpt-fix-srpt_handle_cmd-send_ioctx-ioctx_kref-leak-on-exception.patch create mode 100644 queue-3.3/md-bitmap-ensure-to-load-bitmap-when-creating-via-sysfs.patch create mode 100644 queue-3.3/md-don-t-set-md-arrays-to-readonly-on-shutdown.patch create mode 100644 queue-3.3/md-fix-clearing-of-the-changed-flags-for-the-bad-blocks-list.patch create mode 100644 queue-3.3/md-raid1-raid10-avoid-deadlock-during-resync-recovery.patch create mode 100644 queue-3.3/target-don-t-set-wbus16-or-sync-bits-in-inquiry-response.patch create mode 100644 queue-3.3/target-fix-16-bit-target-ports-for-set-target-port-groups-emulation.patch create mode 100644 queue-3.3/target-fix-up-handling-of-short-inquiry-buffers.patch create mode 100644 queue-3.3/target-fix-use-after-free-in-target_report_luns.patch create mode 100644 queue-3.3/target-prevent-null-pointer-dereference-in-target_report_luns.patch create mode 100644 queue-3.3/target-set-peripheral-device-type-consistently-in-inquiry-response.patch create mode 100644 queue-3.3/tcm_fc-fix-fc_exch-memory-leak-in-ft_send_resp_status.patch create mode 100644 queue-3.3/udlfb-remove-sysfs-framebuffer-device-with-usb-.disconnect.patch diff --git a/queue-3.3/bluetooth-add-ar30xx-device-id-on-asus-laptops.patch b/queue-3.3/bluetooth-add-ar30xx-device-id-on-asus-laptops.patch new file mode 100644 index 00000000000..7cabe404951 --- /dev/null +++ b/queue-3.3/bluetooth-add-ar30xx-device-id-on-asus-laptops.patch @@ -0,0 +1,63 @@ +From 6b6ba88b5bb8779156b21bb957520a448c3642e2 Mon Sep 17 00:00:00 2001 +From: Keng-Yu Lin +Date: Wed, 30 Nov 2011 18:32:37 +0800 +Subject: Bluetooth: Add AR30XX device ID on Asus laptops + +From: Keng-Yu Lin + +commit 6b6ba88b5bb8779156b21bb957520a448c3642e2 upstream. + +The ID is found on Asus K54HR and K53U. +Blacklist the AR3011-based device ID [0489:e03d] +and add to ath3k.c for firmware loading. + +Below is the output of usb-devices script: + +Before the fiwmware loading: + +T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0489 ProdID=e03d Rev=00.01 +C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb + +After the fiwmware loading: + +T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 5 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0cf3 ProdID=3005 Rev=00.01 +C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb + +Signed-off-by: Keng-Yu Lin +Signed-off-by: Gustavo F. Padovan +Signed-off-by: Johan Hedberg +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/bluetooth/ath3k.c | 1 + + drivers/bluetooth/btusb.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -65,6 +65,7 @@ static struct usb_device_id ath3k_table[ + { USB_DEVICE(0x0CF3, 0x3002) }, + { USB_DEVICE(0x13d3, 0x3304) }, + { USB_DEVICE(0x0930, 0x0215) }, ++ { USB_DEVICE(0x0489, 0xE03D) }, + + /* Atheros AR9285 Malbec with sflash firmware */ + { USB_DEVICE(0x03F0, 0x311D) }, +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -121,6 +121,7 @@ static struct usb_device_id blacklist_ta + { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, ++ { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, + + /* Atheros AR9285 Malbec with sflash firmware */ + { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, diff --git a/queue-3.3/drm-i915-only-clear-the-gpu-domains-upon-a-successful-finish.patch b/queue-3.3/drm-i915-only-clear-the-gpu-domains-upon-a-successful-finish.patch new file mode 100644 index 00000000000..f7ea368cb70 --- /dev/null +++ b/queue-3.3/drm-i915-only-clear-the-gpu-domains-upon-a-successful-finish.patch @@ -0,0 +1,61 @@ +From c501ae7f332cdaf42e31af30b72b4b66cbbb1604 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 14 Dec 2011 13:57:23 +0100 +Subject: drm/i915: Only clear the GPU domains upon a successful finish + +From: Chris Wilson + +commit c501ae7f332cdaf42e31af30b72b4b66cbbb1604 upstream. + +By clearing the GPU read domains before waiting upon the buffer, we run +the risk of the wait being interrupted and the domains prematurely +cleared. The next time we attempt to wait upon the buffer (after +userspace handles the signal), we believe that the buffer is idle and so +skip the wait. + +There are a number of bugs across all generations which show signs of an +overly haste reuse of active buffers. + +Such as: + + https://bugs.freedesktop.org/show_bug.cgi?id=29046 + https://bugs.freedesktop.org/show_bug.cgi?id=35863 + https://bugs.freedesktop.org/show_bug.cgi?id=38952 + https://bugs.freedesktop.org/show_bug.cgi?id=40282 + https://bugs.freedesktop.org/show_bug.cgi?id=41098 + https://bugs.freedesktop.org/show_bug.cgi?id=41102 + https://bugs.freedesktop.org/show_bug.cgi?id=41284 + https://bugs.freedesktop.org/show_bug.cgi?id=42141 + +A couple of those pre-date i915_gem_object_finish_gpu(), so may be +unrelated (such as a wild write from a userspace command buffer), but +this does look like a convincing cause for most of those bugs. + +Signed-off-by: Chris Wilson +Reviewed-by: Daniel Vetter +Reviewed-by: Eugeni Dodonov +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_gem.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3084,10 +3084,13 @@ i915_gem_object_finish_gpu(struct drm_i9 + return ret; + } + ++ ret = i915_gem_object_wait_rendering(obj); ++ if (ret) ++ return ret; ++ + /* Ensure that we invalidate the GPU's caches and TLBs. */ + obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; +- +- return i915_gem_object_wait_rendering(obj); ++ return 0; + } + + /** diff --git a/queue-3.3/drm-radeon-kms-add-connector-quirk-for-fujitsu-d3003-s2-board.patch b/queue-3.3/drm-radeon-kms-add-connector-quirk-for-fujitsu-d3003-s2-board.patch new file mode 100644 index 00000000000..1917dfc9099 --- /dev/null +++ b/queue-3.3/drm-radeon-kms-add-connector-quirk-for-fujitsu-d3003-s2-board.patch @@ -0,0 +1,45 @@ +From 4c1b2d2da3451f5c8dd59bd7e05bd9729d2aee05 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 16 Mar 2012 12:22:10 -0400 +Subject: drm/radeon/kms: add connector quirk for Fujitsu D3003-S2 board + +From: Alex Deucher + +commit 4c1b2d2da3451f5c8dd59bd7e05bd9729d2aee05 upstream. + +vbios lists DVI-I port as VGA and DVI-D. + +Fixes: +https://bugs.freedesktop.org/show_bug.cgi?id=47007 + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_atombios.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/gpu/drm/radeon/radeon_atombios.c ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c +@@ -442,6 +442,20 @@ static bool radeon_atom_apply_quirks(str + struct radeon_device *rdev = dev->dev_private; + *i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93); + } ++ ++ /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ ++ if ((dev->pdev->device == 0x9802) && ++ (dev->pdev->subsystem_vendor == 0x1734) && ++ (dev->pdev->subsystem_device == 0x11bd)) { ++ if (*connector_type == DRM_MODE_CONNECTOR_VGA) { ++ *connector_type = DRM_MODE_CONNECTOR_DVII; ++ *line_mux = 0x3103; ++ } else if (*connector_type == DRM_MODE_CONNECTOR_DVID) { ++ *connector_type = DRM_MODE_CONNECTOR_DVII; ++ } ++ } ++ ++ + return true; + } + diff --git a/queue-3.3/drm-radeon-kms-fix-analog-load-detection-on-dvi-i-connectors.patch b/queue-3.3/drm-radeon-kms-fix-analog-load-detection-on-dvi-i-connectors.patch new file mode 100644 index 00000000000..886d38d6be6 --- /dev/null +++ b/queue-3.3/drm-radeon-kms-fix-analog-load-detection-on-dvi-i-connectors.patch @@ -0,0 +1,37 @@ +From e00e8b5e760cbbe9067daeae5454d67c44c8d035 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 16 Mar 2012 12:22:09 -0400 +Subject: drm/radeon/kms: fix analog load detection on DVI-I connectors + +From: Alex Deucher + +commit e00e8b5e760cbbe9067daeae5454d67c44c8d035 upstream. + +We digital encoders have a detect function as well (for +DP to VGA bridges), so we make sure we choose the analog +one here. + +Fixes: +https://bugs.freedesktop.org/show_bug.cgi?id=47007 + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_connectors.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -946,6 +946,10 @@ radeon_dvi_detect(struct drm_connector * + + encoder = obj_to_encoder(obj); + ++ if (encoder->encoder_type != DRM_MODE_ENCODER_DAC || ++ encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) ++ continue; ++ + encoder_funcs = encoder->helper_private; + if (encoder_funcs->detect) { + if (ret != connector_status_connected) { diff --git a/queue-3.3/drm-radeon-restrict-offset-for-legacy-hardware-cursor.patch b/queue-3.3/drm-radeon-restrict-offset-for-legacy-hardware-cursor.patch new file mode 100644 index 00000000000..bd302547ace --- /dev/null +++ b/queue-3.3/drm-radeon-restrict-offset-for-legacy-hardware-cursor.patch @@ -0,0 +1,124 @@ +From c4353016dac10133fa5d8535af83f0c4845a2915 Mon Sep 17 00:00:00 2001 +From: Michel Dänzer +Date: Wed, 14 Mar 2012 17:12:41 +0100 +Subject: drm/radeon: Restrict offset for legacy hardware cursor. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michel Dänzer + +commit c4353016dac10133fa5d8535af83f0c4845a2915 upstream. + +The hardware only takes 27 bits for the offset, so larger offsets are +truncated, and the hardware cursor shows random bits other than the intended +ones. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=46796 + +Signed-off-by: Michel Dänzer +Reviewed-by: Alex Deucher +Signed-off-by: Dave Airlie + +--- + drivers/gpu/drm/radeon/radeon_cursor.c | 13 +++++++++++-- + drivers/gpu/drm/radeon/radeon_object.c | 18 +++++++++++++++++- + drivers/gpu/drm/radeon/radeon_object.h | 2 ++ + 3 files changed, 30 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_cursor.c ++++ b/drivers/gpu/drm/radeon/radeon_cursor.c +@@ -151,7 +151,9 @@ int radeon_crtc_cursor_set(struct drm_cr + uint32_t height) + { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); ++ struct radeon_device *rdev = crtc->dev->dev_private; + struct drm_gem_object *obj; ++ struct radeon_bo *robj; + uint64_t gpu_addr; + int ret; + +@@ -173,7 +175,15 @@ int radeon_crtc_cursor_set(struct drm_cr + return -ENOENT; + } + +- ret = radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &gpu_addr); ++ robj = gem_to_radeon_bo(obj); ++ ret = radeon_bo_reserve(robj, false); ++ if (unlikely(ret != 0)) ++ goto fail; ++ /* Only 27 bit offset for legacy cursor */ ++ ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, ++ ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, ++ &gpu_addr); ++ radeon_bo_unreserve(robj); + if (ret) + goto fail; + +@@ -181,7 +191,6 @@ int radeon_crtc_cursor_set(struct drm_cr + radeon_crtc->cursor_height = height; + + radeon_lock_cursor(crtc, true); +- /* XXX only 27 bit offset for legacy cursor */ + radeon_set_cursor(crtc, obj, gpu_addr); + radeon_show_cursor(crtc); + radeon_lock_cursor(crtc, false); +--- a/drivers/gpu/drm/radeon/radeon_object.c ++++ b/drivers/gpu/drm/radeon/radeon_object.c +@@ -224,7 +224,8 @@ void radeon_bo_unref(struct radeon_bo ** + *bo = NULL; + } + +-int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) ++int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, ++ u64 *gpu_addr) + { + int r, i; + +@@ -232,6 +233,7 @@ int radeon_bo_pin(struct radeon_bo *bo, + bo->pin_count++; + if (gpu_addr) + *gpu_addr = radeon_bo_gpu_offset(bo); ++ WARN_ON_ONCE(max_offset != 0); + return 0; + } + radeon_ttm_placement_from_domain(bo, domain); +@@ -239,6 +241,15 @@ int radeon_bo_pin(struct radeon_bo *bo, + /* force to pin into visible video ram */ + bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT; + } ++ if (max_offset) { ++ u64 lpfn = max_offset >> PAGE_SHIFT; ++ ++ if (!bo->placement.lpfn) ++ bo->placement.lpfn = bo->rdev->mc.gtt_size >> PAGE_SHIFT; ++ ++ if (lpfn < bo->placement.lpfn) ++ bo->placement.lpfn = lpfn; ++ } + for (i = 0; i < bo->placement.num_placement; i++) + bo->placements[i] |= TTM_PL_FLAG_NO_EVICT; + r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false, false); +@@ -252,6 +263,11 @@ int radeon_bo_pin(struct radeon_bo *bo, + return r; + } + ++int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) ++{ ++ return radeon_bo_pin_restricted(bo, domain, 0, gpu_addr); ++} ++ + int radeon_bo_unpin(struct radeon_bo *bo) + { + int r, i; +--- a/drivers/gpu/drm/radeon/radeon_object.h ++++ b/drivers/gpu/drm/radeon/radeon_object.h +@@ -118,6 +118,8 @@ extern int radeon_bo_kmap(struct radeon_ + extern void radeon_bo_kunmap(struct radeon_bo *bo); + extern void radeon_bo_unref(struct radeon_bo **bo); + extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr); ++extern int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, ++ u64 max_offset, u64 *gpu_addr); + extern int radeon_bo_unpin(struct radeon_bo *bo); + extern int radeon_bo_evict_vram(struct radeon_device *rdev); + extern void radeon_bo_force_delete(struct radeon_device *rdev); diff --git a/queue-3.3/gma500-fix-mmap-frambuffer.patch b/queue-3.3/gma500-fix-mmap-frambuffer.patch new file mode 100644 index 00000000000..75f71120f57 --- /dev/null +++ b/queue-3.3/gma500-fix-mmap-frambuffer.patch @@ -0,0 +1,35 @@ +From 1278f7de7fa5606ed513a5271f7fb63910ef1b8b Mon Sep 17 00:00:00 2001 +From: Yoichi Yuasa +Date: Thu, 15 Mar 2012 14:50:16 +0000 +Subject: gma500: Fix mmap frambuffer + +From: Yoichi Yuasa + +commit 1278f7de7fa5606ed513a5271f7fb63910ef1b8b upstream. + +It cannot map correctly if page fault begins from a intermediate address. + +[The driver prefaults the mapping, so we need to work from the correct + base address not the faulting address otherwise the map appears offset by + the fault offset] + +Signed-off-by: Yoichi Yuasa +Signed-off-by: Alan Cox +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/gma500/framebuffer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/gma500/framebuffer.c ++++ b/drivers/gpu/drm/gma500/framebuffer.c +@@ -158,7 +158,7 @@ static int psbfb_vm_fault(struct vm_area + unsigned long phys_addr = (unsigned long)dev_priv->stolen_base; + + page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; +- address = (unsigned long)vmf->virtual_address; ++ address = (unsigned long)vmf->virtual_address - (vmf->pgoff << PAGE_SHIFT); + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + diff --git a/queue-3.3/hid-add-extra-hotkeys-in-asus-aio-keyboards.patch b/queue-3.3/hid-add-extra-hotkeys-in-asus-aio-keyboards.patch new file mode 100644 index 00000000000..a8dcc0081f5 --- /dev/null +++ b/queue-3.3/hid-add-extra-hotkeys-in-asus-aio-keyboards.patch @@ -0,0 +1,65 @@ +From 3596bb929f2abd3433c2eaa5755fad48ac207af1 Mon Sep 17 00:00:00 2001 +From: Keng-Yu Lin +Date: Thu, 2 Feb 2012 10:31:26 +0100 +Subject: HID: add extra hotkeys in Asus AIO keyboards + +From: Keng-Yu Lin + +commit 3596bb929f2abd3433c2eaa5755fad48ac207af1 upstream. + +The Asus All-In-One PC has a wireless keyboard with wifi toggle, +brightness up, brightness down and display off hotkeys. + +This patch adds suppoort for these hotkeys. + +Signed-off-by: Keng-Yu Lin +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-chicony.c | 5 +++++ + drivers/hid/hid-core.c | 1 + + drivers/hid/hid-ids.h | 1 + + 3 files changed, 7 insertions(+) + +--- a/drivers/hid/hid-chicony.c ++++ b/drivers/hid/hid-chicony.c +@@ -45,6 +45,10 @@ static int ch_input_mapping(struct hid_d + case 0xff09: ch_map_key_clear(BTN_9); break; + case 0xff0a: ch_map_key_clear(BTN_A); break; + case 0xff0b: ch_map_key_clear(BTN_B); break; ++ case 0x00f1: ch_map_key_clear(KEY_WLAN); break; ++ case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break; ++ case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break; ++ case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break; + default: + return 0; + } +@@ -53,6 +57,7 @@ static int ch_input_mapping(struct hid_d + + static const struct hid_device_id ch_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, + { } + }; + MODULE_DEVICE_TABLE(hid, ch_devices); +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1396,6 +1396,7 @@ static const struct hid_device_id hid_ha + { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -193,6 +193,7 @@ + #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 + #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d + #define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 ++#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 + + #define USB_VENDOR_ID_CHUNGHWAT 0x2247 + #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 diff --git a/queue-3.3/hid-add-more-hotkeys-in-asus-aio-keyboards.patch b/queue-3.3/hid-add-more-hotkeys-in-asus-aio-keyboards.patch new file mode 100644 index 00000000000..6668cd54a6c --- /dev/null +++ b/queue-3.3/hid-add-more-hotkeys-in-asus-aio-keyboards.patch @@ -0,0 +1,32 @@ +From 6c30d5a53229aad22bb675e0bd6eb518ecaa4316 Mon Sep 17 00:00:00 2001 +From: Keng-Yu Lin +Date: Mon, 30 Jan 2012 14:25:45 +0800 +Subject: HID: add more hotkeys in Asus AIO keyboards + +From: Keng-Yu Lin + +commit 6c30d5a53229aad22bb675e0bd6eb518ecaa4316 upstream. + +Add support for the camera key. The hotkey for +Asus S.H.E(Super Hybrid Engine) mode is mapped to KEY_KEY_PROG1 +just for notifying the userspace. + +Signed-off-by: Keng-Yu Lin +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-chicony.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/hid/hid-chicony.c ++++ b/drivers/hid/hid-chicony.c +@@ -49,6 +49,8 @@ static int ch_input_mapping(struct hid_d + case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break; + case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break; + case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break; ++ case 0x00f7: ch_map_key_clear(KEY_CAMERA); break; ++ case 0x00f8: ch_map_key_clear(KEY_PROG1); break; + default: + return 0; + } diff --git a/queue-3.3/ib_srpt-fix-srpt_handle_cmd-send_ioctx-ioctx_kref-leak-on-exception.patch b/queue-3.3/ib_srpt-fix-srpt_handle_cmd-send_ioctx-ioctx_kref-leak-on-exception.patch new file mode 100644 index 00000000000..a3b74f765b9 --- /dev/null +++ b/queue-3.3/ib_srpt-fix-srpt_handle_cmd-send_ioctx-ioctx_kref-leak-on-exception.patch @@ -0,0 +1,70 @@ +From 187e70a554e0f0717a65998bc9199945cbbd4692 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Sat, 17 Mar 2012 20:12:36 -0700 +Subject: ib_srpt: Fix srpt_handle_cmd send_ioctx->ioctx_kref leak on exception + +From: Nicholas Bellinger + +commit 187e70a554e0f0717a65998bc9199945cbbd4692 upstream. + +This patch addresses a bug in srpt_handle_cmd() failure handling where +send_ioctx->kref is being leaked with the local extra reference after init, +causing the expected kref_put() in srpt_handle_send_comp() to not be the final +call to invoke srpt_put_send_ioctx_kref() -> transport_generic_free_cmd() and +perform se_cmd descriptor memory release. + +It also fixes a SCF_SCSI_RESERVATION_CONFLICT handling bug where this code +is incorrectly falling through to transport_handle_cdb_direct() after +invoking srpt_queue_status() to send SAM_STAT_RESERVATION_CONFLICT status. + +Note this patch is for >= v3.3 mainline code, and current lio-core.git +code has already been converted to target_submit_cmd() + se_cmd->cmd_kref usage, +and internal ioctx->kref usage has been removed. I'm including this patch +now into target-pending/for-next with a CC' for v3.3 stable. + +Cc: Bart Van Assche +Cc: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/srpt/ib_srpt.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/drivers/infiniband/ulp/srpt/ib_srpt.c ++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c +@@ -1750,6 +1750,7 @@ static int srpt_handle_cmd(struct srpt_r + srp_cmd->tag); + cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; ++ kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); + goto send_sense; + } + +@@ -1757,15 +1758,19 @@ static int srpt_handle_cmd(struct srpt_r + cmd->data_direction = dir; + unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun, + sizeof(srp_cmd->lun)); +- if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) ++ if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) { ++ kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); + goto send_sense; ++ } + ret = transport_generic_allocate_tasks(cmd, srp_cmd->cdb); +- if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) +- srpt_queue_status(cmd); +- else if (cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) +- goto send_sense; +- else +- WARN_ON_ONCE(ret); ++ if (ret < 0) { ++ kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); ++ if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) { ++ srpt_queue_status(cmd); ++ return 0; ++ } else ++ goto send_sense; ++ } + + transport_handle_cdb_direct(cmd); + return 0; diff --git a/queue-3.3/md-bitmap-ensure-to-load-bitmap-when-creating-via-sysfs.patch b/queue-3.3/md-bitmap-ensure-to-load-bitmap-when-creating-via-sysfs.patch new file mode 100644 index 00000000000..b7808163e67 --- /dev/null +++ b/queue-3.3/md-bitmap-ensure-to-load-bitmap-when-creating-via-sysfs.patch @@ -0,0 +1,34 @@ +From 4474ca42e2577563a919fd3ed782e2ec55bf11a2 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 19 Mar 2012 12:46:37 +1100 +Subject: md/bitmap: ensure to load bitmap when creating via sysfs. + +From: NeilBrown + +commit 4474ca42e2577563a919fd3ed782e2ec55bf11a2 upstream. + +When commit 69e51b449d383e (md/bitmap: separate out loading a bitmap...) +created bitmap_load, it missed calling it after bitmap_create when a +bitmap is created through the sysfs interface. +So if a bitmap is added this way, we don't allocate memory properly +and can crash. + +This is suitable for any -stable release since 2.6.35. +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/bitmap.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/md/bitmap.c ++++ b/drivers/md/bitmap.c +@@ -1904,6 +1904,8 @@ location_store(struct mddev *mddev, cons + if (mddev->pers) { + mddev->pers->quiesce(mddev, 1); + rv = bitmap_create(mddev); ++ if (!rv) ++ rv = bitmap_load(mddev); + if (rv) { + bitmap_destroy(mddev); + mddev->bitmap_info.offset = 0; diff --git a/queue-3.3/md-don-t-set-md-arrays-to-readonly-on-shutdown.patch b/queue-3.3/md-don-t-set-md-arrays-to-readonly-on-shutdown.patch new file mode 100644 index 00000000000..64bde860fa0 --- /dev/null +++ b/queue-3.3/md-don-t-set-md-arrays-to-readonly-on-shutdown.patch @@ -0,0 +1,80 @@ +From c744a65c1e2d59acc54333ce80a5b0702a98010b Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 19 Mar 2012 12:46:37 +1100 +Subject: md: don't set md arrays to readonly on shutdown. + +From: NeilBrown + +commit c744a65c1e2d59acc54333ce80a5b0702a98010b upstream. + +It seems that with recent kernel, writeback can still be happening +while shutdown is happening, and consequently data can be written +after the md reboot notifier switches all arrays to read-only. +This causes a BUG. + +So don't switch them to read-only - just mark them clean and +set 'safemode' to '2' which mean that immediately after any +write the array will be switch back to 'clean'. + +This could result in the shutdown happening when array is marked +dirty, thus forcing a resync on reboot. However if you reboot +without performing a "sync" first, you get to keep both halves. + +This is suitable for any stable kernel (though there might be some +conflicts with obvious fixes in earlier kernels). + +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/md.c | 37 +++++++++++++++---------------------- + 1 file changed, 15 insertions(+), 22 deletions(-) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -8157,30 +8157,23 @@ static int md_notify_reboot(struct notif + struct mddev *mddev; + int need_delay = 0; + +- if ((code == SYS_DOWN) || (code == SYS_HALT) || (code == SYS_POWER_OFF)) { +- +- printk(KERN_INFO "md: stopping all md devices.\n"); +- +- for_each_mddev(mddev, tmp) { +- if (mddev_trylock(mddev)) { +- /* Force a switch to readonly even array +- * appears to still be in use. Hence +- * the '100'. +- */ +- md_set_readonly(mddev, 100); +- mddev_unlock(mddev); +- } +- need_delay = 1; ++ for_each_mddev(mddev, tmp) { ++ if (mddev_trylock(mddev)) { ++ __md_stop_writes(mddev); ++ mddev->safemode = 2; ++ mddev_unlock(mddev); + } +- /* +- * certain more exotic SCSI devices are known to be +- * volatile wrt too early system reboots. While the +- * right place to handle this issue is the given +- * driver, we do want to have a safe RAID driver ... +- */ +- if (need_delay) +- mdelay(1000*1); ++ need_delay = 1; + } ++ /* ++ * certain more exotic SCSI devices are known to be ++ * volatile wrt too early system reboots. While the ++ * right place to handle this issue is the given ++ * driver, we do want to have a safe RAID driver ... ++ */ ++ if (need_delay) ++ mdelay(1000*1); ++ + return NOTIFY_DONE; + } + diff --git a/queue-3.3/md-fix-clearing-of-the-changed-flags-for-the-bad-blocks-list.patch b/queue-3.3/md-fix-clearing-of-the-changed-flags-for-the-bad-blocks-list.patch new file mode 100644 index 00000000000..7b832825d36 --- /dev/null +++ b/queue-3.3/md-fix-clearing-of-the-changed-flags-for-the-bad-blocks-list.patch @@ -0,0 +1,52 @@ +From d0962936bff659d20522555b517582a2715fd23f Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 19 Mar 2012 12:46:41 +1100 +Subject: md: fix clearing of the 'changed' flags for the bad blocks list. + +From: NeilBrown + +commit d0962936bff659d20522555b517582a2715fd23f upstream. + +In super_1_sync (the first hunk) we need to clear 'changed' before +checking read_seqretry(), otherwise we might race with other code +adding a bad block and so won't retry later. + +In md_update_sb (the second hunk), in the case where there is no +metadata (neither persistent nor external), we treat any bad blocks as +an error. However we need to clear the 'changed' flag before calling +md_ack_all_badblocks, else it won't do anything. + +This patch is suitable for -stable release 3.0 and later. + +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/md.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -1805,13 +1805,13 @@ retry: + | BB_LEN(internal_bb)); + *bbp++ = cpu_to_le64(store_bb); + } ++ bb->changed = 0; + if (read_seqretry(&bb->lock, seq)) + goto retry; + + bb->sector = (rdev->sb_start + + (int)le32_to_cpu(sb->bblog_offset)); + bb->size = le16_to_cpu(sb->bblog_size); +- bb->changed = 0; + } + } + +@@ -2366,6 +2366,7 @@ repeat: + clear_bit(MD_CHANGE_PENDING, &mddev->flags); + list_for_each_entry(rdev, &mddev->disks, same_set) { + if (rdev->badblocks.changed) { ++ rdev->badblocks.changed = 0; + md_ack_all_badblocks(&rdev->badblocks); + md_error(mddev, rdev); + } diff --git a/queue-3.3/md-raid1-raid10-avoid-deadlock-during-resync-recovery.patch b/queue-3.3/md-raid1-raid10-avoid-deadlock-during-resync-recovery.patch new file mode 100644 index 00000000000..e226da78ff1 --- /dev/null +++ b/queue-3.3/md-raid1-raid10-avoid-deadlock-during-resync-recovery.patch @@ -0,0 +1,92 @@ +From d6b42dcb995e6acd7cc276774e751ffc9f0ef4bf Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 19 Mar 2012 12:46:38 +1100 +Subject: md/raid1,raid10: avoid deadlock during resync/recovery. + +From: NeilBrown + +commit d6b42dcb995e6acd7cc276774e751ffc9f0ef4bf upstream. + +If RAID1 or RAID10 is used under LVM or some other stacking +block device, it is possible to enter a deadlock during +resync or recovery. +This can happen if the upper level block device creates +two requests to the RAID1 or RAID10. The first request gets +processed, blocks recovery and queue requests for underlying +requests in current->bio_list. A resync request then starts +which will wait for those requests and block new IO. + +But then the second request to the RAID1/10 will be attempted +and it cannot progress until the resync request completes, +which cannot progress until the underlying device requests complete, +which are on a queue behind that second request. + +So allow that second request to proceed even though there is +a resync request about to start. + +This is suitable for any -stable kernel. + +Reported-by: Ray Morris +Tested-by: Ray Morris +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid1.c | 17 +++++++++++++++-- + drivers/md/raid10.c | 17 +++++++++++++++-- + 2 files changed, 30 insertions(+), 4 deletions(-) + +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -737,9 +737,22 @@ static void wait_barrier(struct r1conf * + spin_lock_irq(&conf->resync_lock); + if (conf->barrier) { + conf->nr_waiting++; +- wait_event_lock_irq(conf->wait_barrier, !conf->barrier, ++ /* Wait for the barrier to drop. ++ * However if there are already pending ++ * requests (preventing the barrier from ++ * rising completely), and the ++ * pre-process bio queue isn't empty, ++ * then don't wait, as we need to empty ++ * that queue to get the nr_pending ++ * count down. ++ */ ++ wait_event_lock_irq(conf->wait_barrier, ++ !conf->barrier || ++ (conf->nr_pending && ++ current->bio_list && ++ !bio_list_empty(current->bio_list)), + conf->resync_lock, +- ); ++ ); + conf->nr_waiting--; + } + conf->nr_pending++; +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -863,9 +863,22 @@ static void wait_barrier(struct r10conf + spin_lock_irq(&conf->resync_lock); + if (conf->barrier) { + conf->nr_waiting++; +- wait_event_lock_irq(conf->wait_barrier, !conf->barrier, ++ /* Wait for the barrier to drop. ++ * However if there are already pending ++ * requests (preventing the barrier from ++ * rising completely), and the ++ * pre-process bio queue isn't empty, ++ * then don't wait, as we need to empty ++ * that queue to get the nr_pending ++ * count down. ++ */ ++ wait_event_lock_irq(conf->wait_barrier, ++ !conf->barrier || ++ (conf->nr_pending && ++ current->bio_list && ++ !bio_list_empty(current->bio_list)), + conf->resync_lock, +- ); ++ ); + conf->nr_waiting--; + } + conf->nr_pending++; diff --git a/queue-3.3/series b/queue-3.3/series index 8e15ba9ccbc..00e49d87419 100644 --- a/queue-3.3/series +++ b/queue-3.3/series @@ -75,3 +75,24 @@ iscsi-target-fix-iscsit_alloc_buffs-failure-cases.patch iscsi-target-fix-dynamic-explict-nodeacl-pointer-reference.patch alsa-hda-fix-printing-of-high-hdmi-sample-rates.patch usb-gadget-fix-a-section-mismatch-when-compiling-g_ffs-with-config_usb_functionfs_eth.patch +gma500-fix-mmap-frambuffer.patch +udlfb-remove-sysfs-framebuffer-device-with-usb-.disconnect.patch +tcm_fc-fix-fc_exch-memory-leak-in-ft_send_resp_status.patch +ib_srpt-fix-srpt_handle_cmd-send_ioctx-ioctx_kref-leak-on-exception.patch +md-bitmap-ensure-to-load-bitmap-when-creating-via-sysfs.patch +md-don-t-set-md-arrays-to-readonly-on-shutdown.patch +md-raid1-raid10-avoid-deadlock-during-resync-recovery.patch +md-fix-clearing-of-the-changed-flags-for-the-bad-blocks-list.patch +drm-i915-only-clear-the-gpu-domains-upon-a-successful-finish.patch +drm-radeon-restrict-offset-for-legacy-hardware-cursor.patch +drm-radeon-kms-fix-analog-load-detection-on-dvi-i-connectors.patch +drm-radeon-kms-add-connector-quirk-for-fujitsu-d3003-s2-board.patch +target-fix-up-handling-of-short-inquiry-buffers.patch +target-set-peripheral-device-type-consistently-in-inquiry-response.patch +target-don-t-set-wbus16-or-sync-bits-in-inquiry-response.patch +target-fix-use-after-free-in-target_report_luns.patch +target-prevent-null-pointer-dereference-in-target_report_luns.patch +target-fix-16-bit-target-ports-for-set-target-port-groups-emulation.patch +bluetooth-add-ar30xx-device-id-on-asus-laptops.patch +hid-add-extra-hotkeys-in-asus-aio-keyboards.patch +hid-add-more-hotkeys-in-asus-aio-keyboards.patch diff --git a/queue-3.3/target-don-t-set-wbus16-or-sync-bits-in-inquiry-response.patch b/queue-3.3/target-don-t-set-wbus16-or-sync-bits-in-inquiry-response.patch new file mode 100644 index 00000000000..b069b63e6df --- /dev/null +++ b/queue-3.3/target-don-t-set-wbus16-or-sync-bits-in-inquiry-response.patch @@ -0,0 +1,38 @@ +From effc6cc8828257c32c37635e737f14fd6e19ecd7 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Mon, 13 Feb 2012 16:18:16 -0800 +Subject: target: Don't set WBUS16 or SYNC bits in INQUIRY response + +From: Roland Dreier + +commit effc6cc8828257c32c37635e737f14fd6e19ecd7 upstream. + +SPC-4 says about the WBUS16 and SYNC bits: + + The meanings of these fields are specific to SPI-5 (see 6.4.3). + For SCSI transport protocols other than the SCSI Parallel + Interface, these fields are reserved. + +We don't have a SPI fabric module, so we should never set these bits. +(The comment was misleading, since it only mentioned Sync but the +actual code set WBUS16 too). + +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_cdb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/target_core_cdb.c ++++ b/drivers/target/target_core_cdb.c +@@ -95,7 +95,7 @@ target_emulate_inquiry_std(struct se_cmd + if (dev->se_sub_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) + target_fill_alua_data(lun->lun_sep, buf); + +- buf[7] = 0x32; /* Sync=1 and CmdQue=1 */ ++ buf[7] = 0x2; /* CmdQue=1 */ + + snprintf(&buf[8], 8, "LIO-ORG"); + snprintf(&buf[16], 16, "%s", dev->se_sub_dev->t10_wwn.model); diff --git a/queue-3.3/target-fix-16-bit-target-ports-for-set-target-port-groups-emulation.patch b/queue-3.3/target-fix-16-bit-target-ports-for-set-target-port-groups-emulation.patch new file mode 100644 index 00000000000..ee1c4ecf1a9 --- /dev/null +++ b/queue-3.3/target-fix-16-bit-target-ports-for-set-target-port-groups-emulation.patch @@ -0,0 +1,51 @@ +From 33395fb8a13731c7ef7b175dbf5a4d8a6738fe6c Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Thu, 23 Feb 2012 17:22:12 -0800 +Subject: target: Fix 16-bit target ports for SET TARGET PORT GROUPS emulation + +From: Roland Dreier + +commit 33395fb8a13731c7ef7b175dbf5a4d8a6738fe6c upstream. + +The old code did (MSB << 8) & 0xff, which always evaluates to 0. Just use +get_unaligned_be16() so we don't have to worry about whether our open-coded +version is correct or not. + +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_alua.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/target/target_core_alua.c ++++ b/drivers/target/target_core_alua.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -267,8 +268,7 @@ int target_emulate_set_target_port_group + * changed. + */ + if (primary) { +- tg_pt_id = ((ptr[2] << 8) & 0xff); +- tg_pt_id |= (ptr[3] & 0xff); ++ tg_pt_id = get_unaligned_be16(ptr + 2); + /* + * Locate the matching target port group ID from + * the global tg_pt_gp list +@@ -312,8 +312,7 @@ int target_emulate_set_target_port_group + * the Target Port in question for the the incoming + * SET_TARGET_PORT_GROUPS op. + */ +- rtpi = ((ptr[2] << 8) & 0xff); +- rtpi |= (ptr[3] & 0xff); ++ rtpi = get_unaligned_be16(ptr + 2); + /* + * Locate the matching relative target port identifer + * for the struct se_device storage object. diff --git a/queue-3.3/target-fix-up-handling-of-short-inquiry-buffers.patch b/queue-3.3/target-fix-up-handling-of-short-inquiry-buffers.patch new file mode 100644 index 00000000000..a7579e7de94 --- /dev/null +++ b/queue-3.3/target-fix-up-handling-of-short-inquiry-buffers.patch @@ -0,0 +1,368 @@ +From d95b82461c56a6ff8ff248b101049a69ebb20278 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Mon, 13 Feb 2012 16:18:14 -0800 +Subject: target: Fix up handling of short INQUIRY buffers + +From: Roland Dreier + +commit d95b82461c56a6ff8ff248b101049a69ebb20278 upstream. + +If the initiator sends us an INQUIRY command with an allocation length +that's shorter than what we want to return, we're simply supposed to +truncate our response and return what the initiator gave us space for, +without signaling any error. Current target code has various tests that +don't fill out the full response if the buffer is too short and +sometimes return errors incorrectly. + +Fix this up by allocating a bounce buffer for INQUIRY responses if we +need to, ie if we have cmd->data_length too small as well as +SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC set in cmd->se_cmd_flags -- for most +fabrics, we always allocate at least a full page, but for tcm_loop we +may have a small buffer coming directly from the SCSI stack. + +This lets us delete a lot of cmd->data_length checking, and also makes +our INQUIRY handling correct per SPC in a lot more cases. + +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_cdb.c | 150 +++++++++----------------------------- + include/target/target_core_base.h | 2 + 2 files changed, 37 insertions(+), 115 deletions(-) + +--- a/drivers/target/target_core_cdb.c ++++ b/drivers/target/target_core_cdb.c +@@ -66,24 +66,11 @@ target_fill_alua_data(struct se_port *po + } + + static int +-target_emulate_inquiry_std(struct se_cmd *cmd) ++target_emulate_inquiry_std(struct se_cmd *cmd, char *buf) + { + struct se_lun *lun = cmd->se_lun; + struct se_device *dev = cmd->se_dev; + struct se_portal_group *tpg = lun->lun_sep->sep_tpg; +- unsigned char *buf; +- +- /* +- * Make sure we at least have 6 bytes of INQUIRY response +- * payload going back for EVPD=0 +- */ +- if (cmd->data_length < 6) { +- pr_err("SCSI Inquiry payload length: %u" +- " too small for EVPD=0\n", cmd->data_length); +- return -EINVAL; +- } +- +- buf = transport_kmap_data_sg(cmd); + + if (dev == tpg->tpg_virt_lun0.lun_se_dev) { + buf[0] = 0x3f; /* Not connected */ +@@ -112,29 +99,13 @@ target_emulate_inquiry_std(struct se_cmd + if (dev->se_sub_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) + target_fill_alua_data(lun->lun_sep, buf); + +- if (cmd->data_length < 8) { +- buf[4] = 1; /* Set additional length to 1 */ +- goto out; +- } +- + buf[7] = 0x32; /* Sync=1 and CmdQue=1 */ + +- /* +- * Do not include vendor, product, reversion info in INQUIRY +- * response payload for cdbs with a small allocation length. +- */ +- if (cmd->data_length < 36) { +- buf[4] = 3; /* Set additional length to 3 */ +- goto out; +- } +- + snprintf(&buf[8], 8, "LIO-ORG"); + snprintf(&buf[16], 16, "%s", dev->se_sub_dev->t10_wwn.model); + snprintf(&buf[32], 4, "%s", dev->se_sub_dev->t10_wwn.revision); + buf[4] = 31; /* Set additional length to 31 */ + +-out: +- transport_kunmap_data_sg(cmd); + return 0; + } + +@@ -152,12 +123,6 @@ target_emulate_evpd_80(struct se_cmd *cm + unit_serial_len = strlen(dev->se_sub_dev->t10_wwn.unit_serial); + unit_serial_len++; /* For NULL Terminator */ + +- if (((len + 4) + unit_serial_len) > cmd->data_length) { +- len += unit_serial_len; +- buf[2] = ((len >> 8) & 0xff); +- buf[3] = (len & 0xff); +- return 0; +- } + len += sprintf(&buf[4], "%s", + dev->se_sub_dev->t10_wwn.unit_serial); + len++; /* Extra Byte for NULL Terminator */ +@@ -229,9 +194,6 @@ target_emulate_evpd_83(struct se_cmd *cm + if (!(dev->se_sub_dev->su_dev_flags & SDF_EMULATED_VPD_UNIT_SERIAL)) + goto check_t10_vend_desc; + +- if (off + 20 > cmd->data_length) +- goto check_t10_vend_desc; +- + /* CODE SET == Binary */ + buf[off++] = 0x1; + +@@ -283,12 +245,6 @@ check_t10_vend_desc: + strlen(&dev->se_sub_dev->t10_wwn.unit_serial[0]); + unit_serial_len++; /* For NULL Terminator */ + +- if ((len + (id_len + 4) + +- (prod_len + unit_serial_len)) > +- cmd->data_length) { +- len += (prod_len + unit_serial_len); +- goto check_port; +- } + id_len += sprintf(&buf[off+12], "%s:%s", prod, + &dev->se_sub_dev->t10_wwn.unit_serial[0]); + } +@@ -306,7 +262,6 @@ check_t10_vend_desc: + /* + * struct se_port is only set for INQUIRY VPD=1 through $FABRIC_MOD + */ +-check_port: + port = lun->lun_sep; + if (port) { + struct t10_alua_lu_gp *lu_gp; +@@ -323,10 +278,6 @@ check_port: + * Get the PROTOCOL IDENTIFIER as defined by spc4r17 + * section 7.5.1 Table 362 + */ +- if (((len + 4) + 8) > cmd->data_length) { +- len += 8; +- goto check_tpgi; +- } + buf[off] = + (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); + buf[off++] |= 0x1; /* CODE SET == Binary */ +@@ -350,15 +301,10 @@ check_port: + * Get the PROTOCOL IDENTIFIER as defined by spc4r17 + * section 7.5.1 Table 362 + */ +-check_tpgi: + if (dev->se_sub_dev->t10_alua.alua_type != + SPC3_ALUA_EMULATED) + goto check_scsi_name; + +- if (((len + 4) + 8) > cmd->data_length) { +- len += 8; +- goto check_lu_gp; +- } + tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; + if (!tg_pt_gp_mem) + goto check_lu_gp; +@@ -391,10 +337,6 @@ check_tpgi: + * section 7.7.3.8 + */ + check_lu_gp: +- if (((len + 4) + 8) > cmd->data_length) { +- len += 8; +- goto check_scsi_name; +- } + lu_gp_mem = dev->dev_alua_lu_gp_mem; + if (!lu_gp_mem) + goto check_scsi_name; +@@ -435,10 +377,6 @@ check_scsi_name: + /* Header size + Designation descriptor */ + scsi_name_len += 4; + +- if (((len + 4) + scsi_name_len) > cmd->data_length) { +- len += scsi_name_len; +- goto set_len; +- } + buf[off] = + (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); + buf[off++] |= 0x3; /* CODE SET == UTF-8 */ +@@ -474,7 +412,6 @@ check_scsi_name: + /* Header size + Designation descriptor */ + len += (scsi_name_len + 4); + } +-set_len: + buf[2] = ((len >> 8) & 0xff); + buf[3] = (len & 0xff); /* Page Length for VPD 0x83 */ + return 0; +@@ -484,9 +421,6 @@ set_len: + static int + target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) + { +- if (cmd->data_length < 60) +- return 0; +- + buf[3] = 0x3c; + /* Set HEADSUP, ORDSUP, SIMPSUP */ + buf[5] = 0x07; +@@ -512,20 +446,6 @@ target_emulate_evpd_b0(struct se_cmd *cm + if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) + have_tp = 1; + +- if (cmd->data_length < (0x10 + 4)) { +- pr_debug("Received data_length: %u" +- " too small for EVPD 0xb0\n", +- cmd->data_length); +- return -EINVAL; +- } +- +- if (have_tp && cmd->data_length < (0x3c + 4)) { +- pr_debug("Received data_length: %u" +- " too small for TPE=1 EVPD 0xb0\n", +- cmd->data_length); +- have_tp = 0; +- } +- + buf[0] = dev->transport->get_device_type(dev); + buf[3] = have_tp ? 0x3c : 0x10; + +@@ -548,10 +468,9 @@ target_emulate_evpd_b0(struct se_cmd *cm + put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.optimal_sectors, &buf[12]); + + /* +- * Exit now if we don't support TP or the initiator sent a too +- * short buffer. ++ * Exit now if we don't support TP. + */ +- if (!have_tp || cmd->data_length < (0x3c + 4)) ++ if (!have_tp) + return 0; + + /* +@@ -589,10 +508,7 @@ target_emulate_evpd_b1(struct se_cmd *cm + + buf[0] = dev->transport->get_device_type(dev); + buf[3] = 0x3c; +- +- if (cmd->data_length >= 5 && +- dev->se_sub_dev->se_dev_attrib.is_nonrot) +- buf[5] = 1; ++ buf[5] = dev->se_sub_dev->se_dev_attrib.is_nonrot ? 1 : 0; + + return 0; + } +@@ -671,8 +587,6 @@ target_emulate_evpd_00(struct se_cmd *cm + { + int p; + +- if (cmd->data_length < 8) +- return 0; + /* + * Only report the INQUIRY EVPD=1 pages after a valid NAA + * Registered Extended LUN WWN has been set via ConfigFS +@@ -681,8 +595,7 @@ target_emulate_evpd_00(struct se_cmd *cm + if (cmd->se_dev->se_sub_dev->su_dev_flags & + SDF_EMULATED_VPD_UNIT_SERIAL) { + buf[3] = ARRAY_SIZE(evpd_handlers); +- for (p = 0; p < min_t(int, ARRAY_SIZE(evpd_handlers), +- cmd->data_length - 4); ++p) ++ for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) + buf[p + 4] = evpd_handlers[p].page; + } + +@@ -693,45 +606,50 @@ int target_emulate_inquiry(struct se_tas + { + struct se_cmd *cmd = task->task_se_cmd; + struct se_device *dev = cmd->se_dev; +- unsigned char *buf; ++ unsigned char *buf, *map_buf; + unsigned char *cdb = cmd->t_task_cdb; + int p, ret; + ++ map_buf = transport_kmap_data_sg(cmd); ++ /* ++ * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we ++ * know we actually allocated a full page. Otherwise, if the ++ * data buffer is too small, allocate a temporary buffer so we ++ * don't have to worry about overruns in all our INQUIRY ++ * emulation handling. ++ */ ++ if (cmd->data_length < SE_INQUIRY_BUF && ++ (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) { ++ buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL); ++ if (!buf) { ++ transport_kunmap_data_sg(cmd); ++ cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; ++ return -ENOMEM; ++ } ++ } else { ++ buf = map_buf; ++ } ++ + if (!(cdb[1] & 0x1)) { + if (cdb[2]) { + pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n", + cdb[2]); + cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; +- return -EINVAL; ++ ret = -EINVAL; ++ goto out; + } + +- ret = target_emulate_inquiry_std(cmd); ++ ret = target_emulate_inquiry_std(cmd, buf); + goto out; + } + +- /* +- * Make sure we at least have 4 bytes of INQUIRY response +- * payload for 0x00 going back for EVPD=1. Note that 0x80 +- * and 0x83 will check for enough payload data length and +- * jump to set_len: label when there is not enough inquiry EVPD +- * payload length left for the next outgoing EVPD metadata +- */ +- if (cmd->data_length < 4) { +- pr_err("SCSI Inquiry payload length: %u" +- " too small for EVPD=1\n", cmd->data_length); +- cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; +- return -EINVAL; +- } +- +- buf = transport_kmap_data_sg(cmd); +- + buf[0] = dev->transport->get_device_type(dev); + + for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) { + if (cdb[2] == evpd_handlers[p].page) { + buf[1] = cdb[2]; + ret = evpd_handlers[p].emulate(cmd, buf); +- goto out_unmap; ++ goto out; + } + } + +@@ -739,9 +657,13 @@ int target_emulate_inquiry(struct se_tas + cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; + ret = -EINVAL; + +-out_unmap: +- transport_kunmap_data_sg(cmd); + out: ++ if (buf != map_buf) { ++ memcpy(map_buf, buf, cmd->data_length); ++ kfree(buf); ++ } ++ transport_kunmap_data_sg(cmd); ++ + if (!ret) { + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); +--- a/include/target/target_core_base.h ++++ b/include/target/target_core_base.h +@@ -118,9 +118,9 @@ + /* Queue Algorithm Modifier default for restricted reordering in control mode page */ + #define DA_EMULATE_REST_REORD 0 + ++#define SE_INQUIRY_BUF 512 + #define SE_MODE_PAGE_BUF 512 + +- + /* struct se_hba->hba_flags */ + enum hba_flags_table { + HBA_FLAGS_INTERNAL_USE = 0x01, diff --git a/queue-3.3/target-fix-use-after-free-in-target_report_luns.patch b/queue-3.3/target-fix-use-after-free-in-target_report_luns.patch new file mode 100644 index 00000000000..58d47953325 --- /dev/null +++ b/queue-3.3/target-fix-use-after-free-in-target_report_luns.patch @@ -0,0 +1,35 @@ +From 382436f8804fe1cb20b9a2a811a10eb2d8554721 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=B6rn=20Engel?= +Date: Wed, 15 Feb 2012 16:51:32 -0500 +Subject: target: fix use after free in target_report_luns + +From: =?UTF-8?q?J=C3=B6rn=20Engel?= + +commit 382436f8804fe1cb20b9a2a811a10eb2d8554721 upstream. + +Fix possible NULL pointer dereference in target_report_luns failure path. + +Signed-off-by: Joern Engel +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_device.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -695,12 +695,12 @@ int target_report_luns(struct se_task *s + * See SPC3 r07, page 159. + */ + done: +- transport_kunmap_data_sg(se_cmd); + lun_count *= 8; + buf[0] = ((lun_count >> 24) & 0xff); + buf[1] = ((lun_count >> 16) & 0xff); + buf[2] = ((lun_count >> 8) & 0xff); + buf[3] = (lun_count & 0xff); ++ transport_kunmap_data_sg(se_cmd); + + se_task->task_scsi_status = GOOD; + transport_complete_task(se_task, 1); diff --git a/queue-3.3/target-prevent-null-pointer-dereference-in-target_report_luns.patch b/queue-3.3/target-prevent-null-pointer-dereference-in-target_report_luns.patch new file mode 100644 index 00000000000..691cc682b02 --- /dev/null +++ b/queue-3.3/target-prevent-null-pointer-dereference-in-target_report_luns.patch @@ -0,0 +1,34 @@ +From 47f1b8803e1e358ebbf4f82bfdb98971c912a2c3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=B6rn=20Engel?= +Date: Wed, 15 Feb 2012 16:52:11 -0500 +Subject: target: prevent NULL pointer dereference in target_report_luns + +From: =?UTF-8?q?J=C3=B6rn=20Engel?= + +commit 47f1b8803e1e358ebbf4f82bfdb98971c912a2c3 upstream. + +transport_kmap_data_sg can return NULL. I never saw this trigger, but +returning -ENOMEM seems better than a crash. Also removes a pointless +case while at it. + +Signed-off-by: Joern Engel +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_device.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -657,7 +657,9 @@ int target_report_luns(struct se_task *s + unsigned char *buf; + u32 cdb_offset = 0, lun_count = 0, offset = 8, i; + +- buf = (unsigned char *) transport_kmap_data_sg(se_cmd); ++ buf = transport_kmap_data_sg(se_cmd); ++ if (!buf) ++ return -ENOMEM; + + /* + * If no struct se_session pointer is present, this struct se_cmd is diff --git a/queue-3.3/target-set-peripheral-device-type-consistently-in-inquiry-response.patch b/queue-3.3/target-set-peripheral-device-type-consistently-in-inquiry-response.patch new file mode 100644 index 00000000000..1a3ee57b87a --- /dev/null +++ b/queue-3.3/target-set-peripheral-device-type-consistently-in-inquiry-response.patch @@ -0,0 +1,76 @@ +From 089461dda1770c10fea0b988ff74519a9be81d7e Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Mon, 13 Feb 2012 16:18:15 -0800 +Subject: target: Set peripheral device type consistently in INQUIRY response + +From: Roland Dreier + +commit 089461dda1770c10fea0b988ff74519a9be81d7e upstream. + +Current code sets the peripheral device type to 0x3f == "not present +unknown" for virtual LUN 0 for standard INQUIRY commands, but leaves it +as 0 == "connected direct access block" for VPD INQUIRY commands. This +is just because the check for LUN 0 only happens in some code paths. + +Make our peripheral device type consistent by moving the LUN 0 check +into the common emulate_inquiry() code. + +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_cdb.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +--- a/drivers/target/target_core_cdb.c ++++ b/drivers/target/target_core_cdb.c +@@ -70,15 +70,11 @@ target_emulate_inquiry_std(struct se_cmd + { + struct se_lun *lun = cmd->se_lun; + struct se_device *dev = cmd->se_dev; +- struct se_portal_group *tpg = lun->lun_sep->sep_tpg; + +- if (dev == tpg->tpg_virt_lun0.lun_se_dev) { +- buf[0] = 0x3f; /* Not connected */ +- } else { +- buf[0] = dev->transport->get_device_type(dev); +- if (buf[0] == TYPE_TAPE) +- buf[1] = 0x80; +- } ++ /* Set RMB (removable media) for tape devices */ ++ if (dev->transport->get_device_type(dev) == TYPE_TAPE) ++ buf[1] = 0x80; ++ + buf[2] = dev->transport->get_device_rev(dev); + + /* +@@ -606,6 +602,7 @@ int target_emulate_inquiry(struct se_tas + { + struct se_cmd *cmd = task->task_se_cmd; + struct se_device *dev = cmd->se_dev; ++ struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; + unsigned char *buf, *map_buf; + unsigned char *cdb = cmd->t_task_cdb; + int p, ret; +@@ -630,6 +627,11 @@ int target_emulate_inquiry(struct se_tas + buf = map_buf; + } + ++ if (dev == tpg->tpg_virt_lun0.lun_se_dev) ++ buf[0] = 0x3f; /* Not connected */ ++ else ++ buf[0] = dev->transport->get_device_type(dev); ++ + if (!(cdb[1] & 0x1)) { + if (cdb[2]) { + pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n", +@@ -643,8 +645,6 @@ int target_emulate_inquiry(struct se_tas + goto out; + } + +- buf[0] = dev->transport->get_device_type(dev); +- + for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) { + if (cdb[2] == evpd_handlers[p].page) { + buf[1] = cdb[2]; diff --git a/queue-3.3/tcm_fc-fix-fc_exch-memory-leak-in-ft_send_resp_status.patch b/queue-3.3/tcm_fc-fix-fc_exch-memory-leak-in-ft_send_resp_status.patch new file mode 100644 index 00000000000..7c5171d1908 --- /dev/null +++ b/queue-3.3/tcm_fc-fix-fc_exch-memory-leak-in-ft_send_resp_status.patch @@ -0,0 +1,47 @@ +From 031ed4d565b31880a4136bb7366bc89f5b1dba7d Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Fri, 9 Mar 2012 23:45:38 -0800 +Subject: tcm_fc: Fix fc_exch memory leak in ft_send_resp_status + +From: Nicholas Bellinger + +commit 031ed4d565b31880a4136bb7366bc89f5b1dba7d upstream. + +This patch fixes a bug in tcm_fc where fc_exch memory from fc_exch_mgr->ep_pool +is currently being leaked by ft_send_resp_status() usage. Following current +code in ft_queue_status() response path, using lport->tt.seq_send() needs to be +followed by a lport->tt.exch_done() in order to release fc_exch memory back into +libfc_em kmem_cache. + +ft_send_resp_status() code is currently used in pre submit se_cmd ft_send_work() +error exceptions, TM request setup exceptions, and main TM response callback +path in ft_queue_tm_resp(). This bugfix addresses the leak in these cases. + +Cc: Mark D Rustad +Cc: Kiran Patil +Cc: Robert Love +Cc: Andy Grover +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/tcm_fc/tfc_cmd.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/target/tcm_fc/tfc_cmd.c ++++ b/drivers/target/tcm_fc/tfc_cmd.c +@@ -325,10 +325,12 @@ static void ft_send_resp_status(struct f + + fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_DD_CMD_STATUS, 0); + sp = fr_seq(fp); +- if (sp) ++ if (sp) { + lport->tt.seq_send(lport, sp, fp); +- else ++ lport->tt.exch_done(sp); ++ } else { + lport->tt.frame_send(lport, fp); ++ } + } + + /* diff --git a/queue-3.3/udlfb-remove-sysfs-framebuffer-device-with-usb-.disconnect.patch b/queue-3.3/udlfb-remove-sysfs-framebuffer-device-with-usb-.disconnect.patch new file mode 100644 index 00000000000..b1035987910 --- /dev/null +++ b/queue-3.3/udlfb-remove-sysfs-framebuffer-device-with-usb-.disconnect.patch @@ -0,0 +1,113 @@ +From ce880cb860f36694d2cdebfac9e6ae18176fe4c4 Mon Sep 17 00:00:00 2001 +From: Kay Sievers +Date: Sat, 28 Jan 2012 19:57:46 +0000 +Subject: udlfb: remove sysfs framebuffer device with USB .disconnect() + +From: Kay Sievers + +commit ce880cb860f36694d2cdebfac9e6ae18176fe4c4 upstream. + +The USB graphics card driver delays the unregistering of the framebuffer +device to a workqueue, which breaks the userspace visible remove uevent +sequence. Recent userspace tools started to support USB graphics card +hotplug out-of-the-box and rely on proper events sent by the kernel. + +The framebuffer device is a direct child of the USB interface which is +removed immediately after the USB .disconnect() callback. But the fb device +in /sys stays around until its final cleanup, at a time where all the parent +devices have been removed already. + +To work around that, we remove the sysfs fb device directly in the USB +.disconnect() callback and leave only the cleanup of the internal fb +data to the delayed work. + +Before: + add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) + add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) + add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb0 (graphics) + remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) + remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) + remove /2-1.2:1.0/graphics/fb0 (graphics) + +After: + add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) + add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) + add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics) + remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics) + remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) + remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) + +Tested-by: Bernie Thompson +Acked-by: Bernie Thompson +Signed-off-by: Kay Sievers +Signed-off-by: Florian Tobias Schandinat +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/fbmem.c | 18 +++++++++++++++++- + drivers/video/udlfb.c | 2 +- + include/linux/fb.h | 1 + + 3 files changed, 19 insertions(+), 2 deletions(-) + +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -1665,6 +1665,7 @@ static int do_unregister_framebuffer(str + if (ret) + return -EINVAL; + ++ unlink_framebuffer(fb_info); + if (fb_info->pixmap.addr && + (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) + kfree(fb_info->pixmap.addr); +@@ -1672,7 +1673,6 @@ static int do_unregister_framebuffer(str + registered_fb[i] = NULL; + num_registered_fb--; + fb_cleanup_device(fb_info); +- device_destroy(fb_class, MKDEV(FB_MAJOR, i)); + event.info = fb_info; + fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); + +@@ -1681,6 +1681,22 @@ static int do_unregister_framebuffer(str + return 0; + } + ++int unlink_framebuffer(struct fb_info *fb_info) ++{ ++ int i; ++ ++ i = fb_info->node; ++ if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) ++ return -EINVAL; ++ ++ if (fb_info->dev) { ++ device_destroy(fb_class, MKDEV(FB_MAJOR, i)); ++ fb_info->dev = NULL; ++ } ++ return 0; ++} ++EXPORT_SYMBOL(unlink_framebuffer); ++ + void remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) + { +--- a/drivers/video/udlfb.c ++++ b/drivers/video/udlfb.c +@@ -1739,7 +1739,7 @@ static void dlfb_usb_disconnect(struct u + for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) + device_remove_file(info->dev, &fb_device_attrs[i]); + device_remove_bin_file(info->dev, &edid_attr); +- ++ unlink_framebuffer(info); + usb_set_intfdata(interface, NULL); + + /* if clients still have us open, will be freed on last close */ +--- a/include/linux/fb.h ++++ b/include/linux/fb.h +@@ -1003,6 +1003,7 @@ extern ssize_t fb_sys_write(struct fb_in + /* drivers/video/fbmem.c */ + extern int register_framebuffer(struct fb_info *fb_info); + extern int unregister_framebuffer(struct fb_info *fb_info); ++extern int unlink_framebuffer(struct fb_info *fb_info); + extern void remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary); + extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); -- 2.47.3