VirtualBox

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

Last change on this file since 34575 was 34233, checked in by vboxsync, 14 years ago

header fixes

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