|
@@ -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);
|