Exemplo n.º 1
0
/**
 *  @brief Sets the configuration values
 *
 *  @param intf		Pointer to usb_interface
 *  @param id		Pointer to usb_device_id
 *
 *  @return 	   	Address of variable usb_cardp, error code otherwise
 */
static int
woal_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
    struct usb_device *udev;
    struct usb_host_interface *iface_desc;
    struct usb_endpoint_descriptor *endpoint;
    int i;
    struct usb_card_rec *usb_cardp = NULL;

    ENTER();

    udev = interface_to_usbdev(intf);
    usb_cardp = kmalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
    memset((t_u8 *) usb_cardp, 0, sizeof(struct usb_card_rec));
    if (!usb_cardp) {
        LEAVE();
        return (-ENOMEM);
    }

    udev->descriptor.idVendor = woal_cpu_to_le16(udev->descriptor.idVendor);
    udev->descriptor.idProduct = woal_cpu_to_le16(udev->descriptor.idProduct);
    udev->descriptor.bcdDevice = woal_cpu_to_le16(udev->descriptor.bcdDevice);
    udev->descriptor.bcdUSB = woal_cpu_to_le16(udev->descriptor.bcdUSB);

    /* Check probe is for our device */
    for (i = 0; woal_usb_table[i].idVendor; i++) {
        if (udev->descriptor.idVendor == woal_usb_table[i].idVendor &&
            udev->descriptor.idProduct == woal_usb_table[i].idProduct) {
            PRINTM(MMSG, "VID/PID = %X/%X, Boot2 version = %X\n",
                   udev->descriptor.idVendor, udev->descriptor.idProduct,
                   udev->descriptor.bcdDevice);
            break;
        }
    }

    if (woal_usb_table[i].idVendor) {
        usb_cardp->udev = udev;
        iface_desc = intf->cur_altsetting;
        usb_cardp->intf = intf;

        PRINTM(MINFO, "bcdUSB = 0x%X bDeviceClass = 0x%X"
               " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
               udev->descriptor.bcdUSB,
               udev->descriptor.bDeviceClass,
               udev->descriptor.bDeviceSubClass,
               udev->descriptor.bDeviceProtocol);

        for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
            endpoint = &iface_desc->endpoint[i].desc;
            if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) &&
                ((endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) ==
                 MLAN_USB_EP_CMD_EVENT) &&
                ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                 USB_ENDPOINT_XFER_BULK)) {
                /* We found a bulk in command/event endpoint */
                PRINTM(MINFO, "Bulk IN: max packet size = %d, address = %d\n",
                       woal_le16_to_cpu(endpoint->wMaxPacketSize),
                       endpoint->bEndpointAddress);
                usb_cardp->rx_cmd_ep =
                    (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
                atomic_set(&usb_cardp->rx_cmd_urb_pending, 0);
            }
            if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) &&
                ((endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) ==
                 MLAN_USB_EP_DATA) &&
                ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                 USB_ENDPOINT_XFER_BULK)) {
                /* We found a bulk in data endpoint */
                PRINTM(MINFO, "Bulk IN: max packet size = %d, address = %d\n",
                       woal_le16_to_cpu(endpoint->wMaxPacketSize),
                       endpoint->bEndpointAddress);
                usb_cardp->rx_data_ep =
                    (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
                atomic_set(&usb_cardp->rx_data_urb_pending, 0);
            }
            if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
                 USB_DIR_OUT) &&
                ((endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) ==
                 MLAN_USB_EP_DATA) &&
                ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                 USB_ENDPOINT_XFER_BULK)) {
                /* We found a bulk out data endpoint */
                PRINTM(MINFO, "Bulk OUT: max packet size = %d, address = %d\n",
                       woal_le16_to_cpu(endpoint->wMaxPacketSize),
                       endpoint->bEndpointAddress);
                usb_cardp->tx_data_ep = endpoint->bEndpointAddress;
                atomic_set(&usb_cardp->tx_data_urb_pending, 0);
            }
            if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
                 USB_DIR_OUT) &&
                ((endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) ==
                 MLAN_USB_EP_CMD_EVENT) &&
                ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                 USB_ENDPOINT_XFER_BULK)) {
                /* We found a bulk out command/event endpoint */
                PRINTM(MINFO, "Bulk OUT: max packet size = %d, address = %d\n",
                       woal_le16_to_cpu(endpoint->wMaxPacketSize),
                       endpoint->bEndpointAddress);
                usb_cardp->tx_cmd_ep = endpoint->bEndpointAddress;
                atomic_set(&usb_cardp->tx_cmd_urb_pending, 0);
                usb_cardp->bulk_out_maxpktsize =
                    woal_le16_to_cpu(endpoint->wMaxPacketSize);
            }
        }
        usb_set_intfdata(intf, usb_cardp);
        /* At this point wlan_add_card() will be called */
        if (!(woal_add_card(usb_cardp))) {
            PRINTM(MERROR, "%s: woal_add_callback failed\n", __FUNCTION__);
            goto error;
        }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
        /* Note: From 2.6.34.2 onwards, remote wakeup is NOT enabled by
           default. So drivers wanting remote wakeup will have to enable this
           using - device_set_wakeup_enable(&udev->dev, 1); It has been
           observed that some cards having device attr = 0xa0 do not support
           remote wakeup. These cards come immediately out of the suspend when 
           power/wakeup file is set to 'enabled'. To support all types of cards 
           i.e. with/without remote wakeup, we are NOT setting the
           'power/wakeup' file from here. Also in principle, we are not
           supposed to change the wakeup policy, which is purely a userspace
           decision. */
        // if (udev->actconfig->desc.bmAttributes & USB_CONFIG_ATT_WAKEUP)
        // intf->needs_remote_wakeup = 1;
#endif
        usb_get_dev(udev);
        LEAVE();
        return 0;
    } else {
        PRINTM(MINFO, "Discard the Probe request\n");
        PRINTM(MINFO, "VID = 0x%X PID = 0x%X\n", udev->descriptor.idVendor,
               udev->descriptor.idProduct);
    }
  error:
    usb_reset_device(udev);
    kfree(usb_cardp);
    usb_cardp = NULL;
    LEAVE();
    return (-ENOMEM);
}
Exemplo n.º 2
0
/**
 *  @brief Sets the configuration values
 *
 *  @param intf		Pointer to usb_interface
 *  @param id		Pointer to usb_device_id
 *
 *  @return 	   	Address of variable usb_cardp
 */
static int
woal_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
    struct usb_device *udev;
    struct usb_host_interface *iface_desc;
    struct usb_endpoint_descriptor *endpoint;
    int i;
    struct usb_card_rec *usb_cardp = NULL;

    ENTER();

    udev = interface_to_usbdev(intf);
    usb_cardp = kzalloc(sizeof(struct usb_card_rec), GFP_ATOMIC);
    if (!usb_cardp) {
        LEAVE();
        return (-ENOMEM);
    }

    udev->descriptor.idVendor = woal_cpu_to_le16(udev->descriptor.idVendor);
    udev->descriptor.idProduct = woal_cpu_to_le16(udev->descriptor.idProduct);
    udev->descriptor.bcdDevice = woal_cpu_to_le16(udev->descriptor.bcdDevice);
    udev->descriptor.bcdUSB = woal_cpu_to_le16(udev->descriptor.bcdUSB);

    /* Check probe is for our device */
    for (i = 0; woal_usb_table[i].idVendor; i++) {
        if (udev->descriptor.idVendor == woal_usb_table[i].idVendor &&
            udev->descriptor.idProduct == woal_usb_table[i].idProduct) {
            PRINTM(MSG, "VID/PID = %X/%X, Boot2 version = %X\n",
                   udev->descriptor.idVendor, udev->descriptor.idProduct,
                   udev->descriptor.bcdDevice);
            break;
        }
    }

    if (woal_usb_table[i].idVendor) {
        usb_cardp->udev = udev;
        iface_desc = intf->cur_altsetting;

        PRINTM(INFO, "bcdUSB = 0x%X bDeviceClass = 0x%X"
               " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
               udev->descriptor.bcdUSB,
               udev->descriptor.bDeviceClass,
               udev->descriptor.bDeviceSubClass,
               udev->descriptor.bDeviceProtocol);

        for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
            endpoint = &iface_desc->endpoint[i].desc;
            if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) &&
                ((endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) ==
                 MLAN_USB_EP_CMD_EVENT) &&
                ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                 USB_ENDPOINT_XFER_BULK)) {
                /* We found a bulk in command/event endpoint */
                PRINTM(INFO, "Bulk IN: max packet size = %d, address = %d\n",
                       woal_le16_to_cpu(endpoint->wMaxPacketSize),
                       endpoint->bEndpointAddress);
                usb_cardp->rx_cmd_ep =
                    (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
                atomic_set(&usb_cardp->rx_cmd_urb_pending, 0);
            }
            if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) &&
                ((endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) ==
                 MLAN_USB_EP_DATA) &&
                ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                 USB_ENDPOINT_XFER_BULK)) {
                /* We found a bulk in data endpoint */
                PRINTM(INFO, "Bulk IN: max packet size = %d, address = %d\n",
                       woal_le16_to_cpu(endpoint->wMaxPacketSize),
                       endpoint->bEndpointAddress);
                usb_cardp->rx_data_ep =
                    (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
                atomic_set(&usb_cardp->rx_data_urb_pending, 0);
                usb_cardp->rx_urb_recall = MFALSE;

            }
            if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
                 USB_DIR_OUT) &&
                ((endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) ==
                 MLAN_USB_EP_DATA) &&
                ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                 USB_ENDPOINT_XFER_BULK)) {
                /* We found a bulk out data endpoint */
                PRINTM(INFO, "Bulk OUT: max packet size = %d, address = %d\n",
                       woal_le16_to_cpu(endpoint->wMaxPacketSize),
                       endpoint->bEndpointAddress);
                usb_cardp->tx_data_ep = endpoint->bEndpointAddress;
                atomic_set(&usb_cardp->tx_data_urb_pending, 0);

            }
            if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
                 USB_DIR_OUT) &&
                ((endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) ==
                 MLAN_USB_EP_CMD_EVENT) &&
                ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                 USB_ENDPOINT_XFER_BULK)) {
                /* We found a bulk out command/event endpoint */
                PRINTM(INFO, "Bulk OUT: max packet size = %d, address = %d\n",
                       woal_le16_to_cpu(endpoint->wMaxPacketSize),
                       endpoint->bEndpointAddress);
                usb_cardp->tx_cmd_ep = endpoint->bEndpointAddress;
                atomic_set(&usb_cardp->tx_cmd_urb_pending, 0);
                usb_cardp->bulk_out_maxpktsize =
                    woal_le16_to_cpu(endpoint->wMaxPacketSize);
            }
        }
        /* At this point wlan_add_card() will be called */
        if (!(woal_add_card(usb_cardp))) {
            PRINTM(ERROR, "%s: woal_add_callback failed\n", __FUNCTION__);
            goto error;
        }
        usb_get_dev(udev);
        usb_set_intfdata(intf, usb_cardp);
        LEAVE();
        return 0;
    } else {
        PRINTM(INFO, "Discard the Probe request\n");
        PRINTM(INFO, "VID = 0x%X PID = 0x%X\n", udev->descriptor.idVendor,
               udev->descriptor.idProduct);
    }
  error:
    usb_reset_device(udev);
    woal_usb_free(usb_cardp);
    kfree(usb_cardp);
    usb_cardp = NULL;
    LEAVE();
    return (-ENOMEM);
}