iiconf.c (167855) | iiconf.c (181304) |
---|---|
1/*- 2 * Copyright (c) 1998 Nicolas Souchu 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1998 Nicolas Souchu 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/dev/iicbus/iiconf.c 167855 2007-03-23 23:03:54Z imp $"); | 28__FBSDID("$FreeBSD: head/sys/dev/iicbus/iiconf.c 181304 2008-08-04 21:03:06Z jhb $"); |
29 30#include <sys/param.h> 31#include <sys/systm.h> | 29 30#include <sys/param.h> 31#include <sys/systm.h> |
32#include <sys/lock.h> |
|
32#include <sys/malloc.h> 33#include <sys/module.h> | 33#include <sys/malloc.h> 34#include <sys/module.h> |
35#include <sys/mutex.h> |
|
34#include <sys/bus.h> 35 36#include <dev/iicbus/iiconf.h> 37#include <dev/iicbus/iicbus.h> 38#include "iicbus_if.h" 39 40/* 41 * iicbus_intr() --- 10 unchanged lines hidden (view full) --- 52 return; 53} 54 55static int 56iicbus_poll(struct iicbus_softc *sc, int how) 57{ 58 int error; 59 | 36#include <sys/bus.h> 37 38#include <dev/iicbus/iiconf.h> 39#include <dev/iicbus/iicbus.h> 40#include "iicbus_if.h" 41 42/* 43 * iicbus_intr() --- 10 unchanged lines hidden (view full) --- 54 return; 55} 56 57static int 58iicbus_poll(struct iicbus_softc *sc, int how) 59{ 60 int error; 61 |
62 IICBUS_ASSERT_LOCKED(sc); |
|
60 switch (how) { | 63 switch (how) { |
61 case (IIC_WAIT | IIC_INTR): 62 error = tsleep(sc, IICPRI|PCATCH, "iicreq", 0); | 64 case IIC_WAIT | IIC_INTR: 65 error = mtx_sleep(sc, &sc->lock, IICPRI|PCATCH, "iicreq", 0); |
63 break; 64 | 66 break; 67 |
65 case (IIC_WAIT | IIC_NOINTR): 66 error = tsleep(sc, IICPRI, "iicreq", 0); | 68 case IIC_WAIT | IIC_NOINTR: 69 error = mtx_sleep(sc, &sc->lock, IICPRI, "iicreq", 0); |
67 break; 68 69 default: 70 return (EWOULDBLOCK); 71 break; 72 } 73 74 return (error); --- 5 unchanged lines hidden (view full) --- 80 * Allocate the device to perform transfers. 81 * 82 * how : IIC_WAIT or IIC_DONTWAIT 83 */ 84int 85iicbus_request_bus(device_t bus, device_t dev, int how) 86{ 87 struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus); | 70 break; 71 72 default: 73 return (EWOULDBLOCK); 74 break; 75 } 76 77 return (error); --- 5 unchanged lines hidden (view full) --- 83 * Allocate the device to perform transfers. 84 * 85 * how : IIC_WAIT or IIC_DONTWAIT 86 */ 87int 88iicbus_request_bus(device_t bus, device_t dev, int how) 89{ 90 struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus); |
88 int s, error = 0; | 91 int error = 0; |
89 90 /* first, ask the underlying layers if the request is ok */ | 92 93 /* first, ask the underlying layers if the request is ok */ |
94 IICBUS_LOCK(sc); |
|
91 do { 92 error = IICBUS_CALLBACK(device_get_parent(bus), 93 IIC_REQUEST_BUS, (caddr_t)&how); 94 if (error) 95 error = iicbus_poll(sc, how); 96 } while (error == EWOULDBLOCK); 97 98 while (!error) { | 95 do { 96 error = IICBUS_CALLBACK(device_get_parent(bus), 97 IIC_REQUEST_BUS, (caddr_t)&how); 98 if (error) 99 error = iicbus_poll(sc, how); 100 } while (error == EWOULDBLOCK); 101 102 while (!error) { |
99 s = splhigh(); | |
100 if (sc->owner && sc->owner != dev) { | 103 if (sc->owner && sc->owner != dev) { |
101 splx(s); | |
102 103 error = iicbus_poll(sc, how); 104 } else { 105 sc->owner = dev; 106 | 104 105 error = iicbus_poll(sc, how); 106 } else { 107 sc->owner = dev; 108 |
107 splx(s); | 109 IICBUS_UNLOCK(sc); |
108 return (0); 109 } 110 111 /* free any allocated resource */ 112 if (error) 113 IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS, 114 (caddr_t)&how); 115 } | 110 return (0); 111 } 112 113 /* free any allocated resource */ 114 if (error) 115 IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS, 116 (caddr_t)&how); 117 } |
118 IICBUS_UNLOCK(sc); |
|
116 117 return (error); 118} 119 120/* 121 * iicbus_release_bus() 122 * 123 * Release the device allocated with iicbus_request_dev() 124 */ 125int 126iicbus_release_bus(device_t bus, device_t dev) 127{ 128 struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus); | 119 120 return (error); 121} 122 123/* 124 * iicbus_release_bus() 125 * 126 * Release the device allocated with iicbus_request_dev() 127 */ 128int 129iicbus_release_bus(device_t bus, device_t dev) 130{ 131 struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus); |
129 int s, error; | 132 int error; |
130 131 /* first, ask the underlying layers if the release is ok */ 132 error = IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS, NULL); 133 134 if (error) 135 return (error); 136 | 133 134 /* first, ask the underlying layers if the release is ok */ 135 error = IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS, NULL); 136 137 if (error) 138 return (error); 139 |
137 s = splhigh(); | 140 IICBUS_LOCK(sc); 141 |
138 if (sc->owner != dev) { | 142 if (sc->owner != dev) { |
139 splx(s); | 143 IICBUS_UNLOCK(sc); |
140 return (EACCES); 141 } 142 | 144 return (EACCES); 145 } 146 |
143 sc->owner = 0; 144 splx(s); | 147 sc->owner = NULL; |
145 146 /* wakeup waiting processes */ 147 wakeup(sc); | 148 149 /* wakeup waiting processes */ 150 wakeup(sc); |
151 IICBUS_UNLOCK(sc); |
|
148 149 return (0); 150} 151 152/* 153 * iicbus_started() 154 * 155 * Test if the iicbus is started by the controller --- 173 unchanged lines hidden (view full) --- 329 error = iicbus_read(bus, buf, len, read, IIC_LAST_READ, 0); 330 331 iicbus_stop(bus); 332 333 return (error); 334} 335 336/* | 152 153 return (0); 154} 155 156/* 157 * iicbus_started() 158 * 159 * Test if the iicbus is started by the controller --- 173 unchanged lines hidden (view full) --- 333 error = iicbus_read(bus, buf, len, read, IIC_LAST_READ, 0); 334 335 iicbus_stop(bus); 336 337 return (error); 338} 339 340/* |
337 * iicbus_trasnfer() | 341 * iicbus_transfer() |
338 * 339 * Do an aribtrary number of transfers on the iicbus. We pass these 340 * raw requests to the bridge driver. If the bridge driver supports 341 * them directly, then it manages all the details. If not, it can use 342 * the helper function iicbus_transfer_gen() which will do the 343 * transfers at a low level. 344 * 345 * Pointers passed in as part of iic_msg must be kernel pointers. --- 13 unchanged lines hidden (view full) --- 359int 360iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) 361{ 362 int i, error, lenread, lenwrote, nkid; 363 device_t *children, bus; 364 365 device_get_children(dev, &children, &nkid); 366 if (nkid != 1) | 342 * 343 * Do an aribtrary number of transfers on the iicbus. We pass these 344 * raw requests to the bridge driver. If the bridge driver supports 345 * them directly, then it manages all the details. If not, it can use 346 * the helper function iicbus_transfer_gen() which will do the 347 * transfers at a low level. 348 * 349 * Pointers passed in as part of iic_msg must be kernel pointers. --- 13 unchanged lines hidden (view full) --- 363int 364iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) 365{ 366 int i, error, lenread, lenwrote, nkid; 367 device_t *children, bus; 368 369 device_get_children(dev, &children, &nkid); 370 if (nkid != 1) |
367 return EIO; | 371 return (EIO); |
368 bus = children[0]; 369 free(children, M_TEMP); 370 for (i = 0, error = 0; i < nmsgs && error == 0; i++) { 371 if (msgs[i].flags & IIC_M_RD) 372 error = iicbus_block_read(bus, msgs[i].slave, 373 msgs[i].buf, msgs[i].len, &lenread); 374 else 375 error = iicbus_block_write(bus, msgs[i].slave, 376 msgs[i].buf, msgs[i].len, &lenwrote); 377 } 378 return (error); 379} | 372 bus = children[0]; 373 free(children, M_TEMP); 374 for (i = 0, error = 0; i < nmsgs && error == 0; i++) { 375 if (msgs[i].flags & IIC_M_RD) 376 error = iicbus_block_read(bus, msgs[i].slave, 377 msgs[i].buf, msgs[i].len, &lenread); 378 else 379 error = iicbus_block_write(bus, msgs[i].slave, 380 msgs[i].buf, msgs[i].len, &lenwrote); 381 } 382 return (error); 383} |