1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 1998, 2001 Nicolas Souchu 5 * Copyright (c) 2023 Juniper Networks, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 #include <sys/param.h> 31 #include <sys/abi_compat.h> 32 #include <sys/bus.h> 33 #include <sys/conf.h> 34 #include <sys/fcntl.h> 35 #include <sys/lock.h> 36 #include <sys/kernel.h> 37 #include <sys/malloc.h> 38 #include <sys/module.h> 39 #include <sys/sx.h> 40 #include <sys/systm.h> 41 #include <sys/uio.h> 42 #include <sys/errno.h> 43 44 #include <dev/iicbus/iiconf.h> 45 #include <dev/iicbus/iicbus.h> 46 #include <dev/iicbus/iic.h> 47 48 #include "iicbus_if.h" 49 50 struct iic_softc { 51 device_t sc_dev; 52 struct cdev *sc_devnode; 53 }; 54 55 struct iic_cdevpriv { 56 struct sx lock; 57 struct iic_softc *sc; 58 bool started; 59 uint8_t addr; 60 }; 61 62 #ifdef COMPAT_FREEBSD32 63 struct iic_msg32 { 64 uint16_t slave; 65 uint16_t flags; 66 uint16_t len; 67 uint32_t buf; 68 }; 69 70 struct iiccmd32 { 71 u_char slave; 72 uint32_t count; 73 uint32_t last; 74 uint32_t buf; 75 }; 76 77 struct iic_rdwr_data32 { 78 uint32_t msgs; 79 uint32_t nmsgs; 80 }; 81 82 #define I2CWRITE32 _IOW('i', 4, struct iiccmd32) 83 #define I2CREAD32 _IOW('i', 5, struct iiccmd32) 84 #define I2CRDWR32 _IOW('i', 6, struct iic_rdwr_data32) 85 #endif 86 87 #define IIC_LOCK(cdp) sx_xlock(&(cdp)->lock) 88 #define IIC_UNLOCK(cdp) sx_xunlock(&(cdp)->lock) 89 90 static MALLOC_DEFINE(M_IIC, "iic", "I2C device data"); 91 92 static int iic_probe(device_t); 93 static int iic_attach(device_t); 94 static int iic_detach(device_t); 95 static void iic_identify(driver_t *driver, device_t parent); 96 static void iicdtor(void *data); 97 static int iicuio_move(struct iic_cdevpriv *priv, struct uio *uio, int last); 98 static int iicuio(struct cdev *dev, struct uio *uio, int ioflag); 99 static int iicrdwr(struct iic_cdevpriv *priv, struct iic_rdwr_data *d, int flags, bool compat32); 100 101 static device_method_t iic_methods[] = { 102 /* device interface */ 103 DEVMETHOD(device_identify, iic_identify), 104 DEVMETHOD(device_probe, iic_probe), 105 DEVMETHOD(device_attach, iic_attach), 106 DEVMETHOD(device_detach, iic_detach), 107 108 /* iicbus interface */ 109 DEVMETHOD(iicbus_intr, iicbus_generic_intr), 110 111 { 0, 0 } 112 }; 113 114 static driver_t iic_driver = { 115 "iic", 116 iic_methods, 117 sizeof(struct iic_softc), 118 }; 119 120 static d_open_t iicopen; 121 static d_ioctl_t iicioctl; 122 123 static struct cdevsw iic_cdevsw = { 124 .d_version = D_VERSION, 125 .d_open = iicopen, 126 .d_read = iicuio, 127 .d_write = iicuio, 128 .d_ioctl = iicioctl, 129 .d_name = "iic", 130 }; 131 132 static void 133 iic_identify(driver_t *driver, device_t parent) 134 { 135 136 if (device_find_child(parent, "iic", -1) == NULL) 137 BUS_ADD_CHILD(parent, 0, "iic", -1); 138 } 139 140 static int 141 iic_probe(device_t dev) 142 { 143 if (iicbus_get_addr(dev) > 0) 144 return (ENXIO); 145 146 device_set_desc(dev, "I2C generic I/O"); 147 148 return (0); 149 } 150 151 static int 152 iic_attach(device_t dev) 153 { 154 struct iic_softc *sc; 155 156 sc = device_get_softc(dev); 157 sc->sc_dev = dev; 158 sc->sc_devnode = make_dev(&iic_cdevsw, device_get_unit(dev), 159 UID_ROOT, GID_WHEEL, 160 0600, "iic%d", device_get_unit(dev)); 161 if (sc->sc_devnode == NULL) { 162 device_printf(dev, "failed to create character device\n"); 163 return (ENXIO); 164 } 165 sc->sc_devnode->si_drv1 = sc; 166 167 return (0); 168 } 169 170 static int 171 iic_detach(device_t dev) 172 { 173 struct iic_softc *sc; 174 175 sc = device_get_softc(dev); 176 177 if (sc->sc_devnode) 178 destroy_dev(sc->sc_devnode); 179 180 return (0); 181 } 182 183 static int 184 iicopen(struct cdev *dev, int flags, int fmt, struct thread *td) 185 { 186 struct iic_cdevpriv *priv; 187 int error; 188 189 priv = malloc(sizeof(*priv), M_IIC, M_WAITOK | M_ZERO); 190 191 sx_init(&priv->lock, "iic"); 192 priv->sc = dev->si_drv1; 193 194 error = devfs_set_cdevpriv(priv, iicdtor); 195 if (error != 0) 196 free(priv, M_IIC); 197 198 return (error); 199 } 200 201 static void 202 iicdtor(void *data) 203 { 204 device_t iicdev, parent; 205 struct iic_cdevpriv *priv; 206 207 priv = data; 208 KASSERT(priv != NULL, ("iic cdevpriv should not be NULL!")); 209 210 iicdev = priv->sc->sc_dev; 211 parent = device_get_parent(iicdev); 212 213 if (priv->started) { 214 iicbus_stop(parent); 215 iicbus_reset(parent, IIC_UNKNOWN, 0, NULL); 216 iicbus_release_bus(parent, iicdev); 217 } 218 219 sx_destroy(&priv->lock); 220 free(priv, M_IIC); 221 } 222 223 static int 224 iicuio_move(struct iic_cdevpriv *priv, struct uio *uio, int last) 225 { 226 device_t parent; 227 int error, num_bytes, transferred_bytes, written_bytes; 228 char buffer[128]; 229 230 parent = device_get_parent(priv->sc->sc_dev); 231 error = 0; 232 233 /* 234 * We can only transfer up to sizeof(buffer) bytes in 1 shot, so loop until 235 * everything has been transferred. 236 */ 237 while ((error == 0) && (uio->uio_resid > 0)) { 238 239 num_bytes = MIN(uio->uio_resid, sizeof(buffer)); 240 transferred_bytes = 0; 241 242 switch (uio->uio_rw) { 243 case UIO_WRITE: 244 error = uiomove(buffer, num_bytes, uio); 245 246 while ((error == 0) && (transferred_bytes < num_bytes)) { 247 written_bytes = 0; 248 error = iicbus_write(parent, &buffer[transferred_bytes], 249 num_bytes - transferred_bytes, &written_bytes, 0); 250 transferred_bytes += written_bytes; 251 } 252 break; 253 case UIO_READ: 254 error = iicbus_read(parent, buffer, 255 num_bytes, &transferred_bytes, 256 ((uio->uio_resid <= sizeof(buffer)) ? last : 0), 0); 257 if (error == 0) 258 error = uiomove(buffer, transferred_bytes, uio); 259 break; 260 } 261 } 262 263 return (error); 264 } 265 266 static int 267 iicuio(struct cdev *dev, struct uio *uio, int ioflag) 268 { 269 device_t parent; 270 struct iic_cdevpriv *priv; 271 int error; 272 uint8_t addr; 273 274 priv = NULL; 275 error = devfs_get_cdevpriv((void**)&priv); 276 277 if (error != 0) 278 return (error); 279 KASSERT(priv != NULL, ("iic cdevpriv should not be NULL!")); 280 281 IIC_LOCK(priv); 282 if (priv->started || (priv->addr == 0)) { 283 IIC_UNLOCK(priv); 284 return (ENXIO); 285 } 286 parent = device_get_parent(priv->sc->sc_dev); 287 288 error = iicbus_request_bus(parent, priv->sc->sc_dev, 289 (ioflag & O_NONBLOCK) ? IIC_DONTWAIT : (IIC_WAIT | IIC_INTR)); 290 if (error != 0) { 291 IIC_UNLOCK(priv); 292 return (error); 293 } 294 295 switch (uio->uio_rw) { 296 case UIO_READ: 297 addr = priv->addr | LSB; 298 break; 299 case UIO_WRITE: 300 addr = priv->addr & ~LSB; 301 break; 302 } 303 304 error = iicbus_start(parent, addr, 0); 305 if (error != 0) 306 { 307 iicbus_release_bus(parent, priv->sc->sc_dev); 308 IIC_UNLOCK(priv); 309 return (error); 310 } 311 312 error = iicuio_move(priv, uio, IIC_LAST_READ); 313 314 iicbus_stop(parent); 315 iicbus_release_bus(parent, priv->sc->sc_dev); 316 IIC_UNLOCK(priv); 317 return (error); 318 } 319 320 #ifdef COMPAT_FREEBSD32 321 static int 322 iic_copyinmsgs32(struct iic_rdwr_data *d, struct iic_msg *buf) 323 { 324 struct iic_msg32 msg32; 325 struct iic_msg32 *m32; 326 int error, i; 327 328 m32 = (struct iic_msg32 *)d->msgs; 329 for (i = 0; i < d->nmsgs; i++) { 330 error = copyin(&m32[i], &msg32, sizeof(msg32)); 331 if (error != 0) 332 return (error); 333 CP(msg32, buf[i], slave); 334 CP(msg32, buf[i], flags); 335 CP(msg32, buf[i], len); 336 PTRIN_CP(msg32, buf[i], buf); 337 } 338 return (0); 339 } 340 #endif 341 342 static int 343 iicrdwr(struct iic_cdevpriv *priv, struct iic_rdwr_data *d, int flags, 344 bool compat32 __unused) 345 { 346 #ifdef COMPAT_FREEBSD32 347 struct iic_rdwr_data dswab; 348 struct iic_rdwr_data32 *d32; 349 #endif 350 struct iic_msg *buf, *m; 351 void **usrbufs; 352 device_t iicdev, parent; 353 int error; 354 uint32_t i; 355 356 iicdev = priv->sc->sc_dev; 357 parent = device_get_parent(iicdev); 358 error = 0; 359 #ifdef COMPAT_FREEBSD32 360 if (compat32) { 361 d32 = (struct iic_rdwr_data32 *)d; 362 PTRIN_CP(*d32, dswab, msgs); 363 CP(*d32, dswab, nmsgs); 364 d = &dswab; 365 } 366 #endif 367 368 if (d->nmsgs > IIC_RDRW_MAX_MSGS) 369 return (EINVAL); 370 371 buf = malloc(sizeof(*d->msgs) * d->nmsgs, M_IIC, M_WAITOK); 372 373 #ifdef COMPAT_FREEBSD32 374 if (compat32) 375 error = iic_copyinmsgs32(d, buf); 376 else 377 #endif 378 error = copyin(d->msgs, buf, sizeof(*d->msgs) * d->nmsgs); 379 if (error != 0) { 380 free(buf, M_IIC); 381 return (error); 382 } 383 384 /* Alloc kernel buffers for userland data, copyin write data */ 385 usrbufs = malloc(sizeof(void *) * d->nmsgs, M_IIC, M_WAITOK | M_ZERO); 386 387 for (i = 0; i < d->nmsgs; i++) { 388 m = &(buf[i]); 389 usrbufs[i] = m->buf; 390 391 /* 392 * At least init the buffer to NULL so we can safely free() it later. 393 * If the copyin() to buf failed, don't try to malloc bogus m->len. 394 */ 395 m->buf = NULL; 396 if (error != 0) 397 continue; 398 399 /* m->len is uint16_t, so allocation size is capped at 64K. */ 400 m->buf = malloc(m->len, M_IIC, M_WAITOK); 401 if (!(m->flags & IIC_M_RD)) 402 error = copyin(usrbufs[i], m->buf, m->len); 403 } 404 405 if (error == 0) 406 error = iicbus_request_bus(parent, iicdev, 407 (flags & O_NONBLOCK) ? IIC_DONTWAIT : (IIC_WAIT | IIC_INTR)); 408 409 if (error == 0) { 410 error = iicbus_transfer(iicdev, buf, d->nmsgs); 411 iicbus_release_bus(parent, iicdev); 412 } 413 414 /* Copyout all read segments, free up kernel buffers */ 415 for (i = 0; i < d->nmsgs; i++) { 416 m = &(buf[i]); 417 if ((error == 0) && (m->flags & IIC_M_RD)) 418 error = copyout(m->buf, usrbufs[i], m->len); 419 free(m->buf, M_IIC); 420 } 421 422 free(usrbufs, M_IIC); 423 free(buf, M_IIC); 424 return (error); 425 } 426 427 static int 428 iicioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td) 429 { 430 #ifdef COMPAT_FREEBSD32 431 struct iiccmd iicswab; 432 #endif 433 device_t parent, iicdev; 434 struct iiccmd *s; 435 #ifdef COMPAT_FREEBSD32 436 struct iiccmd32 *s32; 437 #endif 438 struct uio ubuf; 439 struct iovec uvec; 440 struct iic_cdevpriv *priv; 441 int error; 442 bool compat32; 443 444 s = (struct iiccmd *)data; 445 #ifdef COMPAT_FREEBSD32 446 s32 = (struct iiccmd32 *)data; 447 #endif 448 error = devfs_get_cdevpriv((void**)&priv); 449 if (error != 0) 450 return (error); 451 452 KASSERT(priv != NULL, ("iic cdevpriv should not be NULL!")); 453 454 iicdev = priv->sc->sc_dev; 455 parent = device_get_parent(iicdev); 456 IIC_LOCK(priv); 457 458 #ifdef COMPAT_FREEBSD32 459 switch (cmd) { 460 case I2CWRITE32: 461 case I2CREAD32: 462 CP(*s32, iicswab, slave); 463 CP(*s32, iicswab, count); 464 CP(*s32, iicswab, last); 465 PTRIN_CP(*s32, iicswab, buf); 466 s = &iicswab; 467 break; 468 default: 469 break; 470 } 471 #endif 472 473 switch (cmd) { 474 case I2CSTART: 475 if (priv->started) { 476 error = EINVAL; 477 break; 478 } 479 error = iicbus_request_bus(parent, iicdev, 480 (flags & O_NONBLOCK) ? IIC_DONTWAIT : (IIC_WAIT | IIC_INTR)); 481 482 if (error == 0) 483 error = iicbus_start(parent, s->slave, 0); 484 485 if (error == 0) { 486 priv->addr = s->slave; 487 priv->started = true; 488 } else 489 iicbus_release_bus(parent, iicdev); 490 491 break; 492 493 case I2CSTOP: 494 if (priv->started) { 495 error = iicbus_stop(parent); 496 iicbus_release_bus(parent, iicdev); 497 priv->started = false; 498 } 499 500 break; 501 502 case I2CRSTCARD: 503 /* 504 * Bus should be owned before we reset it. 505 * We allow the bus to be already owned as the result of an in-progress 506 * sequence; however, bus reset will always be followed by release 507 * (a new start is presumably needed for I/O anyway). */ 508 if (!priv->started) 509 error = iicbus_request_bus(parent, iicdev, 510 (flags & O_NONBLOCK) ? IIC_DONTWAIT : (IIC_WAIT | IIC_INTR)); 511 512 if (error == 0) { 513 error = iicbus_reset(parent, IIC_UNKNOWN, 0, NULL); 514 /* 515 * Ignore IIC_ENOADDR as it only means we have a master-only 516 * controller. 517 */ 518 if (error == IIC_ENOADDR) 519 error = 0; 520 521 iicbus_release_bus(parent, iicdev); 522 priv->started = false; 523 } 524 break; 525 526 case I2CWRITE: 527 #ifdef COMPAT_FREEBSD32 528 case I2CWRITE32: 529 #endif 530 if (!priv->started) { 531 error = EINVAL; 532 break; 533 } 534 uvec.iov_base = s->buf; 535 uvec.iov_len = s->count; 536 ubuf.uio_iov = &uvec; 537 ubuf.uio_iovcnt = 1; 538 ubuf.uio_segflg = UIO_USERSPACE; 539 ubuf.uio_td = td; 540 ubuf.uio_resid = s->count; 541 ubuf.uio_offset = 0; 542 ubuf.uio_rw = UIO_WRITE; 543 error = iicuio_move(priv, &ubuf, 0); 544 break; 545 546 case I2CREAD: 547 #ifdef COMPAT_FREEBSD32 548 case I2CREAD32: 549 #endif 550 if (!priv->started) { 551 error = EINVAL; 552 break; 553 } 554 uvec.iov_base = s->buf; 555 uvec.iov_len = s->count; 556 ubuf.uio_iov = &uvec; 557 ubuf.uio_iovcnt = 1; 558 ubuf.uio_segflg = UIO_USERSPACE; 559 ubuf.uio_td = td; 560 ubuf.uio_resid = s->count; 561 ubuf.uio_offset = 0; 562 ubuf.uio_rw = UIO_READ; 563 error = iicuio_move(priv, &ubuf, s->last); 564 break; 565 566 #ifdef COMPAT_FREEBSD32 567 case I2CRDWR32: 568 #endif 569 case I2CRDWR: 570 /* 571 * The rdwr list should be a self-contained set of 572 * transactions. Fail if another transaction is in progress. 573 */ 574 if (priv->started) { 575 error = EINVAL; 576 break; 577 } 578 579 #ifdef COMPAT_FREEBSD32 580 compat32 = (cmd == I2CRDWR32); 581 #else 582 compat32 = false; 583 #endif 584 error = iicrdwr(priv, (struct iic_rdwr_data *)data, flags, 585 compat32); 586 587 break; 588 589 case I2CRPTSTART: 590 if (!priv->started) { 591 error = EINVAL; 592 break; 593 } 594 error = iicbus_repeated_start(parent, s->slave, 0); 595 break; 596 597 case I2CSADDR: 598 priv->addr = *((uint8_t*)data); 599 break; 600 601 default: 602 error = ENOTTY; 603 } 604 605 IIC_UNLOCK(priv); 606 return (error); 607 } 608 609 DRIVER_MODULE(iic, iicbus, iic_driver, 0, 0); 610 MODULE_DEPEND(iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER); 611 MODULE_VERSION(iic, 1); 612