.. | .. |
---|
355 | 355 | char __user *user_data, int length) |
---|
356 | 356 | { |
---|
357 | 357 | void __iomem *vaddr; |
---|
358 | | - bool fail = false; |
---|
| 358 | + unsigned long unwritten; |
---|
359 | 359 | |
---|
360 | 360 | /* We can use the cpu mem copy function because this is X86. */ |
---|
361 | | - vaddr = io_mapping_map_local_wc(mapping, base); |
---|
362 | | - if (copy_to_user(user_data, (void __force *)vaddr + offset, length)) |
---|
363 | | - fail = true; |
---|
364 | | - io_mapping_unmap_local(vaddr); |
---|
365 | | - |
---|
366 | | - return fail; |
---|
| 361 | + vaddr = io_mapping_map_atomic_wc(mapping, base); |
---|
| 362 | + unwritten = __copy_to_user_inatomic(user_data, |
---|
| 363 | + (void __force *)vaddr + offset, |
---|
| 364 | + length); |
---|
| 365 | + io_mapping_unmap_atomic(vaddr); |
---|
| 366 | + if (unwritten) { |
---|
| 367 | + vaddr = io_mapping_map_wc(mapping, base, PAGE_SIZE); |
---|
| 368 | + unwritten = copy_to_user(user_data, |
---|
| 369 | + (void __force *)vaddr + offset, |
---|
| 370 | + length); |
---|
| 371 | + io_mapping_unmap(vaddr); |
---|
| 372 | + } |
---|
| 373 | + return unwritten; |
---|
367 | 374 | } |
---|
368 | 375 | |
---|
369 | 376 | static int |
---|
.. | .. |
---|
532 | 539 | char __user *user_data, int length) |
---|
533 | 540 | { |
---|
534 | 541 | void __iomem *vaddr; |
---|
535 | | - bool fail = false; |
---|
| 542 | + unsigned long unwritten; |
---|
536 | 543 | |
---|
537 | 544 | /* We can use the cpu mem copy function because this is X86. */ |
---|
538 | | - vaddr = io_mapping_map_local_wc(mapping, base); |
---|
539 | | - if (copy_from_user((void __force *)vaddr + offset, user_data, length)) |
---|
540 | | - fail = true; |
---|
541 | | - io_mapping_unmap_local(vaddr); |
---|
542 | | - return fail; |
---|
| 545 | + vaddr = io_mapping_map_atomic_wc(mapping, base); |
---|
| 546 | + unwritten = __copy_from_user_inatomic_nocache((void __force *)vaddr + offset, |
---|
| 547 | + user_data, length); |
---|
| 548 | + io_mapping_unmap_atomic(vaddr); |
---|
| 549 | + if (unwritten) { |
---|
| 550 | + vaddr = io_mapping_map_wc(mapping, base, PAGE_SIZE); |
---|
| 551 | + unwritten = copy_from_user((void __force *)vaddr + offset, |
---|
| 552 | + user_data, length); |
---|
| 553 | + io_mapping_unmap(vaddr); |
---|
| 554 | + } |
---|
| 555 | + |
---|
| 556 | + return unwritten; |
---|
543 | 557 | } |
---|
544 | 558 | |
---|
545 | 559 | /** |
---|