aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_mass_storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/f_mass_storage.c')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c68
1 files changed, 23 insertions, 45 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 6d8e533949eb..efb58f9f5aa9 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -347,6 +347,7 @@ struct fsg_operations {
347/* Data shared by all the FSG instances. */ 347/* Data shared by all the FSG instances. */
348struct fsg_common { 348struct fsg_common {
349 struct usb_gadget *gadget; 349 struct usb_gadget *gadget;
350 struct usb_composite_dev *cdev;
350 struct fsg_dev *fsg, *new_fsg; 351 struct fsg_dev *fsg, *new_fsg;
351 wait_queue_head_t fsg_wait; 352 wait_queue_head_t fsg_wait;
352 353
@@ -613,6 +614,11 @@ static int fsg_setup(struct usb_function *f,
613 if (!fsg_is_set(fsg->common)) 614 if (!fsg_is_set(fsg->common))
614 return -EOPNOTSUPP; 615 return -EOPNOTSUPP;
615 616
617 ++fsg->common->ep0_req_tag; /* Record arrival of a new request */
618 req->context = NULL;
619 req->length = 0;
620 dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl));
621
616 switch (ctrl->bRequest) { 622 switch (ctrl->bRequest) {
617 623
618 case USB_BULK_RESET_REQUEST: 624 case USB_BULK_RESET_REQUEST:
@@ -1584,37 +1590,6 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
1584 return rc; 1590 return rc;
1585} 1591}
1586 1592
1587static int pad_with_zeros(struct fsg_dev *fsg)
1588{
1589 struct fsg_buffhd *bh = fsg->common->next_buffhd_to_fill;
1590 u32 nkeep = bh->inreq->length;
1591 u32 nsend;
1592 int rc;
1593
1594 bh->state = BUF_STATE_EMPTY; /* For the first iteration */
1595 fsg->common->usb_amount_left = nkeep + fsg->common->residue;
1596 while (fsg->common->usb_amount_left > 0) {
1597
1598 /* Wait for the next buffer to be free */
1599 while (bh->state != BUF_STATE_EMPTY) {
1600 rc = sleep_thread(fsg->common);
1601 if (rc)
1602 return rc;
1603 }
1604
1605 nsend = min(fsg->common->usb_amount_left, FSG_BUFLEN);
1606 memset(bh->buf + nkeep, 0, nsend - nkeep);
1607 bh->inreq->length = nsend;
1608 bh->inreq->zero = 0;
1609 start_transfer(fsg, fsg->bulk_in, bh->inreq,
1610 &bh->inreq_busy, &bh->state);
1611 bh = fsg->common->next_buffhd_to_fill = bh->next;
1612 fsg->common->usb_amount_left -= nsend;
1613 nkeep = 0;
1614 }
1615 return 0;
1616}
1617
1618static int throw_away_data(struct fsg_common *common) 1593static int throw_away_data(struct fsg_common *common)
1619{ 1594{
1620 struct fsg_buffhd *bh; 1595 struct fsg_buffhd *bh;
@@ -1702,6 +1677,10 @@ static int finish_reply(struct fsg_common *common)
1702 if (common->data_size == 0) { 1677 if (common->data_size == 0) {
1703 /* Nothing to send */ 1678 /* Nothing to send */
1704 1679
1680 /* Don't know what to do if common->fsg is NULL */
1681 } else if (!fsg_is_set(common)) {
1682 rc = -EIO;
1683
1705 /* If there's no residue, simply send the last buffer */ 1684 /* If there's no residue, simply send the last buffer */
1706 } else if (common->residue == 0) { 1685 } else if (common->residue == 0) {
1707 bh->inreq->zero = 0; 1686 bh->inreq->zero = 0;
@@ -1710,24 +1689,19 @@ static int finish_reply(struct fsg_common *common)
1710 common->next_buffhd_to_fill = bh->next; 1689 common->next_buffhd_to_fill = bh->next;
1711 1690
1712 /* 1691 /*
1713 * For Bulk-only, if we're allowed to stall then send the 1692 * For Bulk-only, mark the end of the data with a short
1714 * short packet and halt the bulk-in endpoint. If we can't 1693 * packet. If we are allowed to stall, halt the bulk-in
1715 * stall, pad out the remaining data with 0's. 1694 * endpoint. (Note: This violates the Bulk-Only Transport
1695 * specification, which requires us to pad the data if we
1696 * don't halt the endpoint. Presumably nobody will mind.)
1716 */ 1697 */
1717 } else if (common->can_stall) { 1698 } else {
1718 bh->inreq->zero = 1; 1699 bh->inreq->zero = 1;
1719 if (!start_in_transfer(common, bh)) 1700 if (!start_in_transfer(common, bh))
1720 /* Don't know what to do if
1721 * common->fsg is NULL */
1722 rc = -EIO; 1701 rc = -EIO;
1723 common->next_buffhd_to_fill = bh->next; 1702 common->next_buffhd_to_fill = bh->next;
1724 if (common->fsg) 1703 if (common->can_stall)
1725 rc = halt_bulk_in_endpoint(common->fsg); 1704 rc = halt_bulk_in_endpoint(common->fsg);
1726 } else if (fsg_is_set(common)) {
1727 rc = pad_with_zeros(common->fsg);
1728 } else {
1729 /* Don't know what to do if common->fsg is NULL */
1730 rc = -EIO;
1731 } 1705 }
1732 break; 1706 break;
1733 1707
@@ -1910,7 +1884,7 @@ static int check_command(struct fsg_common *common, int cmnd_size,
1910 common->lun, lun); 1884 common->lun, lun);
1911 1885
1912 /* Check the LUN */ 1886 /* Check the LUN */
1913 if (common->lun >= 0 && common->lun < common->nluns) { 1887 if (common->lun < common->nluns) {
1914 curlun = &common->luns[common->lun]; 1888 curlun = &common->luns[common->lun];
1915 common->curlun = curlun; 1889 common->curlun = curlun;
1916 if (common->cmnd[0] != REQUEST_SENSE) { 1890 if (common->cmnd[0] != REQUEST_SENSE) {
@@ -2468,7 +2442,7 @@ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
2468 struct fsg_dev *fsg = fsg_from_func(f); 2442 struct fsg_dev *fsg = fsg_from_func(f);
2469 fsg->common->new_fsg = fsg; 2443 fsg->common->new_fsg = fsg;
2470 raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); 2444 raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
2471 return 0; 2445 return USB_GADGET_DELAYED_STATUS;
2472} 2446}
2473 2447
2474static void fsg_disable(struct usb_function *f) 2448static void fsg_disable(struct usb_function *f)
@@ -2604,6 +2578,8 @@ static void handle_exception(struct fsg_common *common)
2604 2578
2605 case FSG_STATE_CONFIG_CHANGE: 2579 case FSG_STATE_CONFIG_CHANGE:
2606 do_set_interface(common, common->new_fsg); 2580 do_set_interface(common, common->new_fsg);
2581 if (common->new_fsg)
2582 usb_composite_setup_continue(common->cdev);
2607 break; 2583 break;
2608 2584
2609 case FSG_STATE_EXIT: 2585 case FSG_STATE_EXIT:
@@ -2774,6 +2750,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
2774 common->gadget = gadget; 2750 common->gadget = gadget;
2775 common->ep0 = gadget->ep0; 2751 common->ep0 = gadget->ep0;
2776 common->ep0req = cdev->req; 2752 common->ep0req = cdev->req;
2753 common->cdev = cdev;
2777 2754
2778 /* Maybe allocate device-global string IDs, and patch descriptors */ 2755 /* Maybe allocate device-global string IDs, and patch descriptors */
2779 if (fsg_strings[FSG_STRING_INTERFACE].id == 0) { 2756 if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
@@ -2800,6 +2777,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
2800 for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) { 2777 for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) {
2801 curlun->cdrom = !!lcfg->cdrom; 2778 curlun->cdrom = !!lcfg->cdrom;
2802 curlun->ro = lcfg->cdrom || lcfg->ro; 2779 curlun->ro = lcfg->cdrom || lcfg->ro;
2780 curlun->initially_ro = curlun->ro;
2803 curlun->removable = lcfg->removable; 2781 curlun->removable = lcfg->removable;
2804 curlun->dev.release = fsg_lun_release; 2782 curlun->dev.release = fsg_lun_release;
2805 curlun->dev.parent = &gadget->dev; 2783 curlun->dev.parent = &gadget->dev;