| .. | .. |
|---|
| 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 | /** |
|---|