Annotation of /trunk/kernel26-alx/patches-2.6.17-r7/0101-2.6.17.8-all-fixes.patch
Parent Directory | Revision Log
Revision 199 -
(hide annotations)
(download)
Fri May 18 11:04:36 2007 UTC (17 years, 4 months ago) by niro
File size: 27634 byte(s)
Fri May 18 11:04:36 2007 UTC (17 years, 4 months ago) by niro
File size: 27634 byte(s)
-import
1 | niro | 199 | diff --git a/MAINTAINERS b/MAINTAINERS |
2 | index c3c5842..6a1bb87 100644 | ||
3 | --- a/MAINTAINERS | ||
4 | +++ b/MAINTAINERS | ||
5 | @@ -2572,6 +2572,14 @@ M: dbrownell@users.sourceforge.net | ||
6 | L: spi-devel-general@lists.sourceforge.net | ||
7 | S: Maintained | ||
8 | |||
9 | +STABLE BRANCH: | ||
10 | +P: Greg Kroah-Hartman | ||
11 | +M: greg@kroah.com | ||
12 | +P: Chris Wright | ||
13 | +M: chrisw@sous-sol.org | ||
14 | +L: stable@kernel.org | ||
15 | +S: Maintained | ||
16 | + | ||
17 | TPM DEVICE DRIVER | ||
18 | P: Kylene Hall | ||
19 | M: kjhall@us.ibm.com | ||
20 | diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c | ||
21 | index 6b1ea0c..e545b09 100644 | ||
22 | --- a/arch/i386/pci/mmconfig.c | ||
23 | +++ b/arch/i386/pci/mmconfig.c | ||
24 | @@ -15,7 +15,9 @@ #include <linux/acpi.h> | ||
25 | #include <asm/e820.h> | ||
26 | #include "pci.h" | ||
27 | |||
28 | -#define MMCONFIG_APER_SIZE (256*1024*1024) | ||
29 | +/* aperture is up to 256MB but BIOS may reserve less */ | ||
30 | +#define MMCONFIG_APER_MIN (2 * 1024*1024) | ||
31 | +#define MMCONFIG_APER_MAX (256 * 1024*1024) | ||
32 | |||
33 | /* Assume systems with more busses have correct MCFG */ | ||
34 | #define MAX_CHECK_BUS 16 | ||
35 | @@ -197,9 +199,10 @@ void __init pci_mmcfg_init(void) | ||
36 | return; | ||
37 | |||
38 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
39 | - pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | ||
40 | + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, | ||
41 | E820_RESERVED)) { | ||
42 | - printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | ||
43 | + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", | ||
44 | + pci_mmcfg_config[0].base_address); | ||
45 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
46 | return; | ||
47 | } | ||
48 | diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c | ||
49 | index a2060e4..3c55c76 100644 | ||
50 | --- a/arch/x86_64/pci/mmconfig.c | ||
51 | +++ b/arch/x86_64/pci/mmconfig.c | ||
52 | @@ -13,7 +13,10 @@ #include <asm/e820.h> | ||
53 | |||
54 | #include "pci.h" | ||
55 | |||
56 | -#define MMCONFIG_APER_SIZE (256*1024*1024) | ||
57 | +/* aperture is up to 256MB but BIOS may reserve less */ | ||
58 | +#define MMCONFIG_APER_MIN (2 * 1024*1024) | ||
59 | +#define MMCONFIG_APER_MAX (256 * 1024*1024) | ||
60 | + | ||
61 | /* Verify the first 16 busses. We assume that systems with more busses | ||
62 | get MCFG right. */ | ||
63 | #define MAX_CHECK_BUS 16 | ||
64 | @@ -175,9 +178,10 @@ void __init pci_mmcfg_init(void) | ||
65 | return; | ||
66 | |||
67 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
68 | - pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | ||
69 | + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, | ||
70 | E820_RESERVED)) { | ||
71 | - printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | ||
72 | + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", | ||
73 | + pci_mmcfg_config[0].base_address); | ||
74 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
75 | return; | ||
76 | } | ||
77 | @@ -190,7 +194,8 @@ void __init pci_mmcfg_init(void) | ||
78 | } | ||
79 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | ||
80 | pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; | ||
81 | - pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); | ||
82 | + pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, | ||
83 | + MMCONFIG_APER_MAX); | ||
84 | if (!pci_mmcfg_virt[i].virt) { | ||
85 | printk("PCI: Cannot map mmconfig aperture for segment %d\n", | ||
86 | pci_mmcfg_config[i].pci_segment_group_number); | ||
87 | diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c | ||
88 | index a88b94a..832163c 100644 | ||
89 | --- a/drivers/char/tty_io.c | ||
90 | +++ b/drivers/char/tty_io.c | ||
91 | @@ -2776,7 +2776,7 @@ static void flush_to_ldisc(void *private | ||
92 | struct tty_struct *tty = (struct tty_struct *) private_; | ||
93 | unsigned long flags; | ||
94 | struct tty_ldisc *disc; | ||
95 | - struct tty_buffer *tbuf; | ||
96 | + struct tty_buffer *tbuf, *head; | ||
97 | int count; | ||
98 | char *char_buf; | ||
99 | unsigned char *flag_buf; | ||
100 | @@ -2793,7 +2793,9 @@ static void flush_to_ldisc(void *private | ||
101 | goto out; | ||
102 | } | ||
103 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
104 | - while((tbuf = tty->buf.head) != NULL) { | ||
105 | + head = tty->buf.head; | ||
106 | + tty->buf.head = NULL; | ||
107 | + while((tbuf = head) != NULL) { | ||
108 | while ((count = tbuf->commit - tbuf->read) != 0) { | ||
109 | char_buf = tbuf->char_buf_ptr + tbuf->read; | ||
110 | flag_buf = tbuf->flag_buf_ptr + tbuf->read; | ||
111 | @@ -2802,10 +2804,12 @@ static void flush_to_ldisc(void *private | ||
112 | disc->receive_buf(tty, char_buf, flag_buf, count); | ||
113 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
114 | } | ||
115 | - if (tbuf->active) | ||
116 | + if (tbuf->active) { | ||
117 | + tty->buf.head = head; | ||
118 | break; | ||
119 | - tty->buf.head = tbuf->next; | ||
120 | - if (tty->buf.head == NULL) | ||
121 | + } | ||
122 | + head = tbuf->next; | ||
123 | + if (head == NULL) | ||
124 | tty->buf.tail = NULL; | ||
125 | tty_buffer_free(tty, tbuf); | ||
126 | } | ||
127 | diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c | ||
128 | index 766cc96..9b4f4ee 100644 | ||
129 | --- a/drivers/i2c/busses/scx200_acb.c | ||
130 | +++ b/drivers/i2c/busses/scx200_acb.c | ||
131 | @@ -181,21 +181,21 @@ static void scx200_acb_machine(struct sc | ||
132 | break; | ||
133 | |||
134 | case state_read: | ||
135 | - /* Set ACK if receiving the last byte */ | ||
136 | - if (iface->len == 1) | ||
137 | + /* Set ACK if _next_ byte will be the last one */ | ||
138 | + if (iface->len == 2) | ||
139 | outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1); | ||
140 | else | ||
141 | outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1); | ||
142 | |||
143 | - *iface->ptr++ = inb(ACBSDA); | ||
144 | - --iface->len; | ||
145 | - | ||
146 | - if (iface->len == 0) { | ||
147 | + if (iface->len == 1) { | ||
148 | iface->result = 0; | ||
149 | iface->state = state_idle; | ||
150 | outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); | ||
151 | } | ||
152 | |||
153 | + *iface->ptr++ = inb(ACBSDA); | ||
154 | + --iface->len; | ||
155 | + | ||
156 | break; | ||
157 | |||
158 | case state_write: | ||
159 | @@ -304,8 +304,12 @@ static s32 scx200_acb_smbus_xfer(struct | ||
160 | buffer = (u8 *)&cur_word; | ||
161 | break; | ||
162 | |||
163 | - case I2C_SMBUS_BLOCK_DATA: | ||
164 | + case I2C_SMBUS_I2C_BLOCK_DATA: | ||
165 | + if (rw == I2C_SMBUS_READ) | ||
166 | + data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */ | ||
167 | len = data->block[0]; | ||
168 | + if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) | ||
169 | + return -EINVAL; | ||
170 | buffer = &data->block[1]; | ||
171 | break; | ||
172 | |||
173 | @@ -369,7 +373,7 @@ static u32 scx200_acb_func(struct i2c_ad | ||
174 | { | ||
175 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | ||
176 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | | ||
177 | - I2C_FUNC_SMBUS_BLOCK_DATA; | ||
178 | + I2C_FUNC_SMBUS_I2C_BLOCK; | ||
179 | } | ||
180 | |||
181 | /* For now, we only handle combined mode (smbus) */ | ||
182 | diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c | ||
183 | index 45e2cdf..2e79137 100644 | ||
184 | --- a/drivers/i2c/i2c-core.c | ||
185 | +++ b/drivers/i2c/i2c-core.c | ||
186 | @@ -756,9 +756,9 @@ int i2c_probe(struct i2c_adapter *adapte | ||
187 | "parameter for adapter %d, " | ||
188 | "addr 0x%02x\n", adap_id, | ||
189 | address_data->ignore[j + 1]); | ||
190 | + ignore = 1; | ||
191 | + break; | ||
192 | } | ||
193 | - ignore = 1; | ||
194 | - break; | ||
195 | } | ||
196 | if (ignore) | ||
197 | continue; | ||
198 | diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c | ||
199 | index 5413dc4..e084dbf 100644 | ||
200 | --- a/drivers/ieee1394/sbp2.c | ||
201 | +++ b/drivers/ieee1394/sbp2.c | ||
202 | @@ -2541,6 +2541,9 @@ static int sbp2scsi_slave_configure(stru | ||
203 | sdev->skip_ms_page_8 = 1; | ||
204 | if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) | ||
205 | sdev->fix_capacity = 1; | ||
206 | + if (scsi_id->ne->guid_vendor_id == 0x0010b9 && /* Maxtor's OUI */ | ||
207 | + (sdev->type == TYPE_DISK || sdev->type == TYPE_RBC)) | ||
208 | + sdev->allow_restart = 1; | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c | ||
213 | index aaaae40..3f4aa08 100644 | ||
214 | --- a/drivers/media/dvb/ttpci/budget-av.c | ||
215 | +++ b/drivers/media/dvb/ttpci/budget-av.c | ||
216 | @@ -58,6 +58,7 @@ struct budget_av { | ||
217 | struct tasklet_struct ciintf_irq_tasklet; | ||
218 | int slot_status; | ||
219 | struct dvb_ca_en50221 ca; | ||
220 | + u8 reinitialise_demod:1; | ||
221 | }; | ||
222 | |||
223 | /* GPIO Connections: | ||
224 | @@ -214,8 +215,9 @@ static int ciintf_slot_reset(struct dvb_ | ||
225 | while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) | ||
226 | msleep(100); | ||
227 | |||
228 | - /* reinitialise the frontend */ | ||
229 | - dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); | ||
230 | + /* reinitialise the frontend if necessary */ | ||
231 | + if (budget_av->reinitialise_demod) | ||
232 | + dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); | ||
233 | |||
234 | if (timeout <= 0) | ||
235 | { | ||
236 | @@ -1064,12 +1066,10 @@ static void frontend_init(struct budget_ | ||
237 | fe = tda10021_attach(&philips_cu1216_config, | ||
238 | &budget_av->budget.i2c_adap, | ||
239 | read_pwm(budget_av)); | ||
240 | - if (fe) { | ||
241 | - fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; | ||
242 | - } | ||
243 | break; | ||
244 | |||
245 | case SUBID_DVBC_KNC1_PLUS: | ||
246 | + budget_av->reinitialise_demod = 1; | ||
247 | fe = tda10021_attach(&philips_cu1216_config, | ||
248 | &budget_av->budget.i2c_adap, | ||
249 | read_pwm(budget_av)); | ||
250 | diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c | ||
251 | index 523c2c9..c5e7023 100644 | ||
252 | --- a/drivers/net/e1000/e1000_hw.c | ||
253 | +++ b/drivers/net/e1000/e1000_hw.c | ||
254 | @@ -353,6 +353,7 @@ e1000_set_mac_type(struct e1000_hw *hw) | ||
255 | case E1000_DEV_ID_82572EI_COPPER: | ||
256 | case E1000_DEV_ID_82572EI_FIBER: | ||
257 | case E1000_DEV_ID_82572EI_SERDES: | ||
258 | + case E1000_DEV_ID_82572EI: | ||
259 | hw->mac_type = e1000_82572; | ||
260 | break; | ||
261 | case E1000_DEV_ID_82573E: | ||
262 | diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h | ||
263 | index 150e45e..c01e5d2 100644 | ||
264 | --- a/drivers/net/e1000/e1000_hw.h | ||
265 | +++ b/drivers/net/e1000/e1000_hw.h | ||
266 | @@ -462,6 +462,7 @@ #define E1000_DEV_ID_82571EB_SERDES | ||
267 | #define E1000_DEV_ID_82572EI_COPPER 0x107D | ||
268 | #define E1000_DEV_ID_82572EI_FIBER 0x107E | ||
269 | #define E1000_DEV_ID_82572EI_SERDES 0x107F | ||
270 | +#define E1000_DEV_ID_82572EI 0x10B9 | ||
271 | #define E1000_DEV_ID_82573E 0x108B | ||
272 | #define E1000_DEV_ID_82573E_IAMT 0x108C | ||
273 | #define E1000_DEV_ID_82573L 0x109A | ||
274 | diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c | ||
275 | index fba1e4d..a3cd0b3 100644 | ||
276 | --- a/drivers/net/sky2.c | ||
277 | +++ b/drivers/net/sky2.c | ||
278 | @@ -2187,9 +2187,6 @@ static int sky2_poll(struct net_device * | ||
279 | int work_done = 0; | ||
280 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); | ||
281 | |||
282 | - if (!~status) | ||
283 | - goto out; | ||
284 | - | ||
285 | if (status & Y2_IS_HW_ERR) | ||
286 | sky2_hw_intr(hw); | ||
287 | |||
288 | @@ -2226,7 +2223,7 @@ static int sky2_poll(struct net_device * | ||
289 | |||
290 | if (sky2_more_work(hw)) | ||
291 | return 1; | ||
292 | -out: | ||
293 | + | ||
294 | netif_rx_complete(dev0); | ||
295 | |||
296 | sky2_read32(hw, B0_Y2_SP_LISR); | ||
297 | diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c | ||
298 | index a06d84c..27909bc 100644 | ||
299 | --- a/drivers/usb/host/uhci-q.c | ||
300 | +++ b/drivers/usb/host/uhci-q.c | ||
301 | @@ -896,12 +896,14 @@ static int uhci_result_common(struct uhc | ||
302 | /* | ||
303 | * This URB stopped short of its end. We have to | ||
304 | * fix up the toggles of the following URBs on the | ||
305 | - * queue and restart the queue. | ||
306 | + * queue and restart the queue. But only if this | ||
307 | + * TD isn't the last one in the URB. | ||
308 | * | ||
309 | * Do this only the first time we encounter the | ||
310 | * short URB. | ||
311 | */ | ||
312 | - if (!urbp->short_transfer) { | ||
313 | + if (!urbp->short_transfer && | ||
314 | + &td->list != urbp->td_list.prev) { | ||
315 | urbp->short_transfer = 1; | ||
316 | urbp->qh->initial_toggle = | ||
317 | uhci_toggle(td_token(td)) ^ 1; | ||
318 | diff --git a/fs/buffer.c b/fs/buffer.c | ||
319 | index 23f1f3a..7f6d659 100644 | ||
320 | --- a/fs/buffer.c | ||
321 | +++ b/fs/buffer.c | ||
322 | @@ -473,13 +473,18 @@ out: | ||
323 | pass does the actual I/O. */ | ||
324 | void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers) | ||
325 | { | ||
326 | + struct address_space *mapping = bdev->bd_inode->i_mapping; | ||
327 | + | ||
328 | + if (mapping->nrpages == 0) | ||
329 | + return; | ||
330 | + | ||
331 | invalidate_bh_lrus(); | ||
332 | /* | ||
333 | * FIXME: what about destroy_dirty_buffers? | ||
334 | * We really want to use invalidate_inode_pages2() for | ||
335 | * that, but not until that's cleaned up. | ||
336 | */ | ||
337 | - invalidate_inode_pages(bdev->bd_inode->i_mapping); | ||
338 | + invalidate_inode_pages(mapping); | ||
339 | } | ||
340 | |||
341 | /* | ||
342 | diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c | ||
343 | index 2edd7ee..21b8bf4 100644 | ||
344 | --- a/fs/ext3/inode.c | ||
345 | +++ b/fs/ext3/inode.c | ||
346 | @@ -1159,7 +1159,7 @@ retry: | ||
347 | ret = PTR_ERR(handle); | ||
348 | goto out; | ||
349 | } | ||
350 | - if (test_opt(inode->i_sb, NOBH)) | ||
351 | + if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) | ||
352 | ret = nobh_prepare_write(page, from, to, ext3_get_block); | ||
353 | else | ||
354 | ret = block_prepare_write(page, from, to, ext3_get_block); | ||
355 | @@ -1245,7 +1245,7 @@ static int ext3_writeback_commit_write(s | ||
356 | if (new_i_size > EXT3_I(inode)->i_disksize) | ||
357 | EXT3_I(inode)->i_disksize = new_i_size; | ||
358 | |||
359 | - if (test_opt(inode->i_sb, NOBH)) | ||
360 | + if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) | ||
361 | ret = nobh_commit_write(file, page, from, to); | ||
362 | else | ||
363 | ret = generic_commit_write(file, page, from, to); | ||
364 | @@ -1495,7 +1495,7 @@ static int ext3_writeback_writepage(stru | ||
365 | goto out_fail; | ||
366 | } | ||
367 | |||
368 | - if (test_opt(inode->i_sb, NOBH)) | ||
369 | + if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) | ||
370 | ret = nobh_writepage(page, ext3_get_block, wbc); | ||
371 | else | ||
372 | ret = block_write_full_page(page, ext3_get_block, wbc); | ||
373 | @@ -2402,14 +2402,15 @@ static unsigned long ext3_get_inode_bloc | ||
374 | struct buffer_head *bh; | ||
375 | struct ext3_group_desc * gdp; | ||
376 | |||
377 | - | ||
378 | - if ((ino != EXT3_ROOT_INO && ino != EXT3_JOURNAL_INO && | ||
379 | - ino != EXT3_RESIZE_INO && ino < EXT3_FIRST_INO(sb)) || | ||
380 | - ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) { | ||
381 | - ext3_error(sb, "ext3_get_inode_block", | ||
382 | - "bad inode number: %lu", ino); | ||
383 | + if (!ext3_valid_inum(sb, ino)) { | ||
384 | + /* | ||
385 | + * This error is already checked for in namei.c unless we are | ||
386 | + * looking at an NFS filehandle, in which case no error | ||
387 | + * report is needed | ||
388 | + */ | ||
389 | return 0; | ||
390 | } | ||
391 | + | ||
392 | block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb); | ||
393 | if (block_group >= EXT3_SB(sb)->s_groups_count) { | ||
394 | ext3_error(sb,"ext3_get_inode_block","group >= groups count"); | ||
395 | diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c | ||
396 | index b8f5cd1..7be89fe 100644 | ||
397 | --- a/fs/ext3/namei.c | ||
398 | +++ b/fs/ext3/namei.c | ||
399 | @@ -1000,7 +1000,12 @@ static struct dentry *ext3_lookup(struct | ||
400 | if (bh) { | ||
401 | unsigned long ino = le32_to_cpu(de->inode); | ||
402 | brelse (bh); | ||
403 | - inode = iget(dir->i_sb, ino); | ||
404 | + if (!ext3_valid_inum(dir->i_sb, ino)) { | ||
405 | + ext3_error(dir->i_sb, "ext3_lookup", | ||
406 | + "bad inode number: %lu", ino); | ||
407 | + inode = NULL; | ||
408 | + } else | ||
409 | + inode = iget(dir->i_sb, ino); | ||
410 | |||
411 | if (!inode) | ||
412 | return ERR_PTR(-EACCES); | ||
413 | @@ -1028,7 +1033,13 @@ struct dentry *ext3_get_parent(struct de | ||
414 | return ERR_PTR(-ENOENT); | ||
415 | ino = le32_to_cpu(de->inode); | ||
416 | brelse(bh); | ||
417 | - inode = iget(child->d_inode->i_sb, ino); | ||
418 | + | ||
419 | + if (!ext3_valid_inum(child->d_inode->i_sb, ino)) { | ||
420 | + ext3_error(child->d_inode->i_sb, "ext3_get_parent", | ||
421 | + "bad inode number: %lu", ino); | ||
422 | + inode = NULL; | ||
423 | + } else | ||
424 | + inode = iget(child->d_inode->i_sb, ino); | ||
425 | |||
426 | if (!inode) | ||
427 | return ERR_PTR(-EACCES); | ||
428 | diff --git a/fs/proc/base.c b/fs/proc/base.c | ||
429 | index f801693..a3b825f 100644 | ||
430 | --- a/fs/proc/base.c | ||
431 | +++ b/fs/proc/base.c | ||
432 | @@ -596,6 +596,27 @@ static int proc_permission(struct inode | ||
433 | return proc_check_root(inode); | ||
434 | } | ||
435 | |||
436 | +static int proc_setattr(struct dentry *dentry, struct iattr *attr) | ||
437 | +{ | ||
438 | + int error; | ||
439 | + struct inode *inode = dentry->d_inode; | ||
440 | + | ||
441 | + if (attr->ia_valid & ATTR_MODE) | ||
442 | + return -EPERM; | ||
443 | + | ||
444 | + error = inode_change_ok(inode, attr); | ||
445 | + if (!error) { | ||
446 | + error = security_inode_setattr(dentry, attr); | ||
447 | + if (!error) | ||
448 | + error = inode_setattr(inode, attr); | ||
449 | + } | ||
450 | + return error; | ||
451 | +} | ||
452 | + | ||
453 | +static struct inode_operations proc_def_inode_operations = { | ||
454 | + .setattr = proc_setattr, | ||
455 | +}; | ||
456 | + | ||
457 | static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd) | ||
458 | { | ||
459 | struct dentry *root; | ||
460 | @@ -987,6 +1008,7 @@ static struct file_operations proc_oom_a | ||
461 | |||
462 | static struct inode_operations proc_mem_inode_operations = { | ||
463 | .permission = proc_permission, | ||
464 | + .setattr = proc_setattr, | ||
465 | }; | ||
466 | |||
467 | #ifdef CONFIG_AUDITSYSCALL | ||
468 | @@ -1184,7 +1206,8 @@ out: | ||
469 | |||
470 | static struct inode_operations proc_pid_link_inode_operations = { | ||
471 | .readlink = proc_pid_readlink, | ||
472 | - .follow_link = proc_pid_follow_link | ||
473 | + .follow_link = proc_pid_follow_link, | ||
474 | + .setattr = proc_setattr, | ||
475 | }; | ||
476 | |||
477 | #define NUMBUF 10 | ||
478 | @@ -1356,6 +1379,7 @@ static struct inode *proc_pid_make_inode | ||
479 | ei->task = NULL; | ||
480 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | ||
481 | inode->i_ino = fake_ino(task->pid, ino); | ||
482 | + inode->i_op = &proc_def_inode_operations; | ||
483 | |||
484 | if (!pid_alive(task)) | ||
485 | goto out_unlock; | ||
486 | @@ -1579,11 +1603,13 @@ static struct file_operations proc_task_ | ||
487 | static struct inode_operations proc_fd_inode_operations = { | ||
488 | .lookup = proc_lookupfd, | ||
489 | .permission = proc_permission, | ||
490 | + .setattr = proc_setattr, | ||
491 | }; | ||
492 | |||
493 | static struct inode_operations proc_task_inode_operations = { | ||
494 | .lookup = proc_task_lookup, | ||
495 | .permission = proc_task_permission, | ||
496 | + .setattr = proc_setattr, | ||
497 | }; | ||
498 | |||
499 | #ifdef CONFIG_SECURITY | ||
500 | @@ -1873,10 +1899,12 @@ static struct file_operations proc_tid_b | ||
501 | |||
502 | static struct inode_operations proc_tgid_base_inode_operations = { | ||
503 | .lookup = proc_tgid_base_lookup, | ||
504 | + .setattr = proc_setattr, | ||
505 | }; | ||
506 | |||
507 | static struct inode_operations proc_tid_base_inode_operations = { | ||
508 | .lookup = proc_tid_base_lookup, | ||
509 | + .setattr = proc_setattr, | ||
510 | }; | ||
511 | |||
512 | #ifdef CONFIG_SECURITY | ||
513 | @@ -1918,10 +1946,12 @@ static struct dentry *proc_tid_attr_look | ||
514 | |||
515 | static struct inode_operations proc_tgid_attr_inode_operations = { | ||
516 | .lookup = proc_tgid_attr_lookup, | ||
517 | + .setattr = proc_setattr, | ||
518 | }; | ||
519 | |||
520 | static struct inode_operations proc_tid_attr_inode_operations = { | ||
521 | .lookup = proc_tid_attr_lookup, | ||
522 | + .setattr = proc_setattr, | ||
523 | }; | ||
524 | #endif | ||
525 | |||
526 | @@ -1946,6 +1976,7 @@ static void *proc_self_follow_link(struc | ||
527 | static struct inode_operations proc_self_inode_operations = { | ||
528 | .readlink = proc_self_readlink, | ||
529 | .follow_link = proc_self_follow_link, | ||
530 | + .setattr = proc_setattr, | ||
531 | }; | ||
532 | |||
533 | /** | ||
534 | diff --git a/include/asm-s390/futex.h b/include/asm-s390/futex.h | ||
535 | index 1802775..ffedf14 100644 | ||
536 | --- a/include/asm-s390/futex.h | ||
537 | +++ b/include/asm-s390/futex.h | ||
538 | @@ -98,9 +98,10 @@ futex_atomic_cmpxchg_inatomic(int __user | ||
539 | |||
540 | if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) | ||
541 | return -EFAULT; | ||
542 | - asm volatile(" cs %1,%4,0(%5)\n" | ||
543 | + asm volatile(" sacf 256\n" | ||
544 | + " cs %1,%4,0(%5)\n" | ||
545 | "0: lr %0,%1\n" | ||
546 | - "1:\n" | ||
547 | + "1: sacf 0\n" | ||
548 | #ifndef __s390x__ | ||
549 | ".section __ex_table,\"a\"\n" | ||
550 | " .align 4\n" | ||
551 | diff --git a/include/asm-sparc64/sfp-machine.h b/include/asm-sparc64/sfp-machine.h | ||
552 | index 5015bb8..89d4243 100644 | ||
553 | --- a/include/asm-sparc64/sfp-machine.h | ||
554 | +++ b/include/asm-sparc64/sfp-machine.h | ||
555 | @@ -34,7 +34,7 @@ #define _FP_MUL_MEAT_S(R,X,Y) \ | ||
556 | #define _FP_MUL_MEAT_D(R,X,Y) \ | ||
557 | _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) | ||
558 | #define _FP_MUL_MEAT_Q(R,X,Y) \ | ||
559 | - _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) | ||
560 | + _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) | ||
561 | |||
562 | #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm) | ||
563 | #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y) | ||
564 | diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h | ||
565 | index 3ade6a4..c60ca4c 100644 | ||
566 | --- a/include/linux/ext3_fs.h | ||
567 | +++ b/include/linux/ext3_fs.h | ||
568 | @@ -495,6 +495,15 @@ static inline struct ext3_inode_info *EX | ||
569 | { | ||
570 | return container_of(inode, struct ext3_inode_info, vfs_inode); | ||
571 | } | ||
572 | + | ||
573 | +static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) | ||
574 | +{ | ||
575 | + return ino == EXT3_ROOT_INO || | ||
576 | + ino == EXT3_JOURNAL_INO || | ||
577 | + ino == EXT3_RESIZE_INO || | ||
578 | + (ino >= EXT3_FIRST_INO(sb) && | ||
579 | + ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); | ||
580 | +} | ||
581 | #else | ||
582 | /* Assume that user mode programs are passing in an ext3fs superblock, not | ||
583 | * a kernel struct super_block. This will allow us to call the feature-test | ||
584 | diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h | ||
585 | index f8f2347..2c31bb0 100644 | ||
586 | --- a/include/linux/skbuff.h | ||
587 | +++ b/include/linux/skbuff.h | ||
588 | @@ -967,15 +967,16 @@ #ifndef NET_SKB_PAD | ||
589 | #define NET_SKB_PAD 16 | ||
590 | #endif | ||
591 | |||
592 | -extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc); | ||
593 | +extern int ___pskb_trim(struct sk_buff *skb, unsigned int len); | ||
594 | |||
595 | static inline void __skb_trim(struct sk_buff *skb, unsigned int len) | ||
596 | { | ||
597 | - if (!skb->data_len) { | ||
598 | - skb->len = len; | ||
599 | - skb->tail = skb->data + len; | ||
600 | - } else | ||
601 | - ___pskb_trim(skb, len, 0); | ||
602 | + if (unlikely(skb->data_len)) { | ||
603 | + WARN_ON(1); | ||
604 | + return; | ||
605 | + } | ||
606 | + skb->len = len; | ||
607 | + skb->tail = skb->data + len; | ||
608 | } | ||
609 | |||
610 | /** | ||
611 | @@ -985,6 +986,7 @@ static inline void __skb_trim(struct sk_ | ||
612 | * | ||
613 | * Cut the length of a buffer down by removing data from the tail. If | ||
614 | * the buffer is already under the length specified it is not modified. | ||
615 | + * The skb must be linear. | ||
616 | */ | ||
617 | static inline void skb_trim(struct sk_buff *skb, unsigned int len) | ||
618 | { | ||
619 | @@ -995,12 +997,10 @@ static inline void skb_trim(struct sk_bu | ||
620 | |||
621 | static inline int __pskb_trim(struct sk_buff *skb, unsigned int len) | ||
622 | { | ||
623 | - if (!skb->data_len) { | ||
624 | - skb->len = len; | ||
625 | - skb->tail = skb->data+len; | ||
626 | - return 0; | ||
627 | - } | ||
628 | - return ___pskb_trim(skb, len, 1); | ||
629 | + if (skb->data_len) | ||
630 | + return ___pskb_trim(skb, len); | ||
631 | + __skb_trim(skb, len); | ||
632 | + return 0; | ||
633 | } | ||
634 | |||
635 | static inline int pskb_trim(struct sk_buff *skb, unsigned int len) | ||
636 | diff --git a/kernel/sched.c b/kernel/sched.c | ||
637 | index c13f1bd..61d1169 100644 | ||
638 | --- a/kernel/sched.c | ||
639 | +++ b/kernel/sched.c | ||
640 | @@ -4044,17 +4044,22 @@ asmlinkage long sys_sched_yield(void) | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | -static inline void __cond_resched(void) | ||
645 | +static inline int __resched_legal(int expected_preempt_count) | ||
646 | +{ | ||
647 | + if (unlikely(preempt_count() != expected_preempt_count)) | ||
648 | + return 0; | ||
649 | + if (unlikely(system_state != SYSTEM_RUNNING)) | ||
650 | + return 0; | ||
651 | + return 1; | ||
652 | +} | ||
653 | + | ||
654 | +static void __cond_resched(void) | ||
655 | { | ||
656 | /* | ||
657 | * The BKS might be reacquired before we have dropped | ||
658 | * PREEMPT_ACTIVE, which could trigger a second | ||
659 | * cond_resched() call. | ||
660 | */ | ||
661 | - if (unlikely(preempt_count())) | ||
662 | - return; | ||
663 | - if (unlikely(system_state != SYSTEM_RUNNING)) | ||
664 | - return; | ||
665 | do { | ||
666 | add_preempt_count(PREEMPT_ACTIVE); | ||
667 | schedule(); | ||
668 | @@ -4064,13 +4069,12 @@ static inline void __cond_resched(void) | ||
669 | |||
670 | int __sched cond_resched(void) | ||
671 | { | ||
672 | - if (need_resched()) { | ||
673 | + if (need_resched() && __resched_legal(0)) { | ||
674 | __cond_resched(); | ||
675 | return 1; | ||
676 | } | ||
677 | return 0; | ||
678 | } | ||
679 | - | ||
680 | EXPORT_SYMBOL(cond_resched); | ||
681 | |||
682 | /* | ||
683 | @@ -4091,7 +4095,7 @@ int cond_resched_lock(spinlock_t *lock) | ||
684 | ret = 1; | ||
685 | spin_lock(lock); | ||
686 | } | ||
687 | - if (need_resched()) { | ||
688 | + if (need_resched() && __resched_legal(1)) { | ||
689 | _raw_spin_unlock(lock); | ||
690 | preempt_enable_no_resched(); | ||
691 | __cond_resched(); | ||
692 | @@ -4100,14 +4104,13 @@ int cond_resched_lock(spinlock_t *lock) | ||
693 | } | ||
694 | return ret; | ||
695 | } | ||
696 | - | ||
697 | EXPORT_SYMBOL(cond_resched_lock); | ||
698 | |||
699 | int __sched cond_resched_softirq(void) | ||
700 | { | ||
701 | BUG_ON(!in_softirq()); | ||
702 | |||
703 | - if (need_resched()) { | ||
704 | + if (need_resched() && __resched_legal(0)) { | ||
705 | __local_bh_enable(); | ||
706 | __cond_resched(); | ||
707 | local_bh_disable(); | ||
708 | @@ -4115,10 +4118,8 @@ int __sched cond_resched_softirq(void) | ||
709 | } | ||
710 | return 0; | ||
711 | } | ||
712 | - | ||
713 | EXPORT_SYMBOL(cond_resched_softirq); | ||
714 | |||
715 | - | ||
716 | /** | ||
717 | * yield - yield the current processor to other threads. | ||
718 | * | ||
719 | diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c | ||
720 | index 3948949..729abc4 100644 | ||
721 | --- a/net/8021q/vlan.c | ||
722 | +++ b/net/8021q/vlan.c | ||
723 | @@ -67,10 +67,6 @@ static struct packet_type vlan_packet_ty | ||
724 | .func = vlan_skb_recv, /* VLAN receive method */ | ||
725 | }; | ||
726 | |||
727 | -/* Bits of netdev state that are propagated from real device to virtual */ | ||
728 | -#define VLAN_LINK_STATE_MASK \ | ||
729 | - ((1<<__LINK_STATE_PRESENT)|(1<<__LINK_STATE_NOCARRIER)|(1<<__LINK_STATE_DORMANT)) | ||
730 | - | ||
731 | /* End of global variables definitions. */ | ||
732 | |||
733 | /* | ||
734 | @@ -470,7 +466,9 @@ #endif | ||
735 | new_dev->flags = real_dev->flags; | ||
736 | new_dev->flags &= ~IFF_UP; | ||
737 | |||
738 | - new_dev->state = real_dev->state & ~(1<<__LINK_STATE_START); | ||
739 | + new_dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | | ||
740 | + (1<<__LINK_STATE_DORMANT))) | | ||
741 | + (1<<__LINK_STATE_PRESENT); | ||
742 | |||
743 | /* need 4 bytes for extra VLAN header info, | ||
744 | * hope the underlying device can handle it. | ||
745 | diff --git a/net/core/skbuff.c b/net/core/skbuff.c | ||
746 | index 0280535..dd0ae1b 100644 | ||
747 | --- a/net/core/skbuff.c | ||
748 | +++ b/net/core/skbuff.c | ||
749 | @@ -251,11 +251,11 @@ nodata: | ||
750 | } | ||
751 | |||
752 | |||
753 | -static void skb_drop_fraglist(struct sk_buff *skb) | ||
754 | +static void skb_drop_list(struct sk_buff **listp) | ||
755 | { | ||
756 | - struct sk_buff *list = skb_shinfo(skb)->frag_list; | ||
757 | + struct sk_buff *list = *listp; | ||
758 | |||
759 | - skb_shinfo(skb)->frag_list = NULL; | ||
760 | + *listp = NULL; | ||
761 | |||
762 | do { | ||
763 | struct sk_buff *this = list; | ||
764 | @@ -264,6 +264,11 @@ static void skb_drop_fraglist(struct sk_ | ||
765 | } while (list); | ||
766 | } | ||
767 | |||
768 | +static inline void skb_drop_fraglist(struct sk_buff *skb) | ||
769 | +{ | ||
770 | + skb_drop_list(&skb_shinfo(skb)->frag_list); | ||
771 | +} | ||
772 | + | ||
773 | static void skb_clone_fraglist(struct sk_buff *skb) | ||
774 | { | ||
775 | struct sk_buff *list; | ||
776 | @@ -802,49 +807,86 @@ struct sk_buff *skb_pad(struct sk_buff * | ||
777 | return nskb; | ||
778 | } | ||
779 | |||
780 | -/* Trims skb to length len. It can change skb pointers, if "realloc" is 1. | ||
781 | - * If realloc==0 and trimming is impossible without change of data, | ||
782 | - * it is BUG(). | ||
783 | +/* Trims skb to length len. It can change skb pointers. | ||
784 | */ | ||
785 | |||
786 | -int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc) | ||
787 | +int ___pskb_trim(struct sk_buff *skb, unsigned int len) | ||
788 | { | ||
789 | + struct sk_buff **fragp; | ||
790 | + struct sk_buff *frag; | ||
791 | int offset = skb_headlen(skb); | ||
792 | int nfrags = skb_shinfo(skb)->nr_frags; | ||
793 | int i; | ||
794 | + int err; | ||
795 | |||
796 | - for (i = 0; i < nfrags; i++) { | ||
797 | + if (skb_cloned(skb) && | ||
798 | + unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))) | ||
799 | + return err; | ||
800 | + | ||
801 | + i = 0; | ||
802 | + if (offset >= len) | ||
803 | + goto drop_pages; | ||
804 | + | ||
805 | + for (; i < nfrags; i++) { | ||
806 | int end = offset + skb_shinfo(skb)->frags[i].size; | ||
807 | - if (end > len) { | ||
808 | - if (skb_cloned(skb)) { | ||
809 | - BUG_ON(!realloc); | ||
810 | - if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) | ||
811 | - return -ENOMEM; | ||
812 | - } | ||
813 | - if (len <= offset) { | ||
814 | - put_page(skb_shinfo(skb)->frags[i].page); | ||
815 | - skb_shinfo(skb)->nr_frags--; | ||
816 | - } else { | ||
817 | - skb_shinfo(skb)->frags[i].size = len - offset; | ||
818 | - } | ||
819 | + | ||
820 | + if (end < len) { | ||
821 | + offset = end; | ||
822 | + continue; | ||
823 | } | ||
824 | - offset = end; | ||
825 | + | ||
826 | + skb_shinfo(skb)->frags[i++].size = len - offset; | ||
827 | + | ||
828 | +drop_pages: | ||
829 | + skb_shinfo(skb)->nr_frags = i; | ||
830 | + | ||
831 | + for (; i < nfrags; i++) | ||
832 | + put_page(skb_shinfo(skb)->frags[i].page); | ||
833 | + | ||
834 | + if (skb_shinfo(skb)->frag_list) | ||
835 | + skb_drop_fraglist(skb); | ||
836 | + goto done; | ||
837 | + } | ||
838 | + | ||
839 | + for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp); | ||
840 | + fragp = &frag->next) { | ||
841 | + int end = offset + frag->len; | ||
842 | + | ||
843 | + if (skb_shared(frag)) { | ||
844 | + struct sk_buff *nfrag; | ||
845 | + | ||
846 | + nfrag = skb_clone(frag, GFP_ATOMIC); | ||
847 | + if (unlikely(!nfrag)) | ||
848 | + return -ENOMEM; | ||
849 | + | ||
850 | + nfrag->next = frag->next; | ||
851 | + kfree_skb(frag); | ||
852 | + frag = nfrag; | ||
853 | + *fragp = frag; | ||
854 | + } | ||
855 | + | ||
856 | + if (end < len) { | ||
857 | + offset = end; | ||
858 | + continue; | ||
859 | + } | ||
860 | + | ||
861 | + if (end > len && | ||
862 | + unlikely((err = pskb_trim(frag, len - offset)))) | ||
863 | + return err; | ||
864 | + | ||
865 | + if (frag->next) | ||
866 | + skb_drop_list(&frag->next); | ||
867 | + break; | ||
868 | } | ||
869 | |||
870 | - if (offset < len) { | ||
871 | +done: | ||
872 | + if (len > skb_headlen(skb)) { | ||
873 | skb->data_len -= skb->len - len; | ||
874 | skb->len = len; | ||
875 | } else { | ||
876 | - if (len <= skb_headlen(skb)) { | ||
877 | - skb->len = len; | ||
878 | - skb->data_len = 0; | ||
879 | - skb->tail = skb->data + len; | ||
880 | - if (skb_shinfo(skb)->frag_list && !skb_cloned(skb)) | ||
881 | - skb_drop_fraglist(skb); | ||
882 | - } else { | ||
883 | - skb->data_len -= skb->len - len; | ||
884 | - skb->len = len; | ||
885 | - } | ||
886 | + skb->len = len; | ||
887 | + skb->data_len = 0; | ||
888 | + skb->tail = skb->data + len; | ||
889 | } | ||
890 | |||
891 | return 0; | ||
892 | diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c | ||
893 | index 518f581..853a3d5 100644 | ||
894 | --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c | ||
895 | +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c | ||
896 | @@ -1092,7 +1092,7 @@ static struct ip_conntrack_expect *find_ | ||
897 | tuple.dst.protonum = IPPROTO_TCP; | ||
898 | |||
899 | exp = __ip_conntrack_expect_find(&tuple); | ||
900 | - if (exp->master == ct) | ||
901 | + if (exp && exp->master == ct) | ||
902 | return exp; | ||
903 | return NULL; | ||
904 | } | ||
905 | diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c | ||
906 | index 7026b08..00cb388 100644 | ||
907 | --- a/net/sunrpc/cache.c | ||
908 | +++ b/net/sunrpc/cache.c | ||
909 | @@ -71,7 +71,12 @@ struct cache_head *sunrpc_cache_lookup(s | ||
910 | new = detail->alloc(); | ||
911 | if (!new) | ||
912 | return NULL; | ||
913 | + /* must fully initialise 'new', else | ||
914 | + * we might get lose if we need to | ||
915 | + * cache_put it soon. | ||
916 | + */ | ||
917 | cache_init(new); | ||
918 | + detail->init(new, key); | ||
919 | |||
920 | write_lock(&detail->hash_lock); | ||
921 | |||
922 | @@ -85,7 +90,6 @@ struct cache_head *sunrpc_cache_lookup(s | ||
923 | return tmp; | ||
924 | } | ||
925 | } | ||
926 | - detail->init(new, key); | ||
927 | new->next = *head; | ||
928 | *head = new; | ||
929 | detail->entries++; | ||
930 | diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c | ||
931 | index ac990bf..785a2ac 100644 | ||
932 | --- a/sound/core/oss/pcm_oss.c | ||
933 | +++ b/sound/core/oss/pcm_oss.c | ||
934 | @@ -1745,6 +1745,8 @@ static int snd_pcm_oss_open_file(struct | ||
935 | for (idx = 0; idx < 2; idx++) { | ||
936 | if (setup[idx].disable) | ||
937 | continue; | ||
938 | + if (! pcm->streams[idx].substream_count) | ||
939 | + continue; /* no matching substream */ | ||
940 | if (idx == SNDRV_PCM_STREAM_PLAYBACK) { | ||
941 | if (! (f_mode & FMODE_WRITE)) | ||
942 | continue; |