VirtualBox

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

Last change on this file since 17995 was 15252, checked in by vboxsync, 16 years ago

ATA/AHCI: Separated the device state structures for the ATA controller again to make it possible to update the LED state and I/O statistics while having the oppurtunity to spot alignment issues in tstDeviceStructSizeGC.

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