The following reply was made to PR usb/138563; it has been noted by GNATS.

From: [email protected] (dfilter service)
To: [email protected]
Cc:  
Subject: Re: usb/138563: commit references a PR
Date: Mon, 28 Sep 2009 07:41:31 +0000 (UTC)

 Author: thompsa
 Date: Mon Sep 28 07:41:17 2009
 New Revision: 197559
 URL: http://svn.freebsd.org/changeset/base/197559
 
 Log:
   Add support for USB language selection.
   
   PR:          usb/138563
   Reported by: Bruce Cran
   Submitted by:        Hans Petter Selasky
 
 Modified:
   head/sys/dev/usb/usb_bus.h
   head/sys/dev/usb/usb_device.c
 
 Modified: head/sys/dev/usb/usb_bus.h
 ==============================================================================
 --- head/sys/dev/usb/usb_bus.h Mon Sep 28 07:39:51 2009        (r197558)
 +++ head/sys/dev/usb/usb_bus.h Mon Sep 28 07:41:17 2009        (r197559)
 @@ -98,10 +98,14 @@ struct usb_bus {
        uint8_t devices_max;            /* maximum number of USB devices */
        uint8_t do_probe;               /* set if USB BUS should be re-probed */
  
 +      /* 
 +       * The scratch area can only be used inside the explore thread
 +       * belonging to the give serial bus.
 +       */
        union {
                struct usb_hw_ep_scratch hw_ep_scratch[1];
                struct usb_temp_setup temp_setup[1];
 -              uint8_t data[128];
 +              uint8_t data[255];
        }       scratch[1];
  };
  
 
 Modified: head/sys/dev/usb/usb_device.c
 ==============================================================================
 --- head/sys/dev/usb/usb_device.c      Mon Sep 28 07:39:51 2009        
(r197558)
 +++ head/sys/dev/usb/usb_device.c      Mon Sep 28 07:41:17 2009        
(r197559)
 @@ -105,9 +105,23 @@ static void       usb_cdev_cleanup(void *);
  
  int   usb_template = 0;
  
 +TUNABLE_INT("hw.usb.usb_template", &usb_template);
  SYSCTL_INT(_hw_usb, OID_AUTO, template, CTLFLAG_RW,
      &usb_template, 0, "Selected USB device side template");
  
 +/* English is default language */
 +
 +static int usb_lang_id = 0x0009;
 +static int usb_lang_mask = 0x00FF;
 +
 +TUNABLE_INT("hw.usb.usb_lang_id", &usb_lang_id);
 +SYSCTL_INT(_hw_usb, OID_AUTO, usb_lang_id, CTLFLAG_RW,
 +    &usb_lang_id, 0, "Preferred USB language ID");
 +
 +TUNABLE_INT("hw.usb.usb_lang_mask", &usb_lang_mask);
 +SYSCTL_INT(_hw_usb, OID_AUTO, usb_lang_mask, CTLFLAG_RW,
 +    &usb_lang_mask, 0, "Preferred USB language mask");
 +
  static const char* statestr[USB_STATE_MAX] = {
        [USB_STATE_DETACHED]    = "DETACHED",
        [USB_STATE_ATTACHED]    = "ATTACHED",
 @@ -1436,7 +1450,7 @@ usb_alloc_device(device_t parent_dev, st
        struct usb_device *adev;
        struct usb_device *hub;
        uint8_t *scratch_ptr;
 -      uint32_t scratch_size;
 +      size_t scratch_size;
        usb_error_t err;
        uint8_t device_index;
  
 @@ -1682,8 +1696,35 @@ usb_alloc_device(device_t parent_dev, st
        if (err || (scratch_ptr[0] < 4)) {
                udev->flags.no_strings = 1;
        } else {
 -              /* pick the first language as the default */
 -              udev->langid = UGETW(scratch_ptr + 2);
 +              uint16_t langid;
 +              uint16_t pref;
 +              uint16_t mask;
 +              uint8_t x;
 +
 +              /* load preferred value and mask */
 +              pref = usb_lang_id;
 +              mask = usb_lang_mask;
 +
 +              /* align length correctly */
 +              scratch_ptr[0] &= ~1;
 +
 +              /* fix compiler warning */
 +              langid = 0;
 +
 +              /* search for preferred language */
 +              for (x = 2; (x < scratch_ptr[0]); x += 2) {
 +                      langid = UGETW(scratch_ptr + x);
 +                      if ((langid & mask) == pref)
 +                              break;
 +              }
 +              if (x >= scratch_ptr[0]) {
 +                      /* pick the first language as the default */
 +                      DPRINTFN(1, "Using first language\n");
 +                      langid = UGETW(scratch_ptr + 2);
 +              }
 +
 +              DPRINTFN(1, "Language selected: 0x%04x\n", langid);
 +              udev->langid = langid;
        }
  
        /* assume 100mA bus powered for now. Changed when configured. */
 @@ -2149,34 +2190,35 @@ usbd_set_device_strings(struct usb_devic
  #ifdef USB_VERBOSE
        const struct usb_knowndev *kdp;
  #endif
 -      char temp[64];
 +      uint8_t *temp_ptr;
 +      size_t temp_size;
        uint16_t vendor_id;
        uint16_t product_id;
  
 +      temp_ptr = udev->bus->scratch[0].data;
 +      temp_size = sizeof(udev->bus->scratch[0].data);
 +
        vendor_id = UGETW(udd->idVendor);
        product_id = UGETW(udd->idProduct);
  
        /* get serial number string */
 -      bzero(temp, sizeof(temp));
 -      usbd_req_get_string_any(udev, NULL, temp, sizeof(temp),
 +      usbd_req_get_string_any(udev, NULL, temp_ptr, temp_size,
            udev->ddesc.iSerialNumber);
 -      udev->serial = strdup(temp, M_USB);
 +      udev->serial = strdup(temp_ptr, M_USB);
  
        /* get manufacturer string */
 -      bzero(temp, sizeof(temp));
 -      usbd_req_get_string_any(udev, NULL, temp, sizeof(temp),
 +      usbd_req_get_string_any(udev, NULL, temp_ptr, temp_size,
            udev->ddesc.iManufacturer);
 -      usb_trim_spaces(temp);
 -      if (temp[0] != '\0')
 -              udev->manufacturer = strdup(temp, M_USB);
 +      usb_trim_spaces(temp_ptr);
 +      if (temp_ptr[0] != '\0')
 +              udev->manufacturer = strdup(temp_ptr, M_USB);
  
        /* get product string */
 -      bzero(temp, sizeof(temp));
 -      usbd_req_get_string_any(udev, NULL, temp, sizeof(temp),
 +      usbd_req_get_string_any(udev, NULL, temp_ptr, temp_size,
            udev->ddesc.iProduct);
 -      usb_trim_spaces(temp);
 -      if (temp[0] != '\0')
 -              udev->product = strdup(temp, M_USB);
 +      usb_trim_spaces(temp_ptr);
 +      if (temp_ptr[0] != '\0')
 +              udev->product = strdup(temp_ptr, M_USB);
  
  #ifdef USB_VERBOSE
        if (udev->manufacturer == NULL || udev->product == NULL) {
 @@ -2202,12 +2244,12 @@ usbd_set_device_strings(struct usb_devic
  #endif
        /* Provide default strings if none were found */
        if (udev->manufacturer == NULL) {
 -              snprintf(temp, sizeof(temp), "vendor 0x%04x", vendor_id);
 -              udev->manufacturer = strdup(temp, M_USB);
 +              snprintf(temp_ptr, temp_size, "vendor 0x%04x", vendor_id);
 +              udev->manufacturer = strdup(temp_ptr, M_USB);
        }
        if (udev->product == NULL) {
 -              snprintf(temp, sizeof(temp), "product 0x%04x", product_id);
 -              udev->product = strdup(temp, M_USB);
 +              snprintf(temp_ptr, temp_size, "product 0x%04x", product_id);
 +              udev->product = strdup(temp_ptr, M_USB);
        }
  }
  
 _______________________________________________
 [email protected] mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "[email protected]"
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[email protected]"

Reply via email to