vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / drivers / audio / ac97 / ich / io.c
blobe373743765446feaaffcdcad9cb61c2634048c2d
1 /*
2 * BeOS Driver for Intel ICH AC'97 Link interface
4 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
6 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without modification,
8 * are permitted provided that the following conditions are met:
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <KernelExport.h>
29 #include <OS.h>
30 #include <PCI.h>
31 #include "debug.h"
32 #include "io.h"
33 #include "ich.h"
34 #include "config.h"
36 extern pci_module_info *pci;
38 status_t ich_codec_wait(void);
40 uint8
41 ich_reg_read_8(int regno)
43 ASSERT(regno >= 0);
44 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
45 if (config->type & TYPE_ICH4)
46 return *(uint8 *)(((char *)config->log_mbbar) + regno);
47 else
48 return pci->read_io_8(config->nabmbar + regno);
51 uint16
52 ich_reg_read_16(int regno)
54 ASSERT(regno >= 0);
55 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
56 if (config->type & TYPE_ICH4)
57 return *(uint16 *)(((char *)config->log_mbbar) + regno);
58 else
59 return pci->read_io_16(config->nabmbar + regno);
62 uint32
63 ich_reg_read_32(int regno)
65 ASSERT(regno >= 0);
66 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
67 if (config->type & TYPE_ICH4)
68 return *(uint32 *)(((char *)config->log_mbbar) + regno);
69 else
70 return pci->read_io_32(config->nabmbar + regno);
73 void
74 ich_reg_write_8(int regno, uint8 value)
76 ASSERT(regno >= 0);
77 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
78 if (config->type & TYPE_ICH4)
79 *(uint8 *)(((char *)config->log_mbbar) + regno) = value;
80 else
81 pci->write_io_8(config->nabmbar + regno, value);
84 void
85 ich_reg_write_16(int regno, uint16 value)
87 ASSERT(regno >= 0);
88 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
89 if (config->type & TYPE_ICH4)
90 *(uint16 *)(((char *)config->log_mbbar) + regno) = value;
91 else
92 pci->write_io_16(config->nabmbar + regno, value);
95 void
96 ich_reg_write_32(int regno, uint32 value)
98 ASSERT(regno >= 0);
99 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 255) || regno <= 63);
100 if (config->type & TYPE_ICH4)
101 *(uint32 *)(((char *)config->log_mbbar) + regno) = value;
102 else
103 pci->write_io_32(config->nabmbar + regno, value);
106 status_t
107 ich_codec_wait(void)
109 int i;
110 for (i = 0; i < 1100; i++) {
111 if ((ich_reg_read_8(ICH_REG_ACC_SEMA) & 0x01) == 0)
112 return B_OK;
113 if (i > 100)
114 snooze(1);
116 return B_TIMED_OUT;
119 uint16
120 ich_codec_read(int regno)
122 status_t rv;
123 ASSERT(regno >= 0);
124 ASSERT((regno & 1) == 0);
125 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
126 if (regno == 0x54) // intel uses 0x54 for GPIO access, we filter it!
127 return 0;
128 rv = ich_codec_wait();
129 if (rv != B_OK)
130 PRINT(("semaphore timeout reading register %#x\n",regno));
131 if (config->type & TYPE_ICH4)
132 return *(uint16 *)(((char *)config->log_mmbar) + regno);
133 else
134 return pci->read_io_16(config->nambar + regno);
137 void
138 ich_codec_write(int regno, uint16 value)
140 status_t rv;
141 ASSERT(regno >= 0);
142 ASSERT((regno & 1) == 0);
143 ASSERT(((config->type & TYPE_ICH4) != 0 && regno <= 511) || regno <= 255);
144 if (regno == 0x54) // intel uses 0x54 for GPIO access, we filter it!
145 return;
146 rv = ich_codec_wait();
147 if (rv != B_OK)
148 PRINT(("semaphore timeout writing register %#x\n",regno));
149 if (config->type & TYPE_ICH4)
150 *(uint16 *)(((char *)config->log_mmbar) + regno) = value;
151 else
152 pci->write_io_16(config->nambar + regno, value);