VirtualBox

source: vbox/trunk/src/VBox/Additions/solaris/Virtio/Virtio-solaris.c@ 57260

Last change on this file since 57260 was 55980, checked in by vboxsync, 10 years ago

iprt/log.h,++: Added extended logger instance getters that also checks whether the given logger and group-flags are enabled, making the LogRel* checks more efficient in avoid uncessary RTLogLoggerEx parameter building and calls. Ditto for debug logging. The LOG_INSTANCE and LOG_REL_INSTANCE tricks are gone for now.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: Virtio-solaris.c 55980 2015-05-20 17:35:22Z vboxsync $ */
2/** @file
3 * VirtualBox Guest Additions - Virtio Driver for Solaris.
4 */
5
6/*
7 * Copyright (C) 2010-2011 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include "Virtio-solaris.h"
31
32#include <iprt/assert.h>
33#include <iprt/mem.h>
34#include <VBox/log.h>
35
36
37/**
38 * Virtio Attach routine that should be called from all Virtio drivers' attach
39 * routines.
40 *
41 * @param pDip The module structure instance.
42 * @param enmCmd Operation type (attach/resume).
43 * @param pDeviceOps Pointer to device ops structure.
44 * @param pHyperOps Pointer to hypervisor ops structure.
45 *
46 * @return Solaris DDI error code. DDI_SUCCESS or DDI_FAILURE.
47 */
48int VirtioAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd, PVIRTIODEVICEOPS pDeviceOps, PVIRTIOHYPEROPS pHyperOps)
49{
50 LogFlowFunc((VIRTIOLOGNAME ":VirtioAttach: pDip=%p enmCmd=%d pDeviceOps=%p pHyperOps=%p\n", pDip, enmCmd, pDeviceOps, pHyperOps));
51
52 AssertReturn(pDip, DDI_EINVAL);
53 AssertReturn(pDeviceOps, DDI_EINVAL);
54 AssertReturn(pHyperOps, DDI_EINVAL);
55
56 if (enmCmd != DDI_ATTACH)
57 {
58 LogRel((VIRTIOLOGNAME ":VirtioAttach: Invalid enmCmd=%#x expected DDI_ATTACH\n", enmCmd));
59 return DDI_FAILURE;
60 }
61
62 int rc = DDI_FAILURE;
63 PVIRTIODEVICE pDevice = RTMemAllocZ(sizeof(VIRTIODEVICE));
64 if (RT_LIKELY(pDevice))
65 {
66 pDevice->pDip = pDip;
67 pDevice->pDeviceOps = pDeviceOps;
68 pDevice->pHyperOps = pHyperOps;
69
70 pDevice->pvDevice = pDevice->pDeviceOps->pfnAlloc(pDevice);
71 if (RT_LIKELY(pDevice->pvDevice))
72 {
73 pDevice->pvHyper = pDevice->pHyperOps->pfnAlloc(pDevice);
74 if (RT_LIKELY(pDevice->pvHyper))
75 {
76 /*
77 * Attach hypervisor interface and obtain features supported by host.
78 */
79 rc = pDevice->pHyperOps->pfnAttach(pDevice);
80 if (rc == DDI_SUCCESS)
81 {
82 pDevice->fHostFeatures = pDevice->pHyperOps->pfnGetFeatures(pDevice);
83 LogFlow((VIRTIOLOGNAME ":VirtioAttach: Host features=%#x\n", pDevice->fHostFeatures));
84
85 /*
86 * Attach the device type interface.
87 */
88 rc = pDevice->pDeviceOps->pfnAttach(pDevice);
89 if (rc == DDI_SUCCESS)
90 {
91 ddi_set_driver_private(pDip, pDevice);
92 return DDI_SUCCESS;
93 }
94 else
95 LogRel((VIRTIOLOGNAME ":VirtioAttach: DeviceOps pfnAttach failed. rc=%d\n", rc));
96
97 pDevice->pHyperOps->pfnDetach(pDevice);
98 }
99 else
100 LogRel((VIRTIOLOGNAME ":VirtioAttach: HyperOps pfnAttach failed. rc=%d\n", rc));
101
102 pDevice->pHyperOps->pfnFree(pDevice);
103 }
104 else
105 LogRel((VIRTIOLOGNAME ":VirtioAttach: HyperOps->pfnAlloc failed!\n"));
106
107 pDevice->pDeviceOps->pfnFree(pDevice);
108 }
109 else
110 LogRel((VIRTIOLOGNAME ":VirtioAttach: DeviceOps->pfnAlloc failed!\n"));
111
112 RTMemFree(pDevice);
113 }
114 else
115 LogRel((VIRTIOLOGNAME ":VirtioAttach: failed to alloc %u bytes for device structure.\n", sizeof(VIRTIODEVICE)));
116
117 return DDI_FAILURE;
118}
119
120
121/**
122 * Virtio Detach routine that should be called from all Virtio drivers' detach
123 * routines.
124 *
125 * @param pDip The module structure instance.
126 * @param enmCmd Operation type (detach/suspend).
127 *
128 * @return Solaris DDI error code. DDI_SUCCESS or DDI_FAILURE.
129 */
130int VirtioDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
131{
132 LogFlowFunc((VIRTIOLOGNAME ":VirtioDetach pDip=%p enmCmd=%d\n", pDip, enmCmd));
133
134 PVIRTIODEVICE pDevice = ddi_get_driver_private(pDip);
135 if (RT_UNLIKELY(!pDevice))
136 return DDI_FAILURE;
137
138 if (enmCmd != DDI_DETACH)
139 {
140 LogRel((VIRTIOLOGNAME ":VirtioDetach: Invalid enmCmd=%#x expected DDI_DETACH.\n", enmCmd));
141 return DDI_FAILURE;
142 }
143
144 int rc = pDevice->pDeviceOps->pfnDetach(pDevice);
145 if (rc == DDI_SUCCESS)
146 {
147 pDevice->pHyperOps->pfnDetach(pDevice);
148 pDevice->pDeviceOps->pfnFree(pDevice);
149 pDevice->pvDevice = NULL;
150 pDevice->pHyperOps->pfnFree(pDevice);
151 pDevice->pvHyper = NULL;
152
153 ddi_set_driver_private(pDevice->pDip, NULL);
154 RTMemFree(pDevice);
155 return DDI_SUCCESS;
156 }
157 else
158 LogRel((VIRTIOLOGNAME ":VirtioDetach: DeviceOps pfnDetach failed. rc=%d\n", rc));
159
160 return DDI_FAILURE;
161}
162
163
164/**
165 * Allocates a Virtio Queue object and assigns it an index.
166 *
167 * @param pDevice Pointer to the Virtio device instance.
168 *
169 * @return A pointer to a Virtio Queue instance.
170 */
171PVIRTIOQUEUE VirtioGetQueue(PVIRTIODEVICE pDevice, uint16_t Index)
172{
173 PVIRTIOQUEUE pQueue = RTMemAllocZ(sizeof(VIRTIOQUEUE));
174 if (RT_UNLIKELY(!pQueue))
175 {
176 LogRel((VIRTIOLOGNAME ":VirtioGetQueue: failed to alloc memory for %u bytes.\n", sizeof(VIRTIOQUEUE)));
177 return NULL;
178 }
179
180 pQueue->QueueIndex = Index;
181 pQueue->pvData = pDevice->pHyperOps->pfnGetQueue(pDevice, pQueue);
182 if (RT_UNLIKELY(!pQueue->pvData))
183 {
184 LogRel((VIRTIOLOGNAME ":VirtioGetQueue: HyperOps GetQueue failed!\n"));
185 RTMemFree(pQueue);
186 return NULL;
187 }
188
189 AssertReturn(pQueue->pQueue, NULL);
190 AssertReturn(pQueue->Ring.cDesc > 0, NULL);
191
192 /* @todo enable interrupt. */
193
194 return pQueue;
195}
196
197
198/**
199 * Puts a queue and destroys the instance.
200 *
201 * @param pDevice Pointer to the Virtio device instance.
202 * @param pQueue Pointer to the Virtio queue.
203 */
204void VirtioPutQueue(PVIRTIODEVICE pDevice, PVIRTIOQUEUE pQueue)
205{
206 AssertReturnVoid(pDevice);
207 AssertReturnVoid(pQueue);
208
209 pDevice->pHyperOps->pfnPutQueue(pDevice, pQueue);
210 RTMemFree(pQueue);
211}
212
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