summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2015-03-03 09:52:25 (GMT)
committerFelipe Balbi <balbi@ti.com>2015-03-10 20:33:39 (GMT)
commit636bc0ed271d996e18365345e9c00fc712edc610 (patch)
treee1f3e81a0266dbb7de5b1643674211c1b465de17 /drivers/usb/gadget
parentd7239f4c6daeb7a987a0e6f37a3ea24b37f7c208 (diff)
downloadlinux-636bc0ed271d996e18365345e9c00fc712edc610.tar.xz
usb: gadget: printer: add req_match for printer function
Verify that a given usb_ctrlrequest is meant for printer function. The following parts of the request are tested: - bmRequestType:Data transfer direction - bmRequestType:Type - bmRequestType:Recipient - bRequest - wValue for bRequest 1 and 2 - wLength Additionally, the request is considered meant for this function iff the decoded interface number matches dev->interface. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/legacy/printer.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c
index 78f5154..c059af1 100644
--- a/drivers/usb/gadget/legacy/printer.c
+++ b/drivers/usb/gadget/legacy/printer.c
@@ -974,6 +974,41 @@ static void printer_soft_reset(struct printer_dev *dev)
/*-------------------------------------------------------------------------*/
+static bool gprinter_req_match(struct usb_function *f,
+ const struct usb_ctrlrequest *ctrl)
+{
+ struct printer_dev *dev = func_to_printer(f);
+ u16 w_index = le16_to_cpu(ctrl->wIndex);
+ u16 w_value = le16_to_cpu(ctrl->wValue);
+ u16 w_length = le16_to_cpu(ctrl->wLength);
+
+ if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE ||
+ (ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS)
+ return false;
+
+ switch (ctrl->bRequest) {
+ case GET_DEVICE_ID:
+ w_index >>= 8;
+ if (w_length <= PNP_STRING_LEN &&
+ (USB_DIR_IN & ctrl->bRequestType))
+ break;
+ return false;
+ case GET_PORT_STATUS:
+ if (!w_value && w_length == 1 &&
+ (USB_DIR_IN & ctrl->bRequestType))
+ break;
+ return false;
+ case SOFT_RESET:
+ if (!w_value && !w_length &&
+ (USB_DIR_OUT & ctrl->bRequestType))
+ break;
+ /* fall through */
+ default:
+ return false;
+ }
+ return w_index == dev->interface;
+}
+
/*
* The setup() callback implements all the ep0 functionality that's not
* handled lower down.
@@ -1251,6 +1286,7 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str,
dev->function.unbind = printer_func_unbind;
dev->function.set_alt = printer_func_set_alt;
dev->function.disable = printer_func_disable;
+ dev->function.req_match = gprinter_req_match;
INIT_LIST_HEAD(&dev->tx_reqs);
INIT_LIST_HEAD(&dev->rx_reqs);
INIT_LIST_HEAD(&dev->rx_buffers);