VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/ATAController.h@ 27361

Last change on this file since 27361 was 27361, checked in by vboxsync, 15 years ago

Storate/ATA: implemented ATA_EVENT_STATUS_MEDIA_EJECT_REQUESTED (currently unused)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.3 KB
Line 
1/* $Id: ATAController.h 27361 2010-03-15 14:24:42Z vboxsync $ */
2/** @file
3 * DevATA, DevAHCI - Shared ATA/ATAPI controller types.
4 */
5
6/*
7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef ___Storage_ATAController_h
23#define ___Storage_ATAController_h
24
25/*******************************************************************************
26* Header Files *
27*******************************************************************************/
28#include <VBox/pdmdev.h>
29#ifdef IN_RING3
30# include <iprt/semaphore.h>
31# include <iprt/thread.h>
32#endif /* IN_RING3 */
33#include <iprt/critsect.h>
34#include <VBox/stam.h>
35
36#include "PIIX3ATABmDma.h"
37#include "ide.h"
38
39
40/*******************************************************************************
41* Defined Constants And Macros *
42*******************************************************************************/
43/**
44 * Maximum number of sectors to transfer in a READ/WRITE MULTIPLE request.
45 * Set to 1 to disable multi-sector read support. According to the ATA
46 * specification this must be a power of 2 and it must fit in an 8 bit
47 * value. Thus the only valid values are 1, 2, 4, 8, 16, 32, 64 and 128.
48 */
49#define ATA_MAX_MULT_SECTORS 128
50
51/**
52 * Fastest PIO mode supported by the drive.
53 */
54#define ATA_PIO_MODE_MAX 4
55/**
56 * Fastest MDMA mode supported by the drive.
57 */
58#define ATA_MDMA_MODE_MAX 2
59/**
60 * Fastest UDMA mode supported by the drive.
61 */
62#define ATA_UDMA_MODE_MAX 6
63
64/** ATAPI sense info size. */
65#define ATAPI_SENSE_SIZE 64
66
67/** The maximum number of release log entries per device. */
68#define MAX_LOG_REL_ERRORS 1024
69
70/* MediaEventStatus */
71#define ATA_EVENT_STATUS_UNCHANGED 0 /**< medium event status not changed */
72#define ATA_EVENT_STATUS_MEDIA_NEW 1 /**< new medium inserted */
73#define ATA_EVENT_STATUS_MEDIA_REMOVED 2 /**< medium removed */
74#define ATA_EVENT_STATUS_MEDIA_CHANGED 3 /**< medium was removed + new medium was inserted */
75#define ATA_EVENT_STATUS_MEDIA_EJECT_REQUESTED 4 /**< medium eject requested (eject button pressed) */
76
77
78/*******************************************************************************
79* Structures and Typedefs *
80*******************************************************************************/
81typedef struct AHCIATADevState {
82 /** Flag indicating whether the current command uses LBA48 mode. */
83 bool fLBA48;
84 /** Flag indicating whether this drive implements the ATAPI command set. */
85 bool fATAPI;
86 /** Set if this interface has asserted the IRQ. */
87 bool fIrqPending;
88 /** Currently configured number of sectors in a multi-sector transfer. */
89 uint8_t cMultSectors;
90 /** PCHS disk geometry. */
91 PDMMEDIAGEOMETRY PCHSGeometry;
92 /** Total number of sectors on this disk. */
93 uint64_t cTotalSectors;
94 /** Number of sectors to transfer per IRQ. */
95 uint32_t cSectorsPerIRQ;
96
97 /** ATA/ATAPI register 1: feature (write-only). */
98 uint8_t uATARegFeature;
99 /** ATA/ATAPI register 1: feature, high order byte. */
100 uint8_t uATARegFeatureHOB;
101 /** ATA/ATAPI register 1: error (read-only). */
102 uint8_t uATARegError;
103 /** ATA/ATAPI register 2: sector count (read/write). */
104 uint8_t uATARegNSector;
105 /** ATA/ATAPI register 2: sector count, high order byte. */
106 uint8_t uATARegNSectorHOB;
107 /** ATA/ATAPI register 3: sector (read/write). */
108 uint8_t uATARegSector;
109 /** ATA/ATAPI register 3: sector, high order byte. */
110 uint8_t uATARegSectorHOB;
111 /** ATA/ATAPI register 4: cylinder low (read/write). */
112 uint8_t uATARegLCyl;
113 /** ATA/ATAPI register 4: cylinder low, high order byte. */
114 uint8_t uATARegLCylHOB;
115 /** ATA/ATAPI register 5: cylinder high (read/write). */
116 uint8_t uATARegHCyl;
117 /** ATA/ATAPI register 5: cylinder high, high order byte. */
118 uint8_t uATARegHCylHOB;
119 /** ATA/ATAPI register 6: select drive/head (read/write). */
120 uint8_t uATARegSelect;
121 /** ATA/ATAPI register 7: status (read-only). */
122 uint8_t uATARegStatus;
123 /** ATA/ATAPI register 7: command (write-only). */
124 uint8_t uATARegCommand;
125 /** ATA/ATAPI drive control register (write-only). */
126 uint8_t uATARegDevCtl;
127
128 /** Currently active transfer mode (MDMA/UDMA) and speed. */
129 uint8_t uATATransferMode;
130 /** Current transfer direction. */
131 uint8_t uTxDir;
132 /** Index of callback for begin transfer. */
133 uint8_t iBeginTransfer;
134 /** Index of callback for source/sink of data. */
135 uint8_t iSourceSink;
136 /** Flag indicating whether the current command transfers data in DMA mode. */
137 bool fDMA;
138 /** Set to indicate that ATAPI transfer semantics must be used. */
139 bool fATAPITransfer;
140
141 /** Total ATA/ATAPI transfer size, shared PIO/DMA. */
142 uint32_t cbTotalTransfer;
143 /** Elementary ATA/ATAPI transfer size, shared PIO/DMA. */
144 uint32_t cbElementaryTransfer;
145 /** Current read/write buffer position, shared PIO/DMA. */
146 uint32_t iIOBufferCur;
147 /** First element beyond end of valid buffer content, shared PIO/DMA. */
148 uint32_t iIOBufferEnd;
149
150 /** ATA/ATAPI current PIO read/write transfer position. Not shared with DMA for safety reasons. */
151 uint32_t iIOBufferPIODataStart;
152 /** ATA/ATAPI current PIO read/write transfer end. Not shared with DMA for safety reasons. */
153 uint32_t iIOBufferPIODataEnd;
154
155 /** ATAPI current LBA position. */
156 uint32_t iATAPILBA;
157 /** ATAPI current sector size. */
158 uint32_t cbATAPISector;
159 /** ATAPI current command. */
160 uint8_t aATAPICmd[ATAPI_PACKET_SIZE];
161 /** ATAPI sense data. */
162 uint8_t abATAPISense[ATAPI_SENSE_SIZE];
163 /** HACK: Countdown till we report a newly unmounted drive as mounted. */
164 uint8_t cNotifiedMediaChange;
165 /** The same for GET_EVENT_STATUS for mechanism */
166 volatile uint32_t MediaEventStatus;
167
168 /** The status LED state for this drive. */
169 R3PTRTYPE(PPDMLED) pLed;
170#if HC_ARCH_BITS == 64
171 uint32_t uAlignment3;
172#endif
173
174 /** Size of I/O buffer. */
175 uint32_t cbIOBuffer;
176 /** Pointer to the I/O buffer. */
177 R3PTRTYPE(uint8_t *) pbIOBufferR3;
178 /** Pointer to the I/O buffer. */
179 R0PTRTYPE(uint8_t *) pbIOBufferR0;
180 /** Pointer to the I/O buffer. */
181 RCPTRTYPE(uint8_t *) pbIOBufferRC;
182
183 RTRCPTR Aligmnent1; /**< Align the statistics at an 8-byte boundrary. */
184
185 /*
186 * No data that is part of the saved state after this point!!!!!
187 */
188
189 /* Release statistics: number of ATA DMA commands. */
190 STAMCOUNTER StatATADMA;
191 /* Release statistics: number of ATA PIO commands. */
192 STAMCOUNTER StatATAPIO;
193 /* Release statistics: number of ATAPI PIO commands. */
194 STAMCOUNTER StatATAPIDMA;
195 /* Release statistics: number of ATAPI PIO commands. */
196 STAMCOUNTER StatATAPIPIO;
197#ifdef VBOX_INSTRUMENT_DMA_WRITES
198 /* Release statistics: number of DMA sector writes and the time spent. */
199 STAMPROFILEADV StatInstrVDWrites;
200#endif
201
202 /** Statistics: number of read operations and the time spent reading. */
203 STAMPROFILEADV StatReads;
204 /** Statistics: number of bytes read. */
205 R3PTRTYPE(PSTAMCOUNTER) pStatBytesRead;
206#if HC_ARCH_BITS == 64
207 uint64_t uAlignment4;
208#endif
209 /** Statistics: number of write operations and the time spent writing. */
210 STAMPROFILEADV StatWrites;
211 /** Statistics: number of bytes written. */
212 R3PTRTYPE(PSTAMCOUNTER) pStatBytesWritten;
213#if HC_ARCH_BITS == 64
214 uint64_t uAlignment5;
215#endif
216 /** Statistics: number of flush operations and the time spend flushing. */
217 STAMPROFILE StatFlushes;
218
219 /** Enable passing through commands directly to the ATAPI drive. */
220 bool fATAPIPassthrough;
221 /** Number of errors we've reported to the release log.
222 * This is to prevent flooding caused by something going horribly wrong.
223 * this value against MAX_LOG_REL_ERRORS in places likely to cause floods
224 * like the ones we currently seeing on the linux smoke tests (2006-11-10). */
225 uint32_t cErrors;
226 /** Timestamp of last started command. 0 if no command pending. */
227 uint64_t u64CmdTS;
228
229 /** Pointer to the attached driver's base interface. */
230 R3PTRTYPE(PPDMIBASE) pDrvBase;
231 /** Pointer to the attached driver's block interface. */
232 R3PTRTYPE(PPDMIBLOCK) pDrvBlock;
233 /** Pointer to the attached driver's block bios interface. */
234 R3PTRTYPE(PPDMIBLOCKBIOS) pDrvBlockBios;
235 /** Pointer to the attached driver's mount interface.
236 * This is NULL if the driver isn't a removable unit. */
237 R3PTRTYPE(PPDMIMOUNT) pDrvMount;
238 /** The base interface. */
239 PDMIBASE IBase;
240 /** The block port interface. */
241 PDMIBLOCKPORT IPort;
242 /** The mount notify interface. */
243 PDMIMOUNTNOTIFY IMountNotify;
244 /** The LUN #. */
245 RTUINT iLUN;
246#if HC_ARCH_BITS == 64
247 RTUINT Alignment2; /**< Align pDevInsR3 correctly. */
248#endif
249 /** Pointer to device instance. */
250 PPDMDEVINSR3 pDevInsR3;
251 /** Pointer to controller instance. */
252 R3PTRTYPE(struct AHCIATACONTROLLER *) pControllerR3;
253 /** Pointer to device instance. */
254 PPDMDEVINSR0 pDevInsR0;
255 /** Pointer to controller instance. */
256 R0PTRTYPE(struct AHCIATACONTROLLER *) pControllerR0;
257 /** Pointer to device instance. */
258 PPDMDEVINSRC pDevInsRC;
259 /** Pointer to controller instance. */
260 RCPTRTYPE(struct AHCIATACONTROLLER *) pControllerRC;
261} AHCIATADevState;
262
263
264typedef struct AHCIATATransferRequest
265{
266 uint8_t iIf;
267 uint8_t iBeginTransfer;
268 uint8_t iSourceSink;
269 uint32_t cbTotalTransfer;
270 uint8_t uTxDir;
271} AHCIATATransferRequest;
272
273
274typedef struct AHCIATAAbortRequest
275{
276 uint8_t iIf;
277 bool fResetDrive;
278} AHCIATAAbortRequest;
279
280
281typedef enum
282{
283 /** Begin a new transfer. */
284 AHCIATA_AIO_NEW = 0,
285 /** Continue a DMA transfer. */
286 AHCIATA_AIO_DMA,
287 /** Continue a PIO transfer. */
288 AHCIATA_AIO_PIO,
289 /** Reset the drives on current controller, stop all transfer activity. */
290 AHCIATA_AIO_RESET_ASSERTED,
291 /** Reset the drives on current controller, resume operation. */
292 AHCIATA_AIO_RESET_CLEARED,
293 /** Abort the current transfer of a particular drive. */
294 AHCIATA_AIO_ABORT
295} AHCIATAAIO;
296
297
298typedef struct AHCIATARequest
299{
300 AHCIATAAIO ReqType;
301 union
302 {
303 AHCIATATransferRequest t;
304 AHCIATAAbortRequest a;
305 } u;
306} AHCIATARequest;
307
308
309typedef struct AHCIATACONTROLLER
310{
311 /** The base of the first I/O Port range. */
312 RTIOPORT IOPortBase1;
313 /** The base of the second I/O Port range. (0 if none) */
314 RTIOPORT IOPortBase2;
315 /** The assigned IRQ. */
316 RTUINT irq;
317 /** Access critical section */
318 PDMCRITSECT lock;
319
320 /** Selected drive. */
321 uint8_t iSelectedIf;
322 /** The interface on which to handle async I/O. */
323 uint8_t iAIOIf;
324 /** The state of the async I/O thread. */
325 uint8_t uAsyncIOState;
326 /** Flag indicating whether the next transfer is part of the current command. */
327 bool fChainedTransfer;
328 /** Set when the reset processing is currently active on this controller. */
329 bool fReset;
330 /** Flag whether the current transfer needs to be redone. */
331 bool fRedo;
332 /** Flag whether the redo suspend has been finished. */
333 bool fRedoIdle;
334 /** Flag whether the DMA operation to be redone is the final transfer. */
335 bool fRedoDMALastDesc;
336 /** The BusMaster DMA state. */
337 BMDMAState BmDma;
338 /** Pointer to first DMA descriptor. */
339 RTGCPHYS32 pFirstDMADesc;
340 /** Pointer to last DMA descriptor. */
341 RTGCPHYS32 pLastDMADesc;
342 /** Pointer to current DMA buffer (for redo operations). */
343 RTGCPHYS32 pRedoDMABuffer;
344 /** Size of current DMA buffer (for redo operations). */
345 uint32_t cbRedoDMABuffer;
346
347 /** The ATA/ATAPI interfaces of this controller. */
348 AHCIATADevState aIfs[2];
349
350 /** Pointer to device instance. */
351 PPDMDEVINSR3 pDevInsR3;
352 /** Pointer to device instance. */
353 PPDMDEVINSR0 pDevInsR0;
354 /** Pointer to device instance. */
355 PPDMDEVINSRC pDevInsRC;
356
357 /** Set when the destroying the device instance and the thread must exit. */
358 uint32_t volatile fShutdown;
359 /** The async I/O thread handle. NIL_RTTHREAD if no thread. */
360 RTTHREAD AsyncIOThread;
361 /** The event semaphore the thread is waiting on for requests. */
362 RTSEMEVENT AsyncIOSem;
363 /** The request queue for the AIO thread. One element is always unused. */
364 AHCIATARequest aAsyncIORequests[4];
365 /** The position at which to insert a new request for the AIO thread. */
366 uint8_t AsyncIOReqHead;
367 /** The position at which to get a new request for the AIO thread. */
368 uint8_t AsyncIOReqTail;
369 /** Whether to call RTThreadUserSignal and PDMDevHlpAsyncNotificationCompleted
370 * when idle. Before setting this, call RTThreadUserReset. */
371 bool volatile fSignalIdle;
372 uint8_t Alignment3[1]; /**< Explicit padding of the 1 byte gap. */
373 /** Magic delay before triggering interrupts in DMA mode. */
374 uint32_t DelayIRQMillies;
375 /** The mutex protecting the request queue. */
376 RTSEMMUTEX AsyncIORequestMutex;
377 /** The event semaphore the thread is waiting on during suspended I/O. */
378 RTSEMEVENT SuspendIOSem;
379#if 0 /*HC_ARCH_BITS == 32*/
380 uint32_t Alignment0;
381#endif
382
383 /* Statistics */
384 STAMCOUNTER StatAsyncOps;
385 uint64_t StatAsyncMinWait;
386 uint64_t StatAsyncMaxWait;
387 STAMCOUNTER StatAsyncTimeUS;
388 STAMPROFILEADV StatAsyncTime;
389 STAMPROFILE StatLockWait;
390} AHCIATACONTROLLER, *PAHCIATACONTROLLER;
391
392#ifndef VBOX_DEVICE_STRUCT_TESTCASE
393
394#define ATADEVSTATE_2_CONTROLLER(pIf) ( (pIf)->CTX_SUFF(pController) )
395#define ATADEVSTATE_2_DEVINS(pIf) ( (pIf)->CTX_SUFF(pDevIns) )
396#define CONTROLLER_2_DEVINS(pController) ( (pController)->CTX_SUFF(pDevIns) )
397#define PDMIBASE_2_ATASTATE(pInterface) ( (AHCIATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(AHCIATADevState, IBase)) )
398
399
400/*******************************************************************************
401 * Internal Functions *
402 ******************************************************************************/
403RT_C_DECLS_BEGIN
404int ataControllerIOPortWrite1(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t u32, unsigned cb);
405int ataControllerIOPortRead1(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t *u32, unsigned cb);
406int ataControllerIOPortWriteStr1(PAHCIATACONTROLLER pCtl, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb);
407int ataControllerIOPortReadStr1(PAHCIATACONTROLLER pCtl, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb);
408int ataControllerIOPortWrite2(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t u32, unsigned cb);
409int ataControllerIOPortRead2(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t *u32, unsigned cb);
410int ataControllerBMDMAIOPortRead(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t *pu32, unsigned cb);
411int ataControllerBMDMAIOPortWrite(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t u32, unsigned cb);
412RT_C_DECLS_END
413
414#ifdef IN_RING3
415/**
416 * Initialize a controller state.
417 *
418 * @returns VBox status code.
419 * @param pDevIns Pointer to the device instance which creates a controller.
420 * @param pCtl Pointer to the unitialized ATA controller structure.
421 * @param pDrvBaseMaster Pointer to the base driver interface which acts as the master.
422 * @param pDrvBaseSlave Pointer to the base driver interface which acts as the slave.
423 * @param pcbSSMState Where to store the size of the device state for loading/saving.
424 * @param szName Name of the controller (Used to initialize the critical section).
425 */
426int ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl, PPDMIBASE pDrvBaseMaster, PPDMIBASE pDrvBaseSlave,
427 uint32_t *pcbSSMState, const char *szName, PPDMLED pLed, PSTAMCOUNTER pStatBytesRead, PSTAMCOUNTER pStatBytesWritten);
428
429/**
430 * Free all allocated resources for one controller instance.
431 *
432 * @returns VBox status code.
433 * @param pCtl The controller instance.
434 */
435int ataControllerDestroy(PAHCIATACONTROLLER pCtl);
436
437/**
438 * Tests if the controller is idle, leaving the PDM notifications on if busy.
439 *
440 * @returns true if idle, false if idle.
441 * @param pCtl the controller instance.
442 */
443bool ataControllerIsIdle(PAHCIATACONTROLLER pCtl);
444
445/**
446 * Reset a controller instance to an initial state.
447 *
448 * @returns VBox status code.
449 * @param pCtl Pointer to the controller.
450 */
451void ataControllerReset(PAHCIATACONTROLLER pCtl);
452
453/**
454 * Resume operation of an controller.
455 *
456 * @returns nothing
457 * @param pCtl The controller instance.
458 */
459
460void ataControllerResume(PAHCIATACONTROLLER pCtl);
461
462/**
463 * Relocate neccessary pointers.
464 *
465 * @returns nothing.
466 * @param pCtl The controller instance.
467 * @param offDelta The relocation delta relative to the old location.
468 */
469void ataControllerRelocate(PAHCIATACONTROLLER pCtl, RTGCINTPTR offDelta);
470
471/**
472 * Execute state save operation.
473 *
474 * @returns VBox status code.
475 * @param pCtl The controller instance.
476 * @param pSSM SSM operation handle.
477 */
478int ataControllerSaveExec(PAHCIATACONTROLLER pCtl, PSSMHANDLE pSSM);
479
480/**
481 * Excute state load operation.
482 *
483 * @returns VBox status code.
484 * @param pCtl The controller instance.
485 * @param pSSM SSM operation handle.
486 */
487int ataControllerLoadExec(PAHCIATACONTROLLER pCtl, PSSMHANDLE pSSM);
488
489#endif /* IN_RING3 */
490
491#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
492#endif /* !___Storage_ATAController_h */
493
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