void uftdi_read(void *vsc, int portno, u_char **ptr, u_int32_t *count) { struct uftdi_softc *sc = vsc; u_char msr, lsr; DPRINTFN(15,("uftdi_read: sc=%p, port=%d count=%d\n", sc, portno, *count)); msr = FTDI_GET_MSR(*ptr); lsr = FTDI_GET_LSR(*ptr); #ifdef UFTDI_DEBUG if (*count != 2) DPRINTFN(10,("uftdi_read: sc=%p, port=%d count=%d data[0]=" "0x%02x\n", sc, portno, *count, (*ptr)[2])); #endif if (sc->sc_msr != msr || (sc->sc_lsr & FTDI_LSR_MASK) != (lsr & FTDI_LSR_MASK)) { DPRINTF(("uftdi_read: status change msr=0x%02x(0x%02x) " "lsr=0x%02x(0x%02x)\n", msr, sc->sc_msr, lsr, sc->sc_lsr)); sc->sc_msr = msr; sc->sc_lsr = lsr; ucom_status_change((struct ucom_softc *)sc->sc_subdev); } /* Pick up status and adjust data part. */ *ptr += 2; *count -= 2; }
Static void uftdi_read(void *vsc, int portno, u_char **ptr, u_int32_t *count) { struct uftdi_softc *sc = vsc; u_char msr, lsr; DPRINTFN(15,("uftdi_read: sc=%p, port=%d count=%d\n", sc, portno, *count)); msr = FTDI_GET_MSR(*ptr); lsr = FTDI_GET_LSR(*ptr); #ifdef UFTDI_DEBUG if (*count != 2) DPRINTFN(10,("uftdi_read: sc=%p, port=%d count=%d data[0]=" "0x%02x\n", sc, portno, *count, (*ptr)[2])); #endif if (sc->sc_msr != msr || (sc->sc_lsr & FTDI_LSR_MASK) != (lsr & FTDI_LSR_MASK)) { DPRINTF(("uftdi_read: status change msr=0x%02x(0x%02x) " "lsr=0x%02x(0x%02x)\n", msr, sc->sc_msr, lsr, sc->sc_lsr)); sc->sc_msr = msr; sc->sc_lsr = lsr; ucom_status_change(device_private(sc->sc_subdev[portno-1])); } /* Adjust buffer pointer to skip status prefix */ *ptr += 2; }
void FTDIDevice::OnRead(char **buffer, size_t *numBytes) { fStatusMSR = FTDI_GET_MSR(*buffer); fStatusLSR = FTDI_GET_LSR(*buffer); TRACE("FTDIDevice::OnRead(): MSR: 0x%02x LSR: 0x%02x\n", fStatusMSR, fStatusLSR); *buffer += 2; *numBytes -= 2; }
/*ARGSUSED*/ static void uftdi_bulkin_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req) { uftdi_state_t *uf = (uftdi_state_t *)req->bulk_client_private; mblk_t *data; int data_len; data = req->bulk_data; data_len = data ? MBLKL(data) : 0; /* * The first two bytes of data are status register bytes * that arrive with every packet from the device. Process * them here before handing the rest of the data on. * * When active, the device will send us these bytes at least * every 40 milliseconds, even if there's no received data. */ if (req->bulk_completion_reason == USB_CR_OK && data_len >= 2) { uint8_t msr = FTDI_GET_MSR(data->b_rptr); uint8_t lsr = FTDI_GET_LSR(data->b_rptr); int new_rx_err; data->b_rptr += 2; mutex_enter(&uf->uf_lock); if (uf->uf_msr != msr) { /* * modem status register changed */ USB_DPRINTF_L3(DPRINT_IN_PIPE, uf->uf_lh, "uftdi_bulkin_cb: new msr: 0x%02x -> 0x%02x", uf->uf_msr, msr); uf->uf_msr = msr; if (uf->uf_port_state == UFTDI_PORT_OPEN && uf->uf_cb.cb_status) { mutex_exit(&uf->uf_lock); uf->uf_cb.cb_status(uf->uf_cb.cb_arg); mutex_enter(&uf->uf_lock); } } if ((uf->uf_lsr & FTDI_LSR_MASK) != (lsr & FTDI_LSR_MASK)) { /* * line status register *receive* bits changed * * (The THRE and TEMT (transmit) status bits are * masked out above.) */ USB_DPRINTF_L3(DPRINT_IN_PIPE, uf->uf_lh, "uftdi_bulkin_cb: new lsr: 0x%02x -> 0x%02x", uf->uf_lsr, lsr); new_rx_err = B_TRUE; } else new_rx_err = B_FALSE; uf->uf_lsr = lsr; /* THRE and TEMT captured here */ if ((lsr & FTDI_LSR_MASK) != 0 && (MBLKL(data) > 0 || new_rx_err) && uf->uf_port_state == UFTDI_PORT_OPEN) { /* * The current line status register value indicates * that there's been some sort of unusual condition * on the receive side. We either received a break, * or got some badly formed characters from the * serial port - framing errors, overrun, parity etc. * So there's either some new data to post, or a * new error (break) to post, or both. * * Invoke uftdi_rxerr_put() to place the inbound * characters as M_BREAK messages on the receive * mblk chain, decorated with error flag(s) for * upper-level modules (e.g. ldterm) to process. */ mutex_exit(&uf->uf_lock); uftdi_rxerr_put(&uf->uf_rx_mp, data, lsr); ASSERT(MBLKL(data) == 0); /* * Since we've converted all the received * characters into M_BREAK messages, we * invoke the rx callback to shove the mblks * up the STREAM. */ if (uf->uf_cb.cb_rx) uf->uf_cb.cb_rx(uf->uf_cb.cb_arg); mutex_enter(&uf->uf_lock); } mutex_exit(&uf->uf_lock); data_len = MBLKL(data); } USB_DPRINTF_L4(DPRINT_IN_PIPE, uf->uf_lh, "uftdi_bulkin_cb: " "cr=%d len=%d", req->bulk_completion_reason, data_len); /* save data and notify GSD */ if (data_len > 0 && uf->uf_port_state == UFTDI_PORT_OPEN && req->bulk_completion_reason == USB_CR_OK) { req->bulk_data = NULL; uftdi_put_tail(&uf->uf_rx_mp, data); if (uf->uf_cb.cb_rx) uf->uf_cb.cb_rx(uf->uf_cb.cb_arg); } usb_free_bulk_req(req); /* receive more */ mutex_enter(&uf->uf_lock); uf->uf_bulkin_state = UFTDI_PIPE_IDLE; if (uf->uf_port_state == UFTDI_PORT_OPEN && uf->uf_dev_state == USB_DEV_ONLINE) { if (uftdi_rx_start(uf) != USB_SUCCESS) { USB_DPRINTF_L2(DPRINT_IN_PIPE, uf->uf_lh, "uftdi_bulkin_cb: restart rx fail"); } } mutex_exit(&uf->uf_lock); }