| @@ -26,26 +26,27 @@ | | | @@ -26,26 +26,27 @@ |
26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | | 26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | | 27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | | 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | | 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | | 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | #include <sys/systm.h> | | 35 | #include <sys/systm.h> |
36 | #include <sys/device.h> | | 36 | #include <sys/device.h> |
37 | #include <sys/file.h> | | 37 | #include <sys/file.h> |
38 | #include <sys/filedesc.h> | | 38 | #include <sys/filedesc.h> |
| | | 39 | #include <sys/kmem.h> |
39 | | | 40 | |
40 | #include "vchiq_core.h" | | 41 | #include "vchiq_core.h" |
41 | #include "vchiq_ioctl.h" | | 42 | #include "vchiq_ioctl.h" |
42 | #include "vchiq_arm.h" | | 43 | #include "vchiq_arm.h" |
43 | | | 44 | |
44 | #define DEVICE_NAME "vchiq" | | 45 | #define DEVICE_NAME "vchiq" |
45 | | | 46 | |
46 | /* Override the default prefix, which would be vchiq_arm (from the filename) */ | | 47 | /* Override the default prefix, which would be vchiq_arm (from the filename) */ |
47 | #undef MODULE_PARAM_PREFIX | | 48 | #undef MODULE_PARAM_PREFIX |
48 | #define MODULE_PARAM_PREFIX DEVICE_NAME "." | | 49 | #define MODULE_PARAM_PREFIX DEVICE_NAME "." |
49 | | | 50 | |
50 | #define VCHIQ_MINOR 0 | | 51 | #define VCHIQ_MINOR 0 |
51 | | | 52 | |
| @@ -186,29 +187,30 @@ struct cdevsw vchiq_cdevsw = { | | | @@ -186,29 +187,30 @@ struct cdevsw vchiq_cdevsw = { |
186 | .d_stop = nostop, | | 187 | .d_stop = nostop, |
187 | .d_tty = notty, | | 188 | .d_tty = notty, |
188 | .d_poll = nopoll, | | 189 | .d_poll = nopoll, |
189 | .d_mmap = nommap, | | 190 | .d_mmap = nommap, |
190 | .d_kqfilter = nokqfilter, | | 191 | .d_kqfilter = nokqfilter, |
191 | .d_discard = nodiscard, | | 192 | .d_discard = nodiscard, |
192 | .d_flag = D_OTHER | D_MPSAFE | | 193 | .d_flag = D_OTHER | D_MPSAFE |
193 | }; | | 194 | }; |
194 | | | 195 | |
195 | extern struct cfdriver vchiq_cd; | | 196 | extern struct cfdriver vchiq_cd; |
196 | | | 197 | |
197 | static int vchiq_ioctl(struct file *, u_long, void *); | | 198 | static int vchiq_ioctl(struct file *, u_long, void *); |
198 | static int vchiq_close(struct file *); | | 199 | static int vchiq_close(struct file *); |
| | | 200 | static int vchiq_read(struct file *, off_t *, struct uio *, kauth_cred_t, int); |
199 | | | 201 | |
200 | static const struct fileops vchiq_fileops = { | | 202 | static const struct fileops vchiq_fileops = { |
201 | .fo_read = fbadop_read, | | 203 | .fo_read = vchiq_read, |
202 | .fo_write = fbadop_write, | | 204 | .fo_write = fbadop_write, |
203 | .fo_ioctl = vchiq_ioctl, | | 205 | .fo_ioctl = vchiq_ioctl, |
204 | .fo_fcntl = fnullop_fcntl, | | 206 | .fo_fcntl = fnullop_fcntl, |
205 | .fo_poll = fnullop_poll, | | 207 | .fo_poll = fnullop_poll, |
206 | .fo_stat = fbadop_stat, | | 208 | .fo_stat = fbadop_stat, |
207 | .fo_close = vchiq_close, | | 209 | .fo_close = vchiq_close, |
208 | .fo_kqfilter = fnullop_kqfilter, | | 210 | .fo_kqfilter = fnullop_kqfilter, |
209 | }; | | 211 | }; |
210 | | | 212 | |
211 | #if 0 | | 213 | #if 0 |
212 | static void | | 214 | static void |
213 | dump_phys_mem(void *virt_addr, uint32_t num_bytes); | | 215 | dump_phys_mem(void *virt_addr, uint32_t num_bytes); |
214 | #endif | | 216 | #endif |
| @@ -1235,40 +1237,36 @@ vchiq_dump(void *dump_context, const cha | | | @@ -1235,40 +1237,36 @@ vchiq_dump(void *dump_context, const cha |
1235 | if (context->actual < context->space) { | | 1237 | if (context->actual < context->space) { |
1236 | int copy_bytes; | | 1238 | int copy_bytes; |
1237 | if (context->offset > 0) { | | 1239 | if (context->offset > 0) { |
1238 | int skip_bytes = min(len, (int)context->offset); | | 1240 | int skip_bytes = min(len, (int)context->offset); |
1239 | str += skip_bytes; | | 1241 | str += skip_bytes; |
1240 | len -= skip_bytes; | | 1242 | len -= skip_bytes; |
1241 | context->offset -= skip_bytes; | | 1243 | context->offset -= skip_bytes; |
1242 | if (context->offset > 0) | | 1244 | if (context->offset > 0) |
1243 | return; | | 1245 | return; |
1244 | } | | 1246 | } |
1245 | copy_bytes = min(len, (int)(context->space - context->actual)); | | 1247 | copy_bytes = min(len, (int)(context->space - context->actual)); |
1246 | if (copy_bytes == 0) | | 1248 | if (copy_bytes == 0) |
1247 | return; | | 1249 | return; |
1248 | if (copy_to_user(context->buf + context->actual, str, | | 1250 | memcpy(context->buf + context->actual, str, copy_bytes); |
1249 | copy_bytes)) | | | |
1250 | context->actual = -EFAULT; | | | |
1251 | context->actual += copy_bytes; | | 1251 | context->actual += copy_bytes; |
1252 | len -= copy_bytes; | | 1252 | len -= copy_bytes; |
1253 | | | 1253 | |
1254 | /* If tne terminating NUL is included in the length, then it | | 1254 | /* If tne terminating NUL is included in the length, then it |
1255 | ** marks the end of a line and should be replaced with a | | 1255 | ** marks the end of a line and should be replaced with a |
1256 | ** carriage return. */ | | 1256 | ** carriage return. */ |
1257 | if ((len == 0) && (str[copy_bytes - 1] == '\0')) { | | 1257 | if ((len == 0) && (str[copy_bytes - 1] == '\0')) { |
1258 | char cr = '\n'; | | 1258 | char cr = '\n'; |
1259 | if (copy_to_user(context->buf + context->actual - 1, | | 1259 | memcpy(context->buf + context->actual - 1, &cr, 1); |
1260 | &cr, 1)) | | | |
1261 | context->actual = -EFAULT; | | | |
1262 | } | | 1260 | } |
1263 | } | | 1261 | } |
1264 | } | | 1262 | } |
1265 | | | 1263 | |
1266 | /**************************************************************************** | | 1264 | /**************************************************************************** |
1267 | * | | 1265 | * |
1268 | * vchiq_dump_platform_instance_state | | 1266 | * vchiq_dump_platform_instance_state |
1269 | * | | 1267 | * |
1270 | ***************************************************************************/ | | 1268 | ***************************************************************************/ |
1271 | | | 1269 | |
1272 | void | | 1270 | void |
1273 | vchiq_dump_platform_instances(void *dump_context) | | 1271 | vchiq_dump_platform_instances(void *dump_context) |
1274 | { | | 1272 | { |
| @@ -1422,50 +1420,57 @@ dump_phys_mem(void *virt_addr, uint32_t | | | @@ -1422,50 +1420,57 @@ dump_phys_mem(void *virt_addr, uint32_t |
1422 | page_offset], | | 1420 | page_offset], |
1423 | &kmapped_virt_ptr[page_offset], 16); | | 1421 | &kmapped_virt_ptr[page_offset], 16); |
1424 | | | 1422 | |
1425 | offset += 16; | | 1423 | offset += 16; |
1426 | } | | 1424 | } |
1427 | if (page != NULL) | | 1425 | if (page != NULL) |
1428 | kunmap(page); | | 1426 | kunmap(page); |
1429 | | | 1427 | |
1430 | for (page_idx = 0; page_idx < num_pages; page_idx++) | | 1428 | for (page_idx = 0; page_idx < num_pages; page_idx++) |
1431 | page_cache_release(pages[page_idx]); | | 1429 | page_cache_release(pages[page_idx]); |
1432 | | | 1430 | |
1433 | kfree(pages); | | 1431 | kfree(pages); |
1434 | } | | 1432 | } |
| | | 1433 | #endif |
1435 | | | 1434 | |
1436 | /**************************************************************************** | | 1435 | /**************************************************************************** |
1437 | * | | 1436 | * |
1438 | * vchiq_read | | 1437 | * vchiq_read |
1439 | * | | 1438 | * |
1440 | ***************************************************************************/ | | 1439 | ***************************************************************************/ |
1441 | | | 1440 | |
1442 | static ssize_t | | 1441 | static int |
1443 | vchiq_read(struct file *file, char __user *buf, | | 1442 | vchiq_read(struct file *file, off_t *ppos, struct uio *uio, kauth_cred_t cred, |
1444 | size_t count, loff_t *ppos) | | 1443 | int flags) |
1445 | { | | 1444 | { |
| | | 1445 | int result; |
| | | 1446 | |
| | | 1447 | char *buf = kmem_zalloc(PAGE_SIZE, KM_SLEEP); |
| | | 1448 | |
1446 | DUMP_CONTEXT_T context; | | 1449 | DUMP_CONTEXT_T context; |
1447 | context.buf = buf; | | 1450 | context.buf = buf; |
1448 | context.actual = 0; | | 1451 | context.actual = 0; |
1449 | context.space = count; | | 1452 | context.space = PAGE_SIZE; |
1450 | context.offset = *ppos; | | 1453 | context.offset = *ppos; |
1451 | | | 1454 | |
1452 | vchiq_dump_state(&context, &g_state); | | 1455 | vchiq_dump_state(&context, &g_state); |
1453 | | | 1456 | |
1454 | *ppos += context.actual; | | 1457 | *ppos += context.actual; |
1455 | | | 1458 | |
1456 | return context.actual; | | 1459 | result = uiomove(buf, context.actual, uio); |
| | | 1460 | kmem_free(buf, PAGE_SIZE); |
| | | 1461 | |
| | | 1462 | return result; |
1457 | } | | 1463 | } |
1458 | #endif | | | |
1459 | | | 1464 | |
1460 | VCHIQ_STATE_T * | | 1465 | VCHIQ_STATE_T * |
1461 | vchiq_get_state(void) | | 1466 | vchiq_get_state(void) |
1462 | { | | 1467 | { |
1463 | | | 1468 | |
1464 | if (g_state.remote == NULL) | | 1469 | if (g_state.remote == NULL) |
1465 | printk(KERN_ERR "%s: g_state.remote == NULL\n", __func__); | | 1470 | printk(KERN_ERR "%s: g_state.remote == NULL\n", __func__); |
1466 | else if (g_state.remote->initialised != 1) | | 1471 | else if (g_state.remote->initialised != 1) |
1467 | printk(KERN_NOTICE "%s: g_state.remote->initialised != 1 (%d)\n", | | 1472 | printk(KERN_NOTICE "%s: g_state.remote->initialised != 1 (%d)\n", |
1468 | __func__, g_state.remote->initialised); | | 1473 | __func__, g_state.remote->initialised); |
1469 | | | 1474 | |
1470 | return ((g_state.remote != NULL) && | | 1475 | return ((g_state.remote != NULL) && |
1471 | (g_state.remote->initialised == 1)) ? &g_state : NULL; | | 1476 | (g_state.remote->initialised == 1)) ? &g_state : NULL; |