umcs.c (239299) | umcs.c (260559) |
---|---|
1/*- 2 * Copyright (c) 2010 Lev Serebryakov <lev@FreeBSD.org>. 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 --- 24 unchanged lines hidden (view full) --- 33 * http://www.moschip.com. The datasheets don't contain full 34 * programming information for the chip. 35 * 36 * It is nornal to have only two enabled ports in devices, based on 37 * quad-port mos7840. 38 * 39 */ 40#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2010 Lev Serebryakov <lev@FreeBSD.org>. 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 --- 24 unchanged lines hidden (view full) --- 33 * http://www.moschip.com. The datasheets don't contain full 34 * programming information for the chip. 35 * 36 * It is nornal to have only two enabled ports in devices, based on 37 * quad-port mos7840. 38 * 39 */ 40#include <sys/cdefs.h> |
41__FBSDID("$FreeBSD: head/sys/dev/usb/serial/umcs.c 239299 2012-08-15 15:42:57Z hselasky $"); | 41__FBSDID("$FreeBSD: head/sys/dev/usb/serial/umcs.c 260559 2014-01-12 11:44:28Z hselasky $"); |
42 43#include <sys/stdint.h> 44#include <sys/stddef.h> 45#include <sys/param.h> 46#include <sys/queue.h> 47#include <sys/types.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> --- 66 unchanged lines hidden (view full) --- 116}; 117 118struct umcs7840_softc_oneport { 119 struct usb_xfer *sc_xfer[UMCS7840_N_TRANSFERS]; /* Control structures 120 * for two transfers */ 121 122 uint8_t sc_lcr; /* local line control register */ 123 uint8_t sc_mcr; /* local modem control register */ | 42 43#include <sys/stdint.h> 44#include <sys/stddef.h> 45#include <sys/param.h> 46#include <sys/queue.h> 47#include <sys/types.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> --- 66 unchanged lines hidden (view full) --- 116}; 117 118struct umcs7840_softc_oneport { 119 struct usb_xfer *sc_xfer[UMCS7840_N_TRANSFERS]; /* Control structures 120 * for two transfers */ 121 122 uint8_t sc_lcr; /* local line control register */ 123 uint8_t sc_mcr; /* local modem control register */ |
124 uint8_t sc_lsr; /* local line status register */ 125 uint8_t sc_msr; /* local modem status register */ | |
126}; 127 128struct umcs7840_softc { 129 struct ucom_super_softc sc_super_ucom; 130 struct ucom_softc sc_ucom[UMCS7840_MAX_PORTS]; /* Need to be continuous 131 * array, so indexed by 132 * LOGICAL port 133 * (subunit) number */ --- 396 unchanged lines hidden (view full) --- 530 531 /* Enable RX */ 532 if (umcs7840_get_reg_sync(sc, umcs7840_port_registers[pn].reg_control, &data)) 533 return; 534 data &= ~MCS7840_DEV_CONTROLx_RX_DISABLE; 535 if (umcs7840_set_reg_sync(sc, umcs7840_port_registers[pn].reg_control, data)) 536 return; 537 | 124}; 125 126struct umcs7840_softc { 127 struct ucom_super_softc sc_super_ucom; 128 struct ucom_softc sc_ucom[UMCS7840_MAX_PORTS]; /* Need to be continuous 129 * array, so indexed by 130 * LOGICAL port 131 * (subunit) number */ --- 396 unchanged lines hidden (view full) --- 528 529 /* Enable RX */ 530 if (umcs7840_get_reg_sync(sc, umcs7840_port_registers[pn].reg_control, &data)) 531 return; 532 data &= ~MCS7840_DEV_CONTROLx_RX_DISABLE; 533 if (umcs7840_set_reg_sync(sc, umcs7840_port_registers[pn].reg_control, data)) 534 return; 535 |
538 /* Read LSR & MSR */ 539 if (umcs7840_get_UART_reg_sync(sc, pn, MCS7840_UART_REG_LSR, &sc->sc_ports[pn].sc_lsr)) 540 return; 541 if (umcs7840_get_UART_reg_sync(sc, pn, MCS7840_UART_REG_MSR, &sc->sc_ports[pn].sc_msr)) 542 return; 543 DPRINTF("Port %d has been opened, LSR=%02x MSR=%02x\n", pn, sc->sc_ports[pn].sc_lsr, sc->sc_ports[pn].sc_msr); | 536 DPRINTF("Port %d has been opened\n", pn); |
544} 545 546static void 547umcs7840_cfg_close(struct ucom_softc *ucom) 548{ 549 struct umcs7840_softc *sc = ucom->sc_parent; 550 uint16_t pn = ucom->sc_portno; 551 uint8_t data; --- 191 unchanged lines hidden (view full) --- 743 /* Stop write transfer */ 744 usbd_transfer_stop(sc->sc_ports[pn].sc_xfer[UMCS7840_BULK_WR_EP]); 745} 746 747static void 748umcs7840_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr) 749{ 750 struct umcs7840_softc *sc = ucom->sc_parent; | 537} 538 539static void 540umcs7840_cfg_close(struct ucom_softc *ucom) 541{ 542 struct umcs7840_softc *sc = ucom->sc_parent; 543 uint16_t pn = ucom->sc_portno; 544 uint8_t data; --- 191 unchanged lines hidden (view full) --- 736 /* Stop write transfer */ 737 usbd_transfer_stop(sc->sc_ports[pn].sc_xfer[UMCS7840_BULK_WR_EP]); 738} 739 740static void 741umcs7840_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr) 742{ 743 struct umcs7840_softc *sc = ucom->sc_parent; |
744 uint8_t pn = ucom->sc_portno; 745 uint8_t hw_lsr = 0; /* local line status register */ 746 uint8_t hw_msr = 0; /* local modem status register */ |
|
751 | 747 |
752 *lsr = sc->sc_ports[ucom->sc_portno].sc_lsr; 753 *msr = sc->sc_ports[ucom->sc_portno].sc_msr; | 748 /* Read LSR & MSR */ 749 umcs7840_get_UART_reg_sync(sc, pn, MCS7840_UART_REG_LSR, &hw_lsr); 750 umcs7840_get_UART_reg_sync(sc, pn, MCS7840_UART_REG_MSR, &hw_msr); 751 752 *lsr = hw_lsr; 753 *msr = hw_msr; 754 |
754 DPRINTF("Port %d status: LSR=%02x MSR=%02x\n", ucom->sc_portno, *lsr, *msr); 755} 756 757static void 758umcs7840_intr_callback(struct usb_xfer *xfer, usb_error_t error) 759{ 760 struct umcs7840_softc *sc = usbd_xfer_softc(xfer); 761 struct usb_page_cache *pc; --- 14 unchanged lines hidden (view full) --- 776 777 if (buf[pn] & MCS7840_UART_ISR_NOPENDING) 778 continue; 779 DPRINTF("Port %d has pending interrupt: %02x (FIFO: %02x)\n", pn, buf[pn] & MCS7840_UART_ISR_INTMASK, buf[pn] & (~MCS7840_UART_ISR_INTMASK)); 780 switch (buf[pn] & MCS7840_UART_ISR_INTMASK) { 781 case MCS7840_UART_ISR_RXERR: 782 case MCS7840_UART_ISR_RXHASDATA: 783 case MCS7840_UART_ISR_RXTIMEOUT: | 755 DPRINTF("Port %d status: LSR=%02x MSR=%02x\n", ucom->sc_portno, *lsr, *msr); 756} 757 758static void 759umcs7840_intr_callback(struct usb_xfer *xfer, usb_error_t error) 760{ 761 struct umcs7840_softc *sc = usbd_xfer_softc(xfer); 762 struct usb_page_cache *pc; --- 14 unchanged lines hidden (view full) --- 777 778 if (buf[pn] & MCS7840_UART_ISR_NOPENDING) 779 continue; 780 DPRINTF("Port %d has pending interrupt: %02x (FIFO: %02x)\n", pn, buf[pn] & MCS7840_UART_ISR_INTMASK, buf[pn] & (~MCS7840_UART_ISR_INTMASK)); 781 switch (buf[pn] & MCS7840_UART_ISR_INTMASK) { 782 case MCS7840_UART_ISR_RXERR: 783 case MCS7840_UART_ISR_RXHASDATA: 784 case MCS7840_UART_ISR_RXTIMEOUT: |
784 /* Read new LSR */ 785 if (umcs7840_get_UART_reg_sync(sc, pn, MCS7840_UART_REG_LSR, &sc->sc_ports[pn].sc_lsr)) 786 break; /* Inner switch */ | 785 case MCS7840_UART_ISR_MSCHANGE: |
787 ucom_status_change(&sc->sc_ucom[subunit]); | 786 ucom_status_change(&sc->sc_ucom[subunit]); |
788 /* Inner switch */ | |
789 break; | 787 break; |
790 case MCS7840_UART_ISR_TXEMPTY: | 788 default: |
791 /* Do nothing */ | 789 /* Do nothing */ |
792 break; /* Inner switch */ 793 case MCS7840_UART_ISR_MSCHANGE: 794 /* Read new MSR */ 795 if (umcs7840_get_UART_reg_sync(sc, pn, MCS7840_UART_REG_MSR, &sc->sc_ports[pn].sc_msr)) 796 break; /* Inner switch */ 797 DPRINTF("Port %d: new MSR %02x\n", pn, sc->sc_ports[pn].sc_msr); 798 ucom_status_change(&sc->sc_ucom[subunit]); | |
799 break; 800 } 801 } 802 } else 803 device_printf(sc->sc_dev, "Invalid interrupt data length %d", actlen); 804 /* FALLTHROUGH */ 805 case USB_ST_SETUP: 806tr_setup: --- 293 unchanged lines hidden --- | 790 break; 791 } 792 } 793 } else 794 device_printf(sc->sc_dev, "Invalid interrupt data length %d", actlen); 795 /* FALLTHROUGH */ 796 case USB_ST_SETUP: 797tr_setup: --- 293 unchanged lines hidden --- |