VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/DrvHostFloppy.cpp@ 61541

Last change on this file since 61541 was 59252, checked in by vboxsync, 9 years ago

pdmifs.h: Move the storage related interfaces (PDMIMEDIA, PDMIMOUNT, PDMISCSICONNECTOR, etc.) into a separate header to reduce the overall size of the header a bit

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 KB
Line 
1/* $Id: DrvHostFloppy.cpp 59252 2016-01-05 10:54:49Z vboxsync $ */
2/** @file
3 *
4 * VBox storage devices:
5 * Host floppy block driver
6 */
7
8/*
9 * Copyright (C) 2006-2015 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20
21/*********************************************************************************************************************************
22* Header Files *
23*********************************************************************************************************************************/
24#define LOG_GROUP LOG_GROUP_DRV_HOST_FLOPPY
25#ifdef RT_OS_LINUX
26# include <sys/ioctl.h>
27# include <linux/fd.h>
28# include <sys/fcntl.h>
29# include <errno.h>
30
31# elif defined(RT_OS_WINDOWS)
32# include <windows.h>
33# include <dbt.h>
34
35#elif defined(RT_OS_L4)
36
37#else /* !RT_OS_WINDOWS nor RT_OS_LINUX nor RT_OS_L4 */
38# error "Unsupported Platform."
39#endif /* !RT_OS_WINDOWS nor RT_OS_LINUX nor RT_OS_L4 */
40
41#include <VBox/vmm/pdmdrv.h>
42#include <VBox/vmm/pdmstorageifs.h>
43#include <iprt/assert.h>
44#include <iprt/file.h>
45#include <iprt/string.h>
46#include <iprt/thread.h>
47#include <iprt/semaphore.h>
48#include <iprt/uuid.h>
49#include <iprt/asm.h>
50#include <iprt/critsect.h>
51
52#include "VBoxDD.h"
53#include "DrvHostBase.h"
54
55
56/**
57 * Floppy driver instance data.
58 */
59typedef struct DRVHOSTFLOPPY
60{
61 DRVHOSTBASE Base;
62 /** Previous poll status. */
63 bool fPrevDiskIn;
64
65} DRVHOSTFLOPPY, *PDRVHOSTFLOPPY;
66
67
68
69#ifdef RT_OS_WINDOWS
70/**
71 * Get media size - needs a special IOCTL.
72 *
73 * @param pThis The instance data.
74 */
75static DECLCALLBACK(int) drvHostFloppyGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
76{
77 DISK_GEOMETRY geom;
78 DWORD cbBytesReturned;
79 int rc;
80 int cbSectors;
81
82 memset(&geom, 0, sizeof(geom));
83 rc = DeviceIoControl((HANDLE)RTFileToNative(pThis->hFileDevice), IOCTL_DISK_GET_DRIVE_GEOMETRY,
84 NULL, 0, &geom, sizeof(geom), &cbBytesReturned, NULL);
85 if (rc) {
86 cbSectors = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack;
87 *pcb = cbSectors * geom.BytesPerSector;
88 rc = VINF_SUCCESS;
89 }
90 else
91 {
92 DWORD dwLastError;
93
94 dwLastError = GetLastError();
95 rc = RTErrConvertFromWin32(dwLastError);
96 Log(("DrvHostFloppy: IOCTL_DISK_GET_DRIVE_GEOMETRY(%s) failed, LastError=%d rc=%Rrc\n",
97 pThis->pszDevice, dwLastError, rc));
98 return rc;
99 }
100
101 return rc;
102}
103#endif /* RT_OS_WINDOWS */
104
105#ifdef RT_OS_LINUX
106/**
107 * Get media size and do change processing.
108 *
109 * @param pThis The instance data.
110 */
111static DECLCALLBACK(int) drvHostFloppyGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
112{
113 int rc = ioctl(RTFileToNative(pThis->hFileDevice), FDFLUSH);
114 if (rc)
115 {
116 rc = RTErrConvertFromErrno (errno);
117 Log(("DrvHostFloppy: FDFLUSH ioctl(%s) failed, errno=%d rc=%Rrc\n", pThis->pszDevice, errno, rc));
118 return rc;
119 }
120
121 floppy_drive_struct DrvStat;
122 rc = ioctl(RTFileToNative(pThis->hFileDevice), FDGETDRVSTAT, &DrvStat);
123 if (rc)
124 {
125 rc = RTErrConvertFromErrno(errno);
126 Log(("DrvHostFloppy: FDGETDRVSTAT ioctl(%s) failed, errno=%d rc=%Rrc\n", pThis->pszDevice, errno, rc));
127 return rc;
128 }
129 pThis->fReadOnly = !(DrvStat.flags & FD_DISK_WRITABLE);
130
131 return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
132}
133#endif /* RT_OS_LINUX */
134
135
136#ifdef RT_OS_LINUX
137/**
138 * This thread will periodically poll the Floppy for media presence.
139 *
140 * @returns Ignored.
141 * @param ThreadSelf Handle of this thread. Ignored.
142 * @param pvUser Pointer to the driver instance structure.
143 */
144static DECLCALLBACK(int) drvHostFloppyPoll(PDRVHOSTBASE pThis)
145{
146 PDRVHOSTFLOPPY pThisFloppy = (PDRVHOSTFLOPPY)pThis;
147 floppy_drive_struct DrvStat;
148 int rc = ioctl(RTFileToNative(pThis->hFileDevice), FDPOLLDRVSTAT, &DrvStat);
149 if (rc)
150 return RTErrConvertFromErrno(errno);
151
152 RTCritSectEnter(&pThis->CritSect);
153 bool fDiskIn = !(DrvStat.flags & (FD_VERIFY | FD_DISK_NEWCHANGE));
154 if ( fDiskIn
155 && !pThisFloppy->fPrevDiskIn)
156 {
157 if (pThis->fMediaPresent)
158 DRVHostBaseMediaNotPresent(pThis);
159 rc = DRVHostBaseMediaPresent(pThis);
160 if (RT_FAILURE(rc))
161 {
162 pThisFloppy->fPrevDiskIn = fDiskIn;
163 RTCritSectLeave(&pThis->CritSect);
164 return rc;
165 }
166 }
167
168 if ( !fDiskIn
169 && pThisFloppy->fPrevDiskIn
170 && pThis->fMediaPresent)
171 DRVHostBaseMediaNotPresent(pThis);
172 pThisFloppy->fPrevDiskIn = fDiskIn;
173
174 RTCritSectLeave(&pThis->CritSect);
175 return VINF_SUCCESS;
176}
177#endif /* RT_OS_LINUX */
178
179
180/**
181 * @copydoc FNPDMDRVCONSTRUCT
182 */
183static DECLCALLBACK(int) drvHostFloppyConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
184{
185 PDRVHOSTFLOPPY pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTFLOPPY);
186 LogFlow(("drvHostFloppyConstruct: iInstance=%d\n", pDrvIns->iInstance));
187
188 /*
189 * Init instance data.
190 */
191 int rc = DRVHostBaseInitData(pDrvIns, pCfg, PDMMEDIATYPE_FLOPPY_1_44);
192 if (RT_SUCCESS(rc))
193 {
194 /*
195 * Validate configuration.
196 */
197 if (CFGMR3AreValuesValid(pCfg, "Path\0ReadOnly\0Interval\0Locked\0BIOSVisible\0"))
198 {
199 /*
200 * Override stuff.
201 */
202#ifdef RT_OS_WINDOWS
203 pThis->Base.pfnGetMediaSize = drvHostFloppyGetMediaSize;
204#endif
205#ifdef RT_OS_LINUX
206 pThis->Base.pfnPoll = drvHostFloppyPoll;
207 pThis->Base.pfnGetMediaSize = drvHostFloppyGetMediaSize;
208#endif
209
210 /*
211 * 2nd init part.
212 */
213 rc = DRVHostBaseInitFinish(&pThis->Base);
214 }
215 else
216 {
217 pThis->Base.fAttachFailError = true;
218 rc = VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
219 }
220 }
221 if (RT_FAILURE(rc))
222 {
223 if (!pThis->Base.fAttachFailError)
224 {
225 /* Suppressing the attach failure error must not affect the normal
226 * DRVHostBaseDestruct, so reset this flag below before leaving. */
227 pThis->Base.fKeepInstance = true;
228 rc = VINF_SUCCESS;
229 }
230 DRVHostBaseDestruct(pDrvIns);
231 pThis->Base.fKeepInstance = false;
232 }
233
234 LogFlow(("drvHostFloppyConstruct: returns %Rrc\n", rc));
235 return rc;
236}
237
238
239/**
240 * Block driver registration record.
241 */
242const PDMDRVREG g_DrvHostFloppy =
243{
244 /* u32Version */
245 PDM_DRVREG_VERSION,
246 /* szName */
247 "HostFloppy",
248 /* szRCMod */
249 "",
250 /* szR0Mod */
251 "",
252 /* pszDescription */
253 "Host Floppy Block Driver.",
254 /* fFlags */
255 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
256 /* fClass. */
257 PDM_DRVREG_CLASS_BLOCK,
258 /* cMaxInstances */
259 ~0U,
260 /* cbInstance */
261 sizeof(DRVHOSTFLOPPY),
262 /* pfnConstruct */
263 drvHostFloppyConstruct,
264 /* pfnDestruct */
265 DRVHostBaseDestruct,
266 /* pfnRelocate */
267 NULL,
268 /* pfnIOCtl */
269 NULL,
270 /* pfnPowerOn */
271 NULL,
272 /* pfnReset */
273 NULL,
274 /* pfnSuspend */
275 NULL,
276 /* pfnResume */
277 NULL,
278 /* pfnAttach */
279 NULL,
280 /* pfnDetach */
281 NULL,
282 /* pfnPowerOff */
283 NULL,
284 /* pfnSoftReset */
285 NULL,
286 /* u32EndVersion */
287 PDM_DRVREG_VERSION
288};
289
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