VirtualBox

source: vbox/trunk/src/VBox/Devices/USB/VUSBUrbPool.cpp@ 59720

Last change on this file since 59720 was 59719, checked in by vboxsync, 9 years ago

VUSB: export new file

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 KB
Line 
1/* $Id: VUSBUrbPool.cpp 59719 2016-02-18 10:52:27Z vboxsync $ */
2/** @file
3 * Virtual USB - URB pool.
4 */
5
6/*
7 * Copyright (C) 2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DRV_VUSB
23#include <VBox/log.h>
24#include <VBox/err.h>
25#include <iprt/mem.h>
26#include <iprt/critsect.h>
27
28#include "VUSBInternal.h"
29
30/*********************************************************************************************************************************
31* Defined Constants And Macros *
32*********************************************************************************************************************************/
33
34/*********************************************************************************************************************************
35* Structures and Typedefs *
36*********************************************************************************************************************************/
37
38/*********************************************************************************************************************************
39* Static Variables *
40*********************************************************************************************************************************/
41
42/*********************************************************************************************************************************
43* Internal Functions *
44*********************************************************************************************************************************/
45
46DECLHIDDEN(int) vusbUrbPoolInit(PVUSBURBPOOL pUrbPool)
47{
48 int rc = RTCritSectInit(&pUrbPool->CritSectPool);
49 if (RT_SUCCESS(rc))
50 {
51 pUrbPool->cUrbsInPool = 0;
52 for (unsigned i = 0; i < RT_ELEMENTS(pUrbPool->apFreeUrbs); i++)
53 pUrbPool->apFreeUrbs[i] = NULL;
54 }
55
56 return rc;
57}
58
59
60DECLHIDDEN(void) vusbUrbPoolDestroy(PVUSBURBPOOL pUrbPool)
61{
62 RTCritSectEnter(&pUrbPool->CritSectPool);
63 for (unsigned i = 0; i < RT_ELEMENTS(pUrbPool->apFreeUrbs); i++)
64 {
65 while (pUrbPool->apFreeUrbs[i])
66 {
67 PVUSBURB pUrb = pUrbPool->apFreeUrbs[i];
68 pUrbPool->apFreeUrbs[i] = pUrb->pVUsb->pNext;
69
70 pUrb->u32Magic = 0;
71 pUrb->enmState = VUSBURBSTATE_INVALID;
72 pUrb->pVUsb->pNext = NULL;
73 RTMemFree(pUrb);
74 }
75 }
76 RTCritSectLeave(&pUrbPool->CritSectPool);
77 RTCritSectDelete(&pUrbPool->CritSectPool);
78}
79
80
81DECLHIDDEN(PVUSBURB) vusbUrbPoolAlloc(PVUSBURBPOOL pUrbPool, VUSBXFERTYPE enmType,
82 VUSBDIRECTION enmDir, size_t cbData, size_t cbHci,
83 size_t cbHciTd, unsigned cTds)
84{
85 /*
86 * Reuse or allocate a new URB.
87 */
88 /** @todo try find a best fit, MSD which submits rather big URBs intermixed with small control
89 * messages ends up with a 2+ of these big URBs when a single one is sufficient. */
90 /** @todo The allocations should be done by the device, at least as an option, since the devices
91 * frequently wish to associate their own stuff with the in-flight URB or need special buffering
92 * (isochronous on Darwin for instance). */
93 /* Get the required amount of additional memory to allocate the whole state. */
94 size_t cbMem = cbData + sizeof(VUSBURBVUSBINT) + cbHci + cTds * cbHciTd;
95 uint32_t cbDataAllocated = 0;
96
97 AssertReturn(enmType < RT_ELEMENTS(pUrbPool->apFreeUrbs), NULL);
98
99 RTCritSectEnter(&pUrbPool->CritSectPool);
100 PVUSBURB pUrbPrev = NULL;
101 PVUSBURB pUrb = pUrbPool->apFreeUrbs[enmType];
102 while (pUrb)
103 {
104 if (pUrb->pVUsb->cbDataAllocated >= cbMem)
105 {
106 /* Unlink and verify part of the state. */
107 if (pUrbPrev)
108 pUrbPrev->pVUsb->pNext = pUrb->pVUsb->pNext;
109 else
110 pUrbPool->apFreeUrbs[enmType] = pUrb->pVUsb->pNext;
111 Assert(pUrb->u32Magic == VUSBURB_MAGIC);
112 Assert(pUrb->enmState == VUSBURBSTATE_FREE);
113 Assert(!pUrb->pVUsb->pNext || pUrb->pVUsb->pNext->enmState == VUSBURBSTATE_FREE);
114 cbDataAllocated = pUrb->pVUsb->cbDataAllocated;
115 break;
116 }
117 pUrbPrev = pUrb;
118 pUrb = pUrb->pVUsb->pNext;
119 }
120
121 if (!pUrb)
122 {
123 /* allocate a new one. */
124 cbDataAllocated = cbMem <= _4K ? RT_ALIGN_32(cbMem, _1K)
125 : cbMem <= _32K ? RT_ALIGN_32(cbMem, _4K)
126 : RT_ALIGN_32(cbMem, 16*_1K);
127
128 pUrb = (PVUSBURB)RTMemAllocZ(RT_OFFSETOF(VUSBURB, abData[cbDataAllocated]));
129 if (RT_UNLIKELY(!pUrb))
130 {
131 RTCritSectLeave(&pUrbPool->CritSectPool);
132 AssertLogRelFailedReturn(NULL);
133 }
134
135 pUrbPool->cUrbsInPool++;
136 pUrb->u32Magic = VUSBURB_MAGIC;
137
138 }
139 RTCritSectLeave(&pUrbPool->CritSectPool);
140
141 Assert(cbDataAllocated >= cbMem);
142
143 /*
144 * (Re)init the URB
145 */
146 uint32_t offAlloc = cbData;
147 pUrb->enmState = VUSBURBSTATE_ALLOCATED;
148 pUrb->fCompleting = false;
149 pUrb->pszDesc = NULL;
150 pUrb->pVUsb = (PVUSBURBVUSB)&pUrb->abData[offAlloc];
151 offAlloc += sizeof(VUSBURBVUSBINT);
152 pUrb->pVUsb->pvFreeCtx = NULL;
153 pUrb->pVUsb->pfnFree = NULL;
154 pUrb->pVUsb->cbDataAllocated = cbDataAllocated;
155 pUrb->pVUsb->pNext = NULL;
156 pUrb->pVUsb->ppPrev = NULL;
157 pUrb->pVUsb->pCtrlUrb = NULL;
158 pUrb->pVUsb->u64SubmitTS = 0;
159 pUrb->pVUsb->pvReadAhead = NULL;
160 pUrb->Dev.pvPrivate = NULL;
161 pUrb->Dev.pNext = NULL;
162 pUrb->EndPt = ~0;
163 pUrb->enmType = enmType;
164 pUrb->enmDir = enmDir;
165 pUrb->fShortNotOk = false;
166 pUrb->enmStatus = VUSBSTATUS_INVALID;
167 pUrb->cbData = cbData;
168 pUrb->pHci = cbHci ? (PVUSBURBHCI)&pUrb->abData[offAlloc] : NULL;
169 offAlloc += cbHci;
170 pUrb->paTds = (cbHciTd && cTds) ? (PVUSBURBHCITD)&pUrb->abData[offAlloc] : NULL;
171
172 return pUrb;
173}
174
175
176DECLHIDDEN(void) vusbUrbPoolFree(PVUSBURBPOOL pUrbPool, PVUSBURB pUrb)
177{
178 /*
179 * Put it into the LIFO of free URBs.
180 * (No ppPrev is needed here.)
181 */
182 VUSBXFERTYPE enmType = pUrb->enmType;
183 AssertReturnVoid(enmType < RT_ELEMENTS(pUrbPool->apFreeUrbs));
184 RTCritSectEnter(&pUrbPool->CritSectPool);
185 pUrb->enmState = VUSBURBSTATE_FREE;
186 pUrb->pVUsb->ppPrev = NULL;
187 pUrb->pVUsb->pNext = pUrbPool->apFreeUrbs[enmType];
188 pUrbPool->apFreeUrbs[enmType] = pUrb;
189 Assert(pUrbPool->apFreeUrbs[enmType]->enmState == VUSBURBSTATE_FREE);
190 RTCritSectLeave(&pUrbPool->CritSectPool);
191}
192
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette