Annotation of /trunk/kernel26-alx/patches-2.6.20-r6/0105-2.6.20.5-all-fixes.patch
Parent Directory | Revision Log
Revision 1175 -
(hide annotations)
(download)
Thu Oct 14 12:15:46 2010 UTC (13 years, 11 months ago) by niro
File size: 60110 byte(s)
Thu Oct 14 12:15:46 2010 UTC (13 years, 11 months ago) by niro
File size: 60110 byte(s)
-2.6.20-alx-r6 new magellan 0.5.2 kernel
1 | niro | 1175 | diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h |
2 | index 66cb400..62403bd 100644 | ||
3 | --- a/arch/um/include/sysdep-x86_64/ptrace.h | ||
4 | +++ b/arch/um/include/sysdep-x86_64/ptrace.h | ||
5 | @@ -104,10 +104,6 @@ union uml_pt_regs { | ||
6 | #endif | ||
7 | #ifdef UML_CONFIG_MODE_SKAS | ||
8 | struct skas_regs { | ||
9 | - /* x86_64 ptrace uses sizeof(user_regs_struct) as its register | ||
10 | - * file size, while i386 uses FRAME_SIZE. Therefore, we need | ||
11 | - * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE. | ||
12 | - */ | ||
13 | unsigned long regs[MAX_REG_NR]; | ||
14 | unsigned long fp[HOST_FP_SIZE]; | ||
15 | struct faultinfo faultinfo; | ||
16 | diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c | ||
17 | index 5a99dd3..13c6cb5 100644 | ||
18 | --- a/arch/um/os-Linux/elf_aux.c | ||
19 | +++ b/arch/um/os-Linux/elf_aux.c | ||
20 | @@ -40,6 +40,9 @@ __init void scan_elf_aux( char **envp) | ||
21 | switch ( auxv->a_type ) { | ||
22 | case AT_SYSINFO: | ||
23 | __kernel_vsyscall = auxv->a_un.a_val; | ||
24 | + /* See if the page is under TASK_SIZE */ | ||
25 | + if (__kernel_vsyscall < (unsigned long) envp) | ||
26 | + __kernel_vsyscall = 0; | ||
27 | break; | ||
28 | case AT_SYSINFO_EHDR: | ||
29 | vsyscall_ehdr = auxv->a_un.a_val; | ||
30 | diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c | ||
31 | index b3c11cf..9383e87 100644 | ||
32 | --- a/arch/um/os-Linux/skas/mem.c | ||
33 | +++ b/arch/um/os-Linux/skas/mem.c | ||
34 | @@ -48,7 +48,7 @@ int multi_op_count = 0; | ||
35 | static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) | ||
36 | { | ||
37 | unsigned long regs[MAX_REG_NR]; | ||
38 | - int n; | ||
39 | + int n, i; | ||
40 | long ret, offset; | ||
41 | unsigned long * data; | ||
42 | unsigned long * syscall; | ||
43 | @@ -66,9 +66,13 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) | ||
44 | (unsigned long) &__syscall_stub_start); | ||
45 | |||
46 | n = ptrace_setregs(pid, regs); | ||
47 | - if(n < 0) | ||
48 | + if(n < 0){ | ||
49 | + printk("Registers - \n"); | ||
50 | + for(i = 0; i < MAX_REG_NR; i++) | ||
51 | + printk("\t%d\t0x%lx\n", i, regs[i]); | ||
52 | panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", | ||
53 | - n); | ||
54 | + -n); | ||
55 | + } | ||
56 | |||
57 | wait_stub_done(pid, 0, "do_syscall_stub"); | ||
58 | |||
59 | diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c | ||
60 | index 9b34fe6..c4998cf 100644 | ||
61 | --- a/arch/um/os-Linux/skas/process.c | ||
62 | +++ b/arch/um/os-Linux/skas/process.c | ||
63 | @@ -67,7 +67,7 @@ void wait_stub_done(int pid, int sig, char * fname) | ||
64 | |||
65 | if((n < 0) || !WIFSTOPPED(status) || | ||
66 | (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ | ||
67 | - unsigned long regs[HOST_FRAME_SIZE]; | ||
68 | + unsigned long regs[MAX_REG_NR]; | ||
69 | |||
70 | if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) | ||
71 | printk("Failed to get registers from stub, " | ||
72 | @@ -76,7 +76,7 @@ void wait_stub_done(int pid, int sig, char * fname) | ||
73 | int i; | ||
74 | |||
75 | printk("Stub registers -\n"); | ||
76 | - for(i = 0; i < HOST_FRAME_SIZE; i++) | ||
77 | + for(i = 0; i < ARRAY_SIZE(regs); i++) | ||
78 | printk("\t%d - %lx\n", i, regs[i]); | ||
79 | } | ||
80 | panic("%s : failed to wait for SIGUSR1/SIGTRAP, " | ||
81 | @@ -328,7 +328,7 @@ void userspace(union uml_pt_regs *regs) | ||
82 | int copy_context_skas0(unsigned long new_stack, int pid) | ||
83 | { | ||
84 | int err; | ||
85 | - unsigned long regs[HOST_FRAME_SIZE]; | ||
86 | + unsigned long regs[MAX_REG_NR]; | ||
87 | unsigned long fp_regs[HOST_FP_SIZE]; | ||
88 | unsigned long current_stack = current_stub_stack(); | ||
89 | struct stub_data *data = (struct stub_data *) current_stack; | ||
90 | diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c | ||
91 | index 7cd0369..ecd21e0 100644 | ||
92 | --- a/arch/um/os-Linux/sys-i386/registers.c | ||
93 | +++ b/arch/um/os-Linux/sys-i386/registers.c | ||
94 | @@ -15,7 +15,7 @@ | ||
95 | |||
96 | /* These are set once at boot time and not changed thereafter */ | ||
97 | |||
98 | -static unsigned long exec_regs[HOST_FRAME_SIZE]; | ||
99 | +static unsigned long exec_regs[MAX_REG_NR]; | ||
100 | static unsigned long exec_fp_regs[HOST_FP_SIZE]; | ||
101 | static unsigned long exec_fpx_regs[HOST_XFP_SIZE]; | ||
102 | static int have_fpx_regs = 1; | ||
103 | @@ -101,6 +101,7 @@ void init_registers(int pid) | ||
104 | { | ||
105 | int err; | ||
106 | |||
107 | + memset(exec_regs, 0, sizeof(exec_regs)); | ||
108 | err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); | ||
109 | if(err) | ||
110 | panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", | ||
111 | @@ -124,7 +125,7 @@ void init_registers(int pid) | ||
112 | |||
113 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) | ||
114 | { | ||
115 | - memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); | ||
116 | + memcpy(regs, exec_regs, sizeof(exec_regs)); | ||
117 | if(fp_regs != NULL) | ||
118 | memcpy(fp_regs, exec_fp_regs, | ||
119 | HOST_FP_SIZE * sizeof(unsigned long)); | ||
120 | diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c | ||
121 | index cb8e8a2..019f6c4 100644 | ||
122 | --- a/arch/um/os-Linux/sys-x86_64/registers.c | ||
123 | +++ b/arch/um/os-Linux/sys-x86_64/registers.c | ||
124 | @@ -14,7 +14,7 @@ | ||
125 | |||
126 | /* These are set once at boot time and not changed thereafter */ | ||
127 | |||
128 | -static unsigned long exec_regs[HOST_FRAME_SIZE]; | ||
129 | +static unsigned long exec_regs[MAX_REG_NR]; | ||
130 | static unsigned long exec_fp_regs[HOST_FP_SIZE]; | ||
131 | |||
132 | void init_thread_registers(union uml_pt_regs *to) | ||
133 | @@ -72,7 +72,7 @@ void init_registers(int pid) | ||
134 | |||
135 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) | ||
136 | { | ||
137 | - memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); | ||
138 | + memcpy(regs, exec_regs, sizeof(exec_regs)); | ||
139 | if(fp_regs != NULL) | ||
140 | memcpy(fp_regs, exec_fp_regs, | ||
141 | HOST_FP_SIZE * sizeof(unsigned long)); | ||
142 | diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c | ||
143 | index 2c11b97..d623e07 100644 | ||
144 | --- a/arch/um/sys-i386/delay.c | ||
145 | +++ b/arch/um/sys-i386/delay.c | ||
146 | @@ -27,14 +27,3 @@ void __udelay(unsigned long usecs) | ||
147 | } | ||
148 | |||
149 | EXPORT_SYMBOL(__udelay); | ||
150 | - | ||
151 | -void __const_udelay(unsigned long usecs) | ||
152 | -{ | ||
153 | - int i, n; | ||
154 | - | ||
155 | - n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
156 | - for(i=0;i<n;i++) | ||
157 | - cpu_relax(); | ||
158 | -} | ||
159 | - | ||
160 | -EXPORT_SYMBOL(__const_udelay); | ||
161 | diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c | ||
162 | index 137f444..dee5be6 100644 | ||
163 | --- a/arch/um/sys-x86_64/delay.c | ||
164 | +++ b/arch/um/sys-x86_64/delay.c | ||
165 | @@ -28,14 +28,3 @@ void __udelay(unsigned long usecs) | ||
166 | } | ||
167 | |||
168 | EXPORT_SYMBOL(__udelay); | ||
169 | - | ||
170 | -void __const_udelay(unsigned long usecs) | ||
171 | -{ | ||
172 | - unsigned long i, n; | ||
173 | - | ||
174 | - n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
175 | - for(i=0;i<n;i++) | ||
176 | - cpu_relax(); | ||
177 | -} | ||
178 | - | ||
179 | -EXPORT_SYMBOL(__const_udelay); | ||
180 | diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c | ||
181 | index 35172d3..a664231 100644 | ||
182 | --- a/crypto/scatterwalk.c | ||
183 | +++ b/crypto/scatterwalk.c | ||
184 | @@ -91,6 +91,8 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk, | ||
185 | memcpy_dir(buf, vaddr, len_this_page, out); | ||
186 | scatterwalk_unmap(vaddr, out); | ||
187 | |||
188 | + scatterwalk_advance(walk, nbytes); | ||
189 | + | ||
190 | if (nbytes == len_this_page) | ||
191 | break; | ||
192 | |||
193 | @@ -99,7 +101,5 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk, | ||
194 | |||
195 | scatterwalk_pagedone(walk, out, 1); | ||
196 | } | ||
197 | - | ||
198 | - scatterwalk_advance(walk, nbytes); | ||
199 | } | ||
200 | EXPORT_SYMBOL_GPL(scatterwalk_copychunks); | ||
201 | diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c | ||
202 | index 667acd2..d6fcf0a 100644 | ||
203 | --- a/drivers/ata/libata-core.c | ||
204 | +++ b/drivers/ata/libata-core.c | ||
205 | @@ -1478,7 +1478,16 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | ||
206 | } | ||
207 | |||
208 | tf.protocol = ATA_PROT_PIO; | ||
209 | - tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */ | ||
210 | + | ||
211 | + /* Some devices choke if TF registers contain garbage. Make | ||
212 | + * sure those are properly initialized. | ||
213 | + */ | ||
214 | + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
215 | + | ||
216 | + /* Device presence detection is unreliable on some | ||
217 | + * controllers. Always poll IDENTIFY if available. | ||
218 | + */ | ||
219 | + tf.flags |= ATA_TFLAG_POLLING; | ||
220 | |||
221 | err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, | ||
222 | id, sizeof(id[0]) * ATA_ID_WORDS); | ||
223 | diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c | ||
224 | index 73902d3..1790542 100644 | ||
225 | --- a/drivers/ata/libata-scsi.c | ||
226 | +++ b/drivers/ata/libata-scsi.c | ||
227 | @@ -295,6 +295,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) | ||
228 | scsi_cmd[8] = args[3]; | ||
229 | scsi_cmd[10] = args[4]; | ||
230 | scsi_cmd[12] = args[5]; | ||
231 | + scsi_cmd[13] = args[6] & 0x0f; | ||
232 | scsi_cmd[14] = args[0]; | ||
233 | |||
234 | /* Good values for timeout and retries? Values below | ||
235 | diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c | ||
236 | index aae0b52..4054cdb 100644 | ||
237 | --- a/drivers/ata/sata_mv.c | ||
238 | +++ b/drivers/ata/sata_mv.c | ||
239 | @@ -139,14 +139,19 @@ enum { | ||
240 | PCI_ERR = (1 << 18), | ||
241 | TRAN_LO_DONE = (1 << 19), /* 6xxx: IRQ coalescing */ | ||
242 | TRAN_HI_DONE = (1 << 20), /* 6xxx: IRQ coalescing */ | ||
243 | + PORTS_0_3_COAL_DONE = (1 << 8), | ||
244 | + PORTS_4_7_COAL_DONE = (1 << 17), | ||
245 | PORTS_0_7_COAL_DONE = (1 << 21), /* 6xxx: IRQ coalescing */ | ||
246 | GPIO_INT = (1 << 22), | ||
247 | SELF_INT = (1 << 23), | ||
248 | TWSI_INT = (1 << 24), | ||
249 | HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ | ||
250 | + HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ | ||
251 | HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | | ||
252 | PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | | ||
253 | HC_MAIN_RSVD), | ||
254 | + HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | | ||
255 | + HC_MAIN_RSVD_5), | ||
256 | |||
257 | /* SATAHC registers */ | ||
258 | HC_CFG_OFS = 0, | ||
259 | @@ -843,23 +848,27 @@ static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio) | ||
260 | u32 cfg = readl(port_mmio + EDMA_CFG_OFS); | ||
261 | |||
262 | /* set up non-NCQ EDMA configuration */ | ||
263 | - cfg &= ~0x1f; /* clear queue depth */ | ||
264 | - cfg &= ~EDMA_CFG_NCQ; /* clear NCQ mode */ | ||
265 | cfg &= ~(1 << 9); /* disable equeue */ | ||
266 | |||
267 | - if (IS_GEN_I(hpriv)) | ||
268 | + if (IS_GEN_I(hpriv)) { | ||
269 | + cfg &= ~0x1f; /* clear queue depth */ | ||
270 | cfg |= (1 << 8); /* enab config burst size mask */ | ||
271 | + } | ||
272 | |||
273 | - else if (IS_GEN_II(hpriv)) | ||
274 | + else if (IS_GEN_II(hpriv)) { | ||
275 | + cfg &= ~0x1f; /* clear queue depth */ | ||
276 | cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN; | ||
277 | + cfg &= ~(EDMA_CFG_NCQ | EDMA_CFG_NCQ_GO_ON_ERR); /* clear NCQ */ | ||
278 | + } | ||
279 | |||
280 | else if (IS_GEN_IIE(hpriv)) { | ||
281 | - cfg |= (1 << 23); /* dis RX PM port mask */ | ||
282 | - cfg &= ~(1 << 16); /* dis FIS-based switching (for now) */ | ||
283 | + cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ | ||
284 | + cfg |= (1 << 22); /* enab 4-entry host queue cache */ | ||
285 | cfg &= ~(1 << 19); /* dis 128-entry queue (for now?) */ | ||
286 | cfg |= (1 << 18); /* enab early completion */ | ||
287 | - cfg |= (1 << 17); /* enab host q cache */ | ||
288 | - cfg |= (1 << 22); /* enab cutthrough */ | ||
289 | + cfg |= (1 << 17); /* enab cut-through (dis stor&forwrd) */ | ||
290 | + cfg &= ~(1 << 16); /* dis FIS-based switching (for now) */ | ||
291 | + cfg &= ~(EDMA_CFG_NCQ | EDMA_CFG_NCQ_GO_ON_ERR); /* clear NCQ */ | ||
292 | } | ||
293 | |||
294 | writelfl(cfg, port_mmio + EDMA_CFG_OFS); | ||
295 | @@ -2283,7 +2292,11 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, | ||
296 | |||
297 | /* and unmask interrupt generation for host regs */ | ||
298 | writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS); | ||
299 | - writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS); | ||
300 | + | ||
301 | + if (IS_50XX(hpriv)) | ||
302 | + writelfl(~HC_MAIN_MASKED_IRQS_5, mmio + HC_MAIN_IRQ_MASK_OFS); | ||
303 | + else | ||
304 | + writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS); | ||
305 | |||
306 | VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x " | ||
307 | "PCI int cause/mask=0x%08x/0x%08x\n", | ||
308 | diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c | ||
309 | index f7a963e..91f24b1 100644 | ||
310 | --- a/drivers/ata/sata_nv.c | ||
311 | +++ b/drivers/ata/sata_nv.c | ||
312 | @@ -214,6 +214,7 @@ struct nv_adma_port_priv { | ||
313 | struct nv_adma_prd *aprd; | ||
314 | dma_addr_t aprd_dma; | ||
315 | u8 flags; | ||
316 | + int last_issue_ncq; | ||
317 | }; | ||
318 | |||
319 | #define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT))))) | ||
320 | @@ -1151,6 +1152,7 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) | ||
321 | { | ||
322 | struct nv_adma_port_priv *pp = qc->ap->private_data; | ||
323 | void __iomem *mmio = nv_adma_ctl_block(qc->ap); | ||
324 | + int curr_ncq = (qc->tf.protocol == ATA_PROT_NCQ); | ||
325 | |||
326 | VPRINTK("ENTER\n"); | ||
327 | |||
328 | @@ -1166,6 +1168,14 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) | ||
329 | /* write append register, command tag in lower 8 bits | ||
330 | and (number of cpbs to append -1) in top 8 bits */ | ||
331 | wmb(); | ||
332 | + | ||
333 | + if(curr_ncq != pp->last_issue_ncq) { | ||
334 | + /* Seems to need some delay before switching between NCQ and non-NCQ | ||
335 | + commands, else we get command timeouts and such. */ | ||
336 | + udelay(20); | ||
337 | + pp->last_issue_ncq = curr_ncq; | ||
338 | + } | ||
339 | + | ||
340 | writew(qc->tag, mmio + NV_ADMA_APPEND); | ||
341 | |||
342 | DPRINTK("Issued tag %u\n",qc->tag); | ||
343 | diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c | ||
344 | index e769811..e2a0b6f 100644 | ||
345 | --- a/drivers/char/generic_serial.c | ||
346 | +++ b/drivers/char/generic_serial.c | ||
347 | @@ -711,12 +711,6 @@ void gs_close(struct tty_struct * tty, struct file * filp) | ||
348 | } | ||
349 | |||
350 | |||
351 | -static unsigned int gs_baudrates[] = { | ||
352 | - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | ||
353 | - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 | ||
354 | -}; | ||
355 | - | ||
356 | - | ||
357 | void gs_set_termios (struct tty_struct * tty, | ||
358 | struct ktermios * old_termios) | ||
359 | { | ||
360 | @@ -772,7 +766,6 @@ void gs_set_termios (struct tty_struct * tty, | ||
361 | |||
362 | baudrate = tty_get_baud_rate(tty); | ||
363 | |||
364 | - baudrate = gs_baudrates[baudrate]; | ||
365 | if ((tiosp->c_cflag & CBAUD) == B38400) { | ||
366 | if ( (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | ||
367 | baudrate = 57600; | ||
368 | diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c | ||
369 | index 5969cec..a2bde80 100644 | ||
370 | --- a/drivers/ide/ide-cd.c | ||
371 | +++ b/drivers/ide/ide-cd.c | ||
372 | @@ -687,15 +687,8 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 sta | ||
373 | static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | ||
374 | { | ||
375 | struct request *rq = HWGROUP(drive)->rq; | ||
376 | - ide_hwif_t *hwif = HWIF(drive); | ||
377 | int stat, err, sense_key; | ||
378 | |||
379 | - /* We may have bogus DMA interrupts in PIO state here */ | ||
380 | - if (HWIF(drive)->dma_status && hwif->atapi_irq_bogon) { | ||
381 | - stat = hwif->INB(hwif->dma_status); | ||
382 | - /* Should we force the bit as well ? */ | ||
383 | - hwif->OUTB(stat, hwif->dma_status); | ||
384 | - } | ||
385 | /* Check for errors. */ | ||
386 | stat = HWIF(drive)->INB(IDE_STATUS_REG); | ||
387 | if (stat_ret) | ||
388 | @@ -930,6 +923,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, | ||
389 | HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); | ||
390 | |||
391 | if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { | ||
392 | + /* waiting for CDB interrupt, not DMA yet. */ | ||
393 | + if (info->dma) | ||
394 | + drive->waiting_for_dma = 0; | ||
395 | + | ||
396 | /* packet command */ | ||
397 | ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry); | ||
398 | return ide_started; | ||
399 | @@ -972,6 +969,10 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive, | ||
400 | /* Check for errors. */ | ||
401 | if (cdrom_decode_status(drive, DRQ_STAT, NULL)) | ||
402 | return ide_stopped; | ||
403 | + | ||
404 | + /* Ok, next interrupt will be DMA interrupt. */ | ||
405 | + if (info->dma) | ||
406 | + drive->waiting_for_dma = 1; | ||
407 | } else { | ||
408 | /* Otherwise, we must wait for DRQ to get set. */ | ||
409 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, | ||
410 | diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c | ||
411 | index 2614f41..99d1c43 100644 | ||
412 | --- a/drivers/ide/ide-io.c | ||
413 | +++ b/drivers/ide/ide-io.c | ||
414 | @@ -1646,6 +1646,17 @@ irqreturn_t ide_intr (int irq, void *dev_id) | ||
415 | del_timer(&hwgroup->timer); | ||
416 | spin_unlock(&ide_lock); | ||
417 | |||
418 | + /* Some controllers might set DMA INTR no matter DMA or PIO; | ||
419 | + * bmdma status might need to be cleared even for | ||
420 | + * PIO interrupts to prevent spurious/lost irq. | ||
421 | + */ | ||
422 | + if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma)) | ||
423 | + /* ide_dma_end() needs bmdma status for error checking. | ||
424 | + * So, skip clearing bmdma status here and leave it | ||
425 | + * to ide_dma_end() if this is dma interrupt. | ||
426 | + */ | ||
427 | + hwif->ide_dma_clear_irq(drive); | ||
428 | + | ||
429 | if (drive->unmask) | ||
430 | local_irq_enable_in_hardirq(); | ||
431 | /* service this interrupt, may set handler for next interrupt */ | ||
432 | diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c | ||
433 | index 6558055..59b10a0 100644 | ||
434 | --- a/drivers/ide/ide-iops.c | ||
435 | +++ b/drivers/ide/ide-iops.c | ||
436 | @@ -598,6 +598,9 @@ u8 eighty_ninty_three (ide_drive_t *drive) | ||
437 | if(HWIF(drive)->udma_four == 0) | ||
438 | return 0; | ||
439 | |||
440 | + printk(KERN_INFO "%s: hw_config=%04x\n", | ||
441 | + drive->name, drive->id->hw_config); | ||
442 | + | ||
443 | /* Check for SATA but only if we are ATA5 or higher */ | ||
444 | if (drive->id->hw_config == 0 && (drive->id->major_rev_num & 0x7FE0)) | ||
445 | return 1; | ||
446 | @@ -607,8 +610,14 @@ u8 eighty_ninty_three (ide_drive_t *drive) | ||
447 | if(!(drive->id->hw_config & 0x4000)) | ||
448 | return 0; | ||
449 | #endif /* CONFIG_IDEDMA_IVB */ | ||
450 | +/* | ||
451 | + * FIXME: enable this after fixing master/slave IDENTIFY order, | ||
452 | + * also ignore the result if the slave device is pre-ATA3 one | ||
453 | + */ | ||
454 | +#if 0 | ||
455 | if (!(drive->id->hw_config & 0x2000)) | ||
456 | return 0; | ||
457 | +#endif | ||
458 | return 1; | ||
459 | } | ||
460 | |||
461 | diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c | ||
462 | index 6c9bd51..8e73fe5 100644 | ||
463 | --- a/drivers/ide/ide.c | ||
464 | +++ b/drivers/ide/ide.c | ||
465 | @@ -503,6 +503,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | ||
466 | hwif->ide_dma_on = tmp_hwif->ide_dma_on; | ||
467 | hwif->ide_dma_off_quietly = tmp_hwif->ide_dma_off_quietly; | ||
468 | hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq; | ||
469 | + hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq; | ||
470 | hwif->ide_dma_host_on = tmp_hwif->ide_dma_host_on; | ||
471 | hwif->ide_dma_host_off = tmp_hwif->ide_dma_host_off; | ||
472 | hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq; | ||
473 | diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c | ||
474 | index f07bbbe..84fb87b 100644 | ||
475 | --- a/drivers/ide/pci/jmicron.c | ||
476 | +++ b/drivers/ide/pci/jmicron.c | ||
477 | @@ -240,12 +240,31 @@ static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_devi | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | +/* If libata is configured, jmicron PCI quirk will configure it such | ||
482 | + * that the SATA ports are in AHCI function while the PATA ports are | ||
483 | + * in a separate IDE function. In such cases, match device class and | ||
484 | + * attach only to IDE. If libata isn't configured, keep the old | ||
485 | + * behavior for backward compatibility. | ||
486 | + */ | ||
487 | +#if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) | ||
488 | +#define JMB_CLASS PCI_CLASS_STORAGE_IDE << 8 | ||
489 | +#define JMB_CLASS_MASK 0xffff00 | ||
490 | +#else | ||
491 | +#define JMB_CLASS 0 | ||
492 | +#define JMB_CLASS_MASK 0 | ||
493 | +#endif | ||
494 | + | ||
495 | static struct pci_device_id jmicron_pci_tbl[] = { | ||
496 | - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
497 | - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | ||
498 | - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, | ||
499 | - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, | ||
500 | - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, | ||
501 | + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, | ||
502 | + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 0}, | ||
503 | + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, | ||
504 | + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 1}, | ||
505 | + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, | ||
506 | + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 2}, | ||
507 | + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, | ||
508 | + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 3}, | ||
509 | + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, | ||
510 | + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 4}, | ||
511 | { 0, }, | ||
512 | }; | ||
513 | |||
514 | diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c | ||
515 | index edb37f3..c5ec6f1 100644 | ||
516 | --- a/drivers/ide/pci/piix.c | ||
517 | +++ b/drivers/ide/pci/piix.c | ||
518 | @@ -411,17 +411,14 @@ fast_ata_pio: | ||
519 | } | ||
520 | |||
521 | /** | ||
522 | - * init_chipset_piix - set up the PIIX chipset | ||
523 | - * @dev: PCI device to set up | ||
524 | - * @name: Name of the device | ||
525 | + * piix_is_ichx - check if ICHx | ||
526 | + * @dev: PCI device to check | ||
527 | * | ||
528 | - * Initialize the PCI device as required. For the PIIX this turns | ||
529 | - * out to be nice and simple | ||
530 | + * returns 1 if ICHx, 0 otherwise. | ||
531 | */ | ||
532 | - | ||
533 | -static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name) | ||
534 | +static int piix_is_ichx(struct pci_dev *dev) | ||
535 | { | ||
536 | - switch(dev->device) { | ||
537 | + switch (dev->device) { | ||
538 | case PCI_DEVICE_ID_INTEL_82801EB_1: | ||
539 | case PCI_DEVICE_ID_INTEL_82801AA_1: | ||
540 | case PCI_DEVICE_ID_INTEL_82801AB_1: | ||
541 | @@ -439,19 +436,51 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char | ||
542 | case PCI_DEVICE_ID_INTEL_ICH7_21: | ||
543 | case PCI_DEVICE_ID_INTEL_ESB2_18: | ||
544 | case PCI_DEVICE_ID_INTEL_ICH8_6: | ||
545 | - { | ||
546 | - unsigned int extra = 0; | ||
547 | - pci_read_config_dword(dev, 0x54, &extra); | ||
548 | - pci_write_config_dword(dev, 0x54, extra|0x400); | ||
549 | - } | ||
550 | - default: | ||
551 | - break; | ||
552 | + return 1; | ||
553 | } | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | /** | ||
559 | + * init_chipset_piix - set up the PIIX chipset | ||
560 | + * @dev: PCI device to set up | ||
561 | + * @name: Name of the device | ||
562 | + * | ||
563 | + * Initialize the PCI device as required. For the PIIX this turns | ||
564 | + * out to be nice and simple | ||
565 | + */ | ||
566 | + | ||
567 | +static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name) | ||
568 | +{ | ||
569 | + if (piix_is_ichx(dev)) { | ||
570 | + unsigned int extra = 0; | ||
571 | + pci_read_config_dword(dev, 0x54, &extra); | ||
572 | + pci_write_config_dword(dev, 0x54, extra|0x400); | ||
573 | + } | ||
574 | + | ||
575 | + return 0; | ||
576 | +} | ||
577 | + | ||
578 | +/** | ||
579 | + * piix_dma_clear_irq - clear BMDMA status | ||
580 | + * @drive: IDE drive to clear | ||
581 | + * | ||
582 | + * Called from ide_intr() for PIO interrupts | ||
583 | + * to clear BMDMA status as needed by ICHx | ||
584 | + */ | ||
585 | +static void piix_dma_clear_irq(ide_drive_t *drive) | ||
586 | +{ | ||
587 | + ide_hwif_t *hwif = HWIF(drive); | ||
588 | + u8 dma_stat; | ||
589 | + | ||
590 | + /* clear the INTR & ERROR bits */ | ||
591 | + dma_stat = hwif->INB(hwif->dma_status); | ||
592 | + /* Should we force the bit as well ? */ | ||
593 | + hwif->OUTB(dma_stat, hwif->dma_status); | ||
594 | +} | ||
595 | + | ||
596 | +/** | ||
597 | * init_hwif_piix - fill in the hwif for the PIIX | ||
598 | * @hwif: IDE interface | ||
599 | * | ||
600 | @@ -473,10 +502,6 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) | ||
601 | /* This is a painful system best to let it self tune for now */ | ||
602 | return; | ||
603 | } | ||
604 | - /* ESB2 appears to generate spurious DMA interrupts in PIO mode | ||
605 | - when in native mode */ | ||
606 | - if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_ESB2_18) | ||
607 | - hwif->atapi_irq_bogon = 1; | ||
608 | |||
609 | hwif->autodma = 0; | ||
610 | hwif->tuneproc = &piix_tune_drive; | ||
611 | @@ -487,6 +512,10 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) | ||
612 | if (!hwif->dma_base) | ||
613 | return; | ||
614 | |||
615 | + /* ICHx need to clear the bmdma status for all interrupts */ | ||
616 | + if (piix_is_ichx(hwif->pci_dev)) | ||
617 | + hwif->ide_dma_clear_irq = &piix_dma_clear_irq; | ||
618 | + | ||
619 | hwif->atapi_dma = 1; | ||
620 | hwif->ultra_mask = 0x3f; | ||
621 | hwif->mwdma_mask = 0x06; | ||
622 | diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c | ||
623 | index 1084da4..59e383c 100644 | ||
624 | --- a/drivers/ieee1394/dv1394.c | ||
625 | +++ b/drivers/ieee1394/dv1394.c | ||
626 | @@ -2267,11 +2267,7 @@ static void dv1394_remove_host (struct hpsb_host *host) | ||
627 | { | ||
628 | struct video_card *video; | ||
629 | unsigned long flags; | ||
630 | - int id = host->id; | ||
631 | - | ||
632 | - /* We only work with the OHCI-1394 driver */ | ||
633 | - if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME)) | ||
634 | - return; | ||
635 | + int id = host->id, found_ohci_card = 0; | ||
636 | |||
637 | /* find the corresponding video_cards */ | ||
638 | do { | ||
639 | @@ -2284,6 +2280,7 @@ static void dv1394_remove_host (struct hpsb_host *host) | ||
640 | if ((tmp_vid->id >> 2) == id) { | ||
641 | list_del(&tmp_vid->list); | ||
642 | video = tmp_vid; | ||
643 | + found_ohci_card = 1; | ||
644 | break; | ||
645 | } | ||
646 | } | ||
647 | @@ -2293,8 +2290,9 @@ static void dv1394_remove_host (struct hpsb_host *host) | ||
648 | dv1394_un_init(video); | ||
649 | } while (video != NULL); | ||
650 | |||
651 | - class_device_destroy(hpsb_protocol_class, | ||
652 | - MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2))); | ||
653 | + if (found_ohci_card) | ||
654 | + class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, | ||
655 | + IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id << 2))); | ||
656 | } | ||
657 | |||
658 | static void dv1394_add_host (struct hpsb_host *host) | ||
659 | diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c | ||
660 | index 988499d..ec473eb 100644 | ||
661 | --- a/drivers/media/dvb/dvb-core/dmxdev.c | ||
662 | +++ b/drivers/media/dvb/dvb-core/dmxdev.c | ||
663 | @@ -181,8 +181,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) | ||
664 | struct dvb_device *dvbdev = file->private_data; | ||
665 | struct dmxdev *dmxdev = dvbdev->priv; | ||
666 | |||
667 | - if (mutex_lock_interruptible(&dmxdev->mutex)) | ||
668 | - return -ERESTARTSYS; | ||
669 | + mutex_lock(&dmxdev->mutex); | ||
670 | |||
671 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) { | ||
672 | dmxdev->demux->disconnect_frontend(dmxdev->demux); | ||
673 | @@ -674,13 +673,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file) | ||
674 | static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, | ||
675 | struct dmxdev_filter *dmxdevfilter) | ||
676 | { | ||
677 | - if (mutex_lock_interruptible(&dmxdev->mutex)) | ||
678 | - return -ERESTARTSYS; | ||
679 | - | ||
680 | - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { | ||
681 | - mutex_unlock(&dmxdev->mutex); | ||
682 | - return -ERESTARTSYS; | ||
683 | - } | ||
684 | + mutex_lock(&dmxdev->mutex); | ||
685 | + mutex_lock(&dmxdevfilter->mutex); | ||
686 | |||
687 | dvb_dmxdev_filter_stop(dmxdevfilter); | ||
688 | dvb_dmxdev_filter_reset(dmxdevfilter); | ||
689 | diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c | ||
690 | index fcff5ea..6d8d1c3 100644 | ||
691 | --- a/drivers/media/dvb/dvb-core/dvb_demux.c | ||
692 | +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | ||
693 | @@ -673,8 +673,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) | ||
694 | struct dvb_demux *demux = feed->demux; | ||
695 | int ret; | ||
696 | |||
697 | - if (mutex_lock_interruptible(&demux->mutex)) | ||
698 | - return -ERESTARTSYS; | ||
699 | + mutex_lock(&demux->mutex); | ||
700 | |||
701 | if (feed->state < DMX_STATE_GO) { | ||
702 | mutex_unlock(&demux->mutex); | ||
703 | @@ -748,8 +747,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, | ||
704 | struct dvb_demux *demux = (struct dvb_demux *)dmx; | ||
705 | struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; | ||
706 | |||
707 | - if (mutex_lock_interruptible(&demux->mutex)) | ||
708 | - return -ERESTARTSYS; | ||
709 | + mutex_lock(&demux->mutex); | ||
710 | |||
711 | if (feed->state == DMX_STATE_FREE) { | ||
712 | mutex_unlock(&demux->mutex); | ||
713 | @@ -916,8 +914,7 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) | ||
714 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
715 | int ret; | ||
716 | |||
717 | - if (mutex_lock_interruptible(&dvbdmx->mutex)) | ||
718 | - return -ERESTARTSYS; | ||
719 | + mutex_lock(&dvbdmx->mutex); | ||
720 | |||
721 | if (!dvbdmx->stop_feed) { | ||
722 | mutex_unlock(&dvbdmx->mutex); | ||
723 | @@ -942,8 +939,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, | ||
724 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; | ||
725 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
726 | |||
727 | - if (mutex_lock_interruptible(&dvbdmx->mutex)) | ||
728 | - return -ERESTARTSYS; | ||
729 | + mutex_lock(&dvbdmx->mutex); | ||
730 | |||
731 | if (dvbdmxfilter->feed != dvbdmxfeed) { | ||
732 | mutex_unlock(&dvbdmx->mutex); | ||
733 | @@ -1016,8 +1012,7 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux, | ||
734 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; | ||
735 | struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; | ||
736 | |||
737 | - if (mutex_lock_interruptible(&dvbdmx->mutex)) | ||
738 | - return -ERESTARTSYS; | ||
739 | + mutex_lock(&dvbdmx->mutex); | ||
740 | |||
741 | if (dvbdmxfeed->state == DMX_STATE_FREE) { | ||
742 | mutex_unlock(&dvbdmx->mutex); | ||
743 | @@ -1126,8 +1121,7 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux, | ||
744 | if (demux->frontend) | ||
745 | return -EINVAL; | ||
746 | |||
747 | - if (mutex_lock_interruptible(&dvbdemux->mutex)) | ||
748 | - return -ERESTARTSYS; | ||
749 | + mutex_lock(&dvbdemux->mutex); | ||
750 | |||
751 | demux->frontend = frontend; | ||
752 | mutex_unlock(&dvbdemux->mutex); | ||
753 | @@ -1138,8 +1132,7 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux) | ||
754 | { | ||
755 | struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; | ||
756 | |||
757 | - if (mutex_lock_interruptible(&dvbdemux->mutex)) | ||
758 | - return -ERESTARTSYS; | ||
759 | + mutex_lock(&dvbdemux->mutex); | ||
760 | |||
761 | demux->frontend = NULL; | ||
762 | mutex_unlock(&dvbdemux->mutex); | ||
763 | diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c | ||
764 | index af35f30..b3a8cbb 100644 | ||
765 | --- a/drivers/media/dvb/dvb-core/dvbdev.c | ||
766 | +++ b/drivers/media/dvb/dvb-core/dvbdev.c | ||
767 | @@ -204,8 +204,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | ||
768 | |||
769 | int id; | ||
770 | |||
771 | - if (mutex_lock_interruptible(&dvbdev_register_lock)) | ||
772 | - return -ERESTARTSYS; | ||
773 | + mutex_lock(&dvbdev_register_lock); | ||
774 | |||
775 | if ((id = dvbdev_get_free_id (adap, type)) < 0) { | ||
776 | mutex_unlock(&dvbdev_register_lock); | ||
777 | @@ -295,8 +294,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu | ||
778 | { | ||
779 | int num; | ||
780 | |||
781 | - if (mutex_lock_interruptible(&dvbdev_register_lock)) | ||
782 | - return -ERESTARTSYS; | ||
783 | + mutex_lock(&dvbdev_register_lock); | ||
784 | |||
785 | if ((num = dvbdev_get_free_adapter_num ()) < 0) { | ||
786 | mutex_unlock(&dvbdev_register_lock); | ||
787 | @@ -324,8 +322,7 @@ EXPORT_SYMBOL(dvb_register_adapter); | ||
788 | |||
789 | int dvb_unregister_adapter(struct dvb_adapter *adap) | ||
790 | { | ||
791 | - if (mutex_lock_interruptible(&dvbdev_register_lock)) | ||
792 | - return -ERESTARTSYS; | ||
793 | + mutex_lock(&dvbdev_register_lock); | ||
794 | list_del (&adap->list_head); | ||
795 | mutex_unlock(&dvbdev_register_lock); | ||
796 | return 0; | ||
797 | diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c | ||
798 | index ef31936..c967148 100644 | ||
799 | --- a/drivers/media/dvb/frontends/isl6421.c | ||
800 | +++ b/drivers/media/dvb/frontends/isl6421.c | ||
801 | @@ -122,6 +122,7 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter | ||
802 | /* detect if it is present or not */ | ||
803 | if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) { | ||
804 | kfree(isl6421); | ||
805 | + fe->sec_priv = NULL; | ||
806 | return NULL; | ||
807 | } | ||
808 | |||
809 | diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c | ||
810 | index 87c286e..b809f83 100644 | ||
811 | --- a/drivers/media/dvb/frontends/nxt200x.c | ||
812 | +++ b/drivers/media/dvb/frontends/nxt200x.c | ||
813 | @@ -562,7 +562,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | ||
814 | |||
815 | /* set input */ | ||
816 | if (state->config->set_pll_input) | ||
817 | - state->config->set_pll_input(buf, 1); | ||
818 | + state->config->set_pll_input(buf+1, 1); | ||
819 | break; | ||
820 | case VSB_8: | ||
821 | /* Set non-punctured clock for VSB */ | ||
822 | @@ -571,7 +571,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | ||
823 | |||
824 | /* set input */ | ||
825 | if (state->config->set_pll_input) | ||
826 | - state->config->set_pll_input(buf, 0); | ||
827 | + state->config->set_pll_input(buf+1, 0); | ||
828 | break; | ||
829 | default: | ||
830 | return -EINVAL; | ||
831 | diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig | ||
832 | index 920b63f..af66a5d 100644 | ||
833 | --- a/drivers/media/radio/Kconfig | ||
834 | +++ b/drivers/media/radio/Kconfig | ||
835 | @@ -3,7 +3,7 @@ | ||
836 | # | ||
837 | |||
838 | menu "Radio Adapters" | ||
839 | - depends on VIDEO_DEV!=n | ||
840 | + depends on VIDEO_DEV | ||
841 | |||
842 | config RADIO_CADET | ||
843 | tristate "ADS Cadet AM/FM Tuner" | ||
844 | diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c | ||
845 | index 2fb9fe6..91078c0 100644 | ||
846 | --- a/drivers/media/video/msp3400-driver.c | ||
847 | +++ b/drivers/media/video/msp3400-driver.c | ||
848 | @@ -825,7 +825,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | ||
849 | if (msp_reset(client) == -1) { | ||
850 | v4l_dbg(1, msp_debug, client, "msp3400 not found\n"); | ||
851 | kfree(client); | ||
852 | - return -1; | ||
853 | + return 0; | ||
854 | } | ||
855 | |||
856 | state = kmalloc(sizeof(*state), GFP_KERNEL); | ||
857 | @@ -859,7 +859,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | ||
858 | v4l_dbg(1, msp_debug, client, "not an msp3400 (cannot read chip version)\n"); | ||
859 | kfree(state); | ||
860 | kfree(client); | ||
861 | - return -1; | ||
862 | + return 0; | ||
863 | } | ||
864 | |||
865 | msp_set_audio(client); | ||
866 | diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c | ||
867 | index c2374ed..7e494c5 100644 | ||
868 | --- a/drivers/media/video/saa7115.c | ||
869 | +++ b/drivers/media/video/saa7115.c | ||
870 | @@ -960,7 +960,7 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std) | ||
871 | reg |= 0x10; | ||
872 | } else if (std == V4L2_STD_NTSC_M_JP) { | ||
873 | reg |= 0x40; | ||
874 | - } else if (std == V4L2_STD_SECAM) { | ||
875 | + } else if (std & V4L2_STD_SECAM) { | ||
876 | reg |= 0x50; | ||
877 | } | ||
878 | saa711x_write(client, R_0E_CHROMA_CNTL_1, reg); | ||
879 | diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c | ||
880 | index da9859f..b17c4b2 100644 | ||
881 | --- a/drivers/message/i2o/i2o_block.c | ||
882 | +++ b/drivers/message/i2o/i2o_block.c | ||
883 | @@ -390,13 +390,6 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req) | ||
884 | return BLKPREP_KILL; | ||
885 | } | ||
886 | |||
887 | - /* request is already processed by us, so return */ | ||
888 | - if (blk_special_request(req)) { | ||
889 | - osm_debug("REQ_SPECIAL already set!\n"); | ||
890 | - req->cmd_flags |= REQ_DONTPREP; | ||
891 | - return BLKPREP_OK; | ||
892 | - } | ||
893 | - | ||
894 | /* connect the i2o_block_request to the request */ | ||
895 | if (!req->special) { | ||
896 | ireq = i2o_block_request_alloc(); | ||
897 | @@ -408,11 +401,8 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req) | ||
898 | ireq->i2o_blk_dev = i2o_blk_dev; | ||
899 | req->special = ireq; | ||
900 | ireq->req = req; | ||
901 | - } else | ||
902 | - ireq = req->special; | ||
903 | - | ||
904 | + } | ||
905 | /* do not come back here */ | ||
906 | - req->cmd_type = REQ_TYPE_SPECIAL; | ||
907 | req->cmd_flags |= REQ_DONTPREP; | ||
908 | |||
909 | return BLKPREP_OK; | ||
910 | diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c | ||
911 | index c6de566..ddf94ea 100644 | ||
912 | --- a/drivers/net/ppp_generic.c | ||
913 | +++ b/drivers/net/ppp_generic.c | ||
914 | @@ -2544,6 +2544,9 @@ static void ppp_destroy_interface(struct ppp *ppp) | ||
915 | ppp->active_filter = NULL; | ||
916 | #endif /* CONFIG_PPP_FILTER */ | ||
917 | |||
918 | + if (ppp->xmit_pending) | ||
919 | + kfree_skb(ppp->xmit_pending); | ||
920 | + | ||
921 | kfree(ppp); | ||
922 | } | ||
923 | |||
924 | diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c | ||
925 | index 15854ae..1d4e835 100644 | ||
926 | --- a/drivers/video/ffb.c | ||
927 | +++ b/drivers/video/ffb.c | ||
928 | @@ -336,14 +336,30 @@ struct ffb_dac { | ||
929 | u32 value2; | ||
930 | }; | ||
931 | |||
932 | +#define FFB_DAC_UCTRL 0x1001 /* User Control */ | ||
933 | +#define FFB_DAC_UCTRL_MANREV 0x00000f00 /* 4-bit Manufacturing Revision */ | ||
934 | +#define FFB_DAC_UCTRL_MANREV_SHIFT 8 | ||
935 | +#define FFB_DAC_TGEN 0x6000 /* Timing Generator */ | ||
936 | +#define FFB_DAC_TGEN_VIDE 0x00000001 /* Video Enable */ | ||
937 | +#define FFB_DAC_DID 0x8000 /* Device Identification */ | ||
938 | +#define FFB_DAC_DID_PNUM 0x0ffff000 /* Device Part Number */ | ||
939 | +#define FFB_DAC_DID_PNUM_SHIFT 12 | ||
940 | +#define FFB_DAC_DID_REV 0xf0000000 /* Device Revision */ | ||
941 | +#define FFB_DAC_DID_REV_SHIFT 28 | ||
942 | + | ||
943 | +#define FFB_DAC_CUR_CTRL 0x100 | ||
944 | +#define FFB_DAC_CUR_CTRL_P0 0x00000001 | ||
945 | +#define FFB_DAC_CUR_CTRL_P1 0x00000002 | ||
946 | + | ||
947 | struct ffb_par { | ||
948 | spinlock_t lock; | ||
949 | struct ffb_fbc __iomem *fbc; | ||
950 | struct ffb_dac __iomem *dac; | ||
951 | |||
952 | u32 flags; | ||
953 | -#define FFB_FLAG_AFB 0x00000001 | ||
954 | -#define FFB_FLAG_BLANKED 0x00000002 | ||
955 | +#define FFB_FLAG_AFB 0x00000001 /* AFB m3 or m6 */ | ||
956 | +#define FFB_FLAG_BLANKED 0x00000002 /* screen is blanked */ | ||
957 | +#define FFB_FLAG_INVCURSOR 0x00000004 /* DAC has inverted cursor logic */ | ||
958 | |||
959 | u32 fg_cache __attribute__((aligned (8))); | ||
960 | u32 bg_cache; | ||
961 | @@ -354,7 +370,6 @@ struct ffb_par { | ||
962 | unsigned long physbase; | ||
963 | unsigned long fbsize; | ||
964 | |||
965 | - int dac_rev; | ||
966 | int board_type; | ||
967 | }; | ||
968 | |||
969 | @@ -426,11 +441,12 @@ static void ffb_switch_from_graph(struct ffb_par *par) | ||
970 | FFBWait(par); | ||
971 | |||
972 | /* Disable cursor. */ | ||
973 | - upa_writel(0x100, &dac->type2); | ||
974 | - if (par->dac_rev <= 2) | ||
975 | + upa_writel(FFB_DAC_CUR_CTRL, &dac->type2); | ||
976 | + if (par->flags & FFB_FLAG_INVCURSOR) | ||
977 | upa_writel(0, &dac->value2); | ||
978 | else | ||
979 | - upa_writel(3, &dac->value2); | ||
980 | + upa_writel((FFB_DAC_CUR_CTRL_P0 | | ||
981 | + FFB_DAC_CUR_CTRL_P1), &dac->value2); | ||
982 | |||
983 | spin_unlock_irqrestore(&par->lock, flags); | ||
984 | } | ||
985 | @@ -664,18 +680,18 @@ ffb_blank(int blank, struct fb_info *info) | ||
986 | struct ffb_par *par = (struct ffb_par *) info->par; | ||
987 | struct ffb_dac __iomem *dac = par->dac; | ||
988 | unsigned long flags; | ||
989 | - u32 tmp; | ||
990 | + u32 val; | ||
991 | + int i; | ||
992 | |||
993 | spin_lock_irqsave(&par->lock, flags); | ||
994 | |||
995 | FFBWait(par); | ||
996 | |||
997 | + upa_writel(FFB_DAC_TGEN, &dac->type); | ||
998 | + val = upa_readl(&dac->value); | ||
999 | switch (blank) { | ||
1000 | case FB_BLANK_UNBLANK: /* Unblanking */ | ||
1001 | - upa_writel(0x6000, &dac->type); | ||
1002 | - tmp = (upa_readl(&dac->value) | 0x1); | ||
1003 | - upa_writel(0x6000, &dac->type); | ||
1004 | - upa_writel(tmp, &dac->value); | ||
1005 | + val |= FFB_DAC_TGEN_VIDE; | ||
1006 | par->flags &= ~FFB_FLAG_BLANKED; | ||
1007 | break; | ||
1008 | |||
1009 | @@ -683,13 +699,16 @@ ffb_blank(int blank, struct fb_info *info) | ||
1010 | case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */ | ||
1011 | case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */ | ||
1012 | case FB_BLANK_POWERDOWN: /* Poweroff */ | ||
1013 | - upa_writel(0x6000, &dac->type); | ||
1014 | - tmp = (upa_readl(&dac->value) & ~0x1); | ||
1015 | - upa_writel(0x6000, &dac->type); | ||
1016 | - upa_writel(tmp, &dac->value); | ||
1017 | + val &= ~FFB_DAC_TGEN_VIDE; | ||
1018 | par->flags |= FFB_FLAG_BLANKED; | ||
1019 | break; | ||
1020 | } | ||
1021 | + upa_writel(FFB_DAC_TGEN, &dac->type); | ||
1022 | + upa_writel(val, &dac->value); | ||
1023 | + for (i = 0; i < 10; i++) { | ||
1024 | + upa_writel(FFB_DAC_TGEN, &dac->type); | ||
1025 | + upa_readl(&dac->value); | ||
1026 | + } | ||
1027 | |||
1028 | spin_unlock_irqrestore(&par->lock, flags); | ||
1029 | |||
1030 | @@ -894,6 +913,7 @@ static int ffb_init_one(struct of_device *op) | ||
1031 | struct ffb_dac __iomem *dac; | ||
1032 | struct all_info *all; | ||
1033 | int err; | ||
1034 | + u32 dac_pnum, dac_rev, dac_mrev; | ||
1035 | |||
1036 | all = kzalloc(sizeof(*all), GFP_KERNEL); | ||
1037 | if (!all) | ||
1038 | @@ -948,17 +968,31 @@ static int ffb_init_one(struct of_device *op) | ||
1039 | if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) | ||
1040 | upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr); | ||
1041 | |||
1042 | - ffb_switch_from_graph(&all->par); | ||
1043 | - | ||
1044 | dac = all->par.dac; | ||
1045 | - upa_writel(0x8000, &dac->type); | ||
1046 | - all->par.dac_rev = upa_readl(&dac->value) >> 0x1c; | ||
1047 | + upa_writel(FFB_DAC_DID, &dac->type); | ||
1048 | + dac_pnum = upa_readl(&dac->value); | ||
1049 | + dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT; | ||
1050 | + dac_pnum = (dac_pnum & FFB_DAC_DID_PNUM) >> FFB_DAC_DID_PNUM_SHIFT; | ||
1051 | + | ||
1052 | + upa_writel(FFB_DAC_UCTRL, &dac->type); | ||
1053 | + dac_mrev = upa_readl(&dac->value); | ||
1054 | + dac_mrev = (dac_mrev & FFB_DAC_UCTRL_MANREV) >> | ||
1055 | + FFB_DAC_UCTRL_MANREV_SHIFT; | ||
1056 | |||
1057 | /* Elite3D has different DAC revision numbering, and no DAC revisions | ||
1058 | - * have the reversed meaning of cursor enable. | ||
1059 | + * have the reversed meaning of cursor enable. Otherwise, Pacifica 1 | ||
1060 | + * ramdacs with manufacturing revision less than 3 have inverted | ||
1061 | + * cursor logic. We identify Pacifica 1 as not Pacifica 2, the | ||
1062 | + * latter having a part number value of 0x236e. | ||
1063 | */ | ||
1064 | - if (all->par.flags & FFB_FLAG_AFB) | ||
1065 | - all->par.dac_rev = 10; | ||
1066 | + if ((all->par.flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) { | ||
1067 | + all->par.flags &= ~FFB_FLAG_INVCURSOR; | ||
1068 | + } else { | ||
1069 | + if (dac_mrev < 3) | ||
1070 | + all->par.flags |= FFB_FLAG_INVCURSOR; | ||
1071 | + } | ||
1072 | + | ||
1073 | + ffb_switch_from_graph(&all->par); | ||
1074 | |||
1075 | /* Unblank it just to be sure. When there are multiple | ||
1076 | * FFB/AFB cards in the system, or it is not the OBP | ||
1077 | @@ -993,10 +1027,12 @@ static int ffb_init_one(struct of_device *op) | ||
1078 | |||
1079 | dev_set_drvdata(&op->dev, all); | ||
1080 | |||
1081 | - printk("%s: %s at %016lx, type %d, DAC revision %d\n", | ||
1082 | + printk("%s: %s at %016lx, type %d, " | ||
1083 | + "DAC pnum[%x] rev[%d] manuf_rev[%d]\n", | ||
1084 | dp->full_name, | ||
1085 | ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"), | ||
1086 | - all->par.physbase, all->par.board_type, all->par.dac_rev); | ||
1087 | + all->par.physbase, all->par.board_type, | ||
1088 | + dac_pnum, dac_rev, dac_mrev); | ||
1089 | |||
1090 | return 0; | ||
1091 | } | ||
1092 | diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c | ||
1093 | index c4fa91b..a894e6d 100644 | ||
1094 | --- a/fs/cifs/inode.c | ||
1095 | +++ b/fs/cifs/inode.c | ||
1096 | @@ -488,6 +488,12 @@ int cifs_get_inode_info(struct inode **pinode, | ||
1097 | mode e.g. 555 */ | ||
1098 | if (cifsInfo->cifsAttrs & ATTR_READONLY) | ||
1099 | inode->i_mode &= ~(S_IWUGO); | ||
1100 | + else if ((inode->i_mode & S_IWUGO) == 0) | ||
1101 | + /* the ATTR_READONLY flag may have been */ | ||
1102 | + /* changed on server -- set any w bits */ | ||
1103 | + /* allowed by mnt_file_mode */ | ||
1104 | + inode->i_mode |= (S_IWUGO & | ||
1105 | + cifs_sb->mnt_file_mode); | ||
1106 | /* BB add code here - | ||
1107 | validate if device or weird share or device type? */ | ||
1108 | } | ||
1109 | @@ -1133,6 +1139,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | ||
1110 | struct cifsFileInfo *open_file = NULL; | ||
1111 | FILE_BASIC_INFO time_buf; | ||
1112 | int set_time = FALSE; | ||
1113 | + int set_dosattr = FALSE; | ||
1114 | __u64 mode = 0xFFFFFFFFFFFFFFFFULL; | ||
1115 | __u64 uid = 0xFFFFFFFFFFFFFFFFULL; | ||
1116 | __u64 gid = 0xFFFFFFFFFFFFFFFFULL; | ||
1117 | @@ -1269,15 +1276,23 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | ||
1118 | else if (attrs->ia_valid & ATTR_MODE) { | ||
1119 | rc = 0; | ||
1120 | if ((mode & S_IWUGO) == 0) /* not writeable */ { | ||
1121 | - if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) | ||
1122 | + if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { | ||
1123 | + set_dosattr = TRUE; | ||
1124 | time_buf.Attributes = | ||
1125 | cpu_to_le32(cifsInode->cifsAttrs | | ||
1126 | ATTR_READONLY); | ||
1127 | + } | ||
1128 | } else if ((mode & S_IWUGO) == S_IWUGO) { | ||
1129 | - if (cifsInode->cifsAttrs & ATTR_READONLY) | ||
1130 | + if (cifsInode->cifsAttrs & ATTR_READONLY) { | ||
1131 | + set_dosattr = TRUE; | ||
1132 | time_buf.Attributes = | ||
1133 | cpu_to_le32(cifsInode->cifsAttrs & | ||
1134 | (~ATTR_READONLY)); | ||
1135 | + /* Windows ignores set to zero */ | ||
1136 | + if(time_buf.Attributes == 0) | ||
1137 | + time_buf.Attributes |= | ||
1138 | + cpu_to_le32(ATTR_NORMAL); | ||
1139 | + } | ||
1140 | } | ||
1141 | /* BB to be implemented - | ||
1142 | via Windows security descriptors or streams */ | ||
1143 | @@ -1315,7 +1330,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | ||
1144 | } else | ||
1145 | time_buf.ChangeTime = 0; | ||
1146 | |||
1147 | - if (set_time || time_buf.Attributes) { | ||
1148 | + if (set_time || set_dosattr) { | ||
1149 | time_buf.CreationTime = 0; /* do not change */ | ||
1150 | /* In the future we should experiment - try setting timestamps | ||
1151 | via Handle (SetFileInfo) instead of by path */ | ||
1152 | diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c | ||
1153 | index 99dfb53..d1d79fe 100644 | ||
1154 | --- a/fs/cifs/readdir.c | ||
1155 | +++ b/fs/cifs/readdir.c | ||
1156 | @@ -215,6 +215,10 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | ||
1157 | tmp_inode->i_mode |= S_IFREG; | ||
1158 | if (attr & ATTR_READONLY) | ||
1159 | tmp_inode->i_mode &= ~(S_IWUGO); | ||
1160 | + else if ((tmp_inode->i_mode & S_IWUGO) == 0) | ||
1161 | + /* the ATTR_READONLY flag may have been changed on */ | ||
1162 | + /* server -- set any w bits allowed by mnt_file_mode */ | ||
1163 | + tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); | ||
1164 | } /* could add code here - to validate if device or weird share type? */ | ||
1165 | |||
1166 | /* can not fill in nlink here as in qpathinfo version and Unx search */ | ||
1167 | diff --git a/include/asm-sparc/mostek.h b/include/asm-sparc/mostek.h | ||
1168 | index bd92a78..958d051 100644 | ||
1169 | --- a/include/asm-sparc/mostek.h | ||
1170 | +++ b/include/asm-sparc/mostek.h | ||
1171 | @@ -87,7 +87,7 @@ extern void __iomem *mstk48t02_regs; | ||
1172 | #define MSTK_DOW_MASK 0x07 | ||
1173 | #define MSTK_DOM_MASK 0x3f | ||
1174 | #define MSTK_MONTH_MASK 0x1f | ||
1175 | -#define MSTK_YEAR_MASK 0xff | ||
1176 | +#define MSTK_YEAR_MASK 0xffU | ||
1177 | |||
1178 | /* Binary coded decimal conversion macros. */ | ||
1179 | #define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04)) | ||
1180 | diff --git a/include/asm-sparc64/mostek.h b/include/asm-sparc64/mostek.h | ||
1181 | index 09b5aba..d14dd89 100644 | ||
1182 | --- a/include/asm-sparc64/mostek.h | ||
1183 | +++ b/include/asm-sparc64/mostek.h | ||
1184 | @@ -89,7 +89,7 @@ extern void __iomem *mstk48t02_regs; | ||
1185 | #define MSTK_DOW_MASK 0x07 | ||
1186 | #define MSTK_DOM_MASK 0x3f | ||
1187 | #define MSTK_MONTH_MASK 0x1f | ||
1188 | -#define MSTK_YEAR_MASK 0xff | ||
1189 | +#define MSTK_YEAR_MASK 0xffU | ||
1190 | |||
1191 | /* Binary coded decimal conversion macros. */ | ||
1192 | #define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04)) | ||
1193 | diff --git a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S | ||
1194 | index f045451..b16222b 100644 | ||
1195 | --- a/include/asm-um/common.lds.S | ||
1196 | +++ b/include/asm-um/common.lds.S | ||
1197 | @@ -15,6 +15,7 @@ | ||
1198 | PROVIDE (_unprotected_end = .); | ||
1199 | |||
1200 | . = ALIGN(4096); | ||
1201 | + .note : { *(note.*) } | ||
1202 | __start___ex_table = .; | ||
1203 | __ex_table : { *(__ex_table) } | ||
1204 | __stop___ex_table = .; | ||
1205 | diff --git a/include/asm-um/delay.h b/include/asm-um/delay.h | ||
1206 | index 0985bda..c71e32b 100644 | ||
1207 | --- a/include/asm-um/delay.h | ||
1208 | +++ b/include/asm-um/delay.h | ||
1209 | @@ -1,9 +1,20 @@ | ||
1210 | #ifndef __UM_DELAY_H | ||
1211 | #define __UM_DELAY_H | ||
1212 | |||
1213 | -#include "asm/arch/delay.h" | ||
1214 | -#include "asm/archparam.h" | ||
1215 | - | ||
1216 | #define MILLION 1000000 | ||
1217 | |||
1218 | +/* Undefined on purpose */ | ||
1219 | +extern void __bad_udelay(void); | ||
1220 | + | ||
1221 | +extern void __udelay(unsigned long usecs); | ||
1222 | +extern void __delay(unsigned long loops); | ||
1223 | + | ||
1224 | +#define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \ | ||
1225 | + __bad_udelay() : __udelay(n)) | ||
1226 | + | ||
1227 | +/* It appears that ndelay is not used at all for UML, and has never been | ||
1228 | + * implemented. */ | ||
1229 | +extern void __unimplemented_ndelay(void); | ||
1230 | +#define ndelay(n) __unimplemented_ndelay() | ||
1231 | + | ||
1232 | #endif | ||
1233 | diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h | ||
1234 | index 84cfa8b..d2a96cb 100644 | ||
1235 | --- a/include/linux/eventpoll.h | ||
1236 | +++ b/include/linux/eventpoll.h | ||
1237 | @@ -31,12 +31,19 @@ | ||
1238 | /* | ||
1239 | * On x86-64 make the 64bit structure have the same alignment as the | ||
1240 | * 32bit structure. This makes 32bit emulation easier. | ||
1241 | + * | ||
1242 | + * UML/x86_64 needs the same packing as x86_64 - UML + UML_X86 + | ||
1243 | + * 64_BIT adds up to UML/x86_64. | ||
1244 | */ | ||
1245 | #ifdef __x86_64__ | ||
1246 | #define EPOLL_PACKED __attribute__((packed)) | ||
1247 | #else | ||
1248 | +#if defined(CONFIG_UML) && defined(CONFIG_UML_X86) && defined(CONFIG_64BIT) | ||
1249 | +#define EPOLL_PACKED __attribute__((packed)) | ||
1250 | +#else | ||
1251 | #define EPOLL_PACKED | ||
1252 | #endif | ||
1253 | +#endif | ||
1254 | |||
1255 | struct epoll_event { | ||
1256 | __u32 events; | ||
1257 | diff --git a/include/linux/ide.h b/include/linux/ide.h | ||
1258 | index e26a039..3808698 100644 | ||
1259 | --- a/include/linux/ide.h | ||
1260 | +++ b/include/linux/ide.h | ||
1261 | @@ -727,6 +727,7 @@ typedef struct hwif_s { | ||
1262 | int (*ide_dma_on)(ide_drive_t *drive); | ||
1263 | int (*ide_dma_off_quietly)(ide_drive_t *drive); | ||
1264 | int (*ide_dma_test_irq)(ide_drive_t *drive); | ||
1265 | + void (*ide_dma_clear_irq)(ide_drive_t *drive); | ||
1266 | int (*ide_dma_host_on)(ide_drive_t *drive); | ||
1267 | int (*ide_dma_host_off)(ide_drive_t *drive); | ||
1268 | int (*ide_dma_lostirq)(ide_drive_t *drive); | ||
1269 | @@ -796,7 +797,6 @@ typedef struct hwif_s { | ||
1270 | unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ | ||
1271 | unsigned no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */ | ||
1272 | unsigned err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */ | ||
1273 | - unsigned atapi_irq_bogon : 1; /* Generates spurious DMA interrupts in PIO mode */ | ||
1274 | |||
1275 | struct device gendev; | ||
1276 | struct completion gendev_rel_comp; /* To deal with device release() */ | ||
1277 | diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h | ||
1278 | index 83fe2e3..50e33b0 100644 | ||
1279 | --- a/include/media/saa7146_vv.h | ||
1280 | +++ b/include/media/saa7146_vv.h | ||
1281 | @@ -239,7 +239,8 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits); | ||
1282 | #define SAA7146_HPS_SYNC_PORT_B 0x01 | ||
1283 | |||
1284 | /* some memory sizes */ | ||
1285 | -#define SAA7146_CLIPPING_MEM (14*PAGE_SIZE) | ||
1286 | +/* max. 16 clipping rectangles */ | ||
1287 | +#define SAA7146_CLIPPING_MEM (16 * 4 * sizeof(u32)) | ||
1288 | |||
1289 | /* some defines for the various clipping-modes */ | ||
1290 | #define SAA7146_CLIPPING_RECT 0x4 | ||
1291 | diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h | ||
1292 | index bc3c264..d585ea9 100644 | ||
1293 | --- a/include/net/fib_rules.h | ||
1294 | +++ b/include/net/fib_rules.h | ||
1295 | @@ -34,6 +34,7 @@ struct fib_rules_ops | ||
1296 | int family; | ||
1297 | struct list_head list; | ||
1298 | int rule_size; | ||
1299 | + int addr_size; | ||
1300 | |||
1301 | int (*action)(struct fib_rule *, | ||
1302 | struct flowi *, int, | ||
1303 | diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h | ||
1304 | index 7be4f4e..1d2037c 100644 | ||
1305 | --- a/include/net/ip6_fib.h | ||
1306 | +++ b/include/net/ip6_fib.h | ||
1307 | @@ -58,6 +58,7 @@ struct fib6_node | ||
1308 | __u16 fn_bit; /* bit key */ | ||
1309 | __u16 fn_flags; | ||
1310 | __u32 fn_sernum; | ||
1311 | + struct rt6_info *rr_ptr; | ||
1312 | }; | ||
1313 | |||
1314 | #ifndef CONFIG_IPV6_SUBTREES | ||
1315 | diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c | ||
1316 | index 3a70522..7c69506 100644 | ||
1317 | --- a/net/appletalk/ddp.c | ||
1318 | +++ b/net/appletalk/ddp.c | ||
1319 | @@ -1417,10 +1417,13 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, | ||
1320 | /* | ||
1321 | * Size check to see if ddp->deh_len was crap | ||
1322 | * (Otherwise we'll detonate most spectacularly | ||
1323 | - * in the middle of recvmsg()). | ||
1324 | + * in the middle of atalk_checksum() or recvmsg()). | ||
1325 | */ | ||
1326 | - if (skb->len < sizeof(*ddp)) | ||
1327 | + if (skb->len < sizeof(*ddp) || skb->len < (len_hops & 1023)) { | ||
1328 | + pr_debug("AppleTalk: dropping corrupted frame (deh_len=%u, " | ||
1329 | + "skb->len=%u)\n", len_hops & 1023, skb->len); | ||
1330 | goto freeit; | ||
1331 | + } | ||
1332 | |||
1333 | /* | ||
1334 | * Any checksums. Note we don't do htons() on this == is assumed to be | ||
1335 | diff --git a/net/core/dev.c b/net/core/dev.c | ||
1336 | index e660cb5..295f8f9 100644 | ||
1337 | --- a/net/core/dev.c | ||
1338 | +++ b/net/core/dev.c | ||
1339 | @@ -1750,10 +1750,10 @@ static int ing_filter(struct sk_buff *skb) | ||
1340 | |||
1341 | skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS); | ||
1342 | |||
1343 | - spin_lock(&dev->ingress_lock); | ||
1344 | + spin_lock(&dev->queue_lock); | ||
1345 | if ((q = dev->qdisc_ingress) != NULL) | ||
1346 | result = q->enqueue(skb, q); | ||
1347 | - spin_unlock(&dev->ingress_lock); | ||
1348 | + spin_unlock(&dev->queue_lock); | ||
1349 | |||
1350 | } | ||
1351 | |||
1352 | diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c | ||
1353 | index 1df6cd4..bdbb479 100644 | ||
1354 | --- a/net/core/fib_rules.c | ||
1355 | +++ b/net/core/fib_rules.c | ||
1356 | @@ -152,6 +152,28 @@ out: | ||
1357 | |||
1358 | EXPORT_SYMBOL_GPL(fib_rules_lookup); | ||
1359 | |||
1360 | +static int validate_rulemsg(struct fib_rule_hdr *frh, struct nlattr **tb, | ||
1361 | + struct fib_rules_ops *ops) | ||
1362 | +{ | ||
1363 | + int err = -EINVAL; | ||
1364 | + | ||
1365 | + if (frh->src_len) | ||
1366 | + if (tb[FRA_SRC] == NULL || | ||
1367 | + frh->src_len > (ops->addr_size * 8) || | ||
1368 | + nla_len(tb[FRA_SRC]) != ops->addr_size) | ||
1369 | + goto errout; | ||
1370 | + | ||
1371 | + if (frh->dst_len) | ||
1372 | + if (tb[FRA_DST] == NULL || | ||
1373 | + frh->dst_len > (ops->addr_size * 8) || | ||
1374 | + nla_len(tb[FRA_DST]) != ops->addr_size) | ||
1375 | + goto errout; | ||
1376 | + | ||
1377 | + err = 0; | ||
1378 | +errout: | ||
1379 | + return err; | ||
1380 | +} | ||
1381 | + | ||
1382 | int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | ||
1383 | { | ||
1384 | struct fib_rule_hdr *frh = nlmsg_data(nlh); | ||
1385 | @@ -173,6 +195,10 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | ||
1386 | if (err < 0) | ||
1387 | goto errout; | ||
1388 | |||
1389 | + err = validate_rulemsg(frh, tb, ops); | ||
1390 | + if (err < 0) | ||
1391 | + goto errout; | ||
1392 | + | ||
1393 | rule = kzalloc(ops->rule_size, GFP_KERNEL); | ||
1394 | if (rule == NULL) { | ||
1395 | err = -ENOMEM; | ||
1396 | @@ -260,6 +286,10 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | ||
1397 | if (err < 0) | ||
1398 | goto errout; | ||
1399 | |||
1400 | + err = validate_rulemsg(frh, tb, ops); | ||
1401 | + if (err < 0) | ||
1402 | + goto errout; | ||
1403 | + | ||
1404 | list_for_each_entry(rule, ops->rules_list, list) { | ||
1405 | if (frh->action && (frh->action != rule->action)) | ||
1406 | continue; | ||
1407 | diff --git a/net/dccp/proto.c b/net/dccp/proto.c | ||
1408 | index 63b3fa2..88ed359 100644 | ||
1409 | --- a/net/dccp/proto.c | ||
1410 | +++ b/net/dccp/proto.c | ||
1411 | @@ -575,7 +575,7 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname, | ||
1412 | if (get_user(len, optlen)) | ||
1413 | return -EFAULT; | ||
1414 | |||
1415 | - if (len < sizeof(int)) | ||
1416 | + if (len < (int)sizeof(int)) | ||
1417 | return -EINVAL; | ||
1418 | |||
1419 | dp = dccp_sk(sk); | ||
1420 | @@ -589,9 +589,11 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname, | ||
1421 | (__be32 __user *)optval, optlen); | ||
1422 | case DCCP_SOCKOPT_SEND_CSCOV: | ||
1423 | val = dp->dccps_pcslen; | ||
1424 | + len = sizeof(val); | ||
1425 | break; | ||
1426 | case DCCP_SOCKOPT_RECV_CSCOV: | ||
1427 | val = dp->dccps_pcrlen; | ||
1428 | + len = sizeof(val); | ||
1429 | break; | ||
1430 | case 128 ... 191: | ||
1431 | return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname, | ||
1432 | diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c | ||
1433 | index e32d0c3..5e86dd5 100644 | ||
1434 | --- a/net/decnet/dn_rules.c | ||
1435 | +++ b/net/decnet/dn_rules.c | ||
1436 | @@ -109,8 +109,6 @@ errout: | ||
1437 | |||
1438 | static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { | ||
1439 | FRA_GENERIC_POLICY, | ||
1440 | - [FRA_SRC] = { .type = NLA_U16 }, | ||
1441 | - [FRA_DST] = { .type = NLA_U16 }, | ||
1442 | }; | ||
1443 | |||
1444 | static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | ||
1445 | @@ -133,7 +131,7 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | ||
1446 | int err = -EINVAL; | ||
1447 | struct dn_fib_rule *r = (struct dn_fib_rule *)rule; | ||
1448 | |||
1449 | - if (frh->src_len > 16 || frh->dst_len > 16 || frh->tos) | ||
1450 | + if (frh->tos) | ||
1451 | goto errout; | ||
1452 | |||
1453 | if (rule->table == RT_TABLE_UNSPEC) { | ||
1454 | @@ -150,11 +148,11 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | ||
1455 | } | ||
1456 | } | ||
1457 | |||
1458 | - if (tb[FRA_SRC]) | ||
1459 | - r->src = nla_get_u16(tb[FRA_SRC]); | ||
1460 | + if (frh->src_len) | ||
1461 | + r->src = nla_get_le16(tb[FRA_SRC]); | ||
1462 | |||
1463 | - if (tb[FRA_DST]) | ||
1464 | - r->dst = nla_get_u16(tb[FRA_DST]); | ||
1465 | + if (frh->dst_len) | ||
1466 | + r->dst = nla_get_le16(tb[FRA_DST]); | ||
1467 | |||
1468 | r->src_len = frh->src_len; | ||
1469 | r->srcmask = dnet_make_mask(r->src_len); | ||
1470 | @@ -176,10 +174,10 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | ||
1471 | if (frh->dst_len && (r->dst_len != frh->dst_len)) | ||
1472 | return 0; | ||
1473 | |||
1474 | - if (tb[FRA_SRC] && (r->src != nla_get_u16(tb[FRA_SRC]))) | ||
1475 | + if (frh->src_len && (r->src != nla_get_le16(tb[FRA_SRC]))) | ||
1476 | return 0; | ||
1477 | |||
1478 | - if (tb[FRA_DST] && (r->dst != nla_get_u16(tb[FRA_DST]))) | ||
1479 | + if (frh->dst_len && (r->dst != nla_get_le16(tb[FRA_DST]))) | ||
1480 | return 0; | ||
1481 | |||
1482 | return 1; | ||
1483 | @@ -214,9 +212,9 @@ static int dn_fib_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | ||
1484 | frh->tos = 0; | ||
1485 | |||
1486 | if (r->dst_len) | ||
1487 | - NLA_PUT_U16(skb, FRA_DST, r->dst); | ||
1488 | + NLA_PUT_LE16(skb, FRA_DST, r->dst); | ||
1489 | if (r->src_len) | ||
1490 | - NLA_PUT_U16(skb, FRA_SRC, r->src); | ||
1491 | + NLA_PUT_LE16(skb, FRA_SRC, r->src); | ||
1492 | |||
1493 | return 0; | ||
1494 | |||
1495 | @@ -249,6 +247,7 @@ int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb) | ||
1496 | static struct fib_rules_ops dn_fib_rules_ops = { | ||
1497 | .family = AF_DECnet, | ||
1498 | .rule_size = sizeof(struct dn_fib_rule), | ||
1499 | + .addr_size = sizeof(u16), | ||
1500 | .action = dn_fib_rule_action, | ||
1501 | .match = dn_fib_rule_match, | ||
1502 | .configure = dn_fib_rule_configure, | ||
1503 | diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c | ||
1504 | index b837c33..c660c07 100644 | ||
1505 | --- a/net/ipv4/fib_rules.c | ||
1506 | +++ b/net/ipv4/fib_rules.c | ||
1507 | @@ -171,8 +171,6 @@ static struct fib_table *fib_empty_table(void) | ||
1508 | |||
1509 | static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { | ||
1510 | FRA_GENERIC_POLICY, | ||
1511 | - [FRA_SRC] = { .type = NLA_U32 }, | ||
1512 | - [FRA_DST] = { .type = NLA_U32 }, | ||
1513 | [FRA_FLOW] = { .type = NLA_U32 }, | ||
1514 | }; | ||
1515 | |||
1516 | @@ -183,8 +181,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | ||
1517 | int err = -EINVAL; | ||
1518 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; | ||
1519 | |||
1520 | - if (frh->src_len > 32 || frh->dst_len > 32 || | ||
1521 | - (frh->tos & ~IPTOS_TOS_MASK)) | ||
1522 | + if (frh->tos & ~IPTOS_TOS_MASK) | ||
1523 | goto errout; | ||
1524 | |||
1525 | if (rule->table == RT_TABLE_UNSPEC) { | ||
1526 | @@ -201,10 +198,10 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | ||
1527 | } | ||
1528 | } | ||
1529 | |||
1530 | - if (tb[FRA_SRC]) | ||
1531 | + if (frh->src_len) | ||
1532 | rule4->src = nla_get_be32(tb[FRA_SRC]); | ||
1533 | |||
1534 | - if (tb[FRA_DST]) | ||
1535 | + if (frh->dst_len) | ||
1536 | rule4->dst = nla_get_be32(tb[FRA_DST]); | ||
1537 | |||
1538 | #ifdef CONFIG_NET_CLS_ROUTE | ||
1539 | @@ -242,10 +239,10 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | ||
1540 | return 0; | ||
1541 | #endif | ||
1542 | |||
1543 | - if (tb[FRA_SRC] && (rule4->src != nla_get_be32(tb[FRA_SRC]))) | ||
1544 | + if (frh->src_len && (rule4->src != nla_get_be32(tb[FRA_SRC]))) | ||
1545 | return 0; | ||
1546 | |||
1547 | - if (tb[FRA_DST] && (rule4->dst != nla_get_be32(tb[FRA_DST]))) | ||
1548 | + if (frh->dst_len && (rule4->dst != nla_get_be32(tb[FRA_DST]))) | ||
1549 | return 0; | ||
1550 | |||
1551 | return 1; | ||
1552 | @@ -309,6 +306,7 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule) | ||
1553 | static struct fib_rules_ops fib4_rules_ops = { | ||
1554 | .family = AF_INET, | ||
1555 | .rule_size = sizeof(struct fib4_rule), | ||
1556 | + .addr_size = sizeof(u32), | ||
1557 | .action = fib4_rule_action, | ||
1558 | .match = fib4_rule_match, | ||
1559 | .configure = fib4_rule_configure, | ||
1560 | diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c | ||
1561 | index 0862809..ea3035b 100644 | ||
1562 | --- a/net/ipv6/fib6_rules.c | ||
1563 | +++ b/net/ipv6/fib6_rules.c | ||
1564 | @@ -131,8 +131,6 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | ||
1565 | |||
1566 | static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { | ||
1567 | FRA_GENERIC_POLICY, | ||
1568 | - [FRA_SRC] = { .len = sizeof(struct in6_addr) }, | ||
1569 | - [FRA_DST] = { .len = sizeof(struct in6_addr) }, | ||
1570 | }; | ||
1571 | |||
1572 | static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | ||
1573 | @@ -142,9 +140,6 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | ||
1574 | int err = -EINVAL; | ||
1575 | struct fib6_rule *rule6 = (struct fib6_rule *) rule; | ||
1576 | |||
1577 | - if (frh->src_len > 128 || frh->dst_len > 128) | ||
1578 | - goto errout; | ||
1579 | - | ||
1580 | if (rule->action == FR_ACT_TO_TBL) { | ||
1581 | if (rule->table == RT6_TABLE_UNSPEC) | ||
1582 | goto errout; | ||
1583 | @@ -155,11 +150,11 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | ||
1584 | } | ||
1585 | } | ||
1586 | |||
1587 | - if (tb[FRA_SRC]) | ||
1588 | + if (frh->src_len) | ||
1589 | nla_memcpy(&rule6->src.addr, tb[FRA_SRC], | ||
1590 | sizeof(struct in6_addr)); | ||
1591 | |||
1592 | - if (tb[FRA_DST]) | ||
1593 | + if (frh->dst_len) | ||
1594 | nla_memcpy(&rule6->dst.addr, tb[FRA_DST], | ||
1595 | sizeof(struct in6_addr)); | ||
1596 | |||
1597 | @@ -186,11 +181,11 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | ||
1598 | if (frh->tos && (rule6->tclass != frh->tos)) | ||
1599 | return 0; | ||
1600 | |||
1601 | - if (tb[FRA_SRC] && | ||
1602 | + if (frh->src_len && | ||
1603 | nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr))) | ||
1604 | return 0; | ||
1605 | |||
1606 | - if (tb[FRA_DST] && | ||
1607 | + if (frh->dst_len && | ||
1608 | nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr))) | ||
1609 | return 0; | ||
1610 | |||
1611 | @@ -240,6 +235,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) | ||
1612 | static struct fib_rules_ops fib6_rules_ops = { | ||
1613 | .family = AF_INET6, | ||
1614 | .rule_size = sizeof(struct fib6_rule), | ||
1615 | + .addr_size = sizeof(struct in6_addr), | ||
1616 | .action = fib6_rule_action, | ||
1617 | .match = fib6_rule_match, | ||
1618 | .configure = fib6_rule_configure, | ||
1619 | diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c | ||
1620 | index 96d8310..2d9c425 100644 | ||
1621 | --- a/net/ipv6/ip6_fib.c | ||
1622 | +++ b/net/ipv6/ip6_fib.c | ||
1623 | @@ -659,6 +659,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | ||
1624 | ins = &iter->u.next; | ||
1625 | } | ||
1626 | |||
1627 | + /* Reset round-robin state, if necessary */ | ||
1628 | + if (ins == &fn->leaf) | ||
1629 | + fn->rr_ptr = NULL; | ||
1630 | + | ||
1631 | /* | ||
1632 | * insert node | ||
1633 | */ | ||
1634 | @@ -1110,6 +1114,10 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, | ||
1635 | rt6_stats.fib_rt_entries--; | ||
1636 | rt6_stats.fib_discarded_routes++; | ||
1637 | |||
1638 | + /* Reset round-robin state, if necessary */ | ||
1639 | + if (fn->rr_ptr == rt) | ||
1640 | + fn->rr_ptr = NULL; | ||
1641 | + | ||
1642 | /* Adjust walkers */ | ||
1643 | read_lock(&fib6_walker_lock); | ||
1644 | FOR_WALKERS(w) { | ||
1645 | diff --git a/net/ipv6/route.c b/net/ipv6/route.c | ||
1646 | index 5f0043c..01bcf4a 100644 | ||
1647 | --- a/net/ipv6/route.c | ||
1648 | +++ b/net/ipv6/route.c | ||
1649 | @@ -354,55 +354,76 @@ static int rt6_score_route(struct rt6_info *rt, int oif, | ||
1650 | return m; | ||
1651 | } | ||
1652 | |||
1653 | -static struct rt6_info *rt6_select(struct rt6_info **head, int oif, | ||
1654 | - int strict) | ||
1655 | +static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict, | ||
1656 | + int *mpri, struct rt6_info *match) | ||
1657 | { | ||
1658 | - struct rt6_info *match = NULL, *last = NULL; | ||
1659 | - struct rt6_info *rt, *rt0 = *head; | ||
1660 | - u32 metric; | ||
1661 | + int m; | ||
1662 | + | ||
1663 | + if (rt6_check_expired(rt)) | ||
1664 | + goto out; | ||
1665 | + | ||
1666 | + m = rt6_score_route(rt, oif, strict); | ||
1667 | + if (m < 0) | ||
1668 | + goto out; | ||
1669 | + | ||
1670 | + if (m > *mpri) { | ||
1671 | + if (strict & RT6_LOOKUP_F_REACHABLE) | ||
1672 | + rt6_probe(match); | ||
1673 | + *mpri = m; | ||
1674 | + match = rt; | ||
1675 | + } else if (strict & RT6_LOOKUP_F_REACHABLE) { | ||
1676 | + rt6_probe(rt); | ||
1677 | + } | ||
1678 | + | ||
1679 | +out: | ||
1680 | + return match; | ||
1681 | +} | ||
1682 | + | ||
1683 | +static struct rt6_info *find_rr_leaf(struct fib6_node *fn, | ||
1684 | + struct rt6_info *rr_head, | ||
1685 | + u32 metric, int oif, int strict) | ||
1686 | +{ | ||
1687 | + struct rt6_info *rt, *match; | ||
1688 | int mpri = -1; | ||
1689 | |||
1690 | - RT6_TRACE("%s(head=%p(*head=%p), oif=%d)\n", | ||
1691 | - __FUNCTION__, head, head ? *head : NULL, oif); | ||
1692 | + match = NULL; | ||
1693 | + for (rt = rr_head; rt && rt->rt6i_metric == metric; | ||
1694 | + rt = rt->u.next) | ||
1695 | + match = find_match(rt, oif, strict, &mpri, match); | ||
1696 | + for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric; | ||
1697 | + rt = rt->u.next) | ||
1698 | + match = find_match(rt, oif, strict, &mpri, match); | ||
1699 | |||
1700 | - for (rt = rt0, metric = rt0->rt6i_metric; | ||
1701 | - rt && rt->rt6i_metric == metric && (!last || rt != rt0); | ||
1702 | - rt = rt->u.next) { | ||
1703 | - int m; | ||
1704 | + return match; | ||
1705 | +} | ||
1706 | |||
1707 | - if (rt6_check_expired(rt)) | ||
1708 | - continue; | ||
1709 | +static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict) | ||
1710 | +{ | ||
1711 | + struct rt6_info *match, *rt0; | ||
1712 | |||
1713 | - last = rt; | ||
1714 | + RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n", | ||
1715 | + __FUNCTION__, fn->leaf, oif); | ||
1716 | |||
1717 | - m = rt6_score_route(rt, oif, strict); | ||
1718 | - if (m < 0) | ||
1719 | - continue; | ||
1720 | + rt0 = fn->rr_ptr; | ||
1721 | + if (!rt0) | ||
1722 | + fn->rr_ptr = rt0 = fn->leaf; | ||
1723 | |||
1724 | - if (m > mpri) { | ||
1725 | - if (strict & RT6_LOOKUP_F_REACHABLE) | ||
1726 | - rt6_probe(match); | ||
1727 | - match = rt; | ||
1728 | - mpri = m; | ||
1729 | - } else if (strict & RT6_LOOKUP_F_REACHABLE) { | ||
1730 | - rt6_probe(rt); | ||
1731 | - } | ||
1732 | - } | ||
1733 | + match = find_rr_leaf(fn, rt0, rt0->rt6i_metric, oif, strict); | ||
1734 | |||
1735 | if (!match && | ||
1736 | - (strict & RT6_LOOKUP_F_REACHABLE) && | ||
1737 | - last && last != rt0) { | ||
1738 | + (strict & RT6_LOOKUP_F_REACHABLE)) { | ||
1739 | + struct rt6_info *next = rt0->u.next; | ||
1740 | + | ||
1741 | /* no entries matched; do round-robin */ | ||
1742 | - static DEFINE_SPINLOCK(lock); | ||
1743 | - spin_lock(&lock); | ||
1744 | - *head = rt0->u.next; | ||
1745 | - rt0->u.next = last->u.next; | ||
1746 | - last->u.next = rt0; | ||
1747 | - spin_unlock(&lock); | ||
1748 | + if (!next || next->rt6i_metric != rt0->rt6i_metric) | ||
1749 | + next = fn->leaf; | ||
1750 | + | ||
1751 | + if (next != rt0) | ||
1752 | + fn->rr_ptr = next; | ||
1753 | } | ||
1754 | |||
1755 | - RT6_TRACE("%s() => %p, score=%d\n", | ||
1756 | - __FUNCTION__, match, mpri); | ||
1757 | + RT6_TRACE("%s() => %p\n", | ||
1758 | + __FUNCTION__, match); | ||
1759 | |||
1760 | return (match ? match : &ip6_null_entry); | ||
1761 | } | ||
1762 | @@ -648,7 +669,7 @@ restart_2: | ||
1763 | fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); | ||
1764 | |||
1765 | restart: | ||
1766 | - rt = rt6_select(&fn->leaf, fl->iif, strict | reachable); | ||
1767 | + rt = rt6_select(fn, fl->iif, strict | reachable); | ||
1768 | BACKTRACK(&fl->fl6_src); | ||
1769 | if (rt == &ip6_null_entry || | ||
1770 | rt->rt6i_flags & RTF_CACHE) | ||
1771 | @@ -743,7 +764,7 @@ restart_2: | ||
1772 | fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); | ||
1773 | |||
1774 | restart: | ||
1775 | - rt = rt6_select(&fn->leaf, fl->oif, strict | reachable); | ||
1776 | + rt = rt6_select(fn, fl->oif, strict | reachable); | ||
1777 | BACKTRACK(&fl->fl6_src); | ||
1778 | if (rt == &ip6_null_entry || | ||
1779 | rt->rt6i_flags & RTF_CACHE) | ||
1780 | diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c | ||
1781 | index 09fda68..23e4459 100644 | ||
1782 | --- a/net/sched/cls_basic.c | ||
1783 | +++ b/net/sched/cls_basic.c | ||
1784 | @@ -82,6 +82,13 @@ static void basic_put(struct tcf_proto *tp, unsigned long f) | ||
1785 | |||
1786 | static int basic_init(struct tcf_proto *tp) | ||
1787 | { | ||
1788 | + struct basic_head *head; | ||
1789 | + | ||
1790 | + head = kzalloc(sizeof(*head), GFP_KERNEL); | ||
1791 | + if (head == NULL) | ||
1792 | + return -ENOBUFS; | ||
1793 | + INIT_LIST_HEAD(&head->flist); | ||
1794 | + tp->root = head; | ||
1795 | return 0; | ||
1796 | } | ||
1797 | |||
1798 | @@ -177,15 +184,6 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, | ||
1799 | } | ||
1800 | |||
1801 | err = -ENOBUFS; | ||
1802 | - if (head == NULL) { | ||
1803 | - head = kzalloc(sizeof(*head), GFP_KERNEL); | ||
1804 | - if (head == NULL) | ||
1805 | - goto errout; | ||
1806 | - | ||
1807 | - INIT_LIST_HEAD(&head->flist); | ||
1808 | - tp->root = head; | ||
1809 | - } | ||
1810 | - | ||
1811 | f = kzalloc(sizeof(*f), GFP_KERNEL); | ||
1812 | if (f == NULL) | ||
1813 | goto errout; | ||
1814 | diff --git a/net/socket.c b/net/socket.c | ||
1815 | index 4e39631..afb6085 100644 | ||
1816 | --- a/net/socket.c | ||
1817 | +++ b/net/socket.c | ||
1818 | @@ -1368,7 +1368,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, | ||
1819 | |||
1820 | err = sock_attach_fd(newsock, newfile); | ||
1821 | if (err < 0) | ||
1822 | - goto out_fd; | ||
1823 | + goto out_fd_simple; | ||
1824 | |||
1825 | err = security_socket_accept(sock, newsock); | ||
1826 | if (err) | ||
1827 | @@ -1401,6 +1401,11 @@ out_put: | ||
1828 | fput_light(sock->file, fput_needed); | ||
1829 | out: | ||
1830 | return err; | ||
1831 | +out_fd_simple: | ||
1832 | + sock_release(newsock); | ||
1833 | + put_filp(newfile); | ||
1834 | + put_unused_fd(newfd); | ||
1835 | + goto out_put; | ||
1836 | out_fd: | ||
1837 | fput(newfile); | ||
1838 | put_unused_fd(newfd); |