]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/meta-ti-glsdk.git/blob - recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.1/0041-usb-fix-number-of-mapped-SG-DMA-entries.patch
linux-ti33x-psp 3.2: update to 3.2.5
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.2 / 3.2.1 / 0041-usb-fix-number-of-mapped-SG-DMA-entries.patch
1 From 61ff4bd883cde399d333204fe9878e90b6f87329 Mon Sep 17 00:00:00 2001
2 From: Clemens Ladisch <clemens@ladisch.de>
3 Date: Sat, 3 Dec 2011 23:41:31 +0100
4 Subject: [PATCH 41/49] usb: fix number of mapped SG DMA entries
6 commit bc677d5b64644c399cd3db6a905453e611f402ab upstream.
8 Add a new field num_mapped_sgs to struct urb so that we have a place to
9 store the number of mapped entries and can also retain the original
10 value of entries in num_sgs.  Previously, usb_hcd_map_urb_for_dma()
11 would overwrite this with the number of mapped entries, which would
12 break dma_unmap_sg() because it requires the original number of entries.
14 This fixes warnings like the following when using USB storage devices:
15  ------------[ cut here ]------------
16  WARNING: at lib/dma-debug.c:902 check_unmap+0x4e4/0x695()
17  ehci_hcd 0000:00:12.2: DMA-API: device driver frees DMA sg list with different entry count [map count=4] [unmap count=1]
18  Modules linked in: ohci_hcd ehci_hcd
19  Pid: 0, comm: kworker/0:1 Not tainted 3.2.0-rc2+ #319
20  Call Trace:
21   <IRQ>  [<ffffffff81036d3b>] warn_slowpath_common+0x80/0x98
22   [<ffffffff81036de7>] warn_slowpath_fmt+0x41/0x43
23   [<ffffffff811fa5ae>] check_unmap+0x4e4/0x695
24   [<ffffffff8105e92c>] ? trace_hardirqs_off+0xd/0xf
25   [<ffffffff8147208b>] ? _raw_spin_unlock_irqrestore+0x33/0x50
26   [<ffffffff811fa84a>] debug_dma_unmap_sg+0xeb/0x117
27   [<ffffffff8137b02f>] usb_hcd_unmap_urb_for_dma+0x71/0x188
28   [<ffffffff8137b166>] unmap_urb_for_dma+0x20/0x22
29   [<ffffffff8137b1c5>] usb_hcd_giveback_urb+0x5d/0xc0
30   [<ffffffffa0000d02>] ehci_urb_done+0xf7/0x10c [ehci_hcd]
31   [<ffffffffa0001140>] qh_completions+0x429/0x4bd [ehci_hcd]
32   [<ffffffffa000340a>] ehci_work+0x95/0x9c0 [ehci_hcd]
33   ...
34  ---[ end trace f29ac88a5a48c580 ]---
35  Mapped at:
36   [<ffffffff811faac4>] debug_dma_map_sg+0x45/0x139
37   [<ffffffff8137bc0b>] usb_hcd_map_urb_for_dma+0x22e/0x478
38   [<ffffffff8137c494>] usb_hcd_submit_urb+0x63f/0x6fa
39   [<ffffffff8137d01c>] usb_submit_urb+0x2c7/0x2de
40   [<ffffffff8137dcd4>] usb_sg_wait+0x55/0x161
42 Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
43 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
44 ---
45  drivers/usb/core/hcd.c       |    5 ++---
46  drivers/usb/host/ehci-q.c    |    2 +-
47  drivers/usb/host/uhci-q.c    |    2 +-
48  drivers/usb/host/whci/qset.c |    4 ++--
49  drivers/usb/host/xhci-ring.c |    4 ++--
50  include/linux/usb.h          |    1 +
51  6 files changed, 9 insertions(+), 9 deletions(-)
53 diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
54 index 13222d3..179e364 100644
55 --- a/drivers/usb/core/hcd.c
56 +++ b/drivers/usb/core/hcd.c
57 @@ -1412,11 +1412,10 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
58                                         ret = -EAGAIN;
59                                 else
60                                         urb->transfer_flags |= URB_DMA_MAP_SG;
61 -                               if (n != urb->num_sgs) {
62 -                                       urb->num_sgs = n;
63 +                               urb->num_mapped_sgs = n;
64 +                               if (n != urb->num_sgs)
65                                         urb->transfer_flags |=
66                                                         URB_DMA_SG_COMBINED;
67 -                               }
68                         } else if (urb->sg) {
69                                 struct scatterlist *sg = urb->sg;
70                                 urb->transfer_dma = dma_map_page(
71 diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
72 index 4e4066c..fef1db3 100644
73 --- a/drivers/usb/host/ehci-q.c
74 +++ b/drivers/usb/host/ehci-q.c
75 @@ -647,7 +647,7 @@ qh_urb_transaction (
76         /*
77          * data transfer stage:  buffer setup
78          */
79 -       i = urb->num_sgs;
80 +       i = urb->num_mapped_sgs;
81         if (len > 0 && i > 0) {
82                 sg = urb->sg;
83                 buf = sg_dma_address(sg);
84 diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
85 index f6ca80e..d2c6f5a 100644
86 --- a/drivers/usb/host/uhci-q.c
87 +++ b/drivers/usb/host/uhci-q.c
88 @@ -943,7 +943,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
89         if (usb_pipein(urb->pipe))
90                 status |= TD_CTRL_SPD;
91  
92 -       i = urb->num_sgs;
93 +       i = urb->num_mapped_sgs;
94         if (len > 0 && i > 0) {
95                 sg = urb->sg;
96                 data = sg_dma_address(sg);
97 diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
98 index a403b53..76083ae 100644
99 --- a/drivers/usb/host/whci/qset.c
100 +++ b/drivers/usb/host/whci/qset.c
101 @@ -443,7 +443,7 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
102  
103         remaining = urb->transfer_buffer_length;
104  
105 -       for_each_sg(urb->sg, sg, urb->num_sgs, i) {
106 +       for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) {
107                 dma_addr_t dma_addr;
108                 size_t dma_remaining;
109                 dma_addr_t sp, ep;
110 @@ -561,7 +561,7 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset,
111  
112         remaining = urb->transfer_buffer_length;
113  
114 -       for_each_sg(urb->sg, sg, urb->num_sgs, i) {
115 +       for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) {
116                 size_t len;
117                 size_t sg_remaining;
118                 void *orig;
119 diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
120 index 9f1d4b1..d28c586 100644
121 --- a/drivers/usb/host/xhci-ring.c
122 +++ b/drivers/usb/host/xhci-ring.c
123 @@ -2561,7 +2561,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb)
124         struct scatterlist *sg;
125  
126         sg = NULL;
127 -       num_sgs = urb->num_sgs;
128 +       num_sgs = urb->num_mapped_sgs;
129         temp = urb->transfer_buffer_length;
130  
131         xhci_dbg(xhci, "count sg list trbs: \n");
132 @@ -2745,7 +2745,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
133                 return -EINVAL;
134  
135         num_trbs = count_sg_trbs_needed(xhci, urb);
136 -       num_sgs = urb->num_sgs;
137 +       num_sgs = urb->num_mapped_sgs;
138         total_packet_count = roundup(urb->transfer_buffer_length,
139                         usb_endpoint_maxp(&urb->ep->desc));
140  
141 diff --git a/include/linux/usb.h b/include/linux/usb.h
142 index 1cea207..7626e5a 100644
143 --- a/include/linux/usb.h
144 +++ b/include/linux/usb.h
145 @@ -1222,6 +1222,7 @@ struct urb {
146         void *transfer_buffer;          /* (in) associated data buffer */
147         dma_addr_t transfer_dma;        /* (in) dma addr for transfer_buffer */
148         struct scatterlist *sg;         /* (in) scatter gather buffer list */
149 +       int num_mapped_sgs;             /* (internal) mapped sg entries */
150         int num_sgs;                    /* (in) number of entries in the sg list */
151         u32 transfer_buffer_length;     /* (in) data buffer length */
152         u32 actual_length;              /* (return) actual transfer length */
153 -- 
154 1.7.7.4