summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2011-07-20 17:08:28 -0700
committerNitin Garg <nitin.garg@freescale.com>2011-12-15 18:24:43 -0600
commit4bd95322c76015dabb6442950f1a10c80912586b (patch)
treef340dd3e8225f4ac0cb80d00494c230da4a0d8a4
parent24647c785cfbf34f746427a00d0ab425ba050924 (diff)
USB: gadget: f_mtp: Move all setup handling to mtp_ctrlrequest
The composite driver no longer sends setup requests to functions if the destination is USB_RECIP_DEVICE, so we need to handle the requests here instead of the function's setup callback. Signed-off-by: Mike Lockwood <lockwood@android.com>
-rw-r--r--drivers/usb/gadget/f_mtp.c148
1 files changed, 56 insertions, 92 deletions
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 4199b1766e5b..7dc5f49262f6 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -982,10 +982,12 @@ static struct miscdevice mtp_device = {
static int mtp_ctrlrequest(struct usb_composite_dev *cdev,
const struct usb_ctrlrequest *ctrl)
{
+ struct mtp_dev *dev = _mtp_dev;
int value = -EOPNOTSUPP;
u16 w_index = le16_to_cpu(ctrl->wIndex);
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);
+ unsigned long flags;
VDBG(cdev, "mtp_ctrlrequest "
"%02x.%02x v%04x i%04x l%u\n",
@@ -1001,7 +1003,61 @@ static int mtp_ctrlrequest(struct usb_composite_dev *cdev,
value = (w_length < sizeof(mtp_os_string)
? w_length : sizeof(mtp_os_string));
memcpy(cdev->req->buf, mtp_os_string, value);
+ } else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) {
+ /* Handle MTP OS descriptor */
+ DBG(cdev, "vendor request: %d index: %d value: %d length: %d\n",
+ ctrl->bRequest, w_index, w_value, w_length);
+
+ if (ctrl->bRequest == 1
+ && (ctrl->bRequestType & USB_DIR_IN)
+ && (w_index == 4 || w_index == 5)) {
+ value = (w_length < sizeof(mtp_ext_config_desc) ?
+ w_length : sizeof(mtp_ext_config_desc));
+ memcpy(cdev->req->buf, &mtp_ext_config_desc, value);
+ }
+ } else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) {
+ DBG(cdev, "class request: %d index: %d value: %d length: %d\n",
+ ctrl->bRequest, w_index, w_value, w_length);
+
+ if (ctrl->bRequest == MTP_REQ_CANCEL && w_index == 0
+ && w_value == 0) {
+ DBG(cdev, "MTP_REQ_CANCEL\n");
+
+ spin_lock_irqsave(&dev->lock, flags);
+ if (dev->state == STATE_BUSY) {
+ dev->state = STATE_CANCELED;
+ wake_up(&dev->read_wq);
+ wake_up(&dev->write_wq);
+ }
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ /* We need to queue a request to read the remaining
+ * bytes, but we don't actually need to look at
+ * the contents.
+ */
+ value = w_length;
+ } else if (ctrl->bRequest == MTP_REQ_GET_DEVICE_STATUS
+ && w_index == 0 && w_value == 0) {
+ struct mtp_device_status *status = cdev->req->buf;
+ status->wLength =
+ __constant_cpu_to_le16(sizeof(*status));
+
+ DBG(cdev, "MTP_REQ_GET_DEVICE_STATUS\n");
+ spin_lock_irqsave(&dev->lock, flags);
+ /* device status is "busy" until we report
+ * the cancelation to userspace
+ */
+ if (dev->state == STATE_CANCELED)
+ status->wCode =
+ __cpu_to_le16(MTP_RESPONSE_DEVICE_BUSY);
+ else
+ status->wCode =
+ __cpu_to_le16(MTP_RESPONSE_OK);
+ spin_unlock_irqrestore(&dev->lock, flags);
+ value = sizeof(*status);
+ }
}
+
/* respond with data transfer or status phase? */
if (value >= 0) {
int rc;
@@ -1067,97 +1123,6 @@ mtp_function_unbind(struct usb_configuration *c, struct usb_function *f)
dev->state = STATE_OFFLINE;
}
-static int mtp_function_setup(struct usb_function *f,
- const struct usb_ctrlrequest *ctrl)
-{
- struct mtp_dev *dev = func_to_mtp(f);
- struct usb_composite_dev *cdev = dev->cdev;
- int value = -EOPNOTSUPP;
- u16 w_index = le16_to_cpu(ctrl->wIndex);
- u16 w_value = le16_to_cpu(ctrl->wValue);
- u16 w_length = le16_to_cpu(ctrl->wLength);
- unsigned long flags;
-
- VDBG(cdev, "mtp_function_setup "
- "%02x.%02x v%04x i%04x l%u\n",
- ctrl->bRequestType, ctrl->bRequest,
- w_value, w_index, w_length);
-
- if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) {
- /* Handle MTP OS descriptor */
- DBG(cdev, "vendor request: %d index: %d value: %d length: %d\n",
- ctrl->bRequest, w_index, w_value, w_length);
-
- if (ctrl->bRequest == 1
- && (ctrl->bRequestType & USB_DIR_IN)
- && (w_index == 4 || w_index == 5)) {
- value = (w_length < sizeof(mtp_ext_config_desc) ?
- w_length : sizeof(mtp_ext_config_desc));
- memcpy(cdev->req->buf, &mtp_ext_config_desc, value);
- }
- }
- if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) {
- DBG(cdev, "class request: %d index: %d value: %d length: %d\n",
- ctrl->bRequest, w_index, w_value, w_length);
-
- if (ctrl->bRequest == MTP_REQ_CANCEL && w_index == 0
- && w_value == 0) {
- DBG(cdev, "MTP_REQ_CANCEL\n");
-
- spin_lock_irqsave(&dev->lock, flags);
- if (dev->state == STATE_BUSY) {
- dev->state = STATE_CANCELED;
- wake_up(&dev->read_wq);
- wake_up(&dev->write_wq);
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- /* We need to queue a request to read the remaining
- * bytes, but we don't actually need to look at
- * the contents.
- */
- value = w_length;
- } else if (ctrl->bRequest == MTP_REQ_GET_DEVICE_STATUS
- && w_index == 0 && w_value == 0) {
- struct mtp_device_status *status = cdev->req->buf;
- status->wLength =
- __constant_cpu_to_le16(sizeof(*status));
-
- DBG(cdev, "MTP_REQ_GET_DEVICE_STATUS\n");
- spin_lock_irqsave(&dev->lock, flags);
- /* device status is "busy" until we report
- * the cancelation to userspace
- */
- if (dev->state == STATE_CANCELED)
- status->wCode =
- __cpu_to_le16(MTP_RESPONSE_DEVICE_BUSY);
- else
- status->wCode =
- __cpu_to_le16(MTP_RESPONSE_OK);
- spin_unlock_irqrestore(&dev->lock, flags);
- value = sizeof(*status);
- }
- }
-
- /* respond with data transfer or status phase? */
- if (value >= 0) {
- int rc;
- cdev->req->zero = value < w_length;
- cdev->req->length = value;
- rc = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC);
- if (rc < 0)
- ERROR(cdev, "%s setup response queue error\n", __func__);
- }
-
- if (value == -EOPNOTSUPP)
- VDBG(cdev,
- "unknown class-specific control req "
- "%02x.%02x v%04x i%04x l%u\n",
- ctrl->bRequestType, ctrl->bRequest,
- w_value, w_index, w_length);
- return value;
-}
-
static int mtp_function_set_alt(struct usb_function *f,
unsigned intf, unsigned alt)
{
@@ -1238,7 +1203,6 @@ static int mtp_bind_config(struct usb_configuration *c, bool ptp_config)
}
dev->function.bind = mtp_function_bind;
dev->function.unbind = mtp_function_unbind;
- dev->function.setup = mtp_function_setup;
dev->function.set_alt = mtp_function_set_alt;
dev->function.disable = mtp_function_disable;