Lines Matching +full:slave +full:- +full:if
1 /*-
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
67 * Enable debugging by defining ICHSMB_DEBUG to a non-zero value.
70 #if ICHSMB_DEBUG != 0
88 BUS-INDEPENDENT BUS METHODS
92 * Handle probe-time duties that are independent of the bus
102 * Handle attach-time duties that are independent of the bus
112 mtx_init(&sc->mutex, device_get_nameunit(dev), "ichsmb", MTX_DEF); in ichsmb_attach()
115 if ((sc->smb = device_add_child(dev, DRIVER_SMBUS, -1)) == NULL) { in ichsmb_attach()
122 bus_write_1(sc->io_res, ICH_HST_STA, 0xff); in ichsmb_attach()
125 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, in ichsmb_attach()
126 NULL, ichsmb_device_intr, sc, &sc->irq_handle); in ichsmb_attach()
127 if (error != 0) { in ichsmb_attach()
136 mtx_destroy(&sc->mutex); in ichsmb_attach()
149 DBG("index=%d how=%d\n", index, data ? *(int *)data : -1); in ichsmb_callback()
164 ichsmb_quick(device_t dev, u_char slave, int how) in ichsmb_quick() argument
169 DBG("slave=0x%02x how=%d\n", slave, how); in ichsmb_quick()
170 KASSERT(sc->ich_cmd == -1, in ichsmb_quick()
171 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_quick()
175 mtx_lock(&sc->mutex); in ichsmb_quick()
176 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_QUICK; in ichsmb_quick()
177 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_quick()
178 slave | (how == SMB_QREAD ? in ichsmb_quick()
180 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_quick()
181 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_quick()
183 mtx_unlock(&sc->mutex); in ichsmb_quick()
193 ichsmb_sendb(device_t dev, u_char slave, char byte) in ichsmb_sendb() argument
198 DBG("slave=0x%02x byte=0x%02x\n", slave, (u_char)byte); in ichsmb_sendb()
199 KASSERT(sc->ich_cmd == -1, in ichsmb_sendb()
200 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_sendb()
201 mtx_lock(&sc->mutex); in ichsmb_sendb()
202 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE; in ichsmb_sendb()
203 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_sendb()
204 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_sendb()
205 bus_write_1(sc->io_res, ICH_HST_CMD, byte); in ichsmb_sendb()
206 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_sendb()
207 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_sendb()
209 mtx_unlock(&sc->mutex); in ichsmb_sendb()
215 ichsmb_recvb(device_t dev, u_char slave, char *byte) in ichsmb_recvb() argument
220 DBG("slave=0x%02x\n", slave); in ichsmb_recvb()
221 KASSERT(sc->ich_cmd == -1, in ichsmb_recvb()
222 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_recvb()
223 mtx_lock(&sc->mutex); in ichsmb_recvb()
224 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE; in ichsmb_recvb()
225 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_recvb()
226 slave | ICH_XMIT_SLVA_READ); in ichsmb_recvb()
227 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_recvb()
228 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_recvb()
229 if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR) in ichsmb_recvb()
230 *byte = bus_read_1(sc->io_res, ICH_D0); in ichsmb_recvb()
231 mtx_unlock(&sc->mutex); in ichsmb_recvb()
237 ichsmb_writeb(device_t dev, u_char slave, char cmd, char byte) in ichsmb_writeb() argument
242 DBG("slave=0x%02x cmd=0x%02x byte=0x%02x\n", in ichsmb_writeb()
243 slave, (u_char)cmd, (u_char)byte); in ichsmb_writeb()
244 KASSERT(sc->ich_cmd == -1, in ichsmb_writeb()
245 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_writeb()
246 mtx_lock(&sc->mutex); in ichsmb_writeb()
247 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA; in ichsmb_writeb()
248 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_writeb()
249 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_writeb()
250 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_writeb()
251 bus_write_1(sc->io_res, ICH_D0, byte); in ichsmb_writeb()
252 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_writeb()
253 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_writeb()
255 mtx_unlock(&sc->mutex); in ichsmb_writeb()
261 ichsmb_writew(device_t dev, u_char slave, char cmd, short word) in ichsmb_writew() argument
266 DBG("slave=0x%02x cmd=0x%02x word=0x%04x\n", in ichsmb_writew()
267 slave, (u_char)cmd, (u_int16_t)word); in ichsmb_writew()
268 KASSERT(sc->ich_cmd == -1, in ichsmb_writew()
269 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_writew()
270 mtx_lock(&sc->mutex); in ichsmb_writew()
271 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA; in ichsmb_writew()
272 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_writew()
273 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_writew()
274 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_writew()
275 bus_write_1(sc->io_res, ICH_D0, word & 0xff); in ichsmb_writew()
276 bus_write_1(sc->io_res, ICH_D1, word >> 8); in ichsmb_writew()
277 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_writew()
278 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_writew()
280 mtx_unlock(&sc->mutex); in ichsmb_writew()
286 ichsmb_readb(device_t dev, u_char slave, char cmd, char *byte) in ichsmb_readb() argument
291 DBG("slave=0x%02x cmd=0x%02x\n", slave, (u_char)cmd); in ichsmb_readb()
292 KASSERT(sc->ich_cmd == -1, in ichsmb_readb()
293 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_readb()
294 mtx_lock(&sc->mutex); in ichsmb_readb()
295 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA; in ichsmb_readb()
296 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_readb()
297 slave | ICH_XMIT_SLVA_READ); in ichsmb_readb()
298 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_readb()
299 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_readb()
300 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_readb()
301 if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR) in ichsmb_readb()
302 *byte = bus_read_1(sc->io_res, ICH_D0); in ichsmb_readb()
303 mtx_unlock(&sc->mutex); in ichsmb_readb()
309 ichsmb_readw(device_t dev, u_char slave, char cmd, short *word) in ichsmb_readw() argument
314 DBG("slave=0x%02x cmd=0x%02x\n", slave, (u_char)cmd); in ichsmb_readw()
315 KASSERT(sc->ich_cmd == -1, in ichsmb_readw()
316 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_readw()
317 mtx_lock(&sc->mutex); in ichsmb_readw()
318 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA; in ichsmb_readw()
319 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_readw()
320 slave | ICH_XMIT_SLVA_READ); in ichsmb_readw()
321 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_readw()
322 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_readw()
323 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_readw()
324 if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR) { in ichsmb_readw()
325 *word = (bus_read_1(sc->io_res, in ichsmb_readw()
327 | (bus_read_1(sc->io_res, in ichsmb_readw()
330 mtx_unlock(&sc->mutex); in ichsmb_readw()
336 ichsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) in ichsmb_pcall() argument
341 DBG("slave=0x%02x cmd=0x%02x sdata=0x%04x\n", in ichsmb_pcall()
342 slave, (u_char)cmd, (u_int16_t)sdata); in ichsmb_pcall()
343 KASSERT(sc->ich_cmd == -1, in ichsmb_pcall()
344 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_pcall()
345 mtx_lock(&sc->mutex); in ichsmb_pcall()
346 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_PROC_CALL; in ichsmb_pcall()
347 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_pcall()
348 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_pcall()
349 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_pcall()
350 bus_write_1(sc->io_res, ICH_D0, sdata & 0xff); in ichsmb_pcall()
351 bus_write_1(sc->io_res, ICH_D1, sdata >> 8); in ichsmb_pcall()
352 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_pcall()
353 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_pcall()
354 if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR) { in ichsmb_pcall()
355 *rdata = (bus_read_1(sc->io_res, in ichsmb_pcall()
357 | (bus_read_1(sc->io_res, in ichsmb_pcall()
360 mtx_unlock(&sc->mutex); in ichsmb_pcall()
366 ichsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) in ichsmb_bwrite() argument
371 DBG("slave=0x%02x cmd=0x%02x count=%d\n", slave, (u_char)cmd, count); in ichsmb_bwrite()
372 #if ICHSMB_DEBUG in ichsmb_bwrite()
377 for (p = (u_char *)buf; p - (u_char *)buf < 32; p += 8) { in ichsmb_bwrite()
379 " %c%c%c%c%c%c%c%c", (p - (u_char *)buf), in ichsmb_bwrite()
387 KASSERT(sc->ich_cmd == -1, in ichsmb_bwrite()
388 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_bwrite()
389 if (count < 1 || count > 32) in ichsmb_bwrite()
391 bcopy(buf, sc->block_data, count); in ichsmb_bwrite()
392 sc->block_count = count; in ichsmb_bwrite()
393 sc->block_index = 1; /* buf[0] is written here */ in ichsmb_bwrite()
394 sc->block_write = true; in ichsmb_bwrite()
396 mtx_lock(&sc->mutex); in ichsmb_bwrite()
397 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK; in ichsmb_bwrite()
398 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_bwrite()
399 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_bwrite()
400 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_bwrite()
401 bus_write_1(sc->io_res, ICH_D0, count); in ichsmb_bwrite()
402 bus_write_1(sc->io_res, ICH_BLOCK_DB, buf[0]); in ichsmb_bwrite()
403 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_bwrite()
404 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_bwrite()
406 mtx_unlock(&sc->mutex); in ichsmb_bwrite()
412 ichsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) in ichsmb_bread() argument
417 DBG("slave=0x%02x cmd=0x%02x\n", slave, (u_char)cmd); in ichsmb_bread()
418 KASSERT(sc->ich_cmd == -1, in ichsmb_bread()
419 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_bread()
420 bzero(sc->block_data, sizeof(sc->block_data)); in ichsmb_bread()
421 sc->block_count = 0; in ichsmb_bread()
422 sc->block_index = 0; in ichsmb_bread()
423 sc->block_write = false; in ichsmb_bread()
425 mtx_lock(&sc->mutex); in ichsmb_bread()
426 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK; in ichsmb_bread()
427 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_bread()
428 slave | ICH_XMIT_SLVA_READ); in ichsmb_bread()
429 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_bread()
430 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_bread()
431 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_bread()
432 if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR) { in ichsmb_bread()
433 bcopy(sc->block_data, buf, sc->block_count); in ichsmb_bread()
434 *count = sc->block_count; in ichsmb_bread()
436 mtx_unlock(&sc->mutex); in ichsmb_bread()
438 #if ICHSMB_DEBUG in ichsmb_bread()
443 for (p = (u_char *)buf; p - (u_char *)buf < 32; p += 8) { in ichsmb_bread()
445 " %c%c%c%c%c%c%c%c", (p - (u_char *)buf), in ichsmb_bread()
484 * Interrupt handler. This handler is bus-independent. Note that our
491 const device_t dev = sc->dev; in ichsmb_device_intr()
498 mtx_lock(&sc->mutex); in ichsmb_device_intr()
502 status = bus_read_1(sc->io_res, ICH_HST_STA); in ichsmb_device_intr()
503 #if ICHSMB_DEBUG in ichsmb_device_intr()
504 if ((status & ~(ICH_HST_STA_INUSE_STS | ICH_HST_STA_HOST_BUSY)) in ichsmb_device_intr()
511 if (status == 0) in ichsmb_device_intr()
517 if (sc->killed) { in ichsmb_device_intr()
518 sc->killed = 0; in ichsmb_device_intr()
520 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_device_intr()
524 if (sc->ich_cmd != -1) { in ichsmb_device_intr()
525 cmd_index = sc->ich_cmd >> 2; in ichsmb_device_intr()
528 sc->ich_cmd)); in ichsmb_device_intr()
531 if ((status & ~ok_bits) != 0) { in ichsmb_device_intr()
533 sc->ich_cmd); in ichsmb_device_intr()
534 bus_write_1(sc->io_res, in ichsmb_device_intr()
540 if (status & ICH_HST_STA_FAILED) { in ichsmb_device_intr()
541 sc->smb_error = SMB_EABORT; in ichsmb_device_intr()
546 if (status & ICH_HST_STA_BUS_ERR) { in ichsmb_device_intr()
547 sc->smb_error = SMB_ECOLLI; /* XXX SMB_EBUSERR? */ in ichsmb_device_intr()
552 if (status & ICH_HST_STA_DEV_ERR) { in ichsmb_device_intr()
553 sc->smb_error = SMB_ENOACK; /* or SMB_ETIMEOUT? */ in ichsmb_device_intr()
558 if (status & ICH_HST_STA_BYTE_DONE_STS) { in ichsmb_device_intr()
559 if (sc->block_write) { in ichsmb_device_intr()
560 if (sc->block_index < sc->block_count) { in ichsmb_device_intr()
563 bus_write_1(sc->io_res, in ichsmb_device_intr()
565 sc->block_data[sc->block_index++]); in ichsmb_device_intr()
570 if (sc->block_index == 0) { in ichsmb_device_intr()
571 sc->block_count = bus_read_1( in ichsmb_device_intr()
572 sc->io_res, ICH_D0); in ichsmb_device_intr()
573 if (sc->block_count < 1 || in ichsmb_device_intr()
574 sc->block_count > 32) { in ichsmb_device_intr()
577 sc->block_count); in ichsmb_device_intr()
578 bus_write_1(sc->io_res, in ichsmb_device_intr()
582 sc->block_count = 0; in ichsmb_device_intr()
583 sc->killed = true; in ichsmb_device_intr()
587 /* Get next byte, if any */ in ichsmb_device_intr()
588 if (sc->block_index < sc->block_count) { in ichsmb_device_intr()
591 sc->block_data[sc->block_index++] = in ichsmb_device_intr()
592 bus_read_1(sc->io_res, in ichsmb_device_intr()
599 if (sc->block_index == in ichsmb_device_intr()
600 sc->block_count - 1) { in ichsmb_device_intr()
601 bus_write_1(sc->io_res, in ichsmb_device_intr()
605 sc->ich_cmd); in ichsmb_device_intr()
612 if (status & ICH_HST_STA_INTR) { in ichsmb_device_intr()
613 sc->smb_error = SMB_ENOERR; in ichsmb_device_intr()
615 sc->ich_cmd = -1; in ichsmb_device_intr()
616 bus_write_1(sc->io_res, in ichsmb_device_intr()
623 bus_write_1(sc->io_res, ICH_HST_STA, status); in ichsmb_device_intr()
625 mtx_unlock(&sc->mutex); in ichsmb_device_intr()
628 if (count == maxloops) { in ichsmb_device_intr()
630 bus_read_1(sc->io_res, ICH_HST_STA)); in ichsmb_device_intr()
641 const device_t dev = sc->dev; in ichsmb_wait()
644 KASSERT(sc->ich_cmd != -1, in ichsmb_wait()
645 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_wait()
646 mtx_assert(&sc->mutex, MA_OWNED); in ichsmb_wait()
647 error = msleep(sc, &sc->mutex, PZERO, "ichsmb", hz / 4); in ichsmb_wait()
648 DBG("msleep -> %d\n", error); in ichsmb_wait()
651 smb_error = sc->smb_error; in ichsmb_wait()
655 bus_read_1(sc->io_res, ICH_HST_STA)); in ichsmb_wait()
656 sc->ich_cmd = -1; in ichsmb_wait()
672 const device_t dev = sc->dev; in ichsmb_release_resources()
674 if (sc->irq_handle != NULL) { in ichsmb_release_resources()
675 bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); in ichsmb_release_resources()
676 sc->irq_handle = NULL; in ichsmb_release_resources()
678 if (sc->irq_res != NULL) { in ichsmb_release_resources()
680 SYS_RES_IRQ, sc->irq_rid, sc->irq_res); in ichsmb_release_resources()
681 sc->irq_res = NULL; in ichsmb_release_resources()
683 if (sc->io_res != NULL) { in ichsmb_release_resources()
685 SYS_RES_IOPORT, sc->io_rid, sc->io_res); in ichsmb_release_resources()
686 sc->io_res = NULL; in ichsmb_release_resources()
697 if (error) in ichsmb_detach()
700 mtx_destroy(&sc->mutex); in ichsmb_detach()