Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Jul 2010 22:21:44 +0000 (15:21 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Jul 2010 22:21:44 +0000 (15:21 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog:
  watchdog: update MAINTAINERS entry

Documentation/credentials.txt
fs/proc/array.c
include/linux/cred.h
include/linux/sched.h
kernel/cred.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_nvhdmi.c
sound/pci/hda/patch_realtek.c

index a2db352870036ba062aa177ce450d0d491f7d8c8..995baf379c076770962a84268fde19b527caa0be 100644 (file)
@@ -417,6 +417,9 @@ reference on them using:
 This does all the RCU magic inside of it.  The caller must call put_cred() on
 the credentials so obtained when they're finished with.
 
+ [*] Note: The result of __task_cred() should not be passed directly to
+     get_cred() as this may race with commit_cred().
+
 There are a couple of convenience functions to access bits of another task's
 credentials, hiding the RCU magic from the caller:
 
index 9b58d38bc911e27faccc7ed9ffb2c53f0885df4a..fff6572676aed7bd337b737da35221af8fa070bb 100644 (file)
@@ -176,7 +176,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
                if (tracer)
                        tpid = task_pid_nr_ns(tracer, ns);
        }
-       cred = get_cred((struct cred *) __task_cred(p));
+       cred = get_task_cred(p);
        seq_printf(m,
                "State:\t%s\n"
                "Tgid:\t%d\n"
index 75c0fa8813088c31148be71b7cbff77670b6e5d0..4d2c39573f3694cdeef07d83c6f141b4804a5f36 100644 (file)
@@ -153,6 +153,7 @@ struct cred {
 extern void __put_cred(struct cred *);
 extern void exit_creds(struct task_struct *);
 extern int copy_creds(struct task_struct *, unsigned long);
+extern const struct cred *get_task_cred(struct task_struct *);
 extern struct cred *cred_alloc_blank(void);
 extern struct cred *prepare_creds(void);
 extern struct cred *prepare_exec_creds(void);
@@ -273,33 +274,18 @@ static inline void put_cred(const struct cred *_cred)
  * @task: The task to query
  *
  * Access the objective credentials of a task.  The caller must hold the RCU
- * readlock.
+ * readlock or the task must be dead and unable to change its own credentials.
  *
- * The caller must make sure task doesn't go away, either by holding a ref on
- * task or by holding tasklist_lock to prevent it from being unlinked.
+ * The result of this function should not be passed directly to get_cred();
+ * rather get_task_cred() should be used instead.
  */
-#define __task_cred(task) \
-       ((const struct cred *)(rcu_dereference_check((task)->real_cred, rcu_read_lock_held() || lockdep_tasklist_lock_is_held())))
-
-/**
- * get_task_cred - Get another task's objective credentials
- * @task: The task to query
- *
- * Get the objective credentials of a task, pinning them so that they can't go
- * away.  Accessing a task's credentials directly is not permitted.
- *
- * The caller must make sure task doesn't go away, either by holding a ref on
- * task or by holding tasklist_lock to prevent it from being unlinked.
- */
-#define get_task_cred(task)                            \
-({                                                     \
-       struct cred *__cred;                            \
-       rcu_read_lock();                                \
-       __cred = (struct cred *) __task_cred((task));   \
-       get_cred(__cred);                               \
-       rcu_read_unlock();                              \
-       __cred;                                         \
-})
+#define __task_cred(task)                                              \
+       ({                                                              \
+               const struct task_struct *__t = (task);                 \
+               rcu_dereference_check(__t->real_cred,                   \
+                                     rcu_read_lock_held() ||           \
+                                     task_is_dead(__t));               \
+       })
 
 /**
  * get_current_cred - Get the current task's subjective credentials
index 747fcaedddb70d6cb0a49b43c0d2f2a6f23a693f..0478888c6899d3c59a1649d38dfdd58030f14918 100644 (file)
@@ -214,6 +214,7 @@ extern char ___assert_task_state[1 - 2*!!(
 
 #define task_is_traced(task)   ((task->state & __TASK_TRACED) != 0)
 #define task_is_stopped(task)  ((task->state & __TASK_STOPPED) != 0)
+#define task_is_dead(task)     ((task)->exit_state != 0)
 #define task_is_stopped_or_traced(task)        \
                        ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
 #define task_contributes_to_load(task) \
index a2d5504fbcc24abb44c44a158521617933df4367..60bc8b1e32e632eb2a51b318f1ae35486d01174f 100644 (file)
@@ -209,6 +209,31 @@ void exit_creds(struct task_struct *tsk)
        }
 }
 
+/**
+ * get_task_cred - Get another task's objective credentials
+ * @task: The task to query
+ *
+ * Get the objective credentials of a task, pinning them so that they can't go
+ * away.  Accessing a task's credentials directly is not permitted.
+ *
+ * The caller must also make sure task doesn't get deleted, either by holding a
+ * ref on task or by holding tasklist_lock to prevent it from being unlinked.
+ */
+const struct cred *get_task_cred(struct task_struct *task)
+{
+       const struct cred *cred;
+
+       rcu_read_lock();
+
+       do {
+               cred = __task_cred((task));
+               BUG_ON(!cred);
+       } while (!atomic_inc_not_zero(&((struct cred *)cred)->usage));
+
+       rcu_read_unlock();
+       return cred;
+}
+
 /*
  * Allocate blank credentials, such that the credentials can be filled in at a
  * later date without risk of ENOMEM.
index 86067ee786324b294be637b202b5c16e381724d0..2fc53961054ede2dc5cf3b1e62cede04a86c389a 100644 (file)
@@ -52,6 +52,10 @@ struct hdmi_spec {
         */
        struct hda_multi_out multiout;
        unsigned int codec_type;
+
+       /* misc flags */
+       /* PD bit indicates only the update, not the current state */
+       unsigned int old_pin_detect:1;
 };
 
 
@@ -616,6 +620,9 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
  * Unsolicited events
  */
 
+static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
+                              struct hdmi_eld *eld);
+
 static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
 {
        struct hdmi_spec *spec = codec->spec;
@@ -632,6 +639,12 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
        if (index < 0)
                return;
 
+       if (spec->old_pin_detect) {
+               if (pind)
+                       hdmi_present_sense(codec, tag, &spec->sink_eld[index]);
+               pind = spec->sink_eld[index].monitor_present;
+       }
+
        spec->sink_eld[index].monitor_present = pind;
        spec->sink_eld[index].eld_valid = eldv;
 
index 3c10c0b149f4c682d683a6ae21ae837b3fe18f4d..b0652acee9b2725541dc99df2af68513aa84009c 100644 (file)
@@ -478,6 +478,7 @@ static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
 
        codec->spec = spec;
        spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
+       spec->old_pin_detect = 1;
 
        if (hdmi_parse_codec(codec) < 0) {
                codec->spec = NULL;
@@ -508,6 +509,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
        spec->multiout.max_channels = 8;
        spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
        spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
+       spec->old_pin_detect = 1;
 
        codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
 
@@ -528,6 +530,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
        spec->multiout.max_channels = 2;
        spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
        spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
+       spec->old_pin_detect = 1;
 
        codec->patch_ops = nvhdmi_patch_ops_2ch;
 
index ff614dd824c1fe97cbfe9ee378b744676bc50e93..596ea2f12cf60a74504efc751a9566265d7b3aeb 100644 (file)
@@ -1267,11 +1267,11 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec)
        unsigned nid = 0;
        struct alc_spec *spec = codec->spec;
 
+       spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
+
        ass = codec->subsystem_id & 0xffff;
-       if (ass != codec->bus->pci->subsystem_device && (ass & 1)) {
-               spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
+       if (ass != codec->bus->pci->subsystem_device && (ass & 1))
                goto do_sku;
-       }
 
        nid = 0x1d;
        if (codec->vendor_id == 0x10ec0260)
@@ -5180,8 +5180,24 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
 #ifdef CONFIG_SND_HDA_INPUT_BEEP
 #define set_beep_amp(spec, nid, idx, dir) \
        ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
+
+static struct snd_pci_quirk beep_white_list[] = {
+       SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
+       {}
+};
+
+static inline int has_cdefine_beep(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       const struct snd_pci_quirk *q;
+       q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
+       if (q)
+               return q->value;
+       return spec->cdefine.enable_pcbeep;
+}
 #else
 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
+#define has_cdefine_beep(codec)                0
 #endif
 
 /*
@@ -10566,10 +10582,12 @@ static int patch_alc882(struct hda_codec *codec)
                }
        }
 
-       err = snd_hda_attach_beep_device(codec, 0x1);
-       if (err < 0) {
-               alc_free(codec);
-               return err;
+       if (has_cdefine_beep(codec)) {
+               err = snd_hda_attach_beep_device(codec, 0x1);
+               if (err < 0) {
+                       alc_free(codec);
+                       return err;
+               }
        }
 
        if (board_config != ALC882_AUTO)
@@ -10619,7 +10637,7 @@ static int patch_alc882(struct hda_codec *codec)
 
        set_capture_mixer(codec);
 
-       if (spec->cdefine.enable_pcbeep)
+       if (has_cdefine_beep(codec))
                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 
        if (board_config == ALC882_AUTO)
@@ -12435,7 +12453,7 @@ static int patch_alc262(struct hda_codec *codec)
                }
        }
 
-       if (!spec->no_analog) {
+       if (!spec->no_analog && has_cdefine_beep(codec)) {
                err = snd_hda_attach_beep_device(codec, 0x1);
                if (err < 0) {
                        alc_free(codec);
@@ -12486,7 +12504,7 @@ static int patch_alc262(struct hda_codec *codec)
        }
        if (!spec->cap_mixer && !spec->no_analog)
                set_capture_mixer(codec);
-       if (!spec->no_analog && spec->cdefine.enable_pcbeep)
+       if (!spec->no_analog && has_cdefine_beep(codec))
                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 
        spec->vmaster_nid = 0x0c;
@@ -14458,10 +14476,12 @@ static int patch_alc269(struct hda_codec *codec)
                }
        }
 
-       err = snd_hda_attach_beep_device(codec, 0x1);
-       if (err < 0) {
-               alc_free(codec);
-               return err;
+       if (has_cdefine_beep(codec)) {
+               err = snd_hda_attach_beep_device(codec, 0x1);
+               if (err < 0) {
+                       alc_free(codec);
+                       return err;
+               }
        }
 
        if (board_config != ALC269_AUTO)
@@ -14494,7 +14514,7 @@ static int patch_alc269(struct hda_codec *codec)
 
        if (!spec->cap_mixer)
                set_capture_mixer(codec);
-       if (spec->cdefine.enable_pcbeep)
+       if (has_cdefine_beep(codec))
                set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
 
        if (board_config == ALC269_AUTO)
@@ -18691,10 +18711,12 @@ static int patch_alc662(struct hda_codec *codec)
                }
        }
 
-       err = snd_hda_attach_beep_device(codec, 0x1);
-       if (err < 0) {
-               alc_free(codec);
-               return err;
+       if (has_cdefine_beep(codec)) {
+               err = snd_hda_attach_beep_device(codec, 0x1);
+               if (err < 0) {
+                       alc_free(codec);
+                       return err;
+               }
        }
 
        if (board_config != ALC662_AUTO)
@@ -18716,7 +18738,7 @@ static int patch_alc662(struct hda_codec *codec)
        if (!spec->cap_mixer)
                set_capture_mixer(codec);
 
-       if (spec->cdefine.enable_pcbeep) {
+       if (has_cdefine_beep(codec)) {
                switch (codec->vendor_id) {
                case 0x10ec0662:
                        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);