Skip to content

Commit

Permalink
usb: gadget: make g_printer enumerate again
Browse files Browse the repository at this point in the history
This was broken in 2e87edf ("usb: gadget: make g_printer use
composite").
The USB-strings were not setup properly and were not used. No function
was added which results in an empty USB config.
While fixing this, the interface number is now auto generated and not
hard coded to 0.

Cc: stable@vger.kernel.org # v3.5
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Sebastian Andrzej Siewior authored and Felipe Balbi committed Sep 10, 2012
1 parent e1f15cc commit 5a175bb
Showing 1 changed file with 65 additions and 63 deletions.
128 changes: 65 additions & 63 deletions drivers/usb/gadget/printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,14 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);
* descriptors are built on demand.
*/

#define STRING_MANUFACTURER 1
#define STRING_PRODUCT 2
#define STRING_SERIALNUM 3
#define STRING_MANUFACTURER 0
#define STRING_PRODUCT 1
#define STRING_SERIALNUM 2

/* holds our biggest descriptor */
#define USB_DESC_BUFSIZE 256
#define USB_BUFSIZE 8192

/* This device advertises one configuration. */
#define DEV_CONFIG_VALUE 1
#define PRINTER_INTERFACE 0

static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
Expand All @@ -159,16 +155,12 @@ static struct usb_device_descriptor device_desc = {
.bDeviceProtocol = 0,
.idVendor = cpu_to_le16(PRINTER_VENDOR_NUM),
.idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.iSerialNumber = STRING_SERIALNUM,
.bNumConfigurations = 1
};

static struct usb_interface_descriptor intf_desc = {
.bLength = sizeof intf_desc,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = PRINTER_INTERFACE,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_PRINTER,
.bInterfaceSubClass = 1, /* Printer Sub-Class */
Expand Down Expand Up @@ -257,9 +249,9 @@ static char pnp_string [1024] =

/* static strings, in UTF-8 */
static struct usb_string strings [] = {
{ STRING_MANUFACTURER, manufacturer, },
{ STRING_PRODUCT, product_desc, },
{ STRING_SERIALNUM, serial_num, },
[STRING_MANUFACTURER].s = manufacturer,
[STRING_PRODUCT].s = product_desc,
[STRING_SERIALNUM].s = serial_num,
{ } /* end of list */
};

Expand Down Expand Up @@ -868,25 +860,13 @@ static int set_interface(struct printer_dev *dev, unsigned number)
int result = 0;

/* Free the current interface */
switch (dev->interface) {
case PRINTER_INTERFACE:
printer_reset_interface(dev);
break;
}
printer_reset_interface(dev);

switch (number) {
case PRINTER_INTERFACE:
result = set_printer_interface(dev);
if (result) {
printer_reset_interface(dev);
} else {
dev->interface = PRINTER_INTERFACE;
}
break;
default:
result = -EINVAL;
/* FALL THROUGH */
}
result = set_printer_interface(dev);
if (result)
printer_reset_interface(dev);
else
dev->interface = number;

if (!result)
INFO(dev, "Using interface %x\n", number);
Expand Down Expand Up @@ -969,7 +949,7 @@ static int printer_func_setup(struct usb_function *f,
switch (ctrl->bRequest) {
case 0: /* Get the IEEE-1284 PNP String */
/* Only one printer interface is supported. */
if ((wIndex>>8) != PRINTER_INTERFACE)
if ((wIndex>>8) != dev->interface)
break;

value = (pnp_string[0]<<8)|pnp_string[1];
Expand All @@ -980,7 +960,7 @@ static int printer_func_setup(struct usb_function *f,

case 1: /* Get Port Status */
/* Only one printer interface is supported. */
if (wIndex != PRINTER_INTERFACE)
if (wIndex != dev->interface)
break;

*(u8 *)req->buf = dev->printer_status;
Expand All @@ -989,7 +969,7 @@ static int printer_func_setup(struct usb_function *f,

case 2: /* Soft Reset */
/* Only one printer interface is supported. */
if (wIndex != PRINTER_INTERFACE)
if (wIndex != dev->interface)
break;

printer_soft_reset(dev);
Expand Down Expand Up @@ -1017,6 +997,37 @@ static int printer_func_setup(struct usb_function *f,
static int __init printer_func_bind(struct usb_configuration *c,
struct usb_function *f)
{
struct printer_dev *dev = container_of(f, struct printer_dev, function);
struct usb_composite_dev *cdev = c->cdev;
struct usb_ep *in_ep, *out_ep;
int id;

id = usb_interface_id(c, f);
if (id < 0)
return id;
intf_desc.bInterfaceNumber = id;

/* all we really need is bulk IN/OUT */
in_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_in_desc);
if (!in_ep) {
autoconf_fail:
dev_err(&cdev->gadget->dev, "can't autoconfigure on %s\n",
cdev->gadget->name);
return -ENODEV;
}
in_ep->driver_data = in_ep; /* claim */

out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc);
if (!out_ep)
goto autoconf_fail;
out_ep->driver_data = out_ep; /* claim */

/* assumes that all endpoints are dual-speed */
hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;

dev->in_ep = in_ep;
dev->out_ep = out_ep;
return 0;
}

Expand All @@ -1032,7 +1043,8 @@ static int printer_func_set_alt(struct usb_function *f,
int ret = -ENOTSUPP;

if (!alt)
ret = set_interface(dev, PRINTER_INTERFACE);
ret = set_interface(dev, intf);

return ret;
}

Expand Down Expand Up @@ -1104,13 +1116,14 @@ static int __init printer_bind_config(struct usb_configuration *c)
{
struct usb_gadget *gadget = c->cdev->gadget;
struct printer_dev *dev;
struct usb_ep *in_ep, *out_ep;
int status = -ENOMEM;
int gcnum;
size_t len;
u32 i;
struct usb_request *req;

usb_ep_autoconfig_reset(gadget);

dev = &usb_printer_gadget;

dev->function.name = shortname;
Expand All @@ -1122,6 +1135,10 @@ static int __init printer_bind_config(struct usb_configuration *c)
dev->function.set_alt = printer_func_set_alt;
dev->function.disable = printer_func_disable;

status = usb_add_function(c, &dev->function);
if (status)
return status;

/* Setup the sysfs files for the printer gadget. */
dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
NULL, "g_printer");
Expand Down Expand Up @@ -1166,26 +1183,6 @@ static int __init printer_bind_config(struct usb_configuration *c)
pnp_string[0] = (len >> 8) & 0xFF;
pnp_string[1] = len & 0xFF;

/* all we really need is bulk IN/OUT */
usb_ep_autoconfig_reset(gadget);
in_ep = usb_ep_autoconfig(gadget, &fs_ep_in_desc);
if (!in_ep) {
autoconf_fail:
dev_err(&gadget->dev, "can't autoconfigure on %s\n",
gadget->name);
return -ENODEV;
}
in_ep->driver_data = in_ep; /* claim */

out_ep = usb_ep_autoconfig(gadget, &fs_ep_out_desc);
if (!out_ep)
goto autoconf_fail;
out_ep->driver_data = out_ep; /* claim */

/* assumes that all endpoints are dual-speed */
hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;

usb_gadget_set_selfpowered(gadget);

if (gadget->is_otg) {
Expand All @@ -1212,9 +1209,6 @@ static int __init printer_bind_config(struct usb_configuration *c)
dev->current_rx_bytes = 0;
dev->current_rx_buf = NULL;

dev->in_ep = in_ep;
dev->out_ep = out_ep;

for (i = 0; i < QLEN; i++) {
req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL);
if (!req) {
Expand Down Expand Up @@ -1247,8 +1241,6 @@ static int __init printer_bind_config(struct usb_configuration *c)
dev->gadget = gadget;

INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, out_ep->name,
in_ep->name);
return 0;

fail:
Expand All @@ -1263,7 +1255,17 @@ static int printer_unbind(struct usb_composite_dev *cdev)

static int __init printer_bind(struct usb_composite_dev *cdev)
{
return usb_add_config(cdev, &printer_cfg_driver, printer_bind_config);
int ret;

ret = usb_string_ids_tab(cdev, strings);
if (ret < 0)
return ret;
device_desc.iManufacturer = strings[STRING_MANUFACTURER].id;
device_desc.iProduct = strings[STRING_PRODUCT].id;
device_desc.iSerialNumber = strings[STRING_SERIALNUM].id;

ret = usb_add_config(cdev, &printer_cfg_driver, printer_bind_config);
return ret;
}

static __refdata struct usb_composite_driver printer_driver = {
Expand Down

0 comments on commit 5a175bb

Please sign in to comment.