VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use