VirtualBox

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

Last change on this file since 6484 was 6153, checked in by vboxsync, 17 years ago

fixed inverted write protect flag of the host floppy drive

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