]>
Commit | Line | Data |
---|---|---|
f365dffd | 1 | diff -Nur linux-2.4.21.org/drivers/scsi/megaraid.c linux-2.4.21/drivers/scsi/megaraid.c |
2 | --- linux-2.4.21.org/drivers/scsi/megaraid.c 2003-06-13 14:51:36.000000000 +0000 | |
3 | +++ linux-2.4.21/drivers/scsi/megaraid.c 2003-07-07 17:44:56.000000000 +0000 | |
4 | @@ -9,7 +9,7 @@ | |
5 | * as published by the Free Software Foundation; either version | |
6 | * 2 of the License, or (at your option) any later version. | |
7 | * | |
8 | - * Version : v1.18f (Dec 10, 2002) | |
9 | + * Version : v1.18j (July 7, 2003) | |
10 | * | |
11 | * Description: Linux device driver for LSI Logic MegaRAID controller | |
12 | * | |
13 | @@ -512,6 +512,47 @@ | |
14 | * | |
15 | * remove GFP_DMA flag for ioctl. This was causing overrun of DMA buffers. | |
16 | * | |
17 | + * Version 1.18g | |
18 | + * Fri Jan 31 18:29:25 EST 2003 - Atul Mukker <atul.mukker@lsil.com> | |
19 | + * | |
20 | + * Write the interrupt valid signature 0x10001234 as soon as reading it to | |
21 | + * flush memory caches. | |
22 | + * | |
23 | + * While sending back the inquiry information, check if the original request | |
24 | + * had an associated scatter-gather list and tranfer data from bounce buffer | |
25 | + * accordingly. | |
26 | + * | |
27 | + * Version 1.18h | |
28 | + * Thu Feb 6 17:18:48 EST 2003 - Atul Mukker <atul.mukker@lsil.com> | |
29 | + * | |
30 | + * Reduce the number of sectors per command to 128 from original value of | |
31 | + * 1024. Big IO sizes along with certain other operation going on in parallel, | |
32 | + * e.g., check consistency and rebuild put a heavy constraint on fW resources | |
33 | + * resulting in aborted commands. | |
34 | + * | |
35 | + * Version 1.18i | |
36 | + * Fri Jun 20 07:39:05 EDT 2003 - Atul Mukker <atulm@lsil.com> | |
37 | + * | |
38 | + * Request and reserve memory/IO regions. Otherwise a panic occurs if 2.00.x | |
39 | + * driver is loaded on top of 1.18x driver | |
40 | + * | |
41 | + * Prevent memory leak in cases when data transfer from/to application fails | |
42 | + * and ioctl is failing. | |
43 | + * | |
44 | + * Set the PCI dma_mask to default value of 0xFFFFFFFF when we get a handle to | |
45 | + * it. The previous value of 64-bit might be sticky and would cause the memory | |
46 | + * for mailbox and scatter lists to be allocated beyond 4GB. This was observed | |
47 | + * on an Itenium | |
48 | + * | |
49 | + * Version 1.18j | |
50 | + * Mon Jul 7 14:39:55 EDT 2003 - Atul Mukker <atulm@lsil.com> | |
51 | + * | |
52 | + * Disable /proc/megaraid/stat file to prevent buffer overflow error during | |
53 | + * read of this file. | |
54 | + * | |
55 | + * Add support for ioctls on AMD-64 bit platforms | |
56 | + * - Sreenivas Bagalkote <sreenib@lsil.com> | |
57 | + * | |
58 | * BUGS: | |
59 | * Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that | |
60 | * fails to detect the controller as a pci device on the system. | |
61 | @@ -575,12 +616,27 @@ | |
62 | #include <linux/reboot.h> | |
63 | #include <linux/init.h> | |
64 | ||
65 | +#ifdef __x86_64__ | |
66 | +#include <asm/ioctl32.h> | |
67 | +#endif | |
68 | + | |
69 | #include "sd.h" | |
70 | #include "scsi.h" | |
71 | #include "hosts.h" | |
72 | ||
73 | #include "megaraid.h" | |
74 | ||
75 | +#ifdef __x86_64__ | |
76 | +/* | |
77 | + * The IOCTL cmd received from 32 bit compiled applications | |
78 | + */ | |
79 | + | |
80 | +extern int register_ioctl32_conversion( unsigned int cmd, | |
81 | + int(*handler)(unsigned int, unsigned int, unsigned long, | |
82 | + struct file* )); | |
83 | +extern int unregister_ioctl32_conversion( unsigned int cmd ); | |
84 | +#endif | |
85 | + | |
86 | /* | |
87 | *================================================================ | |
88 | * #Defines | |
89 | @@ -1141,8 +1197,14 @@ | |
90 | switch (SCpnt->cmnd[0]) { | |
91 | case INQUIRY: | |
92 | case READ_CAPACITY: | |
93 | - memcpy (SCpnt->request_buffer, | |
94 | - pScb->bounce_buffer, SCpnt->request_bufflen); | |
95 | + if ( SCpnt->use_sg ) { | |
96 | + sgList = (struct scatterlist *)SCpnt->request_buffer; | |
97 | + memcpy(sgList[0].address, pScb->bounce_buffer, | |
98 | + SCpnt->request_bufflen); | |
99 | + } else { | |
100 | + memcpy (SCpnt->request_buffer, pScb->bounce_buffer, | |
101 | + SCpnt->request_bufflen); | |
102 | + } | |
103 | break; | |
104 | } | |
105 | #endif | |
106 | @@ -2202,30 +2264,22 @@ | |
107 | megaCfg = (mega_host_config *) devp; | |
108 | mbox = (mega_mailbox *) tmpBox; | |
109 | ||
110 | - if (megaCfg->host->irq == irq) { | |
111 | - if (megaCfg->flag & IN_ISR) { | |
112 | - TRACE (("ISR called reentrantly!!\n")); | |
113 | - printk ("ISR called reentrantly!!\n"); | |
114 | - } | |
115 | - megaCfg->flag |= IN_ISR; | |
116 | - | |
117 | - if (mega_busyWaitMbox (megaCfg)) { | |
118 | - printk (KERN_WARNING "Error: mailbox busy in isr!\n"); | |
119 | - } | |
120 | + IO_LOCK; | |
121 | ||
122 | /* Check if a valid interrupt is pending */ | |
123 | if (megaCfg->flag & BOARD_QUARTZ) { | |
124 | dword = RDOUTDOOR (megaCfg); | |
125 | if (dword != 0x10001234) { | |
126 | /* Spurious interrupt */ | |
127 | - megaCfg->flag &= ~IN_ISR; | |
128 | + IO_UNLOCK; | |
129 | return; | |
130 | } | |
131 | + WROUTDOOR (megaCfg, 0x10001234); | |
132 | } else { | |
133 | byte = READ_PORT (megaCfg->host->io_port, INTR_PORT); | |
134 | if ((byte & VALID_INTR_BYTE) == 0) { | |
135 | /* Spurious interrupt */ | |
136 | - megaCfg->flag &= ~IN_ISR; | |
137 | + IO_UNLOCK; | |
138 | return; | |
139 | } | |
140 | WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte); | |
141 | @@ -2234,58 +2288,26 @@ | |
142 | for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++) | |
143 | completed[idx] = 0; | |
144 | ||
145 | - IO_LOCK; | |
146 | ||
147 | megaCfg->nInterrupts++; | |
148 | - qCnt = 0xff; | |
149 | while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) ; | |
150 | + megaCfg->mbox->numstatus = 0xFF; | |
151 | ||
152 | - qStatus = 0xff; | |
153 | - while ((qStatus = megaCfg->mbox->status) == 0xFF) ; | |
154 | + qStatus = megaCfg->mbox->status; | |
155 | ||
156 | /* Get list of completed requests */ | |
157 | for (idx = 0; idx < qCnt; idx++) { | |
158 | - while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) { | |
159 | - printk ("p"); | |
160 | - } | |
161 | - completed[idx] = sIdx; | |
162 | - sIdx = 0xFF; | |
163 | + completed[idx] = megaCfg->mbox->completed[idx]; | |
164 | } | |
165 | ||
166 | if (megaCfg->flag & BOARD_QUARTZ) { | |
167 | - WROUTDOOR (megaCfg, dword); | |
168 | /* Acknowledge interrupt */ | |
169 | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) | |
170 | - /* In this case mbox contains physical address */ | |
171 | -#if 0 | |
172 | - WRINDOOR (megaCfg, megaCfg->adjdmahandle64 | 0x2); | |
173 | -#else | |
174 | WRINDOOR (megaCfg, 0x2); | |
175 | -#endif | |
176 | - | |
177 | -#else | |
178 | - | |
179 | -#if 0 | |
180 | - WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2); | |
181 | -#else | |
182 | - WRINDOOR (megaCfg, 0x2); | |
183 | -#endif | |
184 | - | |
185 | -#endif | |
186 | - | |
187 | -#if 0 | |
188 | while (RDINDOOR (megaCfg) & 0x02) ; | |
189 | -#endif | |
190 | } else { | |
191 | CLEAR_INTR (megaCfg->host->io_port); | |
192 | } | |
193 | ||
194 | -#if DEBUG | |
195 | - if (qCnt >= MAX_FIRMWARE_STATUS) { | |
196 | - printk ("megaraid_isr: cmplt=%d ", qCnt); | |
197 | - } | |
198 | -#endif | |
199 | - | |
200 | for (idx = 0; idx < qCnt; idx++) { | |
201 | sIdx = completed[idx]; | |
202 | if ((sIdx > 0) && (sIdx <= MAX_COMMANDS)) { | |
203 | @@ -2355,26 +2377,24 @@ | |
204 | mega_runpendq (megaCfg); | |
205 | IO_UNLOCK; | |
206 | ||
207 | - } | |
208 | - | |
209 | } | |
210 | ||
211 | /*==================================================*/ | |
212 | /* Wait until the controller's mailbox is available */ | |
213 | /*==================================================*/ | |
214 | ||
215 | -static int mega_busyWaitMbox (mega_host_config * megaCfg) | |
216 | +static inline int mega_busyWaitMbox (mega_host_config * megaCfg) | |
217 | { | |
218 | mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox; | |
219 | long counter; | |
220 | ||
221 | - for (counter = 0; counter < 10000; counter++) { | |
222 | + for (counter = 0; counter < 10; counter++) { | |
223 | if (!mbox->busy) { | |
224 | return 0; | |
225 | } | |
226 | - udelay (100); | |
227 | + udelay (1); | |
228 | } | |
229 | - return -1; /* give up after 1 second */ | |
230 | + return -1; /* give up after 10 usecs */ | |
231 | } | |
232 | ||
233 | /*===================================================== | |
234 | @@ -2420,25 +2440,8 @@ | |
235 | phys_mbox = virt_to_bus (megaCfg->mbox); | |
236 | #endif | |
237 | ||
238 | -#if DEBUG | |
239 | - ShowMbox (pScb); | |
240 | -#endif | |
241 | - | |
242 | /* Wait until mailbox is free */ | |
243 | if (mega_busyWaitMbox (megaCfg)) { | |
244 | - printk ("Blocked mailbox......!!\n"); | |
245 | - udelay (1000); | |
246 | - | |
247 | -#if DEBUG | |
248 | - showMbox (pLastScb); | |
249 | -#endif | |
250 | - | |
251 | - /* Abort command */ | |
252 | - if (pScb == NULL) { | |
253 | - TRACE (("NULL pScb in megaIssue\n")); | |
254 | - printk ("NULL pScb in megaIssue\n"); | |
255 | - } | |
256 | - mega_cmd_done (megaCfg, pScb, 0x08); | |
257 | return -1; | |
258 | } | |
259 | ||
260 | @@ -2486,13 +2489,10 @@ | |
261 | WRINDOOR (megaCfg, phys_mbox | 0x1); | |
262 | ||
263 | while (mbox->numstatus == 0xFF) ; | |
264 | - while (mbox->status == 0xFF) ; | |
265 | while (mbox->mraid_poll != 0x77) ; | |
266 | mbox->mraid_poll = 0; | |
267 | mbox->mraid_ack = 0x77; | |
268 | - | |
269 | - /* while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234); | |
270 | - WROUTDOOR (megaCfg, cmdDone); */ | |
271 | + mbox->numstatus = 0xFF; | |
272 | ||
273 | if (pScb) { | |
274 | mega_cmd_done (megaCfg, pScb, mbox->status); | |
275 | @@ -2523,12 +2523,6 @@ | |
276 | enable_irq (megaCfg->host->irq); | |
277 | retval = mbox->status; | |
278 | } | |
279 | -#if DEBUG | |
280 | - while (mega_busyWaitMbox (megaCfg)) { | |
281 | - printk(KERN_ERR "Blocked mailbox on exit......!\n"); | |
282 | - udelay (1000); | |
283 | - } | |
284 | -#endif | |
285 | ||
286 | return retval; | |
287 | } | |
288 | @@ -2964,15 +2958,15 @@ | |
289 | ||
290 | int i, j; | |
291 | ||
292 | -#if BITS_PER_LONG==64 | |
293 | - u64 megaBase; | |
294 | -#else | |
295 | - u32 megaBase; | |
296 | -#endif | |
297 | + unsigned long megaBase; | |
298 | + unsigned long tbase; | |
299 | ||
300 | u16 pciIdx = 0; | |
301 | u16 numFound = 0; | |
302 | u16 subsysid, subsysvid; | |
303 | + u8 did_mem_map_f = 0; | |
304 | + u8 did_io_map_f = 0; | |
305 | + u8 did_scsi_register_f = 0; | |
306 | ||
307 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) /* 0x20100 */ | |
308 | while (!pcibios_find_device | |
309 | @@ -2991,6 +2985,17 @@ | |
310 | pciBus = pdev->bus->number; | |
311 | pciDevFun = pdev->devfn; | |
312 | #endif | |
313 | + | |
314 | + /* | |
315 | + * Set the dma_mask to default value. It might be sticky from previous | |
316 | + * insmod-rmmod sequence | |
317 | + */ | |
318 | + pdev->dma_mask = 0xFFFFFFFF; | |
319 | + | |
320 | + did_mem_map_f = 0; | |
321 | + did_io_map_f = 0; | |
322 | + did_scsi_register_f = 0; | |
323 | + | |
324 | if ((flag & BOARD_QUARTZ) && (skip_id == -1)) { | |
325 | if( (pciVendor == PCI_VENDOR_ID_PERC4_DI_YSTONE && | |
326 | pciDev == PCI_DEVICE_ID_PERC4_DI_YSTONE) || | |
327 | @@ -3041,6 +3046,7 @@ | |
328 | if( (subsysvid != AMI_SUBSYS_ID) && | |
329 | (subsysvid != DELL_SUBSYS_ID) && | |
330 | (subsysvid != LSI_SUBSYS_ID) && | |
331 | + (subsysvid != INTEL_SUBSYS_ID) && | |
332 | (subsysvid != HP_SUBSYS_ID) ) continue; | |
333 | ||
334 | } | |
335 | @@ -3065,22 +3071,55 @@ | |
336 | megaIrq = pdev->irq; | |
337 | #endif | |
338 | ||
339 | + tbase = megaBase; | |
340 | + | |
341 | pciIdx++; | |
342 | ||
343 | if (flag & BOARD_QUARTZ) { | |
344 | + | |
345 | megaBase &= PCI_BASE_ADDRESS_MEM_MASK; | |
346 | + | |
347 | + if( ! request_mem_region(megaBase, 128, | |
348 | + "MegaRAID: LSI Logic Corporation" ) ) { | |
349 | + | |
350 | + printk(KERN_WARNING "megaraid: mem region busy!\n"); | |
351 | + | |
352 | + continue; | |
353 | + } | |
354 | + | |
355 | megaBase = (long) ioremap (megaBase, 128); | |
356 | - if (!megaBase) | |
357 | + | |
358 | + if (!megaBase) { | |
359 | + | |
360 | + printk(KERN_WARNING "megaraid: could not map hba memory!\n"); | |
361 | + | |
362 | + release_mem_region(tbase, 128); | |
363 | + | |
364 | continue; | |
365 | + } | |
366 | + did_mem_map_f = 1; | |
367 | + | |
368 | } else { | |
369 | megaBase &= PCI_BASE_ADDRESS_IO_MASK; | |
370 | megaBase += 0x10; | |
371 | + | |
372 | + if( ! request_region(megaBase, 16, | |
373 | + "MegaRAID: LSI Logic Corporation") ) { | |
374 | + | |
375 | + printk(KERN_WARNING "megaraid: region busy.\n"); | |
376 | + | |
377 | + continue; | |
378 | + } | |
379 | + did_io_map_f = 1; | |
380 | + | |
381 | } | |
382 | ||
383 | /* Initialize SCSI Host structure */ | |
384 | host = scsi_register (pHostTmpl, sizeof (mega_host_config)); | |
385 | if (!host) | |
386 | - goto err_unmap; | |
387 | + goto fail_attach; | |
388 | + | |
389 | + did_scsi_register_f = 1; | |
390 | ||
391 | /* | |
392 | * Comment the following initialization if you know 'max_sectors' is | |
393 | @@ -3088,7 +3127,7 @@ | |
394 | * This field was introduced in Linus's kernel 2.4.7pre3 and it | |
395 | * greatly increases the IO performance - AM | |
396 | */ | |
397 | - host->max_sectors = 1024; | |
398 | + host->max_sectors = 128; | |
399 | ||
400 | scsi_set_pci_device(host, pdev); | |
401 | megaCfg = (mega_host_config *) host->hostdata; | |
402 | @@ -3130,11 +3169,8 @@ | |
403 | megaCfg->host->unique_id = (pciBus << 8) | pciDevFun; | |
404 | megaCtlrs[numCtlrs] = megaCfg; | |
405 | ||
406 | - if (!(flag & BOARD_QUARTZ)) { | |
407 | - | |
408 | - /* Request our IO Range */ | |
409 | - if( !request_region(megaBase, 16, "megaraid") ) | |
410 | - goto err_unregister; | |
411 | + if (flag & BOARD_QUARTZ) { | |
412 | + megaCfg->host->base = tbase; | |
413 | } | |
414 | ||
415 | /* Request our IRQ */ | |
416 | @@ -3143,7 +3179,7 @@ | |
417 | printk (KERN_WARNING | |
418 | "megaraid: Couldn't register IRQ %d!\n", | |
419 | megaIrq); | |
420 | - goto err_release; | |
421 | + goto fail_attach; | |
422 | } | |
423 | ||
424 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) | |
425 | @@ -3265,8 +3301,7 @@ | |
426 | sizeof (mega_mailbox64), | |
427 | (void *) megaCfg->mailbox64ptr, | |
428 | megaCfg->dma_handle64); | |
429 | - scsi_unregister (host); | |
430 | - continue; | |
431 | + goto fail_attach; | |
432 | } | |
433 | ||
434 | /* | |
435 | @@ -3301,14 +3336,17 @@ | |
436 | #endif | |
437 | #endif | |
438 | continue; | |
439 | - err_release: | |
440 | - if (flag & BOARD_QUARTZ) | |
441 | - release_region (megaBase, 16); | |
442 | - err_unregister: | |
443 | - scsi_unregister (host); | |
444 | - err_unmap: | |
445 | - if (flag & BOARD_QUARTZ) | |
446 | - iounmap ((void *) megaBase); | |
447 | +fail_attach: | |
448 | + if( did_mem_map_f ) { | |
449 | + iounmap((void *)megaBase); | |
450 | + release_mem_region(tbase, 128); | |
451 | + } | |
452 | + if( did_io_map_f ) { | |
453 | + release_region(megaBase, 16); | |
454 | + } | |
455 | + if( did_scsi_register_f ) { | |
456 | + scsi_unregister (host); | |
457 | + } | |
458 | } | |
459 | return numFound; | |
460 | } | |
461 | @@ -3408,6 +3446,12 @@ | |
462 | } | |
463 | ||
464 | init_MUTEX (&mimd_entry_mtx); | |
465 | +#ifdef __x86_64__ | |
466 | + /* | |
467 | + * Register the 32-bit ioctl conversion | |
468 | + */ | |
469 | + register_ioctl32_conversion( MEGAIOCCMD, sys_ioctl ); | |
470 | +#endif | |
471 | } | |
472 | ||
473 | return count; | |
474 | @@ -3439,6 +3483,7 @@ | |
475 | /* Free our resources */ | |
476 | if (megaCfg->flag & BOARD_QUARTZ) { | |
477 | iounmap ((void *) megaCfg->base); | |
478 | + release_mem_region(megaCfg->host->base, 128); | |
479 | } else { | |
480 | release_region (megaCfg->host->io_port, 16); | |
481 | } | |
482 | @@ -3485,6 +3530,9 @@ | |
483 | ||
484 | unregister_chrdev (major, "megadev"); | |
485 | unregister_reboot_notifier (&mega_notifier); | |
486 | +#ifdef __x86_64__ | |
487 | + unregister_ioctl32_conversion( MEGAIOCCMD ); | |
488 | +#endif | |
489 | ||
490 | return 0; | |
491 | } | |
492 | @@ -4244,6 +4292,11 @@ | |
493 | proc_printf (megaCfg, "Interrupts Collected = %lu\n", | |
494 | megaCfg->nInterrupts); | |
495 | ||
496 | + proc_printf (megaCfg, "INTERFACE DISABLED\n"); | |
497 | + COPY_BACK; | |
498 | + return count; | |
499 | + | |
500 | +#if 0 // can cause buffer overrun with 40 logical drives and IO information | |
501 | for (i = 0; i < megaCfg->numldrv; i++) { | |
502 | proc_printf (megaCfg, "Logical Drive %d:\n", i); | |
503 | ||
504 | @@ -4259,6 +4312,7 @@ | |
505 | ||
506 | COPY_BACK; | |
507 | return count; | |
508 | +#endif | |
509 | } | |
510 | ||
511 | static int proc_read_status (char *page, char **start, off_t offset, | |
512 | @@ -4896,16 +4950,16 @@ | |
513 | if( kvaddr == NULL ) { | |
514 | printk(KERN_WARNING "megaraid:allocation failed\n"); | |
515 | ret = -ENOMEM; | |
516 | - goto out; | |
517 | + goto out_ioctl_cmd_new; | |
518 | } | |
519 | ||
520 | ioc.ui.fcs.buffer = kvaddr; | |
521 | ||
522 | if (inlen) { | |
523 | /* copyin the user data */ | |
524 | - if (copy_from_user(kvaddr, (char *)uaddr, length )) { | |
525 | - ret = -EFAULT; | |
526 | - goto out; | |
527 | + if( copy_from_user(kvaddr, (char *)uaddr, length ) ) { | |
528 | + ret = -EFAULT; | |
529 | + goto out_ioctl_cmd_new; | |
530 | } | |
531 | } | |
532 | } | |
a3854b07 | 533 | @@ -4923,7 +4977,7 @@ |
f365dffd | 534 | if( !scsicmd->result && outlen ) { |
a3854b07 JR |
535 | if (copy_to_user(uaddr, kvaddr, length)) { |
536 | ret = -EFAULT; | |
f365dffd | 537 | - goto out; |
f365dffd | 538 | + goto out_ioctl_cmd_new; |
a3854b07 | 539 | } |
f365dffd | 540 | } |
541 | ||
f365dffd | 542 | @@ -4944,7 +4999,8 @@ |
543 | put_user (scsicmd->result, &uioc->mbox[17]); | |
544 | } | |
545 | ||
546 | -out: | |
547 | +out_ioctl_cmd_new: | |
548 | + | |
549 | if (kvaddr) { | |
550 | dma_free_consistent(pdevp, length, kvaddr, dma_addr); | |
551 | } | |
552 | @@ -5045,12 +5101,8 @@ | |
553 | ||
554 | if( kvaddr == NULL ) { | |
555 | printk (KERN_WARNING "megaraid:allocation failed\n"); | |
556 | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /*0x20400 */ | |
557 | - kfree(scsicmd); | |
558 | -#else | |
559 | - scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd)); | |
560 | -#endif | |
561 | - return -ENOMEM; | |
562 | + ret = -ENOMEM; | |
563 | + goto out_ioctl_cmd; | |
564 | } | |
565 | ||
566 | ioc.data = kvaddr; | |
567 | @@ -5058,9 +5110,15 @@ | |
568 | if (inlen) { | |
569 | if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) { | |
570 | /* copyin the user data */ | |
571 | - copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen); | |
572 | + if( copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen)){ | |
573 | + ret = -EFAULT; | |
574 | + goto out_ioctl_cmd; | |
575 | + } | |
576 | } else { | |
577 | - copy_from_user (kvaddr, uaddr, inlen); | |
578 | + if( copy_from_user (kvaddr, uaddr, inlen) ) { | |
579 | + ret = -EFAULT; | |
580 | + goto out_ioctl_cmd; | |
581 | + } | |
582 | } | |
583 | } | |
584 | } | |
585 | @@ -5078,11 +5136,15 @@ | |
586 | ||
587 | if (!scsicmd->result && outlen) { | |
588 | if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) { | |
589 | - if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen)) | |
590 | + if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen)) { | |
591 | ret = -EFAULT; | |
592 | + goto out_ioctl_cmd; | |
593 | + } | |
594 | } else { | |
595 | - if (copy_to_user (uaddr, kvaddr, outlen)) | |
596 | + if (copy_to_user (uaddr, kvaddr, outlen)) { | |
597 | ret = -EFAULT; | |
598 | + goto out_ioctl_cmd; | |
599 | + } | |
600 | } | |
601 | } | |
602 | ||
603 | @@ -5107,6 +5169,8 @@ | |
604 | put_user (scsicmd->result, &uioc->mbox[17]); /* status */ | |
605 | } | |
606 | ||
607 | +out_ioctl_cmd: | |
608 | + | |
609 | if (kvaddr) { | |
610 | dma_free_consistent(pdevp, PAGE_SIZE, kvaddr, dma_addr ); | |
611 | } | |
612 | diff -Nur linux-2.4.21.org/drivers/scsi/megaraid.h linux-2.4.21/drivers/scsi/megaraid.h | |
613 | --- linux-2.4.21.org/drivers/scsi/megaraid.h 2003-06-13 14:51:36.000000000 +0000 | |
614 | +++ linux-2.4.21/drivers/scsi/megaraid.h 2003-07-07 17:43:59.000000000 +0000 | |
615 | @@ -30,7 +30,8 @@ | |
616 | #define M_RD_IOCTL_CMD_NEW 0x81 | |
617 | #define M_RD_DRIVER_IOCTL_INTERFACE 0x82 | |
618 | ||
619 | -#define MEGARAID_VERSION "v1.18f (Release Date: Tue Dec 10 09:54:39 EST 2002)\n" | |
620 | +#define MEGARAID_VERSION "v1.18j (Release Date: Mon Jul 7 14:39:55 EDT 2003)\n" | |
621 | + | |
622 | ||
623 | #define MEGARAID_IOCTL_VERSION 114 | |
624 | ||
625 | @@ -190,6 +191,7 @@ | |
626 | #define AMI_SUBSYS_ID 0x101E | |
627 | #define DELL_SUBSYS_ID 0x1028 | |
628 | #define HP_SUBSYS_ID 0x103C | |
629 | +#define INTEL_SUBSYS_ID 0x8086 | |
630 | ||
631 | #define AMI_SIGNATURE 0x3344 | |
632 | #define AMI_SIGNATURE_471 0xCCCC | |
633 | @@ -899,7 +901,9 @@ | |
634 | * Defines for Driver IOCTL interface, Op-code:M_RD_DRIVER_IOCTL_INTERFACE | |
635 | */ | |
636 | #define MEGAIOC_MAGIC 'm' | |
637 | -#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0) /* Mega IOCTL command */ | |
638 | + | |
639 | +/* Mega IOCTL command */ | |
640 | +#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t) | |
641 | ||
642 | #define MEGAIOC_QNADAP 'm' /* Query # of adapters */ | |
643 | #define MEGAIOC_QDRVRVER 'e' /* Query driver version */ |