Subversion Repositories shark

Rev

Rev 846 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1049 mauro 1
/*
2
 * Copyright (c) 2001 by David Brownell
3
 *
4
 * This program is free software; you can redistribute it and/or modify it
5
 * under the terms of the GNU General Public License as published by the
6
 * Free Software Foundation; either version 2 of the License, or (at your
7
 * option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful, but
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 * for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
 */
18
 
19
/* this file is part of ehci-hcd.c */
20
 
21
/*-------------------------------------------------------------------------*/
22
 
23
/*
24
 * There's basically three types of memory:
25
 *      - data used only by the HCD ... kmalloc is fine
26
 *      - async and periodic schedules, shared by HC and HCD ... these
27
 *        need to use pci_pool or pci_alloc_consistent_usb
28
 *      - driver buffers, read/written by HC ... single shot DMA mapped
29
 *
30
 * There's also PCI "register" data, which is memory mapped.
31
 * No memory seen by this driver is pagable.
32
 */
33
 
34
/*-------------------------------------------------------------------------*/
35
/*
36
 * Allocator / cleanup for the per device structure
37
 * Called by hcd init / removal code
38
 */
39
static struct usb_hcd *ehci_hcd_alloc (void)
40
{
41
        struct ehci_hcd *ehci;
42
 
43
        ehci = (struct ehci_hcd *)
44
                kmalloc (sizeof (struct ehci_hcd), GFP_KERNEL);
45
        if (ehci != 0) {
46
                memset (ehci, 0, sizeof (struct ehci_hcd));
47
                ehci->hcd.product_desc = "EHCI Host Controller";
48
                return &ehci->hcd;
49
        }
50
        return 0;
51
}
52
 
53
static void ehci_hcd_free (struct usb_hcd *hcd)
54
{
55
        kfree (hcd_to_ehci (hcd));
56
}
57
 
58
/*-------------------------------------------------------------------------*/
59
 
60
/* Allocate the key transfer structures from the previously allocated pool */
61
 
62
static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
63
{
64
        memset (qtd, 0, sizeof *qtd);
65
        qtd->qtd_dma = dma;
66
        qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
67
        qtd->hw_next = EHCI_LIST_END;
68
        qtd->hw_alt_next = EHCI_LIST_END;
69
        INIT_LIST_HEAD (&qtd->qtd_list);
70
}
71
 
72
static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags)
73
{
74
        struct ehci_qtd         *qtd;
75
        dma_addr_t              dma;
76
 
77
        qtd = pci_pool_alloc_usb (ehci->qtd_pool, flags, &dma);
78
        if (qtd != 0) {
79
                ehci_qtd_init (qtd, dma);
80
        }
81
        return qtd;
82
}
83
 
84
static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
85
{
86
        pci_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma);
87
}
88
 
89
 
90
static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
91
{
92
        struct ehci_qh          *qh;
93
        dma_addr_t              dma;
94
 
95
        qh = (struct ehci_qh *)
96
                pci_pool_alloc_usb (ehci->qh_pool, flags, &dma);
97
        if (!qh)
98
                return qh;
99
 
100
        memset (qh, 0, sizeof *qh);
101
        atomic_set (&qh->refcount, 1);
102
        qh->qh_dma = dma;
103
        // INIT_LIST_HEAD (&qh->qh_list);
104
        INIT_LIST_HEAD (&qh->qtd_list);
105
 
106
        /* dummy td enables safe urb queuing */
107
        qh->dummy = ehci_qtd_alloc (ehci, flags);
108
        if (qh->dummy == 0) {
109
                ehci_dbg (ehci, "no dummy td\n");
110
                pci_pool_free (ehci->qh_pool, qh, qh->qh_dma);
111
                qh = 0;
112
        }
113
        return qh;
114
}
115
 
116
/* to share a qh (cpu threads, or hc) */
117
static inline struct ehci_qh *qh_get (/* ehci, */ struct ehci_qh *qh)
118
{
119
        atomic_inc (&qh->refcount);
120
        return qh;
121
}
122
 
123
static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
124
{
125
        if (!atomic_dec_and_test (&qh->refcount))
126
                return;
127
        /* clean qtds first, and know this is not linked */
128
        if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) {
129
                ehci_dbg (ehci, "unused qh not empty!\n");
130
                BUG ();
131
        }
132
        if (qh->dummy)
133
                ehci_qtd_free (ehci, qh->dummy);
134
        pci_pool_free (ehci->qh_pool, qh, qh->qh_dma);
135
}
136
 
137
/*-------------------------------------------------------------------------*/
138
 
139
/* The queue heads and transfer descriptors are managed from pools tied
140
 * to each of the "per device" structures.
141
 * This is the initialisation and cleanup code.
142
 */
143
 
144
static void ehci_mem_cleanup (struct ehci_hcd *ehci)
145
{
146
        if (ehci->async)
147
                qh_put (ehci, ehci->async);
148
        ehci->async = 0;
149
 
150
        /* PCI consistent memory and pools */
151
        if (ehci->qtd_pool)
152
                pci_pool_destroy (ehci->qtd_pool);
153
        ehci->qtd_pool = 0;
154
 
155
        if (ehci->qh_pool) {
156
                pci_pool_destroy (ehci->qh_pool);
157
                ehci->qh_pool = 0;
158
        }
159
 
160
        if (ehci->itd_pool)
161
                pci_pool_destroy (ehci->itd_pool);
162
        ehci->itd_pool = 0;
163
 
164
        if (ehci->sitd_pool)
165
                pci_pool_destroy (ehci->sitd_pool);
166
        ehci->sitd_pool = 0;
167
 
168
        if (ehci->periodic)
169
                pci_free_consistent (ehci->hcd.pdev,
170
                        ehci->periodic_size * sizeof (u32),
171
                        ehci->periodic, ehci->periodic_dma);
172
        ehci->periodic = 0;
173
 
174
        /* shadow periodic table */
175
        if (ehci->pshadow)
176
                kfree (ehci->pshadow);
177
        ehci->pshadow = 0;
178
}
179
 
180
/* remember to add cleanup code (above) if you add anything here */
181
static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
182
{
183
        int i;
184
 
185
        /* QTDs for control/bulk/intr transfers */
186
        ehci->qtd_pool = pci_pool_create ("ehci_qtd", ehci->hcd.pdev,
187
                        sizeof (struct ehci_qtd),
188
                        32 /* byte alignment (for hw parts) */,
189
                        4096 /* can't cross 4K */);
190
        if (!ehci->qtd_pool) {
191
                goto fail;
192
        }
193
 
194
        /* QHs for control/bulk/intr transfers */
195
        ehci->qh_pool = pci_pool_create ("ehci_qh", ehci->hcd.pdev,
196
                        sizeof (struct ehci_qh),
197
                        32 /* byte alignment (for hw parts) */,
198
                        4096 /* can't cross 4K */);
199
        if (!ehci->qh_pool) {
200
                goto fail;
201
        }
202
        ehci->async = ehci_qh_alloc (ehci, flags);
203
        if (!ehci->async) {
204
                goto fail;
205
        }
206
 
207
        /* ITD for high speed ISO transfers */
208
        ehci->itd_pool = pci_pool_create ("ehci_itd", ehci->hcd.pdev,
209
                        sizeof (struct ehci_itd),
210
                        32 /* byte alignment (for hw parts) */,
211
                        4096 /* can't cross 4K */);
212
        if (!ehci->itd_pool) {
213
                goto fail;
214
        }
215
 
216
        /* SITD for full/low speed split ISO transfers */
217
        ehci->sitd_pool = pci_pool_create ("ehci_sitd", ehci->hcd.pdev,
218
                        sizeof (struct ehci_sitd),
219
                        32 /* byte alignment (for hw parts) */,
220
                        4096 /* can't cross 4K */);
221
        if (!ehci->sitd_pool) {
222
                goto fail;
223
        }
224
 
225
        /* Hardware periodic table */
226
        ehci->periodic = (u32 *)
227
                pci_alloc_consistent_usb (ehci->hcd.pdev,
228
                        ehci->periodic_size * sizeof (u32),
229
                        &ehci->periodic_dma);
230
        if (ehci->periodic == 0) {
231
                goto fail;
232
        }
233
        for (i = 0; i < ehci->periodic_size; i++)
234
                ehci->periodic [i] = EHCI_LIST_END;
235
 
236
        /* software shadow of hardware table */
237
        ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *), flags);
238
        if (ehci->pshadow == 0) {
239
                goto fail;
240
        }
241
        memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *));
242
 
243
        return 0;
244
 
245
fail:
246
        ehci_dbg (ehci, "couldn't init memory\n");
247
        ehci_mem_cleanup (ehci);
248
        return -ENOMEM;
249
}