From owner-p4-projects@FreeBSD.ORG Sat Feb 28 00:52:01 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9960A1065676; Sat, 28 Feb 2009 00:51:59 +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 6D9D6106564A for ; Sat, 28 Feb 2009 00:51:58 +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 516558FC13 for ; Sat, 28 Feb 2009 00:51:58 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n1S0pv9j091792 for ; Sat, 28 Feb 2009 00:51:57 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n1S0pvQ0091790 for perforce@freebsd.org; Sat, 28 Feb 2009 00:51:57 GMT (envelope-from hselasky@FreeBSD.org) Date: Sat, 28 Feb 2009 00:51:57 GMT Message-Id: <200902280051.n1S0pvQ0091790@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 158418 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: Sat, 28 Feb 2009 00:52:08 -0000 http://perforce.freebsd.org/chv.cgi?CH=158418 Change 158418 by hselasky@hselasky_laptop001 on 2009/02/28 00:51:00 USB NDIS: Fix the last bits and pieces. - mostly fix locking issues - add support for pipe abortion - remove IFF_NEEDSGIANT Affected files ... .. //depot/projects/usb/src/sys/compat/ndis/kern_windrv.c#6 edit .. //depot/projects/usb/src/sys/compat/ndis/subr_usbd.c#7 edit .. //depot/projects/usb/src/sys/compat/ndis/usbd_var.h#4 edit .. //depot/projects/usb/src/sys/dev/if_ndis/if_ndis.c#18 edit .. //depot/projects/usb/src/sys/dev/if_ndis/if_ndis_usb.c#13 edit .. //depot/projects/usb/src/sys/dev/if_ndis/if_ndisvar.h#9 edit .. //depot/projects/usb/src/sys/dev/usb/usb_hub.h#2 edit Differences ... ==== //depot/projects/usb/src/sys/compat/ndis/kern_windrv.c#6 (text+ko) ==== @@ -56,6 +56,9 @@ #include #endif +#include +#include + #include #include #include @@ -431,6 +434,9 @@ STAILQ_INSERT_HEAD(&drvdb_head, new, link); mtx_unlock(&drvdb_mtx); + /* Make sure all driver-less USB devices get explored again! */ + usb2_needs_explore_all(); + return (0); } ==== //depot/projects/usb/src/sys/compat/ndis/subr_usbd.c#7 (text+ko) ==== @@ -96,10 +96,11 @@ static int32_t usbd_func_getdesc(irp *ip); static usb2_error_t usbd_get_desc_ndis(struct usb2_device *udev, struct mtx *mtx, uint16_t id, uint16_t maxlen, uint8_t type, uint8_t index, uint8_t retries, void *desc, uint16_t *actlen); static int32_t usbd_func_selconf(irp *ip); +static int32_t usbd_func_pipe_abort(irp *ip); static int32_t usbd_func_vendorclass(irp *ip); static void usbd_irpcancel(device_object *dobj, irp *ip); static int32_t ndis_setup_endpoint(struct ndis_softc *sc, uint8_t iface_index, struct usb2_endpoint_descriptor *edesc, uint32_t bufsize); -static void ndis_xfer_complete(struct ndisusb_ep *nuep, int32_t status); +static void ndis_xfer_complete(struct ndis_softc *sc, struct ndisusb_ep *nuep, int32_t status); static int32_t usbd_func_bulkintr(irp *ip); static union usbd_urb *USBD_CreateConfigurationRequest(struct usb2_config_descriptor *conf, uint16_t *len); static union usbd_urb *USBD_CreateConfigurationRequestEx(struct usb2_config_descriptor *conf, struct usbd_interface_list_entry *list); @@ -415,6 +416,10 @@ status = usbd_func_selconf(ip); USBD_URB_STATUS(urb) = status; break; + case URB_FUNCTION_ABORT_PIPE: + status = usbd_func_pipe_abort(ip); + USBD_URB_STATUS(urb) = status; + break; case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: status = usbd_func_getdesc(ip); USBD_URB_STATUS(urb) = status; @@ -425,7 +430,6 @@ USBD_URB_STATUS(urb) = status = USBD_STATUS_NOT_SUPPORTED; break; } - return (status); } @@ -469,7 +473,7 @@ /* Success */ status = USB_ERR_NORMAL_COMPLETION; } else { - status = usbd_get_desc_ndis(sc->ndisusb_dev, &sc->ndis_mtx, + status = usbd_get_desc_ndis(sc->ndisusb_dev, NULL, ctldesc->ucd_langid, ctldesc->ucd_trans_buflen, ctldesc->ucd_desctype, ctldesc->ucd_idx, 3, ctldesc->ucd_trans_buf, &actlen); @@ -532,13 +536,9 @@ intf = &selconf->usc_intf; for (i = 0; i < conf->bNumInterface && intf->uii_len > 0; i++) { - mtx_unlock(&sc->ndis_mtx); - err = usb2_set_alt_interface_index(sc->ndisusb_dev, intf->uii_intfnum, intf->uii_altset); - mtx_lock(&sc->ndis_mtx); - if (err != USB_ERR_NORMAL_COMPLETION) { device_printf(dev, "setting alternate interface failed: %s\n", @@ -585,6 +585,47 @@ } static int32_t +usbd_func_pipe_abort(irp *ip) +{ + device_t dev = IRP_NDIS_DEV(ip); + struct ndis_softc *sc; + struct usb2_endpoint_descriptor *edesc; + struct usbd_urb_pipe_abort *upa; + struct usbd_urb_bulk_or_intr_transfer *ubi; + union usbd_urb *urb; + static struct ndisusb_ep *nuep; + + sc = device_get_softc(dev); + urb = usbd_geturb(ip); + + upa = &urb->uu_pipe_abort; + edesc = upa->upa_handle; + if (edesc == NULL) { + device_printf(dev, "pipe handle is NULL\n"); + return USBD_STATUS_REQUEST_FAILED; + } + + nuep = usbd_get_ndisusb_ep(sc, edesc->bEndpointAddress); + if (nuep == NULL) { + device_printf(dev, "endpoint does not exist\n"); + return USBD_STATUS_REQUEST_FAILED; + } + + NDIS_LOCK(sc); + + usb2_transfer_stop(nuep->urb_xfer[0]); + + while ((ubi = usbd_first_ubi(nuep))) { + ndis_xfer_complete(sc, nuep, USBD_STATUS_CANCELED); + } + + usb2_transfer_start(nuep->urb_xfer[0]); + + NDIS_UNLOCK(sc); + return USBD_STATUS_SUCCESS; +} + +static int32_t usbd_func_vendorclass(irp *ip) { device_t dev = IRP_NDIS_DEV(ip); @@ -639,7 +680,7 @@ USETW(req.wLength, vcreq->uvc_trans_buflen); err = usb2_do_request(sc->ndisusb_dev, - &sc->ndis_mtx, &req, vcreq->uvc_trans_buf); + NULL, &req, vcreq->uvc_trans_buf); return usbd_usb2urb(err); } @@ -647,13 +688,23 @@ static void usbd_irpcancel(device_object *dobj, irp *ip) { + device_t dev = IRP_NDIS_DEV(ip); + struct ndis_softc *sc = device_get_softc(dev); struct ndisusb_ep *nuep; union usbd_urb *urb; struct usbd_urb_bulk_or_intr_transfer *ubi; + struct usbd_urb_bulk_or_intr_transfer *ubi_first; + + /* XXX we have a LOR here ! --hps */ + IoReleaseCancelSpinLock(ip->irp_cancelirql); + NDIS_LOCK(sc); + IoAcquireCancelSpinLock(&ip->irp_cancelirql); + if (IRP_NDISUSB_EP(ip) == NULL) { ip->irp_cancel = TRUE; IoReleaseCancelSpinLock(ip->irp_cancelirql); + NDIS_UNLOCK(sc); return; } @@ -663,13 +714,14 @@ urb = usbd_geturb(ip); ubi = &urb->uu_bulkintr; + /* get current UBI */ + ubi_first = usbd_first_ubi(nuep); + /* remove UBI from queue */ usbd_remove_ubi(nuep, ubi); /* check if the currently executing transfer is being cancelled */ - if (nuep->irp_curr == ip) { - nuep->irp_curr = NULL; - + if (ubi == ubi_first) { /* * Make sure that the current USB transfer proxy is * cancelled and then restarted. @@ -680,6 +732,7 @@ ip->irp_cancel = TRUE; IoReleaseCancelSpinLock(ip->irp_cancelirql); + NDIS_UNLOCK(sc); } static int32_t @@ -718,13 +771,9 @@ cfg[0].mh.flags.proxy_buffer = 1; cfg[0].mh.flags.short_xfer_ok = 1; - mtx_unlock(&sc->ndis_mtx); - err = usb2_transfer_setup(sc->ndisusb_dev, &iface_index, nuep->urb_xfer, cfg, 1, sc, &sc->ndis_mtx); - mtx_lock(&sc->ndis_mtx); - if (err) return (usbd_usb2urb(err)); @@ -760,14 +809,19 @@ } static void -ndis_xfer_complete(struct ndisusb_ep *nuep, int32_t status) +ndis_xfer_complete(struct ndis_softc *sc, struct ndisusb_ep *nuep, int32_t status) { - irp *ip = nuep->irp_curr; + irp *ip; struct usbd_urb_bulk_or_intr_transfer *ubi; union usbd_urb *urb; + ubi = usbd_first_ubi(nuep); + if (ubi == NULL) + return; /* cancelled */ + + ip = ubi->ubi_hca.reserved8[2]; if (ip == NULL) - return; /* cancelled */ + return; /* cancelled */ if (status != USBD_STATUS_SUCCESS) nuep->urb_actlen = 0; @@ -790,7 +844,11 @@ ip->irp_iostat.isb_status = usbd_urb2nt(USBD_URB_STATUS(urb)); + NDIS_UNLOCK(sc); + IoCompleteRequest(ip, IO_NO_INCREMENT); + + NDIS_LOCK(sc); } /*------------------------------------------------------------------------* @@ -810,6 +868,7 @@ switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: + if (nuep->urb_rx_data) { /* copy in data with regard to the URB */ usb2_copy_out(xfer->frbuffers, 0, @@ -825,15 +884,15 @@ nuep->urb_len = 0; /* check if short transfer is ok */ if (nuep->urb_short_flag) - ndis_xfer_complete(nuep, USBD_STATUS_ERROR_SHORT_TRANSFER); + ndis_xfer_complete(sc, nuep, USBD_STATUS_ERROR_SHORT_TRANSFER); else - ndis_xfer_complete(nuep, USBD_STATUS_SUCCESS); + ndis_xfer_complete(sc, nuep, USBD_STATUS_SUCCESS); } else { /* check remainder */ if (nuep->urb_len > 0) goto setup_bulk; - ndis_xfer_complete(nuep, USBD_STATUS_SUCCESS); + ndis_xfer_complete(sc, nuep, USBD_STATUS_SUCCESS); } case USB_ST_SETUP: @@ -851,6 +910,10 @@ nuep->urb_len = ubi->ubi_trans_buflen; nuep->urb_data = ubi->ubi_trans_buf; nuep->urb_actlen = 0; + if (ubi->ubi_trans_flags & USBD_SHORT_TRANSFER_OK) + nuep->urb_short_flag = 0; + else + nuep->urb_short_flag = 1; setup_bulk: if (max_bulk > nuep->urb_len) @@ -874,12 +937,11 @@ break; default: - ndis_xfer_complete(nuep, usbd_usb2urb(xfer->error)); - if (xfer->error != USB_ERR_CANCELLED) { xfer->flags.stall_pipe = 1; device_printf(sc->ndis_dev, "USB error (%s)\n", usb2_errstr(xfer->error)); + ndis_xfer_complete(sc, nuep, usbd_usb2urb(xfer->error)); goto tr_setup; } break; @@ -916,6 +978,8 @@ return (USBD_STATUS_REQUEST_FAILED); } + NDIS_LOCK(sc); + /* final UBI transfer setup */ IoAcquireCancelSpinLock(&ip->irp_cancelirql); @@ -931,9 +995,14 @@ /* enqueue the URB */ usbd_enqueue_ubi(nuep, ubi); + /* store reference to IRP */ + ubi->ubi_hca.reserved8[2] = ip; + /* start USB transfer, if any */ usb2_transfer_start(nuep->urb_xfer[0]); + NDIS_UNLOCK(sc); + /* return pending status code */ return (USBD_STATUS_PENDING); } @@ -1095,4 +1164,4 @@ { NULL, NULL, NULL } }; -MODULE_DEPEND(ndis, usb2_core, 1, 1, 1); +MODULE_DEPEND(ndis, usb, 1, 1, 1); ==== //depot/projects/usb/src/sys/compat/ndis/usbd_var.h#4 (text+ko) ==== @@ -44,7 +44,9 @@ #define IOCTL_INTERNAL_USB_SUBMIT_URB 0x00220003 #define URB_FUNCTION_SELECT_CONFIGURATION 0x0000 +#define URB_FUNCTION_ABORT_PIPE 0x0002 #define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER 0x0009 +#define URB_FUNCTION_ISOCH_TRANSFER 0x000A #define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 0x000B #define URB_FUNCTION_VENDOR_DEVICE 0x0017 #define URB_FUNCTION_VENDOR_INTERFACE 0x0018 @@ -136,6 +138,12 @@ struct usbd_interface_information usc_intf; }; +struct usbd_urb_pipe_abort { + struct usbd_urb_header upa_hdr; + struct usb2_endpoint_descriptor *upa_handle; + uint32_t upa_reserved; +}; + struct usbd_hcd_area { void *reserved8[8]; }; @@ -192,10 +200,11 @@ union usbd_urb { struct usbd_urb_header uu_hdr; - struct usbd_urb_select_configuration uu_selconf; - struct usbd_urb_bulk_or_intr_transfer uu_bulkintr; - struct usbd_urb_control_descriptor_request uu_ctldesc; - struct usbd_urb_vendor_or_class_request uu_vcreq; + struct usbd_urb_select_configuration uu_selconf; + struct usbd_urb_pipe_abort uu_pipe_abort; + struct usbd_urb_bulk_or_intr_transfer uu_bulkintr; + struct usbd_urb_control_descriptor_request uu_ctldesc; + struct usbd_urb_vendor_or_class_request uu_vcreq; }; #define USBD_URB_STATUS(urb) ((urb)->uu_hdr.uuh_status) ==== //depot/projects/usb/src/sys/dev/if_ndis/if_ndis.c#18 (text+ko) ==== @@ -713,8 +713,6 @@ if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - if (sc->ndis_iftype == PNPBus) - ifp->if_flags |= IFF_NEEDSGIANT; ifp->if_ioctl = ndis_ioctl; ifp->if_start = ndis_start; ifp->if_init = ndis_init; ==== //depot/projects/usb/src/sys/dev/if_ndis/if_ndis_usb.c#13 (text+ko) ==== @@ -69,7 +69,6 @@ MODULE_DEPEND(ndis, usb, 1, 1, 1); MODULE_DEPEND(ndis, ndisapi, 1, 1, 1); -MODULE_DEPEND(ndis, if_ndis, 1, 1, 1); static device_probe_t ndisusb_probe; static device_attach_t ndisusb_attach; ==== //depot/projects/usb/src/sys/dev/if_ndis/if_ndisvar.h#9 (text+ko) ==== @@ -123,7 +123,6 @@ struct ndisusb_ep { struct usbd_urb_bulk_or_intr_transfer *ubi_first; struct usbd_urb_bulk_or_intr_transfer **ubi_last; - irp *irp_curr; struct usb2_xfer *urb_xfer[1]; uint8_t *urb_data; uint32_t urb_len; ==== //depot/projects/usb/src/sys/dev/usb/usb_hub.h#2 (text+ko) ==== @@ -27,6 +27,11 @@ #ifndef _USB2_HUB_H_ #define _USB2_HUB_H_ +#include + +struct usb2_bus; +struct usb2_device; + /* * The following structure defines an USB port. */