VirtualBox

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

Last change on this file since 63100 was 62529, checked in by vboxsync, 8 years ago

(C) 2016

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