Date: Mon, 12 Jun 2006 06:53:52 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 99038 for review Message-ID: <200606120653.k5C6rqUC026319@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=99038 Change 99038 by hselasky@hselasky_mini_itx on 2006/06/12 06:53:02 Finished reworking "uvscom.c". Please test! Affected files ... .. //depot/projects/usb/src/sys/dev/usb/uvscom.c#5 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/uvscom.c#5 (text+ko) ==== @@ -134,13 +134,38 @@ #define UVSCOM_CTS 0x01 #define UVSCOM_USTAT_MASK (UVSCOM_NOCARD | UVSCOM_DSR | UVSCOM_CTS) +/* + * These are the maximum number of bytes transferred per frame. + * The output buffer size cannot be increased due to the size encoding. + */ +#define UVSCOM_IBUFSIZE 512 /* bytes */ +#define UVSCOM_OBUFSIZE 64 /* bytes */ +#define UVSCOM_INTR_SIZE 64 /* bytes */ + +#ifndef UVSCOM_DEFAULT_OPKTSIZE +#define UVSCOM_DEFAULT_OPKTSIZE 8 +#endif + +#define UVSCOM_N_TRANSFER 10 + struct uvscom_softc { struct ucom_softc sc_ucom; struct __callout sc_watchdog; + struct usbd_xfer * sc_xfer[UVSCOM_N_TRANSFER]; + u_int16_t sc_line_ctrl; /* line control register */ u_int16_t sc_line_speed; /* line speed */ u_int16_t sc_line_param; /* line parameters */ + u_int16_t sc_flag; +#define UVSCOM_FLAG_WAIT_USB 0x0001 +#define UVSCOM_FLAG_WRITE_STALL 0x0002 +#define UVSCOM_FLAG_READ_STALL 0x0004 +#define UVSCOM_FLAG_INTR_STALL 0x0008 +#define UVSCOM_FLAG_OPEN 0x0010 +#define UVSCOM_FLAG_SET_LINE 0x0020 +#define UVSCOM_FLAG_SET_LINE_SPEED 0x0040 +#define UVSCOM_FLAG_SET_LINE_PARM 0x0080 u_int8_t sc_iface_no; /* interface number */ u_int8_t sc_iface_index; /* interface index */ @@ -148,37 +173,89 @@ u_int8_t sc_rts; /* current RTS state */ u_int8_t sc_lsr; /* local status register */ u_int8_t sc_msr; /* uvscom status register */ + u_int8_t sc_unit_status; /* unit status */ + u_int8_t sc_wakeup_detach; /* dummy */ +}; - XXX: - int sc_iface_number;/* interface number */ +static device_probe_t uvscom_probe; +static device_attach_t uvscom_attach; +static device_detach_t uvscom_detach; + +static void +uvscom_detach_complete(struct usbd_memory_info *info); + +static void +uvscom_watchdog(void *arg); + +static void +uvscom_write_callback(struct usbd_xfer *xfer); + +static void +uvscom_write_clear_stall_callback(struct usbd_xfer *xfer); + +static void +uvscom_read_callback(struct usbd_xfer *xfer); + +static void +uvscom_read_clear_stall_callback(struct usbd_xfer *xfer); + +static void +uvscom_intr_callback(struct usbd_xfer *xfer); + +static void +uvscom_intr_clear_stall_callback(struct usbd_xfer *xfer); + +static void +uvscom_read_status_callback(struct usbd_xfer *xfer); + +static void +uvscom_shutdown_callback(struct usbd_xfer *xfer); + +static void +uvscom_set_line_callback(struct usbd_xfer *xfer); + +static void +uvscom_set_line_coding_callback(struct usbd_xfer *xfer); + +static void +uvscom_set_dtr(struct ucom_softc *ucom, u_int8_t onoff); + +static void +uvscom_set_rts(struct ucom_softc *ucom, u_int8_t onoff); + +static void +uvscom_set_break(struct ucom_softc *ucom, u_int8_t onoff); + +static int +uvscom_param(struct ucom_softc *ucom, struct termios *t); + +static int +uvscom_open(struct ucom_softc *ucom); - usbd_interface_handle sc_intr_iface; /* interrupt interface */ - int sc_intr_number; /* interrupt number */ - usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */ - u_int8_t *sc_intr_buf; /* interrupt buffer */ - int sc_isize; +static void +uvscom_close(struct ucom_softc *ucom); +static void +uvscom_start_read(struct ucom_softc *ucom); - u_int8_t sc_unit_status; /* unit status */ +static void +uvscom_stop_read(struct ucom_softc *ucom); - struct task sc_task; -}; +static void +uvscom_start_write(struct ucom_softc *ucom); -/* - * These are the maximum number of bytes transferred per frame. - * The output buffer size cannot be increased due to the size encoding. - */ -#define UVSCOM_IBUFSIZE 512 -#define UVSCOM_OBUFSIZE 64 +static void +uvscom_stop_write(struct ucom_softc *ucom); -#ifndef UVSCOM_DEFAULT_OPKTSIZE -#define UVSCOM_DEFAULT_OPKTSIZE 8 -#endif +static void +uvscom_get_status(struct ucom_softc *ucom, u_int8_t *lsr, u_int8_t *msr); -#define UVSCOM_N_TRANSFER X +static int +uvscom_ioctl(struct ucom_softc *ucom, u_long cmd, caddr_t data, int fflag, + struct thread *td); -static const struct usbd_config umodem_config_data[UVSCOM_N_TRANSFER] = { +static const struct usbd_config uvscom_config[UVSCOM_N_TRANSFER] = { [0] = { .type = UE_BULK, @@ -186,7 +263,7 @@ .direction = UE_DIR_OUT, .bufsize = UVSCOM_OBUFSIZE, .flags = 0, - .callback = &umodem_write_callback, + .callback = &uvscom_write_callback, }, [1] = { @@ -195,7 +272,7 @@ .direction = UE_DIR_IN, .bufsize = UVSCOM_IBUFSIZE, .flags = USBD_SHORT_XFER_OK, - .callback = &umodem_read_callback, + .callback = &uvscom_read_callback, }, [2] = { @@ -203,7 +280,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = -1, .bufsize = sizeof(usb_device_request_t), - .callback = &umodem_write_clear_stall_callback, + .callback = &uvscom_write_clear_stall_callback, .timeout = 1000, /* 1 second */ }, @@ -212,7 +289,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = -1, .bufsize = sizeof(usb_device_request_t), - .callback = &umodem_read_clear_stall_callback, + .callback = &uvscom_read_clear_stall_callback, .timeout = 1000, /* 1 second */ }, @@ -221,8 +298,8 @@ .endpoint = -1, /* any */ .direction = UE_DIR_IN, .flags = USBD_SHORT_XFER_OK, - .bufsize = XXX, - .callback = &umodem_intr_callback, + .bufsize = UVSCOM_INTR_SIZE, + .callback = &uvscom_intr_callback, }, [5] = { @@ -230,7 +307,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = -1, .bufsize = sizeof(usb_device_request_t), - .callback = &umodem_intr_clear_stall_callback, + .callback = &uvscom_intr_clear_stall_callback, .timeout = 1000, /* 1 second */ }, @@ -269,26 +346,21 @@ .callback = &uvscom_set_line_coding_callback, .timeout = 1000, /* 1 second */ }, - - - - -XXX }; static const struct ucom_callback uvscom_callback = { - .ucom_get_status = &uvscom_get_status, - .ucom_set_dtr = &uvscom_set_dtr, - .ucom_set_rts = &uvscom_set_rts, - .ucom_break = &uvscom_set_break, - .ucom_param = &uvscom_param, - .ucom_ioctl = &uvscom_ioctl, - .ucom_open = &uvscom_open, - .ucom_close = &uvscom_close, - .ucom_start_read = &uvscom_start_read, - .ucom_stop_read = &uvscom_stop_read, - .ucom_start_write = &uvscom_start_write, - .ucom_stop_write = &uvscom_stop_write, + .ucom_get_status = &uvscom_get_status, + .ucom_set_dtr = &uvscom_set_dtr, + .ucom_set_rts = &uvscom_set_rts, + .ucom_set_break = &uvscom_set_break, + .ucom_param = &uvscom_param, + .ucom_ioctl = &uvscom_ioctl, + .ucom_open = &uvscom_open, + .ucom_close = &uvscom_close, + .ucom_start_read = &uvscom_start_read, + .ucom_stop_read = &uvscom_stop_read, + .ucom_start_write = &uvscom_start_write, + .ucom_stop_write = &uvscom_stop_write, }; static const struct usb_devno uvscom_devs [] = { @@ -304,22 +376,17 @@ { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_VS10U }, }; -static device_probe_t uvscom_match; -static device_attach_t uvscom_attach; -static device_detach_t uvscom_detach; - static device_method_t uvscom_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, uvscom_match), - DEVMETHOD(device_attach, uvscom_attach), - DEVMETHOD(device_detach, uvscom_detach), - { 0, 0 } + DEVMETHOD(device_probe, uvscom_probe), + DEVMETHOD(device_attach, uvscom_attach), + DEVMETHOD(device_detach, uvscom_detach), + { 0, 0 } }; static driver_t uvscom_driver = { - "ucom", - uvscom_methods, - sizeof (struct uvscom_softc) + .name = "ucom", + .methods = uvscom_methods, + .size = sizeof (struct uvscom_softc), }; DRIVER_MODULE(uvscom, uhub, uvscom_driver, ucom_devclass, usbd_driver_load, 0); @@ -327,53 +394,7 @@ MODULE_DEPEND(uvscom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER); MODULE_VERSION(uvscom, UVSCOM_MODVER); -static int uvscomobufsiz = UVSCOM_DEFAULT_OPKTSIZE; -static int uvscominterval = UVSCOM_INTR_INTERVAL; - -remove: - static int -sysctl_hw_usb_uvscom_opktsize(SYSCTL_HANDLER_ARGS) -{ - int err, val; - - val = uvscomobufsiz; - err = sysctl_handle_int(oidp, &val, sizeof(val), req); - if (err != 0 || req->newptr == NULL) - return (err); - if (0 < val && val <= UVSCOM_OBUFSIZE) - uvscomobufsiz = val; - else - err = EINVAL; - - return (err); -} - -static int -sysctl_hw_usb_uvscom_interval(SYSCTL_HANDLER_ARGS) -{ - int err, val; - - val = uvscominterval; - err = sysctl_handle_int(oidp, &val, sizeof(val), req); - if (err != 0 || req->newptr == NULL) - return (err); - if (0 < val && val <= 1000) - uvscominterval = val; - else - err = EINVAL; - - return (err); -} - -SYSCTL_PROC(_hw_usb_uvscom, OID_AUTO, opktsize, CTLTYPE_INT | CTLFLAG_RW, - 0, sizeof(int), sysctl_hw_usb_uvscom_opktsize, - "I", "uvscom output packet size"); -SYSCTL_PROC(_hw_usb_uvscom, OID_AUTO, interval, CTLTYPE_INT | CTLFLAG_RW, - 0, sizeof(int), sysctl_hw_usb_uvscom_interval, - "I", "uvscom interrpt pipe interval"); - -static int uvscom_probe(device_t dev) { struct usb_attach_arg *uaa = device_get_ivars(dev); @@ -444,25 +465,25 @@ sc->sc_flag |= UVSCOM_FLAG_WAIT_USB; -isize = UGETW(sc->sc_xfer[->wMaxPacketSize) + + isize = UGETW(sc->sc_xfer[4]->pipe->edesc->wMaxPacketSize); - if (isize > UPLCOM_INTR_SIZE) { + if (isize > UVSCOM_INTR_SIZE) { DPRINTF(0, "cannot handle an interrupt " "packet of %d bytes\n", isize); goto detach; } - /* set transfer length */ - sc->sc_xfer_intr[0]->length = isize; + /* set interrupt transfer length */ + sc->sc_xfer[4]->length = isize; sc->sc_dtr = -1; sc->sc_rts = -1; - sc->sc_break = -1; sc->sc_line_ctrl = UVSCOM_LINE_INIT; - ucom->sc_parent = sc; - ucom->sc_portno = 0; - ucom->sc_callback = &uvscom_callback; + sc->sc_ucom.sc_parent = sc; + sc->sc_ucom.sc_portno = 0; + sc->sc_ucom.sc_callback = &uvscom_callback; error = ucom_attach(&(sc->sc_ucom), dev); @@ -487,21 +508,27 @@ return ENXIO; } -#if 0 +static void +uvscom_detach_complete(struct usbd_memory_info *info) { - UCOM_UNK_PORTNO; - /* bulkin, bulkout set above */ - ucom->sc_ibufsize = UVSCOM_IBUFSIZE; - ucom->sc_obufsize = uvscomobufsiz; - ucom->sc_ibufsizepad = UVSCOM_IBUFSIZE; - ucom->sc_opkthdrlen = 0; - } -#endif + struct uvscom_softc *sc = info->priv_sc; + + mtx_lock(&Giant); + + if (sc->sc_flag & UVSCOM_FLAG_WAIT_USB) { + sc->sc_flag &= ~UVSCOM_FLAG_WAIT_USB; + wakeup(&(sc->sc_wakeup_detach)); + } + + mtx_unlock(&Giant); + + return; +} static int uvscom_detach(device_t dev) { - struct umodem_softc *sc = device_get_softc(dev); + struct uvscom_softc *sc = device_get_softc(dev); int error; DPRINTF(0, "sc=%p\n", sc); @@ -520,7 +547,7 @@ /* wait for callbacks to finish */ - while (sc->sc_flag & UMODEM_FLAG_WAIT_USB) { + while (sc->sc_flag & UVSCOM_FLAG_WAIT_USB) { error = msleep(&(sc->sc_wakeup_detach), &Giant, PRIBIO, "uvscom_sync", 0); @@ -547,10 +574,191 @@ } static void +uvscom_write_callback(struct usbd_xfer *xfer) +{ + struct uvscom_softc *sc = xfer->priv_sc; + u_int32_t actlen; + + USBD_CHECK_STATUS(xfer); + +tr_error: + if (xfer->error != USBD_CANCELLED) { + sc->sc_flag |= UVSCOM_FLAG_WRITE_STALL; + usbd_transfer_start(sc->sc_xfer[2]); + } + return; + +tr_setup: +tr_transferred: + if (sc->sc_flag & UVSCOM_FLAG_WRITE_STALL) { + usbd_transfer_start(sc->sc_xfer[2]); + return; + } + + if(ucom_get_data(&(sc->sc_ucom), xfer->buffer, UVSCOM_OBUFSIZE, &actlen)) { + + xfer->length = actlen; + + usbd_start_hardware(xfer); + } + return; +} + +static void +uvscom_write_clear_stall_callback(struct usbd_xfer *xfer) +{ + struct uvscom_softc *sc = xfer->priv_sc; + + USBD_CHECK_STATUS(xfer); + + tr_setup: + /* start clear stall */ + usbd_clear_stall_tr_setup(xfer, sc->sc_xfer[0]); + return; + + tr_transferred: + usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer[0]); + sc->sc_flag &= ~UVSCOM_FLAG_WRITE_STALL; + usbd_transfer_start(sc->sc_xfer[0]); + return; + + tr_error: + sc->sc_flag &= ~UVSCOM_FLAG_WRITE_STALL; + DPRINTF(0, "clear stall failed, error=%s\n", + usbd_errstr(xfer->error)); + return; +} + +static void +uvscom_read_callback(struct usbd_xfer *xfer) +{ + struct uvscom_softc *sc = xfer->priv_sc; + + USBD_CHECK_STATUS(xfer); + + tr_error: + if (xfer->error != USBD_CANCELLED) { + sc->sc_flag |= UVSCOM_FLAG_READ_STALL; + usbd_transfer_start(sc->sc_xfer[3]); + } + return; + + tr_transferred: + ucom_put_data(&(sc->sc_ucom), xfer->buffer, xfer->actlen); + + tr_setup: + if (sc->sc_flag & UVSCOM_FLAG_READ_STALL) { + usbd_transfer_start(sc->sc_xfer[3]); + } else { + usbd_start_hardware(xfer); + } + return; +} + +static void +uvscom_read_clear_stall_callback(struct usbd_xfer *xfer) +{ + struct uvscom_softc *sc = xfer->priv_sc; + + USBD_CHECK_STATUS(xfer); + + tr_setup: + /* start clear stall */ + usbd_clear_stall_tr_setup(xfer, sc->sc_xfer[1]); + return; + + tr_transferred: + usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer[1]); + sc->sc_flag &= ~UVSCOM_FLAG_READ_STALL; + usbd_transfer_start(sc->sc_xfer[1]); + return; + + tr_error: + sc->sc_flag &= ~UVSCOM_FLAG_READ_STALL; + DPRINTF(0, "clear stall failed, error=%s\n", + usbd_errstr(xfer->error)); + return; +} + +static void +uvscom_intr_callback(struct usbd_xfer *xfer) +{ + struct uvscom_softc *sc = xfer->priv_sc; + u_int8_t *buf = xfer->buffer; + + USBD_CHECK_STATUS(xfer); + + tr_error: + if (xfer->error != USBD_CANCELLED) { + sc->sc_flag |= UVSCOM_FLAG_INTR_STALL; + usbd_transfer_start(sc->sc_xfer[5]); + } + return; + + tr_transferred: + if (xfer->actlen >= 2) { + sc->sc_lsr = 0; + sc->sc_msr = 0; + sc->sc_unit_status = buf[1]; + + if (buf[0] & UVSCOM_TXRDY) { + sc->sc_lsr |= ULSR_TXRDY; + } + if (buf[0] & UVSCOM_RXRDY) { + sc->sc_lsr |= ULSR_RXRDY; + } + if (buf[1] & UVSCOM_CTS) { + sc->sc_msr |= SER_CTS; + } + if (buf[1] & UVSCOM_DSR) { + sc->sc_msr |= SER_DSR; + } + if (buf[1] & UVSCOM_DCD) { + sc->sc_msr |= SER_DCD; + } + + if (sc->sc_flag & UVSCOM_FLAG_OPEN) { + ucom_status_change(&(sc->sc_ucom)); + } + } + tr_setup: + if (sc->sc_flag & UVSCOM_FLAG_INTR_STALL) { + usbd_transfer_start(sc->sc_xfer[5]); + } else { + usbd_start_hardware(xfer); + } + return; +} + +static void +uvscom_intr_clear_stall_callback(struct usbd_xfer *xfer) +{ + struct uvscom_softc *sc = xfer->priv_sc; + + USBD_CHECK_STATUS(xfer); + + tr_setup: + /* start clear stall */ + usbd_clear_stall_tr_setup(xfer, sc->sc_xfer[4]); + return; + + tr_transferred: + usbd_clear_stall_tr_transferred(xfer, sc->sc_xfer[4]); + sc->sc_flag &= ~UVSCOM_FLAG_INTR_STALL; + usbd_transfer_start(sc->sc_xfer[4]); + return; + + tr_error: + sc->sc_flag &= ~UVSCOM_FLAG_INTR_STALL; + DPRINTF(0, "clear stall failed, error=%s\n", + usbd_errstr(xfer->error)); + return; +} + +static void uvscom_read_status_callback(struct usbd_xfer *xfer) { usb_device_request_t *req = xfer->buffer; - struct uvscom_softc *sc = xfer->priv_sc; USBD_CHECK_STATUS(xfer); @@ -570,18 +778,10 @@ return; } -static usbd_status -uvscom_readstat(struct uvscom_softc *sc) -{ - usbd_transfer_start(sc->sc_xfer[6]); - return USBD_NORMAL_COMPLETION; -} - static void uvscom_shutdown_callback(struct usbd_xfer *xfer) { usb_device_request_t *req = xfer->buffer; - struct uvscom_softc *sc = xfer->priv_sc; USBD_CHECK_STATUS(xfer); @@ -602,13 +802,6 @@ } static void -uvscom_shutdown(struct uvscom_softc *sc) -{ - usbd_transfer_start(sc->sc_xfer[7]); - return; -} - -static void uvscom_set_line_callback(struct usbd_xfer *xfer) { usb_device_request_t *req = xfer->buffer; @@ -664,7 +857,7 @@ req->bmRequestType = UT_WRITE_VENDOR_DEVICE; req->bRequest = UVSCOM_SET_PARAM; - USETW(req->wValue, sc->sc_line_parm); + USETW(req->wValue, sc->sc_line_param); USETW(req->wIndex, 0); USETW(req->wLength, 0); usbd_start_hardware(xfer); @@ -674,8 +867,10 @@ } static void -uvscom_set_dtr(struct uvscom_softc *sc, u_int8_t onoff) +uvscom_set_dtr(struct ucom_softc *ucom, u_int8_t onoff) { + struct uvscom_softc *sc = ucom->sc_parent; + DPRINTF(0, "onoff = %d\n", onoff); if (sc->sc_dtr != onoff) { @@ -693,8 +888,10 @@ } static void -uvscom_set_rts(struct uvscom_softc *sc, u_int8_t onoff) +uvscom_set_rts(struct ucom_softc *ucom, u_int8_t onoff) { + struct uvscom_softc *sc = ucom->sc_parent; + DPRINTF(0, "onoff = %d\n", onoff); if (sc->sc_rts != onoff) { @@ -712,8 +909,10 @@ } static void -uvscom_set_break(struct uvscom_softc *sc, u_int8_t onoff) +uvscom_set_break(struct ucom_softc *ucom, u_int8_t onoff) { + struct uvscom_softc *sc = ucom->sc_parent; + DPRINTF(0, "onoff = %d\n", onoff); if (onoff) @@ -771,12 +970,12 @@ return (EIO); } - sc->sc_line_parm = 0; /* reset */ + sc->sc_line_param = 0; /* reset */ - sc->sc_line_parm |= ((t->c_cflag & CSTOPB) ? + sc->sc_line_param |= ((t->c_cflag & CSTOPB) ? UVSCOM_STOP_BIT_2 : UVSCOM_STOP_BIT_1); - sc->sc_line_parm |= ((t->c_cflag & PARENB) ? + sc->sc_line_param |= ((t->c_cflag & PARENB) ? ((t->c_cflag & PARODD) ? UVSCOM_PARITY_ODD : UVSCOM_PARITY_EVEN) : @@ -784,16 +983,16 @@ switch (t->c_cflag & CSIZE) { case CS5: - sc->sc_line_parm |= UVSCOM_DATA_BIT_5; + sc->sc_line_param |= UVSCOM_DATA_BIT_5; break; case CS6: - sc->sc_line_parm |= UVSCOM_DATA_BIT_6; + sc->sc_line_param |= UVSCOM_DATA_BIT_6; break; case CS7: - sc->sc_line_parm |= UVSCOM_DATA_BIT_7; + sc->sc_line_param |= UVSCOM_DATA_BIT_7; break; case CS8: - sc->sc_line_parm |= UVSCOM_DATA_BIT_8; + sc->sc_line_param |= UVSCOM_DATA_BIT_8; break; default: return EIO; @@ -804,143 +1003,73 @@ usbd_transfer_start(sc->sc_xfer[9]); - return; + return 0; } static int uvscom_open(struct ucom_softc *ucom) { struct uvscom_softc *sc = ucom->sc_parent; - int err; - int i; - if (sc->sc_ucom.sc_dying) - return (ENXIO); + DPRINTF(0, "sc = %p\n", sc); - DPRINTF(("uvscom_open: sc = %p\n", sc)); + sc->sc_flag |= UVSCOM_FLAG_OPEN; - /* change output packet size */ - sc->sc_ucom.sc_obufsize = uvscomobufsiz; + /* check if PC card was inserted */ - - sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); - err = usbd_open_pipe_intr(sc->sc_ucom.sc_iface, - sc->sc_intr_number, - USBD_SHORT_XFER_OK, - &sc->sc_intr_pipe, - sc, - sc->sc_intr_buf, - sc->sc_isize, - uvscom_intr, - uvscominterval); - if (err) { - printf("%s: cannot open interrupt pipe (addr %d)\n", - USBDEVNAME(sc->sc_ucom.sc_dev), - sc->sc_intr_number); - return (ENXIO); - } - } else { - DPRINTF(("uvscom_open: did not open interrupt pipe.\n")); + if (sc->sc_unit_status & UVSCOM_NOCARD) { + DPRINTF(0, "no PC card!\n"); + return ENXIO; } - if ((sc->sc_unit_status & UVSCOM_USTAT_MASK) == 0) { - /* unit is not ready */ - - for (i = UVSCOM_UNIT_WAIT; i > 0; --i) { - tsleep(&err, TTIPRI, "uvsop", hz); /* XXX */ - if (ISSET(sc->sc_unit_status, UVSCOM_USTAT_MASK)) - break; - } - if (i == 0) { - DPRINTF(("%s: unit is not ready\n", - USBDEVNAME(sc->sc_ucom.sc_dev))); - return (ENXIO); - } - - /* check PC Card was inserted */ - if (ISSET(sc->sc_unit_status, UVSCOM_NOCARD)) { - DPRINTF(("%s: no card\n", - USBDEVNAME(sc->sc_ucom.sc_dev))); - return (ENXIO); - } - } - - return (0); + return 0; } static void uvscom_close(struct ucom_softc *ucom) { struct uvscom_softc *sc = ucom->sc_parent; - int err; - if (sc->sc_ucom.sc_dying) - return; + DPRINTF(0, "sc=%p\n", sc); - DPRINTF(("uvscom_close: close\n")); + usbd_transfer_start(sc->sc_xfer[7]); - uvscom_shutdown(sc); + sc->sc_flag &= ~UVSCOM_FLAG_OPEN; - if (sc->sc_intr_pipe != NULL) { - err = usbd_abort_pipe(sc->sc_intr_pipe); - if (err) - printf("%s: abort interrupt pipe failed: %s\n", - USBDEVNAME(sc->sc_ucom.sc_dev), - usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_intr_pipe); - if (err) - printf("%s: close interrupt pipe failed: %s\n", - USBDEVNAME(sc->sc_ucom.sc_dev), - usbd_errstr(err)); - free(sc->sc_intr_buf, M_USBDEV); - sc->sc_intr_pipe = NULL; - } + return; } static void -uvscom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +uvscom_start_read(struct ucom_softc *ucom) { - struct uvscom_softc *sc = priv; - u_int8_t *buf = sc->sc_intr_buf; - u_int8_t pstatus; + struct uvscom_softc *sc = ucom->sc_parent; + usbd_transfer_start(sc->sc_xfer[1]); + return; +} - if (sc->sc_ucom.sc_dying) - return; +static void +uvscom_stop_read(struct ucom_softc *ucom) +{ + struct uvscom_softc *sc = ucom->sc_parent; + usbd_transfer_stop(sc->sc_xfer[3]); + usbd_transfer_stop(sc->sc_xfer[1]); + return; +} - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; +static void +uvscom_start_write(struct ucom_softc *ucom) +{ + struct uvscom_softc *sc = ucom->sc_parent; + usbd_transfer_start(sc->sc_xfer[0]); + return; +} - printf("%s: uvscom_intr: abnormal status: %s\n", - USBDEVNAME(sc->sc_ucom.sc_dev), - usbd_errstr(status)); - usbd_clear_endpoint_stall_async(sc->sc_intr_pipe); - return; - } - - DPRINTFN(2, ("%s: uvscom status = %02x %02x\n", - USBDEVNAME(sc->sc_ucom.sc_dev), buf[0], buf[1])); - - sc->sc_lsr = sc->sc_msr = 0; - sc->sc_unit_status = buf[1]; - - pstatus = buf[0]; - if (ISSET(pstatus, UVSCOM_TXRDY)) - SET(sc->sc_lsr, ULSR_TXRDY); - if (ISSET(pstatus, UVSCOM_RXRDY)) - SET(sc->sc_lsr, ULSR_RXRDY); - - pstatus = buf[1]; - if (ISSET(pstatus, UVSCOM_CTS)) - SET(sc->sc_msr, SER_CTS); - if (ISSET(pstatus, UVSCOM_DSR)) - SET(sc->sc_msr, SER_DSR); - if (ISSET(pstatus, UVSCOM_DCD)) - SET(sc->sc_msr, SER_DCD); - - if (sc->sc_flag & UVSCOM_FLAG_OPEN) { - ucom_status_change(&(sc->sc_ucom)); - } +static void +uvscom_stop_write(struct ucom_softc *ucom) +{ + struct uvscom_softc *sc = ucom->sc_parent; + usbd_transfer_stop(sc->sc_xfer[2]); + usbd_transfer_stop(sc->sc_xfer[0]); return; } @@ -949,37 +1078,33 @@ { struct uvscom_softc *sc = ucom->sc_parent; - if (lsr != NULL) - *lsr = sc->sc_lsr; - if (msr != NULL) - *msr = sc->sc_msr; + if (lsr) { + *lsr = sc->sc_lsr; + } + if (msr) { + *msr = sc->sc_msr; + } + return; } -#if 0 /* TODO */ static int -uvscom_ioctl(struct ucom_softc *ucom, u_long cmd, caddr_t data, int flag, - usb_proc_ptr p) +uvscom_ioctl(struct ucom_softc *ucom, u_long cmd, caddr_t data, int fflag, + struct thread *td) { - struct uvscom_softc *sc = ucom->sc_parent; - int error = 0; + int error = ENOTTY; - if (sc->sc_ucom.sc_dying) - return (EIO); - - DPRINTF(("uvscom_ioctl: cmd = 0x%08lx\n", cmd)); + DPRINTF(0, "cmd = 0x%08lx\n", cmd); switch (cmd) { case TIOCNOTTY: case TIOCMGET: case TIOCMSET: - break; + break; default: - DPRINTF(("uvscom_ioctl: unknown\n")); - error = ENOTTY; - break; + DPRINTF(0, "unknown\n"); + error = ENOTTY; + break; } - - return (error); + return error; } -#endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606120653.k5C6rqUC026319>