]>
Commit | Line | Data |
---|---|---|
1a59d1b8 | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4 | 2 | /* |
c1017a4c | 3 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
1da177e4 | 4 | * DRAM access routines |
1da177e4 LT |
5 | */ |
6 | ||
1da177e4 LT |
7 | #include <linux/time.h> |
8 | #include <sound/core.h> | |
9 | #include <sound/gus.h> | |
10 | #include <sound/info.h> | |
11 | ||
12 | ||
5e2da206 | 13 | static int snd_gus_dram_poke(struct snd_gus_card *gus, char __user *_buffer, |
1da177e4 LT |
14 | unsigned int address, unsigned int size) |
15 | { | |
16 | unsigned long flags; | |
17 | unsigned int size1, size2; | |
18 | char buffer[256], *pbuffer; | |
19 | ||
20 | while (size > 0) { | |
21 | size1 = size > sizeof(buffer) ? sizeof(buffer) : size; | |
22 | if (copy_from_user(buffer, _buffer, size1)) | |
23 | return -EFAULT; | |
24 | if (gus->interwave) { | |
25 | spin_lock_irqsave(&gus->reg_lock, flags); | |
26 | snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01); | |
27 | snd_gf1_dram_addr(gus, address); | |
28 | outsb(GUSP(gus, DRAM), buffer, size1); | |
29 | spin_unlock_irqrestore(&gus->reg_lock, flags); | |
30 | address += size1; | |
31 | } else { | |
32 | pbuffer = buffer; | |
33 | size2 = size1; | |
34 | while (size2--) | |
35 | snd_gf1_poke(gus, address++, *pbuffer++); | |
36 | } | |
37 | size -= size1; | |
38 | _buffer += size1; | |
39 | } | |
40 | return 0; | |
41 | } | |
42 | ||
43 | ||
5e2da206 | 44 | int snd_gus_dram_write(struct snd_gus_card *gus, char __user *buffer, |
1da177e4 LT |
45 | unsigned int address, unsigned int size) |
46 | { | |
47 | return snd_gus_dram_poke(gus, buffer, address, size); | |
48 | } | |
49 | ||
5e2da206 | 50 | static int snd_gus_dram_peek(struct snd_gus_card *gus, char __user *_buffer, |
1da177e4 LT |
51 | unsigned int address, unsigned int size, |
52 | int rom) | |
53 | { | |
54 | unsigned long flags; | |
55 | unsigned int size1, size2; | |
56 | char buffer[256], *pbuffer; | |
57 | ||
58 | while (size > 0) { | |
59 | size1 = size > sizeof(buffer) ? sizeof(buffer) : size; | |
60 | if (gus->interwave) { | |
61 | spin_lock_irqsave(&gus->reg_lock, flags); | |
62 | snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, rom ? 0x03 : 0x01); | |
63 | snd_gf1_dram_addr(gus, address); | |
64 | insb(GUSP(gus, DRAM), buffer, size1); | |
65 | snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01); | |
66 | spin_unlock_irqrestore(&gus->reg_lock, flags); | |
67 | address += size1; | |
68 | } else { | |
69 | pbuffer = buffer; | |
70 | size2 = size1; | |
71 | while (size2--) | |
72 | *pbuffer++ = snd_gf1_peek(gus, address++); | |
73 | } | |
74 | if (copy_to_user(_buffer, buffer, size1)) | |
75 | return -EFAULT; | |
76 | size -= size1; | |
77 | _buffer += size1; | |
78 | } | |
79 | return 0; | |
80 | } | |
81 | ||
5e2da206 | 82 | int snd_gus_dram_read(struct snd_gus_card *gus, char __user *buffer, |
1da177e4 LT |
83 | unsigned int address, unsigned int size, |
84 | int rom) | |
85 | { | |
86 | return snd_gus_dram_peek(gus, buffer, address, size, rom); | |
87 | } |