From owner-p4-projects@FreeBSD.ORG Sun Dec 30 13:51:15 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7861216A469; Sun, 30 Dec 2007 13:51:15 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3B63416A417 for ; Sun, 30 Dec 2007 13:51:15 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 2975213C459 for ; Sun, 30 Dec 2007 13:51:15 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id lBUDpE8F072474 for ; Sun, 30 Dec 2007 13:51:14 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id lBUDpExO072471 for perforce@freebsd.org; Sun, 30 Dec 2007 13:51:14 GMT (envelope-from hselasky@FreeBSD.org) Date: Sun, 30 Dec 2007 13:51:14 GMT Message-Id: <200712301351.lBUDpExO072471@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 132094 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Dec 2007 13:51:15 -0000 http://perforce.freebsd.org/chv.cgi?CH=132094 Change 132094 by hselasky@hselasky_laptop001 on 2007/12/30 13:50:55 Getting the uchcom probe and attach routines right. Some code borrowed from uplcom. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/uchcom.c#4 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/uchcom.c#4 (text+ko) ==== @@ -147,26 +147,23 @@ #define UCHCOM_INTR_STAT2 0x03 #define UCHCOM_INTR_LEAST 4 -#define UCHCOMIBUFSIZE 256 -#define UCHCOMOBUFSIZE 256 +#define UCHCOM_BULK_BUF_SIZE 1024 /* bytes */ +#define UCHCOM_N_TRANSFER 6 /* units */ + +struct uchcom_softc { + struct ucom_super_softc sc_super_ucom; + struct ucom_softc sc_ucom; -struct uchcom_softc -{ - struct ucom_softc sc_ucom; + struct usbd_xfer *sc_xfer[UCHCOM_N_TRANSFER]; + struct usbd_device *sc_udev; - /* */ - int sc_intr_endpoint; - int sc_intr_size; - usbd_pipe_handle sc_intr_pipe; - u_char *sc_intr_buf; - /* */ - uint8_t sc_version; - int sc_dtr; - int sc_rts; - u_char sc_lsr; - u_char sc_msr; - int sc_lcr1; - int sc_lcr2; + uint8_t sc_version; + uint8_t sc_msr; + uint8_t sc_lsr; /* local status register */ + uint8_t sc_flag; +#define UCHCOM_FLAG_INTR_STALL 0x01 +#define UCHCOM_FLAG_READ_STALL 0x02 +#define UCHCOM_FLAG_WRITE_STALL 0x04 }; struct uchcom_endpoints @@ -213,19 +210,78 @@ static int uchcom_param(void *, int, struct termios *); static int uchcom_open(void *, int); static void uchcom_close(void *, int); -static void uchcom_intr(usbd_xfer_handle, usbd_private_handle, - usbd_status); - -static int uchcom_set_config(device_t ); -static int uchcom_find_ifaces(struct uchcom_softc *, usbd_interface_handle *); -static int uchcom_find_endpoints(struct uchcom_softc *, - struct uchcom_endpoints *); -static void uchcom_close_intr_pipe(struct uchcom_softc *); static device_probe_t uchcom_probe; static device_attach_t uchcom_attach; static device_detach_t uchcom_detach; +static usbd_callback_t uchcom_intr_callback; +static usbd_callback_t uchcom_intr_clear_stall_callback; +static usbd_callback_t uchcom_write_callback; +static usbd_callback_t uchcom_write_clear_stall_callback; +static usbd_callback_t uchcom_read_callback; +static usbd_callback_t uchcom_read_clear_stall_callback; + +static const struct usbd_config uchcom_config_data[UCHCOM_N_TRANSFER] = { + + [0] = { + .type = UE_BULK, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_OUT, + .bufsize = UCHCOM_BULK_BUF_SIZE, + .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,}, + .mh.callback = &uchcom_write_callback, + }, + + [1] = { + .type = UE_BULK, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_IN, + .bufsize = UCHCOM_BULK_BUF_SIZE, + .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, + .mh.callback = &uchcom_read_callback, + }, + + [2] = { + .type = UE_CONTROL, + .endpoint = 0x00, /* Control pipe */ + .direction = UE_DIR_ANY, + .bufsize = sizeof(usb_device_request_t), + .mh.callback = &uchcom_write_clear_stall_callback, + .mh.timeout = 1000, /* 1 second */ + .interval = 50, /* 50ms */ + }, + + [3] = { + .type = UE_CONTROL, + .endpoint = 0x00, /* Control pipe */ + .direction = UE_DIR_ANY, + .bufsize = sizeof(usb_device_request_t), + .mh.callback = &uchcom_read_clear_stall_callback, + .mh.timeout = 1000, /* 1 second */ + .interval = 50, /* 50ms */ + }, + + [4] = { + .type = UE_INTERRUPT, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_IN, + .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, + .bufsize = 0, /* use wMaxPacketSize */ + .mh.callback = &uchcom_intr_callback, + }, + + [5] = { + .type = UE_CONTROL, + .endpoint = 0x00, /* Control pipe */ + .direction = UE_DIR_ANY, + .bufsize = sizeof(usb_device_request_t), + .mh.callback = &uchcom_intr_clear_stall_callback, + .mh.timeout = 1000, /* 1 second */ + .interval = 50, /* 50ms */ + }, +}; + struct ucom_callback uchcom_callback = { .ucom_get_status = uchcom_get_status, .ucom_set = uchcom_set, @@ -238,190 +294,106 @@ }; - - /* ---------------------------------------------------------------------- * driver entry points */ -static int uchcom_probe(device_t self) +static int +uchcom_probe(device_t dev) { - struct usb_attach_arg *uaa = device_get_ivars(self); + struct usb_attach_arg *uaa = device_get_ivars(dev); + + DPRINTF(10, "\n"); + + if (uaa->usb_mode != USB_MODE_HOST) { + return (UMATCH_NONE); + } + + if (uaa->iface) { + return (UMATCH_NONE); + } return (uchcom_lookup(uaa->vendor, uaa->product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE); } -static int uchcom_attach(device_t self) +static int +uchcom_attach(device_t dev) { - struct uchcom_softc *sc = device_get_softc(self); - struct usb_attach_arg *uaa = device_get_ivars(self); - usbd_device_handle dev = uaa->device; + struct uchcom_softc *sc = device_get_softc(dev); + struct usb_attach_arg *uaa = device_get_ivars(dev); + int error; + uint8_t iface_index; + + DPRINTF(10, "\n"); - struct uchcom_endpoints endpoints; - struct ucom_softc *ucom = &sc->sc_ucom; + if (sc == NULL) { + return (ENOMEM); + } + usbd_set_device_desc(dev); - ucom->sc_dev = self; - ucom->sc_udev = dev; + sc->sc_udev = uaa->device; - ucom->sc_dying = 0; - sc->sc_dtr = sc->sc_rts = -1; - sc->sc_lsr = sc->sc_msr = 0; + /* configure the chip */ - DPRINTF(("\n\nuchcom attach: sc=%p\n", sc)); + error = usbd_set_config_index(uaa->device, UCHCOM_CONFIG_INDEX, 1); - if (uchcom_set_config(self)) - goto failed; + if (error) { + device_printf(dev, "failed to set configuration, " + "error=%s\n", usbd_errstr(error)); + goto detach; + } switch (uaa->release) { case UCHCOM_REV_CH340: - device_printf(self, "CH340 detected\n"); + device_printf(dev, "CH340 detected\n"); break; default: - device_printf(self, "CH341 detected\n"); + device_printf(dev, "CH341 detected\n"); break; } - if (uchcom_find_ifaces(sc, &ucom->sc_iface)) - goto failed; + iface_index = UCHCOM_IFACE_INDEX; + error = usbd_transfer_setup(uaa->device, + &iface_index, sc->sc_xfer, uchcom_config_data, + UCHCOM_N_TRANSFER, sc, &Giant); - if (uchcom_find_endpoints(sc, &endpoints)) - goto failed; + if (error) { + DPRINTF(0, "one or more missing USB endpoints, " + "error=%s\n", usbd_errstr(error)); + goto detach; + } - sc->sc_intr_endpoint = endpoints.ep_intr; - sc->sc_intr_size = endpoints.ep_intr_size; + /* clear stall at first run */ + sc->sc_flag |= (UCHCOM_FLAG_READ_STALL | + UCHCOM_FLAG_WRITE_STALL); - /* setup ucom layer */ - ucom->sc_portno = UCOM_UNK_PORTNO; - ucom->sc_bulkin_no = endpoints.ep_bulkin; - ucom->sc_bulkout_no = endpoints.ep_bulkout; - ucom->sc_ibufsize = UCHCOMIBUFSIZE; - ucom->sc_obufsize = UCHCOMOBUFSIZE; - ucom->sc_ibufsizepad = UCHCOMIBUFSIZE; - ucom->sc_opkthdrlen = 0; - ucom->sc_parent = sc; - - ucom->sc_callback = &uchcom_callback; - - ucom_attach(&sc->sc_ucom); - + error = ucom_attach(&(sc->sc_super_ucom), &(sc->sc_ucom), 1, sc, + &uchcom_callback, &Giant); + if (error) { + goto detach; + } return 0; -failed: - ucom->sc_dying = 1; - return ENXIO; +detach: + uchcom_detach(dev); + return (ENXIO); } -static int uchcom_detach(device_t self) -{ - struct uchcom_softc *sc = device_get_softc(self); - struct ucom_softc *ucom = &sc->sc_ucom ; - int rv = 0; - - DPRINTF(("uchcom_detach: sc=%p flags=%d\n", sc, flags)); - - uchcom_close_intr_pipe(sc); - - ucom->sc_dying = 1; - - rv = ucom_detach(ucom); - - return rv; -} static int -uchcom_set_config(device_t dev) +uchcom_detach(device_t dev) { struct uchcom_softc *sc = device_get_softc(dev); - struct ucom_softc *ucom = &sc->sc_ucom; - usbd_status err; - - err = usbd_set_config_index(ucom->sc_udev, UCHCOM_CONFIG_INDEX, 1); - if (err) { - device_printf(dev, "failed to set configuration: %s\n", - usbd_errstr(err)); - return -1; - } - return 0; -} + DPRINTF(10, "\n"); -static int -uchcom_find_ifaces(struct uchcom_softc *sc, usbd_interface_handle *riface) -{ - usbd_status err; - struct ucom_softc *ucom = &sc->sc_ucom; + ucom_detach(&(sc->sc_super_ucom), &(sc->sc_ucom), 1); - err = usbd_device2interface_handle(ucom->sc_udev, UCHCOM_IFACE_INDEX, - riface); - if (err) { - device_printf(ucom->sc_dev, "failed to get interface: %s\n", - usbd_errstr(err)); - return -1; - } + usbd_transfer_unsetup(sc->sc_xfer, UCHCOM_N_TRANSFER); - return 0; -} - -static int -uchcom_find_endpoints(struct uchcom_softc *sc, struct uchcom_endpoints *endpoints) -{ - struct ucom_softc *ucom= &sc->sc_ucom; - int i, bin=-1, bout=-1, intr=-1, isize=0; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - - id = usbd_get_interface_descriptor(ucom->sc_iface); - - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i); - if (ed == NULL) { - device_printf(ucom->sc_dev, "no endpoint descriptor for %d\n", i); - return -1; - } - - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { - intr = ed->bEndpointAddress; - isize = UGETW(ed->wMaxPacketSize); - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - bin = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - bout = ed->bEndpointAddress; - } - } - - if (intr == -1 || bin == -1 || bout == -1) { - if (intr == -1) { - device_printf(ucom->sc_dev, "no interrupt end point\n"); - } - if (bin == -1) { - device_printf(ucom->sc_dev, "no data bulk in end point\n"); - - } - if (bout == -1) { - device_printf(ucom->sc_dev, "no data bulk out end point\n"); - } - return -1; - } - if (isize < UCHCOM_INTR_LEAST) { - device_printf(ucom->sc_dev, "intr pipe is too short"); - return -1; - } - - DPRINTF(("%s: bulkin=%d, bulkout=%d, intr=%d, isize=%d\n", - USBDEVNAME(sc->sc_dev), bin, bout, intr, isize)); - - endpoints->ep_intr = intr; - endpoints->ep_intr_size = isize; - endpoints->ep_bulkin = bin; - endpoints->ep_bulkout = bout; - - return 0; + return (0); } - /* ---------------------------------------------------------------------- * low level i/o */