]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/alsa-post-ga-hda-internal-binary-compat
Disable build of xen kernel.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / alsa-post-ga-hda-internal-binary-compat
1 From: Takashi Iwai <tiwai@suse.de>
2 Subject: ALSA: hda - keep internal structure binary compatibility
3 Patch-mainline: NEVER EVER PUSH THIS EVIL!!
4 References: bnc#497341
5
6 Add evil hacks to keep the *INTERNAL* binary compatibility, which
7 agrmodem driver pokes around. We fake the old bus_ops.
8
9 Signed-off-by: Takashi Iwai <tiwai@suse.de>
10
11 ---
12 sound/pci/hda/hda_codec.c | 28 ++++++++++++++++++++++++++++
13 sound/pci/hda/hda_codec.h | 22 +++++++++++++++++++---
14 sound/pci/hda/hda_intel.c | 39 ++++++++++++++++++++++++++++-----------
15 3 files changed, 75 insertions(+), 14 deletions(-)
16
17 --- a/sound/pci/hda/hda_codec.h
18 +++ b/sound/pci/hda/hda_codec.h
19 @@ -549,6 +549,17 @@
20 #endif
21 };
22
23 +/* old hda_bus_ops struct -- just for really evil binary compatibility issues */
24 +struct hda_old_bus_ops {
25 + int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct,
26 + unsigned int verb, unsigned int parm);
27 + unsigned int (*get_response)(struct hda_codec *codec);
28 + void (*private_free)(struct hda_bus *);
29 +#ifdef CONFIG_SND_HDA_POWER_SAVE
30 + void (*pm_notify)(struct hda_codec *codec);
31 +#endif
32 +};
33 +
34 /* template to pass to the bus constructor */
35 struct hda_bus_template {
36 void *private_data;
37 @@ -570,7 +581,7 @@
38 void *private_data;
39 struct pci_dev *pci;
40 const char *modelname;
41 - struct hda_bus_ops ops;
42 + struct hda_old_bus_ops old_ops; /* old ops; for binary compatibility */
43
44 /* codec linked list */
45 struct list_head codec_list;
46 @@ -581,8 +592,6 @@
47
48 /* unsolicited event queue */
49 struct hda_bus_unsolicited *unsol;
50 - char workq_name[16];
51 - struct workqueue_struct *workq; /* common workqueue for codecs */
52
53 struct snd_info_entry *proc;
54
55 @@ -594,6 +603,13 @@
56 unsigned int rirb_error:1; /* error in codec communication */
57 unsigned int response_reset:1; /* controller was reset */
58 unsigned int in_reset:1; /* during reset operation */
59 +
60 + /* real ops */
61 + struct hda_bus_ops ops;
62 +
63 + /* additional workq stuff */
64 + char workq_name[16];
65 + struct workqueue_struct *workq; /* common workqueue for codecs */
66 };
67
68 /*
69 --- a/sound/pci/hda/hda_intel.c
70 +++ b/sound/pci/hda/hda_intel.c
71 @@ -306,9 +306,6 @@
72 unsigned int period_bytes; /* size of the period in bytes */
73 unsigned int frags; /* number for period in the play buffer */
74 unsigned int fifo_size; /* FIFO size */
75 - unsigned int start_flag: 1; /* stream full start flag */
76 - unsigned long start_jiffies; /* start + minimum jiffies */
77 - unsigned long min_jiffies; /* minimum jiffies before position is valid */
78
79 void __iomem *sd_addr; /* stream descriptor pointer */
80
81 @@ -327,6 +324,7 @@
82 unsigned int opened :1;
83 unsigned int running :1;
84 unsigned int irq_pending :1;
85 + unsigned int irq_ignore :1; /* not used; just placeholder for compat */
86 /*
87 * For VIA:
88 * A flag to ensure DMA position is 0
89 @@ -335,6 +333,14 @@
90 unsigned int insufficient :1;
91 };
92
93 +/* new stuff; moved here to keep bloody binary compatibility */
94 +struct azx_dev_ext {
95 + unsigned int start_flag: 1; /* stream full start flag */
96 + unsigned long start_jiffies; /* start + minimum jiffies */
97 + unsigned long min_jiffies; /* minimum jiffies before position is valid */
98 +
99 +};
100 +
101 /* CORB/RIRB */
102 struct azx_rb {
103 u32 *buf; /* CORB/RIRB buffer
104 @@ -377,7 +383,6 @@
105
106 /* HD codec */
107 unsigned short codec_mask;
108 - int codec_probe_mask; /* copied from probe_mask option */
109 struct hda_bus *bus;
110
111 /* CORB/RIRB */
112 @@ -407,6 +412,10 @@
113
114 /* reboot notifier (for mysterious hangup problem at power-down) */
115 struct notifier_block reboot_notifier;
116 +
117 + /* moved here for binary compatibility */
118 + struct azx_dev_ext *azx_dev_ext;
119 + int codec_probe_mask; /* copied from probe_mask option */
120 };
121
122 /* driver types */
123 @@ -1497,6 +1506,7 @@
124 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
125 struct azx *chip = apcm->chip;
126 struct azx_dev *azx_dev = get_azx_dev(substream);
127 + struct azx_dev_ext *azx_dev_ext;
128 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
129 struct snd_pcm_runtime *runtime = substream->runtime;
130 unsigned int bufsize, period_bytes, format_val;
131 @@ -1531,7 +1541,8 @@
132 return err;
133 }
134
135 - azx_dev->min_jiffies = (runtime->period_size * HZ) /
136 + azx_dev_ext = &chip->azx_dev_ext[azx_dev->index];
137 + azx_dev_ext->min_jiffies = (runtime->period_size * HZ) /
138 (runtime->rate * 2);
139 azx_setup_controller(chip, azx_dev);
140 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
141 @@ -1548,6 +1559,7 @@
142 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
143 struct azx *chip = apcm->chip;
144 struct azx_dev *azx_dev;
145 + struct azx_dev_ext *azx_dev_ext;
146 struct snd_pcm_substream *s;
147 int rstart = 0, start, nsync = 0, sbits = 0;
148 int nwait, timeout;
149 @@ -1586,9 +1598,10 @@
150 if (s->pcm->card != substream->pcm->card)
151 continue;
152 azx_dev = get_azx_dev(s);
153 + azx_dev_ext = &chip->azx_dev_ext[azx_dev->index];
154 if (rstart) {
155 - azx_dev->start_flag = 1;
156 - azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies;
157 + azx_dev_ext->start_flag = 1;
158 + azx_dev_ext->start_jiffies = jiffies + azx_dev_ext->min_jiffies;
159 }
160 if (start)
161 azx_stream_start(chip, azx_dev);
162 @@ -1738,11 +1751,12 @@
163 static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
164 {
165 unsigned int pos;
166 + struct azx_dev_ext *azx_dev_ext = &chip->azx_dev_ext[azx_dev->index];
167
168 - if (azx_dev->start_flag &&
169 - time_before_eq(jiffies, azx_dev->start_jiffies))
170 + if (azx_dev_ext->start_flag &&
171 + time_before_eq(jiffies, azx_dev_ext->start_jiffies))
172 return -1; /* bogus (too early) interrupt */
173 - azx_dev->start_flag = 0;
174 + azx_dev_ext->start_flag = 0;
175
176 pos = azx_get_position(chip, azx_dev);
177 if (chip->position_fix == POS_FIX_AUTO) {
178 @@ -2144,6 +2158,7 @@
179 pci_release_regions(chip->pci);
180 pci_disable_device(chip->pci);
181 kfree(chip->azx_dev);
182 + kfree(chip->azx_dev_ext);
183 kfree(chip);
184
185 return 0;
186 @@ -2376,7 +2391,9 @@
187 chip->num_streams = chip->playback_streams + chip->capture_streams;
188 chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
189 GFP_KERNEL);
190 - if (!chip->azx_dev) {
191 + chip->azx_dev_ext = kcalloc(chip->num_streams,
192 + sizeof(*chip->azx_dev_ext), GFP_KERNEL);
193 + if (!chip->azx_dev || !chip->azx_dev_ext) {
194 snd_printk(KERN_ERR "cannot malloc azx_dev\n");
195 goto errout;
196 }
197 --- a/sound/pci/hda/hda_codec.c
198 +++ b/sound/pci/hda/hda_codec.c
199 @@ -485,6 +485,28 @@
200 return snd_hda_bus_free(bus);
201 }
202
203 +/*
204 + * backward-compatible ops
205 + */
206 +static int old_bus_ops_command(struct hda_codec *codec, hda_nid_t nid,
207 + int direct, unsigned int verb, unsigned int parm)
208 +{
209 + unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm);
210 + return codec->bus->ops.command(codec->bus, cmd);
211 +}
212 +
213 +static unsigned int old_bus_ops_get_response(struct hda_codec *codec)
214 +{
215 + return codec->bus->ops.get_response(codec->bus);
216 +}
217 +
218 +#ifdef CONFIG_SND_HDA_POWER_SAVE
219 +static void old_bus_ops_pm_notify(struct hda_codec *codec)
220 +{
221 + codec->bus->ops.pm_notify(codec->bus);
222 +}
223 +#endif
224 +
225 /**
226 * snd_hda_bus_new - create a HDA bus
227 * @card: the card entry
228 @@ -520,6 +542,12 @@
229 bus->pci = temp->pci;
230 bus->modelname = temp->modelname;
231 bus->ops = temp->ops;
232 + bus->old_ops.command = old_bus_ops_command;
233 + bus->old_ops.get_response = old_bus_ops_get_response;
234 + bus->old_ops.private_free = bus->ops.private_free;
235 +#ifdef CONFIG_SND_HDA_POWER_SAVE
236 + bus->old_ops.pm_notify = old_bus_ops_pm_notify;
237 +#endif
238
239 mutex_init(&bus->cmd_mutex);
240 INIT_LIST_HEAD(&bus->codec_list);