diff --git a/Makefile b/Makefile
index 53c9a5d..8c8330e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 0
-SUBLEVEL = 97
+SUBLEVEL = 98
 EXTRAVERSION =
 NAME = Sneaky Weasel
 
diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index d3264b9..eecd3dc 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -419,7 +419,8 @@ static u32 evergreen_line_buffer_adjust(struct 
radeon_device *rdev,
                                        struct drm_display_mode *mode,
                                        struct drm_display_mode *other_mode)
 {
-       u32 tmp;
+       u32 tmp, buffer_alloc, i;
+       u32 pipe_offset = radeon_crtc->crtc_id * 0x20;
        /*
         * Line Buffer Setup
         * There are 3 line buffers, each one shared by 2 display controllers.
@@ -442,18 +443,34 @@ static u32 evergreen_line_buffer_adjust(struct 
radeon_device *rdev,
         * non-linked crtcs for maximum line buffer allocation.
         */
        if (radeon_crtc->base.enabled && mode) {
-               if (other_mode)
+               if (other_mode) {
                        tmp = 0; /* 1/2 */
-               else
+                       buffer_alloc = 1;
+               } else {
                        tmp = 2; /* whole */
-       } else
+                       buffer_alloc = 2;
+               }
+       } else {
                tmp = 0;
+               buffer_alloc = 0;
+       }
 
        /* second controller of the pair uses second half of the lb */
        if (radeon_crtc->crtc_id % 2)
                tmp += 4;
        WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp);
 
+       if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
+               WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset,
+                      DMIF_BUFFERS_ALLOCATED(buffer_alloc));
+               for (i = 0; i < rdev->usec_timeout; i++) {
+                       if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) &
+                           DMIF_BUFFERS_ALLOCATED_COMPLETED)
+                               break;
+                       udelay(1);
+               }
+       }
+
        if (radeon_crtc->base.enabled && mode) {
                switch (tmp) {
                case 0:
diff --git a/drivers/gpu/drm/radeon/evergreend.h 
b/drivers/gpu/drm/radeon/evergreend.h
index 6078ae4..ab670c3 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -450,6 +450,10 @@
 #       define LATENCY_LOW_WATERMARK(x)                   ((x) << 0)
 #       define LATENCY_HIGH_WATERMARK(x)                  ((x) << 16)
 
+#define        PIPE0_DMIF_BUFFER_CONTROL                         0x0ca0
+#       define DMIF_BUFFERS_ALLOCATED(x)                  ((x) << 0)
+#       define DMIF_BUFFERS_ALLOCATED_COMPLETED           (1 << 4)
+
 #define IH_RB_CNTL                                        0x3e00
 #       define IH_RB_ENABLE                               (1 << 0)
 #       define IH_IB_SIZE(x)                              ((x) << 1) /* log2 */
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c 
b/drivers/gpu/drm/radeon/radeon_atombios.c
index b1aade0..f9d49e3 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -751,13 +751,16 @@ bool 
radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                                
(ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
                                                                (ctx->bios + 
data_offset +
                                                                 
le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset));
+                                                       u8 *num_dst_objs = (u8 
*)
+                                                               ((u8 
*)router_src_dst_table + 1 +
+                                                                
(router_src_dst_table->ucNumberOfSrc * 2));
+                                                       u16 *dst_objs = (u16 
*)(num_dst_objs + 1);
                                                        int enum_id;
 
                                                        router.router_id = 
router_obj_id;
-                                                       for (enum_id = 0; 
enum_id < router_src_dst_table->ucNumberOfDst;
-                                                            enum_id++) {
+                                                       for (enum_id = 0; 
enum_id < (*num_dst_objs); enum_id++) {
                                                                if 
(le16_to_cpu(path->usConnObjectId) ==
-                                                                   
le16_to_cpu(router_src_dst_table->usDstObjectID[enum_id]))
+                                                                   
le16_to_cpu(dst_objs[enum_id]))
                                                                        break;
                                                        }
 
@@ -1658,7 +1661,9 @@ struct radeon_encoder_atom_dig 
*radeon_atombios_get_lvds_info(struct
                                                                kfree(edid);
                                                }
                                        }
-                                       record += 
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
+                                       record += 
fake_edid_record->ucFakeEDIDLength ?
+                                               
fake_edid_record->ucFakeEDIDLength + 2 :
+                                               
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
                                        break;
                                case LCD_PANEL_RESOLUTION_RECORD_TYPE:
                                        panel_res_record = 
(ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index aa6a66e..317eac1 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -174,10 +174,13 @@ int rs400_gart_enable(struct radeon_device *rdev)
        /* FIXME: according to doc we should set HIDE_MMCFG_BAR=0,
         * AGPMODE30=0 & AGP30ENHANCED=0 in NB_CNTL */
        if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) {
-               WREG32_MC(RS480_MC_MISC_CNTL,
-                         (RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN));
+               tmp = RREG32_MC(RS480_MC_MISC_CNTL);
+               tmp |= RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN;
+               WREG32_MC(RS480_MC_MISC_CNTL, tmp);
        } else {
-               WREG32_MC(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN);
+               tmp = RREG32_MC(RS480_MC_MISC_CNTL);
+               tmp |= RS480_GART_INDEX_REG_EN;
+               WREG32_MC(RS480_MC_MISC_CNTL, tmp);
        }
        /* Enable gart */
        WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg));
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index a9c2b68..8fa2cd7 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -815,6 +815,64 @@ static int search(__s32 *array, __s32 value, unsigned n)
        return -1;
 }
 
+static const char * const hid_report_names[] = {
+       "HID_INPUT_REPORT",
+       "HID_OUTPUT_REPORT",
+       "HID_FEATURE_REPORT",
+};
+/**
+ * hid_validate_values - validate existing device report's value indexes
+ *
+ * @device: hid device
+ * @type: which report type to examine
+ * @id: which report ID to examine (0 for first)
+ * @field_index: which report field to examine
+ * @report_counts: expected number of values
+ *
+ * Validate the number of values in a given field of a given report, after
+ * parsing.
+ */
+struct hid_report *hid_validate_values(struct hid_device *hid,
+                                      unsigned int type, unsigned int id,
+                                      unsigned int field_index,
+                                      unsigned int report_counts)
+{
+       struct hid_report *report;
+
+       if (type > HID_FEATURE_REPORT) {
+               hid_err(hid, "invalid HID report type %u\n", type);
+               return NULL;
+       }
+
+       if (id >= HID_MAX_IDS) {
+               hid_err(hid, "invalid HID report id %u\n", id);
+               return NULL;
+       }
+
+       /*
+        * Explicitly not using hid_get_report() here since it depends on
+        * ->numbered being checked, which may not always be the case when
+        * drivers go to access report values.
+        */
+       report = hid->report_enum[type].report_id_hash[id];
+       if (!report) {
+               hid_err(hid, "missing %s %u\n", hid_report_names[type], id);
+               return NULL;
+       }
+       if (report->maxfield <= field_index) {
+               hid_err(hid, "not enough fields in %s %u\n",
+                       hid_report_names[type], id);
+               return NULL;
+       }
+       if (report->field[field_index]->report_count < report_counts) {
+               hid_err(hid, "not enough values in %s %u field %u\n",
+                       hid_report_names[type], id, field_index);
+               return NULL;
+       }
+       return report;
+}
+EXPORT_SYMBOL_GPL(hid_validate_values);
+
 /**
  * hid_match_report - check if driver's raw_event should be called
  *
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index f31fab0..5c8f628 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -69,21 +69,13 @@ static int zpff_init(struct hid_device *hid)
        struct hid_report *report;
        struct hid_input *hidinput = list_entry(hid->inputs.next,
                                                struct hid_input, list);
-       struct list_head *report_list =
-                       &hid->report_enum[HID_OUTPUT_REPORT].report_list;
        struct input_dev *dev = hidinput->input;
-       int error;
+       int i, error;
 
-       if (list_empty(report_list)) {
-               hid_err(hid, "no output report found\n");
-               return -ENODEV;
-       }
-
-       report = list_entry(report_list->next, struct hid_report, list);
-
-       if (report->maxfield < 4) {
-               hid_err(hid, "not enough fields in report\n");
-               return -ENODEV;
+       for (i = 0; i < 4; i++) {
+               report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1);
+               if (!report)
+                       return -ENODEV;
        }
 
        zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index d429f0a..26e4cca 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -311,8 +311,9 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue 
*rx_queue,
 
        index = rx_queue->added_count & rx_queue->ptr_mask;
        new_buf = efx_rx_buffer(rx_queue, index);
-       new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1);
        new_buf->u.page = rx_buf->u.page;
+       new_buf->page_offset = rx_buf->page_offset ^ (PAGE_SIZE >> 1);
+       new_buf->dma_addr = state->dma_addr + new_buf->page_offset;
        new_buf->len = rx_buf->len;
        new_buf->is_page = true;
        ++rx_queue->added_count;
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 544c309..e48a677 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -615,6 +615,11 @@ static const struct usb_device_id  products [] = {
        .bInterfaceProtocol     = USB_CDC_PROTO_NONE,
        .driver_info = (unsigned long)&wwan_info,
 }, {
+       /* Telit modules */
+       USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+       .driver_info = (kernel_ulong_t) &wwan_info,
+}, {
        USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
                        USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long) &cdc_info,
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c 
b/drivers/net/wireless/rt2x00/rt2800lib.c
index 9457987..62b92c4 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1861,6 +1861,13 @@ static int rt2800_get_gain_calibration_delta(struct 
rt2x00_dev *rt2x00dev)
        int i;
 
        /*
+        * First check if temperature compensation is supported.
+        */
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+       if (!rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC))
+               return 0;
+
+       /*
         * Read TSSI boundaries for temperature compensation from
         * the EEPROM.
         *
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 3fd16d7..acc53e2 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1747,7 +1747,7 @@ iscsi_if_rx(struct sk_buff *skb)
                                break;
                        err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
                                nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
-               } while (err < 0 && err != -ECONNREFUSED);
+               } while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
                skb_pull(skb, rlen);
        }
        mutex_unlock(&rx_queue_mutex);
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index a506360..0c2f912 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -18,6 +18,12 @@ static bool should_merge(struct fsnotify_event *old, struct 
fsnotify_event *new)
            old->tgid == new->tgid) {
                switch (old->data_type) {
                case (FSNOTIFY_EVENT_PATH):
+#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
+                       /* dont merge two permission events */
+                       if ((old->mask & FAN_ALL_PERM_EVENTS) &&
+                           (new->mask & FAN_ALL_PERM_EVENTS))
+                               return false;
+#endif
                        if ((old->path.mnt == new->path.mnt) &&
                            (old->path.dentry == new->path.dentry))
                                return true;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index af30c64..4649e29 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -713,6 +713,10 @@ void hid_output_report(struct hid_report *report, __u8 
*data);
 struct hid_device *hid_allocate_device(void);
 struct hid_report *hid_register_report(struct hid_device *device, unsigned 
type, unsigned id);
 int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
+struct hid_report *hid_validate_values(struct hid_device *hid,
+                                      unsigned int type, unsigned int id,
+                                      unsigned int field_index,
+                                      unsigned int report_counts);
 int hid_check_keys_pressed(struct hid_device *hid);
 int hid_connect(struct hid_device *hid, unsigned int connect_mask);
 void hid_disconnect(struct hid_device *hid);
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 67b9fbc..e4d3640 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -939,7 +939,7 @@ struct perf_cpu_context {
        int                             exclusive;
        struct list_head                rotation_list;
        int                             jiffies_interval;
-       struct pmu                      *active_pmu;
+       struct pmu                      *unique_pmu;
        struct perf_cgroup              *cgrp;
 };
 
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 5d40afe..38f7f76 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -3498,6 +3498,7 @@ static int cgroup_write_event_control(struct cgroup 
*cgrp, struct cftype *cft,
                                      const char *buffer)
 {
        struct cgroup_event *event = NULL;
+       struct cgroup *cgrp_cfile;
        unsigned int efd, cfd;
        struct file *efile = NULL;
        struct file *cfile = NULL;
@@ -3552,6 +3553,16 @@ static int cgroup_write_event_control(struct cgroup 
*cgrp, struct cftype *cft,
                goto fail;
        }
 
+       /*
+        * The file to be monitored must be in the same cgroup as
+        * cgroup.event_control is.
+        */
+       cgrp_cfile = __d_cgrp(cfile->f_dentry->d_parent);
+       if (cgrp_cfile != cgrp) {
+               ret = -EINVAL;
+               goto fail;
+       }
+
        if (!event->cft->register_event || !event->cft->unregister_event) {
                ret = -EINVAL;
                goto fail;
diff --git a/kernel/events/core.c b/kernel/events/core.c
index a8102d2..acdc087 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -342,6 +342,8 @@ void perf_cgroup_switch(struct task_struct *task, int mode)
        list_for_each_entry_rcu(pmu, &pmus, entry) {
 
                cpuctx = this_cpu_ptr(pmu->pmu_cpu_context);
+               if (cpuctx->unique_pmu != pmu)
+                       continue; /* ensure we process each cpuctx once */
 
                perf_pmu_disable(cpuctx->ctx.pmu);
 
@@ -365,9 +367,10 @@ void perf_cgroup_switch(struct task_struct *task, int mode)
 
                        if (mode & PERF_CGROUP_SWIN) {
                                WARN_ON_ONCE(cpuctx->cgrp);
-                               /* set cgrp before ctxsw in to
-                                * allow event_filter_match() to not
-                                * have to pass task around
+                               /*
+                                * set cgrp before ctxsw in to allow
+                                * event_filter_match() to not have to pass
+                                * task around
                                 */
                                cpuctx->cgrp = perf_cgroup_from_task(task);
                                cpu_ctx_sched_in(cpuctx, EVENT_ALL, task);
@@ -4579,7 +4582,7 @@ static void perf_event_task_event(struct perf_task_event 
*task_event)
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
-               if (cpuctx->active_pmu != pmu)
+               if (cpuctx->unique_pmu != pmu)
                        goto next;
                perf_event_task_ctx(&cpuctx->ctx, task_event);
 
@@ -4725,7 +4728,7 @@ static void perf_event_comm_event(struct perf_comm_event 
*comm_event)
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
-               if (cpuctx->active_pmu != pmu)
+               if (cpuctx->unique_pmu != pmu)
                        goto next;
                perf_event_comm_ctx(&cpuctx->ctx, comm_event);
 
@@ -4921,7 +4924,7 @@ got_name:
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
-               if (cpuctx->active_pmu != pmu)
+               if (cpuctx->unique_pmu != pmu)
                        goto next;
                perf_event_mmap_ctx(&cpuctx->ctx, mmap_event,
                                        vma->vm_flags & VM_EXEC);
@@ -5947,8 +5950,8 @@ static void update_pmu_context(struct pmu *pmu, struct 
pmu *old_pmu)
 
                cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
 
-               if (cpuctx->active_pmu == old_pmu)
-                       cpuctx->active_pmu = pmu;
+               if (cpuctx->unique_pmu == old_pmu)
+                       cpuctx->unique_pmu = pmu;
        }
 }
 
@@ -6080,7 +6083,7 @@ skip_type:
                cpuctx->ctx.pmu = pmu;
                cpuctx->jiffies_interval = 1;
                INIT_LIST_HEAD(&cpuctx->rotation_list);
-               cpuctx->active_pmu = pmu;
+               cpuctx->unique_pmu = pmu;
        }
 
 got_cpu_context:
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index edac24a..6e0f882 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1604,9 +1604,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                                        asoc->outqueue.outstanding_bytes;
                        sackh.num_gap_ack_blocks = 0;
                        sackh.num_dup_tsns = 0;
-                       chunk->subh.sack_hdr = &sackh;
                        sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK,
-                                       SCTP_CHUNK(chunk));
+                                       SCTP_SACKH(&sackh));
                        break;
 
                case SCTP_CMD_DISCARD_PACKET:
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index d793001..ba3d9df 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -2044,6 +2044,9 @@ sub process_file($) {
 
     $section_counter = 0;
     while (<IN>) {
+       while (s/\\\s*$//) {
+           $_ .= <IN>;
+       }
        if ($state == 0) {
            if (/$doc_start/o) {
                $state = 1;             # next line is always the function name
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 9a5d1b9..84e157e 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -16,6 +16,7 @@ const char *map_type__name[MAP__NR_TYPES] = {
 static inline int is_anon_memory(const char *filename)
 {
        return !strcmp(filename, "//anon") ||
+              !strcmp(filename, "/dev/zero (deleted)") ||
               !strcmp(filename, "/anon_hugepage (deleted)");
 }
 
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to