PERFORCE change 132104 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Dec 30 07:46:16 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=132104
Change 132104 by hselasky at hselasky_laptop001 on 2007/12/30 15:45:28
Get all the ucom callbacks right in "uchcom".
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/uchcom.c#12 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/uchcom.c#12 (text+ko) ====
@@ -163,6 +163,8 @@
struct usbd_xfer *sc_xfer[UCHCOM_N_TRANSFER];
struct usbd_device *sc_udev;
+ uint8_t sc_dtr; /* local copy */
+ uint8_t sc_rts; /* local copy */
uint8_t sc_version;
uint8_t sc_msr;
uint8_t sc_lsr; /* local status register */
@@ -211,11 +213,17 @@
};
#define uchcom_lookup(v, p) usb_lookup(uchcom_devs, v, p)
-static void uchcom_get_status(void *, int, u_char *, u_char *);
-static void uchcom_set(void *, int, int, int);
-static int uchcom_param(void *, int, struct termios *);
-static int uchcom_open(void *, int);
-static void uchcom_close(void *, int);
+static int uchcom_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data, int flag, struct thread *td);
+static int uchcom_pre_param(struct ucom_softc *ucom, struct termios *t);
+static void uchcom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr);
+static void uchcom_cfg_param(struct ucom_softc *ucom, struct termios *t);
+static void uchcom_cfg_set_break(struct ucom_softc *sc, uint8_t onoff);
+static void uchcom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff);
+static void uchcom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff);
+static void uchcom_start_read(struct ucom_softc *ucom);
+static void uchcom_start_write(struct ucom_softc *ucom);
+static void uchcom_stop_read(struct ucom_softc *ucom);
+static void uchcom_stop_write(struct ucom_softc *ucom);
static device_probe_t uchcom_probe;
static device_attach_t uchcom_attach;
@@ -288,18 +296,20 @@
},
};
-struct ucom_callback uchcom_callback = {
- .ucom_get_status = uchcom_get_status,
- .ucom_set = uchcom_set,
- .ucom_param = uchcom_param,
- .ucom_ioctl = NULL,
- .ucom_open = uchcom_open,
- .ucom_close = uchcom_close,
- .ucom_read = NULL,
- .ucom_write = NULL,
+struct ucom_callback uchcom_callback = {
+ .ucom_cfg_get_status = &uchcom_cfg_get_status,
+ .ucom_cfg_set_dtr = &uchcom_cfg_set_dtr,
+ .ucom_cfg_set_rts = &uchcom_cfg_set_rts,
+ .ucom_cfg_set_break = &uchcom_cfg_set_break,
+ .ucom_cfg_param = &uchcom_cfg_param,
+ .ucom_pre_param = &uchcom_pre_param,
+ .ucom_ioctl = &uchcom_ioctl,
+ .ucom_start_read = &uchcom_start_read,
+ .ucom_stop_read = &uchcom_stop_read,
+ .ucom_start_write = &uchcom_start_write,
+ .ucom_stop_write = &uchcom_stop_write,
};
-
/* ----------------------------------------------------------------------
* driver entry points
*/
@@ -370,6 +380,17 @@
goto detach;
}
+ /*
+ * Do the initialization during attach so that the system does not
+ * sleep during open:
+ */
+ uchcom_update_version(sc);
+ uchcom_clear_chip(sc);
+ uchcom_reset_chip(sc);
+
+ sc->sc_dtr = 1;
+ sc->sc_rts = 1;
+
/* clear stall at first run */
sc->sc_flag |= (UCHCOM_FLAG_READ_STALL |
UCHCOM_FLAG_WRITE_STALL);
@@ -516,18 +537,21 @@
uchcom_get_status(struct uchcom_softc *sc, uint8_t *rval)
{
uchcom_read_reg(sc, UCHCOM_REG_STAT1, rval, UCHCOM_REG_STAT2, NULL);
+ return;
}
static void
uchcom_set_dtrrts_10(struct uchcom_softc *sc, uint8_t val)
{
uchcom_write_reg(sc, UCHCOM_REG_STAT1, val, UCHCOM_REG_STAT1, val);
+ return;
}
static void
uchcom_set_dtrrts_20(struct uchcom_softc *sc, uint8_t val)
{
uchcom_ctrl_write(sc, UCHCOM_REQ_SET_DTRRTS, val, 0);
+ return;
}
@@ -535,10 +559,11 @@
* middle layer
*/
-static int
+static void
uchcom_update_version(struct uchcom_softc *sc)
{
uchcom_get_version(sc, &sc->sc_version);
+ return;
}
static void
@@ -562,13 +587,13 @@
}
-static int
-uchcom_set_dtrrts(struct uchcom_softc *sc, int dtr, int rts)
+static void
+uchcom_set_dtrrts(struct uchcom_softc *sc)
{
uint8_t val = 0;
- if (dtr) val |= UCHCOM_DTR_MASK;
- if (rts) val |= UCHCOM_RTS_MASK;
+ if (sc->sc_dtr) val |= UCHCOM_DTR_MASK;
+ if (sc->sc_rts) val |= UCHCOM_RTS_MASK;
if (sc->sc_version < UCHCOM_VER_20)
uchcom_set_dtrrts_10(sc, ~val);
@@ -578,10 +603,12 @@
return (0);
}
-static int
-uchcom_set_break(struct uchcom_softc *sc, int onoff)
+static void
+uchcom_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)
{
- uint8_t brk1, brk2;
+ struct uchcom_softc *sc = ucom->sc_parent;
+ uint8_t brk1;
+ uint8_t brk2;
uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_BREAK2, &brk2);
if (onoff) {
@@ -595,18 +622,20 @@
}
uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_BREAK2, brk2);
- return (0);
+ return;
}
static int
uchcom_calc_divider_settings(struct uchcom_divider *dp, uint32_t rate)
{
- int i;
const struct uchcom_divider_record *rp;
- uint32_t div, rem, mod;
+ uint32_t div;
+ uint32_t rem;
+ uint32_t mod;
+ uint8_t i;
/* find record */
- for (i=0; i<NUM_DIVIDERS; i++) {
+ for (i=0; i != NUM_DIVIDERS; i++) {
if (dividers[i].dvr_high >= rate &&
dividers[i].dvr_low <= rate) {
rp = ÷rs[i];
@@ -637,14 +666,13 @@
return (0);
}
-static int
+static void
uchcom_set_dte_rate(struct uchcom_softc *sc, uint32_t rate)
{
- usbd_status err;
struct uchcom_divider dv;
if (uchcom_calc_divider_settings(&dv, rate))
- return (EINVAL);
+ return;
uchcom_write_reg(sc,
UCHCOM_REG_BPS_PRE, dv.dv_prescaler,
@@ -652,14 +680,14 @@
uchcom_write_reg(sc,
UCHCOM_REG_BPS_MOD, dv.dv_mod,
UCHCOM_REG_BPS_PAD, 0);
- return (0);
+ return;
}
-static int
+static void
uchcom_set_line_control(struct uchcom_softc *sc, tcflag_t cflag)
{
- usbd_status err;
- uint8_t lcr1 = 0, lcr2 = 0;
+ uint8_t lcr1 = 0;
+ uint8_t lcr2 = 0;
uchcom_read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
@@ -675,18 +703,9 @@
* - it is unclear how to handle stop bits.
*/
- switch (ISSET(cflag, CSIZE)) {
- case CS5:
- case CS6:
- case CS7:
- return (EINVAL);
- case CS8:
- break;
- }
-
- if (ISSET(cflag, PARENB)) {
+ if (cflag & PARENB) {
lcr1 |= UCHCOM_LCR1_PARENB;
- if (ISSET(cflag, PARODD))
+ if (cflag & PARODD)
lcr2 |= UCHCOM_LCR2_PARODD;
else
lcr2 |= UCHCOM_LCR2_PAREVEN;
@@ -694,10 +713,10 @@
uchcom_write_reg(sc, UCHCOM_REG_LCR1, lcr1, UCHCOM_REG_LCR2, lcr2);
- return (0);
+ return;
}
-static int
+static void
uchcom_clear_chip(struct uchcom_softc *sc)
{
DPRINTFN(0, "\n");
@@ -705,19 +724,23 @@
return;
}
-static int
+static void
uchcom_reset_chip(struct uchcom_softc *sc)
{
- usbd_status err;
- uint8_t lcr1, lcr2, pre, div, mod;
- uint16_t val=0, idx=0;
+ uint16_t val;
+ uint16_t idx;
+ uint8_t lcr1;
+ uint8_t lcr2;
+ uint8_t pre;
+ uint8_t div;
+ uint8_t mod;
uchcom_read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
-
uchcom_read_reg(sc, UCHCOM_REG_BPS_PRE, &pre, UCHCOM_REG_BPS_DIV, &div);
-
uchcom_read_reg(sc, UCHCOM_REG_BPS_MOD, &mod, UCHCOM_REG_BPS_PAD, NULL);
+ val = 0;
+ idx = 0;
val |= (uint16_t)(lcr1&0xF0) << 8;
val |= 0x01;
val |= (uint16_t)(lcr2&0x0F) << 8;
@@ -733,164 +756,84 @@
uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, val, idx);
- return (0);
+ return;
}
-static int
-uchcom_setup_comm(struct uchcom_softc *sc)
+/* ----------------------------------------------------------------------
+ * methods for ucom
+ */
+static void
+uchcom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
{
- int ret;
+ struct uchcom_softc *sc = ucom->sc_parent;
- ret = uchcom_update_version(sc);
- if (ret)
- return (ret);
+ DPRINTF(0, "\n");
- ret = uchcom_clear_chip(sc);
- if (ret)
- return (ret);
-
- ret = uchcom_set_dte_rate(sc, TTYDEF_SPEED);
- if (ret)
- return (ret);
-
- ret = uchcom_set_line_control(sc, CS8);
- if (ret)
- return (ret);
-
- ret = update_status(sc);
- if (ret)
- return (ret);
-
- ret = uchcom_reset_chip(sc);
- if (ret)
- return (ret);
-
- ret = uchcom_set_dte_rate(sc, TTYDEF_SPEED); /* XXX */
- if (ret)
- return (ret);
-
- sc->sc_dtr = sc->sc_rts = 1;
- ret = uchcom_set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
- if (ret)
- return (ret);
-
- return (0);
+ *lsr = sc->sc_lsr;
+ *msr = sc->sc_msr;
+ return;
}
static int
-uchcom_setup_intr_pipe(struct uchcom_softc *sc)
+uchcom_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data, int flag,
+ struct thread *td)
{
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
- if (sc->sc_intr_endpoint != -1 && sc->sc_intr_pipe == NULL) {
- sc->sc_intr_buf = malloc(sc->sc_intr_size, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(ucom->sc_iface,
- sc->sc_intr_endpoint,
- USBD_SHORT_XFER_OK,
- &sc->sc_intr_pipe, sc,
- sc->sc_intr_buf,
- sc->sc_intr_size,
- uchcom_intr, USBD_DEFAULT_INTERVAL);
- if (err) {
- device_printf(ucom->sc_dev,
- "cannot open interrupt pipe: %s\n",
- usbd_errstr(err));
- return (EIO);
- }
- }
- return (0);
+ return (ENOTTY);
}
-/* ----------------------------------------------------------------------
- * methods for ucom
- */
-void
-uchcom_uchcom_get_status(void *arg, int portno, u_char *rlsr, u_char *rmsr)
+static void
+uchcom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
{
- struct uchcom_softc *sc = arg;
+ struct uchcom_softc *sc = ucom->sc_parent;
- if (sc->sc_ucom.sc_dying)
- return;
+ DPRINTF(0, "onoff = %d\n", onoff);
- *rlsr = sc->sc_lsr;
- *rmsr = sc->sc_msr;
+ sc->sc_dtr = onoff;
+ uchcom_set_dtrrts(sc);
+ return;
}
-void
-uchcom_set(void *arg, int portno, int reg, int onoff)
+static void
+uchcom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff)
{
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return;
+ struct uchcom_softc *sc = ucom->sc_parent;
- switch (reg) {
- case UCOM_SET_DTR:
- sc->sc_dtr = !!onoff;
- uchcom_set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
- break;
- case UCOM_SET_RTS:
- sc->sc_rts = !!onoff;
- uchcom_set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
- break;
- case UCOM_SET_BREAK:
- uchcom_set_break(sc, onoff);
- break;
- }
-}
+ DPRINTF(0, "onoff = %d\n", onoff);
-int
-uchcom_param(void *arg, int portno, struct termios *t)
-{
- struct uchcom_softc *sc = arg;
- int ret;
-
- if (sc->sc_ucom.sc_dying)
- return (0);
-
- ret = uchcom_set_line_control(sc, t->c_cflag);
- if (ret)
- return (ret);
-
- ret = uchcom_set_dte_rate(sc, t->c_ospeed);
- if (ret)
- return (ret);
-
- return (0);
+ sc->sc_rts = onoff;
+ uchcom_set_dtrrts(sc);
+ return;
}
-int
-uchcom_open(void *arg, int portno)
+static int
+uchcom_pre_param(struct ucom_softc *ucom, struct termios *t)
{
- int ret;
- struct uchcom_softc *sc = arg;
+ struct uchcom_divider dv;
- if (sc->sc_ucom.sc_dying)
- return (EIO);
+ switch (t->c_cflag & CSIZE) {
+ case CS5:
+ case CS6:
+ case CS7:
+ return (EIO);
+ defaul:
+ break;
+ }
- ret = uchcom_setup_intr_pipe(sc);
- if (ret)
- return (ret);
-
- ret = uchcom_setup_comm(sc);
- if (ret)
- return (ret);
-
- return (0);
+ if (uchcom_calc_divider_settings(&dv, t->c_ospeed)) {
+ return (EIO);
+ }
+ return (0); /* success */
}
-void
-uchcom_close(void *arg, int portno)
+static void
+uchcom_cfg_param(struct ucom_softc *ucom, struct termios *t)
{
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- uchcom_close_intr_pipe(sc);
+ struct uchcom_softc *sc = ucom->sc_parent;
+ uchcom_set_line_control(sc, t->c_cflag);
+ uchcom_set_dte_rate(sc, t->c_ospeed);
+ return;
}
-
/* ----------------------------------------------------------------------
* callback when the modem status is changed.
*/
More information about the p4-projects
mailing list