VirtualBox

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

Last change on this file since 38813 was 38736, checked in by vboxsync, 13 years ago

*: Please don NOT redefine logger macros.

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