VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/DevATA.cpp@ 18434

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

pdmifs.h,DevATA,ATAController,DrvHostDVD: Changed the pcbBuf parameter of PDMIBLOCK::pfnSendCmd from size_t to uint32_t pointer to avoid a bunch of size_t conversion warnings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 256.8 KB
Line 
1/* $Id: DevATA.cpp 18434 2009-03-28 02:19:08Z vboxsync $ */
2/** @file
3 * VBox storage devices: ATA/ATAPI controller device (disk and cdrom).
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/*******************************************************************************
23* Defined Constants And Macros *
24*******************************************************************************/
25/** Temporary instrumentation for tracking down potential virtual disk
26 * write performance issues. */
27#undef VBOX_INSTRUMENT_DMA_WRITES
28
29/**
30 * The SSM saved state versions.
31 */
32#define ATA_SAVED_STATE_VERSION 19
33#define ATA_SAVED_STATE_VERSION_WITH_BOOL_TYPE 18
34#define ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE 16
35#define ATA_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS 17
36
37
38/*******************************************************************************
39* Header Files *
40*******************************************************************************/
41#define LOG_GROUP LOG_GROUP_DEV_IDE
42#include <VBox/pdmdev.h>
43#include <iprt/assert.h>
44#include <iprt/string.h>
45#ifdef IN_RING3
46# include <iprt/uuid.h>
47# include <iprt/semaphore.h>
48# include <iprt/thread.h>
49# include <iprt/time.h>
50# include <iprt/alloc.h>
51#endif /* IN_RING3 */
52#include <iprt/critsect.h>
53#include <iprt/asm.h>
54#include <VBox/stam.h>
55#include <VBox/mm.h>
56#include <VBox/pgm.h>
57
58#include <VBox/scsi.h>
59
60#include "PIIX3ATABmDma.h"
61#include "ide.h"
62#include "../Builtins.h"
63
64/*******************************************************************************
65* Defined Constants And Macros *
66*******************************************************************************/
67/**
68 * Maximum number of sectors to transfer in a READ/WRITE MULTIPLE request.
69 * Set to 1 to disable multi-sector read support. According to the ATA
70 * specification this must be a power of 2 and it must fit in an 8 bit
71 * value. Thus the only valid values are 1, 2, 4, 8, 16, 32, 64 and 128.
72 */
73#define ATA_MAX_MULT_SECTORS 128
74
75/**
76 * Fastest PIO mode supported by the drive.
77 */
78#define ATA_PIO_MODE_MAX 4
79/**
80 * Fastest MDMA mode supported by the drive.
81 */
82#define ATA_MDMA_MODE_MAX 2
83/**
84 * Fastest UDMA mode supported by the drive.
85 */
86#define ATA_UDMA_MODE_MAX 6
87
88/** ATAPI sense info size. */
89#define ATAPI_SENSE_SIZE 64
90
91/** The maximum number of release log entries per device. */
92#define MAX_LOG_REL_ERRORS 1024
93
94/* MediaEventStatus */
95#define ATA_EVENT_STATUS_UNCHANGED 0 /**< medium event status not changed */
96#define ATA_EVENT_STATUS_MEDIA_NEW 1 /**< new medium inserted */
97#define ATA_EVENT_STATUS_MEDIA_REMOVED 2 /**< medium removed */
98#define ATA_EVENT_STATUS_MEDIA_CHANGED 3 /**< medium was removed + new medium was inserted */
99
100/**
101 * Length of the configurable VPD data (without termination)
102 */
103#define ATA_SERIAL_NUMBER_LENGTH 20
104#define ATA_FIRMWARE_REVISION_LENGTH 8
105#define ATA_MODEL_NUMBER_LENGTH 40
106
107/*******************************************************************************
108* Structures and Typedefs *
109*******************************************************************************/
110typedef struct ATADevState {
111 /** Flag indicating whether the current command uses LBA48 mode. */
112 bool fLBA48;
113 /** Flag indicating whether this drive implements the ATAPI command set. */
114 bool fATAPI;
115 /** Set if this interface has asserted the IRQ. */
116 bool fIrqPending;
117 /** Currently configured number of sectors in a multi-sector transfer. */
118 uint8_t cMultSectors;
119 /** PCHS disk geometry. */
120 PDMMEDIAGEOMETRY PCHSGeometry;
121 /** Total number of sectors on this disk. */
122 uint64_t cTotalSectors;
123 /** Number of sectors to transfer per IRQ. */
124 uint32_t cSectorsPerIRQ;
125
126 /** ATA/ATAPI register 1: feature (write-only). */
127 uint8_t uATARegFeature;
128 /** ATA/ATAPI register 1: feature, high order byte. */
129 uint8_t uATARegFeatureHOB;
130 /** ATA/ATAPI register 1: error (read-only). */
131 uint8_t uATARegError;
132 /** ATA/ATAPI register 2: sector count (read/write). */
133 uint8_t uATARegNSector;
134 /** ATA/ATAPI register 2: sector count, high order byte. */
135 uint8_t uATARegNSectorHOB;
136 /** ATA/ATAPI register 3: sector (read/write). */
137 uint8_t uATARegSector;
138 /** ATA/ATAPI register 3: sector, high order byte. */
139 uint8_t uATARegSectorHOB;
140 /** ATA/ATAPI register 4: cylinder low (read/write). */
141 uint8_t uATARegLCyl;
142 /** ATA/ATAPI register 4: cylinder low, high order byte. */
143 uint8_t uATARegLCylHOB;
144 /** ATA/ATAPI register 5: cylinder high (read/write). */
145 uint8_t uATARegHCyl;
146 /** ATA/ATAPI register 5: cylinder high, high order byte. */
147 uint8_t uATARegHCylHOB;
148 /** ATA/ATAPI register 6: select drive/head (read/write). */
149 uint8_t uATARegSelect;
150 /** ATA/ATAPI register 7: status (read-only). */
151 uint8_t uATARegStatus;
152 /** ATA/ATAPI register 7: command (write-only). */
153 uint8_t uATARegCommand;
154 /** ATA/ATAPI drive control register (write-only). */
155 uint8_t uATARegDevCtl;
156
157 /** Currently active transfer mode (MDMA/UDMA) and speed. */
158 uint8_t uATATransferMode;
159 /** Current transfer direction. */
160 uint8_t uTxDir;
161 /** Index of callback for begin transfer. */
162 uint8_t iBeginTransfer;
163 /** Index of callback for source/sink of data. */
164 uint8_t iSourceSink;
165 /** Flag indicating whether the current command transfers data in DMA mode. */
166 bool fDMA;
167 /** Set to indicate that ATAPI transfer semantics must be used. */
168 bool fATAPITransfer;
169
170 /** Total ATA/ATAPI transfer size, shared PIO/DMA. */
171 uint32_t cbTotalTransfer;
172 /** Elementary ATA/ATAPI transfer size, shared PIO/DMA. */
173 uint32_t cbElementaryTransfer;
174 /** Current read/write buffer position, shared PIO/DMA. */
175 uint32_t iIOBufferCur;
176 /** First element beyond end of valid buffer content, shared PIO/DMA. */
177 uint32_t iIOBufferEnd;
178
179 /** ATA/ATAPI current PIO read/write transfer position. Not shared with DMA for safety reasons. */
180 uint32_t iIOBufferPIODataStart;
181 /** ATA/ATAPI current PIO read/write transfer end. Not shared with DMA for safety reasons. */
182 uint32_t iIOBufferPIODataEnd;
183
184 /** ATAPI current LBA position. */
185 uint32_t iATAPILBA;
186 /** ATAPI current sector size. */
187 uint32_t cbATAPISector;
188 /** ATAPI current command. */
189 uint8_t aATAPICmd[ATAPI_PACKET_SIZE];
190 /** ATAPI sense data. */
191 uint8_t abATAPISense[ATAPI_SENSE_SIZE];
192 /** HACK: Countdown till we report a newly unmounted drive as mounted. */
193 uint8_t cNotifiedMediaChange;
194 /** The same for GET_EVENT_STATUS for mechanism */
195 volatile uint32_t MediaEventStatus;
196
197 uint32_t Alignment0;
198
199 /** The status LED state for this drive. */
200 PDMLED Led;
201
202 /** Size of I/O buffer. */
203 uint32_t cbIOBuffer;
204 /** Pointer to the I/O buffer. */
205 R3PTRTYPE(uint8_t *) pbIOBufferR3;
206 /** Pointer to the I/O buffer. */
207 R0PTRTYPE(uint8_t *) pbIOBufferR0;
208 /** Pointer to the I/O buffer. */
209 RCPTRTYPE(uint8_t *) pbIOBufferRC;
210
211 RTRCPTR Aligmnent1; /**< Align the statistics at an 8-byte boundrary. */
212
213 /*
214 * No data that is part of the saved state after this point!!!!!
215 */
216
217 /* Release statistics: number of ATA DMA commands. */
218 STAMCOUNTER StatATADMA;
219 /* Release statistics: number of ATA PIO commands. */
220 STAMCOUNTER StatATAPIO;
221 /* Release statistics: number of ATAPI PIO commands. */
222 STAMCOUNTER StatATAPIDMA;
223 /* Release statistics: number of ATAPI PIO commands. */
224 STAMCOUNTER StatATAPIPIO;
225#ifdef VBOX_INSTRUMENT_DMA_WRITES
226 /* Release statistics: number of DMA sector writes and the time spent. */
227 STAMPROFILEADV StatInstrVDWrites;
228#endif
229
230 /** Statistics: number of read operations and the time spent reading. */
231 STAMPROFILEADV StatReads;
232 /** Statistics: number of bytes read. */
233 STAMCOUNTER StatBytesRead;
234 /** Statistics: number of write operations and the time spent writing. */
235 STAMPROFILEADV StatWrites;
236 /** Statistics: number of bytes written. */
237 STAMCOUNTER StatBytesWritten;
238 /** Statistics: number of flush operations and the time spend flushing. */
239 STAMPROFILE StatFlushes;
240
241 /** Enable passing through commands directly to the ATAPI drive. */
242 bool fATAPIPassthrough;
243 /** Number of errors we've reported to the release log.
244 * This is to prevent flooding caused by something going horribly wrong.
245 * this value against MAX_LOG_REL_ERRORS in places likely to cause floods
246 * like the ones we currently seeing on the linux smoke tests (2006-11-10). */
247 uint32_t cErrors;
248 /** Timestamp of last started command. 0 if no command pending. */
249 uint64_t u64CmdTS;
250
251 /** Pointer to the attached driver's base interface. */
252 R3PTRTYPE(PPDMIBASE) pDrvBase;
253 /** Pointer to the attached driver's block interface. */
254 R3PTRTYPE(PPDMIBLOCK) pDrvBlock;
255 /** Pointer to the attached driver's block bios interface. */
256 R3PTRTYPE(PPDMIBLOCKBIOS) pDrvBlockBios;
257 /** Pointer to the attached driver's mount interface.
258 * This is NULL if the driver isn't a removable unit. */
259 R3PTRTYPE(PPDMIMOUNT) pDrvMount;
260 /** The base interface. */
261 PDMIBASE IBase;
262 /** The block port interface. */
263 PDMIBLOCKPORT IPort;
264 /** The mount notify interface. */
265 PDMIMOUNTNOTIFY IMountNotify;
266 /** The LUN #. */
267 RTUINT iLUN;
268#if HC_ARCH_BITS == 64
269 RTUINT Alignment2; /**< Align pDevInsR3 correctly. */
270#endif
271 /** Pointer to device instance. */
272 PPDMDEVINSR3 pDevInsR3;
273 /** Pointer to controller instance. */
274 R3PTRTYPE(struct ATACONTROLLER *) pControllerR3;
275 /** Pointer to device instance. */
276 PPDMDEVINSR0 pDevInsR0;
277 /** Pointer to controller instance. */
278 R0PTRTYPE(struct ATACONTROLLER *) pControllerR0;
279 /** Pointer to device instance. */
280 PPDMDEVINSRC pDevInsRC;
281 /** Pointer to controller instance. */
282 RCPTRTYPE(struct ATACONTROLLER *) pControllerRC;
283
284 /** The serial numnber to use for IDENTIFY DEVICE commands. */
285 char szSerialNumber[ATA_SERIAL_NUMBER_LENGTH+1];
286 /** The firmware revision to use for IDENTIFY DEVICE commands. */
287 char szFirmwareRevision[ATA_FIRMWARE_REVISION_LENGTH+1];
288 /** The model number to use for IDENTIFY DEVICE commands. */
289 char szModelNumber[ATA_MODEL_NUMBER_LENGTH+1];
290
291#if HC_ARCH_BITS == 64
292 uint32_t Alignment3[2];
293#endif
294} ATADevState;
295
296
297typedef struct ATATransferRequest
298{
299 uint8_t iIf;
300 uint8_t iBeginTransfer;
301 uint8_t iSourceSink;
302 uint32_t cbTotalTransfer;
303 uint8_t uTxDir;
304} ATATransferRequest;
305
306
307typedef struct ATAAbortRequest
308{
309 uint8_t iIf;
310 bool fResetDrive;
311} ATAAbortRequest;
312
313
314typedef enum
315{
316 /** Begin a new transfer. */
317 ATA_AIO_NEW = 0,
318 /** Continue a DMA transfer. */
319 ATA_AIO_DMA,
320 /** Continue a PIO transfer. */
321 ATA_AIO_PIO,
322 /** Reset the drives on current controller, stop all transfer activity. */
323 ATA_AIO_RESET_ASSERTED,
324 /** Reset the drives on current controller, resume operation. */
325 ATA_AIO_RESET_CLEARED,
326 /** Abort the current transfer of a particular drive. */
327 ATA_AIO_ABORT
328} ATAAIO;
329
330
331typedef struct ATARequest
332{
333 ATAAIO ReqType;
334 union
335 {
336 ATATransferRequest t;
337 ATAAbortRequest a;
338 } u;
339} ATARequest;
340
341
342typedef struct ATACONTROLLER
343{
344 /** The base of the first I/O Port range. */
345 RTIOPORT IOPortBase1;
346 /** The base of the second I/O Port range. (0 if none) */
347 RTIOPORT IOPortBase2;
348 /** The assigned IRQ. */
349 RTUINT irq;
350 /** Access critical section */
351 PDMCRITSECT lock;
352
353 /** Selected drive. */
354 uint8_t iSelectedIf;
355 /** The interface on which to handle async I/O. */
356 uint8_t iAIOIf;
357 /** The state of the async I/O thread. */
358 uint8_t uAsyncIOState;
359 /** Flag indicating whether the next transfer is part of the current command. */
360 bool fChainedTransfer;
361 /** Set when the reset processing is currently active on this controller. */
362 bool fReset;
363 /** Flag whether the current transfer needs to be redone. */
364 bool fRedo;
365 /** Flag whether the redo suspend has been finished. */
366 bool fRedoIdle;
367 /** Flag whether the DMA operation to be redone is the final transfer. */
368 bool fRedoDMALastDesc;
369 /** The BusMaster DMA state. */
370 BMDMAState BmDma;
371 /** Pointer to first DMA descriptor. */
372 RTGCPHYS32 pFirstDMADesc;
373 /** Pointer to last DMA descriptor. */
374 RTGCPHYS32 pLastDMADesc;
375 /** Pointer to current DMA buffer (for redo operations). */
376 RTGCPHYS32 pRedoDMABuffer;
377 /** Size of current DMA buffer (for redo operations). */
378 uint32_t cbRedoDMABuffer;
379
380 /** The ATA/ATAPI interfaces of this controller. */
381 ATADevState aIfs[2];
382
383 /** Pointer to device instance. */
384 PPDMDEVINSR3 pDevInsR3;
385 /** Pointer to device instance. */
386 PPDMDEVINSR0 pDevInsR0;
387 /** Pointer to device instance. */
388 PPDMDEVINSRC pDevInsRC;
389
390 /** Set when the destroying the device instance and the thread must exit. */
391 uint32_t volatile fShutdown;
392 /** The async I/O thread handle. NIL_RTTHREAD if no thread. */
393 RTTHREAD AsyncIOThread;
394 /** The event semaphore the thread is waiting on for requests. */
395 RTSEMEVENT AsyncIOSem;
396 /** The request queue for the AIO thread. One element is always unused. */
397 ATARequest aAsyncIORequests[4];
398 /** The position at which to insert a new request for the AIO thread. */
399 uint8_t AsyncIOReqHead;
400 /** The position at which to get a new request for the AIO thread. */
401 uint8_t AsyncIOReqTail;
402 uint8_t Alignment3[2]; /**< Explicit padding of the 2 byte gap. */
403 /** Magic delay before triggering interrupts in DMA mode. */
404 uint32_t DelayIRQMillies;
405 /** The mutex protecting the request queue. */
406 RTSEMMUTEX AsyncIORequestMutex;
407 /** The event semaphore the thread is waiting on during suspended I/O. */
408 RTSEMEVENT SuspendIOSem;
409#if 0 /*HC_ARCH_BITS == 32*/
410 uint32_t Alignment0;
411#endif
412
413 /** Timestamp we started the reset. */
414 uint64_t u64ResetTime;
415
416 /* Statistics */
417 STAMCOUNTER StatAsyncOps;
418 uint64_t StatAsyncMinWait;
419 uint64_t StatAsyncMaxWait;
420 STAMCOUNTER StatAsyncTimeUS;
421 STAMPROFILEADV StatAsyncTime;
422 STAMPROFILE StatLockWait;
423} ATACONTROLLER, *PATACONTROLLER;
424
425typedef enum CHIPSET
426{
427 /** PIIX3 chipset, must be 0 for saved state compatibility */
428 CHIPSET_PIIX3 = 0,
429 /** PIIX4 chipset, must be 1 for saved state compatibility */
430 CHIPSET_PIIX4 = 1,
431 /** ICH6 chipset */
432 CHIPSET_ICH6 = 2
433} CHIPSET;
434
435typedef struct PCIATAState {
436 PCIDEVICE dev;
437 /** The controllers. */
438 ATACONTROLLER aCts[2];
439 /** Pointer to device instance. */
440 PPDMDEVINSR3 pDevIns;
441 /** Status Port - Base interface. */
442 PDMIBASE IBase;
443 /** Status Port - Leds interface. */
444 PDMILEDPORTS ILeds;
445 /** Partner of ILeds. */
446 R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector;
447 /** Flag whether GC is enabled. */
448 bool fGCEnabled;
449 /** Flag whether R0 is enabled. */
450 bool fR0Enabled;
451 /** Flag indicating chipset being emulated. */
452 uint8_t u8Type;
453 bool Alignment0[HC_ARCH_BITS == 64 ? 5 : 1 ]; /**< Align the struct size. */
454} PCIATAState;
455
456#define PDMIBASE_2_PCIATASTATE(pInterface) ( (PCIATAState *)((uintptr_t)(pInterface) - RT_OFFSETOF(PCIATAState, IBase)) )
457#define PDMILEDPORTS_2_PCIATASTATE(pInterface) ( (PCIATAState *)((uintptr_t)(pInterface) - RT_OFFSETOF(PCIATAState, ILeds)) )
458#define PDMIBLOCKPORT_2_ATASTATE(pInterface) ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IPort)) )
459#define PDMIMOUNT_2_ATASTATE(pInterface) ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IMount)) )
460#define PDMIMOUNTNOTIFY_2_ATASTATE(pInterface) ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IMountNotify)) )
461#define PCIDEV_2_PCIATASTATE(pPciDev) ( (PCIATAState *)(pPciDev) )
462
463#define ATACONTROLLER_IDX(pController) ( (pController) - PDMINS_2_DATA(CONTROLLER_2_DEVINS(pController), PCIATAState *)->aCts )
464
465#define ATADEVSTATE_2_CONTROLLER(pIf) ( (pIf)->CTX_SUFF(pController) )
466#define ATADEVSTATE_2_DEVINS(pIf) ( (pIf)->CTX_SUFF(pDevIns) )
467#define CONTROLLER_2_DEVINS(pController) ( (pController)->CTX_SUFF(pDevIns) )
468#define PDMIBASE_2_ATASTATE(pInterface) ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IBase)) )
469
470#ifndef VBOX_DEVICE_STRUCT_TESTCASE
471/*******************************************************************************
472 * Internal Functions *
473 ******************************************************************************/
474__BEGIN_DECLS
475PDMBOTHCBDECL(int) ataIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
476PDMBOTHCBDECL(int) ataIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *u32, unsigned cb);
477PDMBOTHCBDECL(int) ataIOPortWriteStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb);
478PDMBOTHCBDECL(int) ataIOPortReadStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb);
479PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
480PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *u32, unsigned cb);
481PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
482PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
483__END_DECLS
484
485
486
487DECLINLINE(void) ataSetStatusValue(ATADevState *s, uint8_t stat)
488{
489 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
490
491 /* Freeze status register contents while processing RESET. */
492 if (!pCtl->fReset)
493 {
494 s->uATARegStatus = stat;
495 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, s->iLUN, s->uATARegStatus));
496 }
497}
498
499
500DECLINLINE(void) ataSetStatus(ATADevState *s, uint8_t stat)
501{
502 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
503
504 /* Freeze status register contents while processing RESET. */
505 if (!pCtl->fReset)
506 {
507 s->uATARegStatus |= stat;
508 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, s->iLUN, s->uATARegStatus));
509 }
510}
511
512
513DECLINLINE(void) ataUnsetStatus(ATADevState *s, uint8_t stat)
514{
515 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
516
517 /* Freeze status register contents while processing RESET. */
518 if (!pCtl->fReset)
519 {
520 s->uATARegStatus &= ~stat;
521 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, s->iLUN, s->uATARegStatus));
522 }
523}
524
525#ifdef IN_RING3
526
527typedef void (*PBeginTransferFunc)(ATADevState *);
528typedef bool (*PSourceSinkFunc)(ATADevState *);
529
530static void ataReadWriteSectorsBT(ATADevState *);
531static void ataPacketBT(ATADevState *);
532static void atapiCmdBT(ATADevState *);
533static void atapiPassthroughCmdBT(ATADevState *);
534
535static bool ataIdentifySS(ATADevState *);
536static bool ataFlushSS(ATADevState *);
537static bool ataReadSectorsSS(ATADevState *);
538static bool ataWriteSectorsSS(ATADevState *);
539static bool ataExecuteDeviceDiagnosticSS(ATADevState *);
540static bool ataPacketSS(ATADevState *);
541static bool atapiGetConfigurationSS(ATADevState *);
542static bool atapiGetEventStatusNotificationSS(ATADevState *);
543static bool atapiIdentifySS(ATADevState *);
544static bool atapiInquirySS(ATADevState *);
545static bool atapiMechanismStatusSS(ATADevState *);
546static bool atapiModeSenseErrorRecoverySS(ATADevState *);
547static bool atapiModeSenseCDStatusSS(ATADevState *);
548static bool atapiReadSS(ATADevState *);
549static bool atapiReadCapacitySS(ATADevState *);
550static bool atapiReadDiscInformationSS(ATADevState *);
551static bool atapiReadTOCNormalSS(ATADevState *);
552static bool atapiReadTOCMultiSS(ATADevState *);
553static bool atapiReadTOCRawSS(ATADevState *);
554static bool atapiReadTrackInformationSS(ATADevState *);
555static bool atapiRequestSenseSS(ATADevState *);
556static bool atapiPassthroughSS(ATADevState *);
557static bool atapiReadDVDStructureSS(ATADevState *);
558
559/**
560 * Begin of transfer function indexes for g_apfnBeginTransFuncs.
561 */
562typedef enum ATAFNBT
563{
564 ATAFN_BT_NULL = 0,
565 ATAFN_BT_READ_WRITE_SECTORS,
566 ATAFN_BT_PACKET,
567 ATAFN_BT_ATAPI_CMD,
568 ATAFN_BT_ATAPI_PASSTHROUGH_CMD,
569 ATAFN_BT_MAX
570} ATAFNBT;
571
572/**
573 * Array of end transfer functions, the index is ATAFNET.
574 * Make sure ATAFNET and this array match!
575 */
576static const PBeginTransferFunc g_apfnBeginTransFuncs[ATAFN_BT_MAX] =
577{
578 NULL,
579 ataReadWriteSectorsBT,
580 ataPacketBT,
581 atapiCmdBT,
582 atapiPassthroughCmdBT,
583};
584
585/**
586 * Source/sink function indexes for g_apfnSourceSinkFuncs.
587 */
588typedef enum ATAFNSS
589{
590 ATAFN_SS_NULL = 0,
591 ATAFN_SS_IDENTIFY,
592 ATAFN_SS_FLUSH,
593 ATAFN_SS_READ_SECTORS,
594 ATAFN_SS_WRITE_SECTORS,
595 ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC,
596 ATAFN_SS_PACKET,
597 ATAFN_SS_ATAPI_GET_CONFIGURATION,
598 ATAFN_SS_ATAPI_GET_EVENT_STATUS_NOTIFICATION,
599 ATAFN_SS_ATAPI_IDENTIFY,
600 ATAFN_SS_ATAPI_INQUIRY,
601 ATAFN_SS_ATAPI_MECHANISM_STATUS,
602 ATAFN_SS_ATAPI_MODE_SENSE_ERROR_RECOVERY,
603 ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS,
604 ATAFN_SS_ATAPI_READ,
605 ATAFN_SS_ATAPI_READ_CAPACITY,
606 ATAFN_SS_ATAPI_READ_DISC_INFORMATION,
607 ATAFN_SS_ATAPI_READ_TOC_NORMAL,
608 ATAFN_SS_ATAPI_READ_TOC_MULTI,
609 ATAFN_SS_ATAPI_READ_TOC_RAW,
610 ATAFN_SS_ATAPI_READ_TRACK_INFORMATION,
611 ATAFN_SS_ATAPI_REQUEST_SENSE,
612 ATAFN_SS_ATAPI_PASSTHROUGH,
613 ATAFN_SS_ATAPI_READ_DVD_STRUCTURE,
614 ATAFN_SS_MAX
615} ATAFNSS;
616
617/**
618 * Array of source/sink functions, the index is ATAFNSS.
619 * Make sure ATAFNSS and this array match!
620 */
621static const PSourceSinkFunc g_apfnSourceSinkFuncs[ATAFN_SS_MAX] =
622{
623 NULL,
624 ataIdentifySS,
625 ataFlushSS,
626 ataReadSectorsSS,
627 ataWriteSectorsSS,
628 ataExecuteDeviceDiagnosticSS,
629 ataPacketSS,
630 atapiGetConfigurationSS,
631 atapiGetEventStatusNotificationSS,
632 atapiIdentifySS,
633 atapiInquirySS,
634 atapiMechanismStatusSS,
635 atapiModeSenseErrorRecoverySS,
636 atapiModeSenseCDStatusSS,
637 atapiReadSS,
638 atapiReadCapacitySS,
639 atapiReadDiscInformationSS,
640 atapiReadTOCNormalSS,
641 atapiReadTOCMultiSS,
642 atapiReadTOCRawSS,
643 atapiReadTrackInformationSS,
644 atapiRequestSenseSS,
645 atapiPassthroughSS,
646 atapiReadDVDStructureSS
647};
648
649
650static const ATARequest ataDMARequest = { ATA_AIO_DMA, };
651static const ATARequest ataPIORequest = { ATA_AIO_PIO, };
652static const ATARequest ataResetARequest = { ATA_AIO_RESET_ASSERTED, };
653static const ATARequest ataResetCRequest = { ATA_AIO_RESET_CLEARED, };
654
655
656static void ataAsyncIOClearRequests(PATACONTROLLER pCtl)
657{
658 int rc;
659
660 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
661 AssertRC(rc);
662 pCtl->AsyncIOReqHead = 0;
663 pCtl->AsyncIOReqTail = 0;
664 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
665 AssertRC(rc);
666}
667
668
669static void ataAsyncIOPutRequest(PATACONTROLLER pCtl, const ATARequest *pReq)
670{
671 int rc;
672
673 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
674 AssertRC(rc);
675 Assert((pCtl->AsyncIOReqHead + 1) % RT_ELEMENTS(pCtl->aAsyncIORequests) != pCtl->AsyncIOReqTail);
676 memcpy(&pCtl->aAsyncIORequests[pCtl->AsyncIOReqHead], pReq, sizeof(*pReq));
677 pCtl->AsyncIOReqHead++;
678 pCtl->AsyncIOReqHead %= RT_ELEMENTS(pCtl->aAsyncIORequests);
679 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
680 AssertRC(rc);
681 LogBird(("ata: %x: signalling\n", pCtl->IOPortBase1));
682 rc = PDMR3CritSectScheduleExitEvent(&pCtl->lock, pCtl->AsyncIOSem);
683 if (RT_FAILURE(rc))
684 {
685 LogBird(("ata: %x: schedule failed, rc=%Rrc\n", pCtl->IOPortBase1, rc));
686 rc = RTSemEventSignal(pCtl->AsyncIOSem);
687 AssertRC(rc);
688 }
689}
690
691
692static const ATARequest *ataAsyncIOGetCurrentRequest(PATACONTROLLER pCtl)
693{
694 int rc;
695 const ATARequest *pReq;
696
697 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
698 AssertRC(rc);
699 if (pCtl->AsyncIOReqHead != pCtl->AsyncIOReqTail)
700 pReq = &pCtl->aAsyncIORequests[pCtl->AsyncIOReqTail];
701 else
702 pReq = NULL;
703 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
704 AssertRC(rc);
705 return pReq;
706}
707
708
709/**
710 * Remove the request with the given type, as it's finished. The request
711 * is not removed blindly, as this could mean a RESET request that is not
712 * yet processed (but has cleared the request queue) is lost.
713 *
714 * @param pCtl Controller for which to remove the request.
715 * @param ReqType Type of the request to remove.
716 */
717static void ataAsyncIORemoveCurrentRequest(PATACONTROLLER pCtl, ATAAIO ReqType)
718{
719 int rc;
720
721 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
722 AssertRC(rc);
723 if (pCtl->AsyncIOReqHead != pCtl->AsyncIOReqTail && pCtl->aAsyncIORequests[pCtl->AsyncIOReqTail].ReqType == ReqType)
724 {
725 pCtl->AsyncIOReqTail++;
726 pCtl->AsyncIOReqTail %= RT_ELEMENTS(pCtl->aAsyncIORequests);
727 }
728 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
729 AssertRC(rc);
730}
731
732
733/**
734 * Dump the request queue for a particular controller. First dump the queue
735 * contents, then the already processed entries, as long as they haven't been
736 * overwritten.
737 *
738 * @param pCtl Controller for which to dump the queue.
739 */
740static void ataAsyncIODumpRequests(PATACONTROLLER pCtl)
741{
742 int rc;
743 uint8_t curr;
744
745 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
746 AssertRC(rc);
747 LogRel(("PIIX3 ATA: Ctl#%d: request queue dump (topmost is current):\n", ATACONTROLLER_IDX(pCtl)));
748 curr = pCtl->AsyncIOReqTail;
749 do
750 {
751 if (curr == pCtl->AsyncIOReqHead)
752 LogRel(("PIIX3 ATA: Ctl#%d: processed requests (topmost is oldest):\n", ATACONTROLLER_IDX(pCtl)));
753 switch (pCtl->aAsyncIORequests[curr].ReqType)
754 {
755 case ATA_AIO_NEW:
756 LogRel(("new transfer request, iIf=%d iBeginTransfer=%d iSourceSink=%d cbTotalTransfer=%d uTxDir=%d\n", pCtl->aAsyncIORequests[curr].u.t.iIf, pCtl->aAsyncIORequests[curr].u.t.iBeginTransfer, pCtl->aAsyncIORequests[curr].u.t.iSourceSink, pCtl->aAsyncIORequests[curr].u.t.cbTotalTransfer, pCtl->aAsyncIORequests[curr].u.t.uTxDir));
757 break;
758 case ATA_AIO_DMA:
759 LogRel(("dma transfer finished\n"));
760 break;
761 case ATA_AIO_PIO:
762 LogRel(("pio transfer finished\n"));
763 break;
764 case ATA_AIO_RESET_ASSERTED:
765 LogRel(("reset asserted request\n"));
766 break;
767 case ATA_AIO_RESET_CLEARED:
768 LogRel(("reset cleared request\n"));
769 break;
770 case ATA_AIO_ABORT:
771 LogRel(("abort request, iIf=%d fResetDrive=%d\n", pCtl->aAsyncIORequests[curr].u.a.iIf, pCtl->aAsyncIORequests[curr].u.a.fResetDrive));
772 break;
773 default:
774 LogRel(("unknown request %d\n", pCtl->aAsyncIORequests[curr].ReqType));
775 }
776 curr = (curr + 1) % RT_ELEMENTS(pCtl->aAsyncIORequests);
777 } while (curr != pCtl->AsyncIOReqTail);
778 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
779 AssertRC(rc);
780}
781
782
783/**
784 * Checks whether the request queue for a particular controller is empty
785 * or whether a particular controller is idle.
786 *
787 * @param pCtl Controller for which to check the queue.
788 * @param fStrict If set then the controller is checked to be idle.
789 */
790static bool ataAsyncIOIsIdle(PATACONTROLLER pCtl, bool fStrict)
791{
792 int rc;
793 bool fIdle;
794
795 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
796 AssertRC(rc);
797 fIdle = pCtl->fRedoIdle;
798 if (!fIdle)
799 fIdle = (pCtl->AsyncIOReqHead == pCtl->AsyncIOReqTail);
800 if (fStrict)
801 fIdle &= (pCtl->uAsyncIOState == ATA_AIO_NEW);
802 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
803 AssertRC(rc);
804 return fIdle;
805}
806
807
808/**
809 * Send a transfer request to the async I/O thread.
810 *
811 * @param s Pointer to the ATA device state data.
812 * @param cbTotalTransfer Data transfer size.
813 * @param uTxDir Data transfer direction.
814 * @param iBeginTransfer Index of BeginTransfer callback.
815 * @param iSourceSink Index of SourceSink callback.
816 * @param fChainedTransfer Whether this is a transfer that is part of the previous command/transfer.
817 */
818static void ataStartTransfer(ATADevState *s, uint32_t cbTotalTransfer, uint8_t uTxDir, ATAFNBT iBeginTransfer, ATAFNSS iSourceSink, bool fChainedTransfer)
819{
820 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
821 ATARequest Req;
822
823 Assert(PDMCritSectIsOwner(&pCtl->lock));
824
825 /* Do not issue new requests while the RESET line is asserted. */
826 if (pCtl->fReset)
827 {
828 Log2(("%s: Ctl#%d: suppressed new request as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
829 return;
830 }
831
832 /* If the controller is already doing something else right now, ignore
833 * the command that is being submitted. Some broken guests issue commands
834 * twice (e.g. the Linux kernel that comes with Acronis True Image 8). */
835 if (!fChainedTransfer && !ataAsyncIOIsIdle(pCtl, true))
836 {
837 Log(("%s: Ctl#%d: ignored command %#04x, controller state %d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegCommand, pCtl->uAsyncIOState));
838 LogRel(("PIIX3 IDE: guest issued command %#04x while controller busy\n", s->uATARegCommand));
839 return;
840 }
841
842 Req.ReqType = ATA_AIO_NEW;
843 if (fChainedTransfer)
844 Req.u.t.iIf = pCtl->iAIOIf;
845 else
846 Req.u.t.iIf = pCtl->iSelectedIf;
847 Req.u.t.cbTotalTransfer = cbTotalTransfer;
848 Req.u.t.uTxDir = uTxDir;
849 Req.u.t.iBeginTransfer = iBeginTransfer;
850 Req.u.t.iSourceSink = iSourceSink;
851 ataSetStatusValue(s, ATA_STAT_BUSY);
852 pCtl->fChainedTransfer = fChainedTransfer;
853
854 /*
855 * Kick the worker thread into action.
856 */
857 Log2(("%s: Ctl#%d: message to async I/O thread, new request\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
858 ataAsyncIOPutRequest(pCtl, &Req);
859}
860
861
862/**
863 * Send an abort command request to the async I/O thread.
864 *
865 * @param s Pointer to the ATA device state data.
866 * @param fResetDrive Whether to reset the drive or just abort a command.
867 */
868static void ataAbortCurrentCommand(ATADevState *s, bool fResetDrive)
869{
870 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
871 ATARequest Req;
872
873 Assert(PDMCritSectIsOwner(&pCtl->lock));
874
875 /* Do not issue new requests while the RESET line is asserted. */
876 if (pCtl->fReset)
877 {
878 Log2(("%s: Ctl#%d: suppressed aborting command as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
879 return;
880 }
881
882 Req.ReqType = ATA_AIO_ABORT;
883 Req.u.a.iIf = pCtl->iSelectedIf;
884 Req.u.a.fResetDrive = fResetDrive;
885 ataSetStatus(s, ATA_STAT_BUSY);
886 Log2(("%s: Ctl#%d: message to async I/O thread, abort command on LUN#%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->iLUN));
887 ataAsyncIOPutRequest(pCtl, &Req);
888}
889
890
891static void ataSetIRQ(ATADevState *s)
892{
893 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
894 PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
895
896 if (!(s->uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ))
897 {
898 Log2(("%s: LUN#%d asserting IRQ\n", __FUNCTION__, s->iLUN));
899 /* The BMDMA unit unconditionally sets BM_STATUS_INT if the interrupt
900 * line is asserted. It monitors the line for a rising edge. */
901 if (!s->fIrqPending)
902 pCtl->BmDma.u8Status |= BM_STATUS_INT;
903 /* Only actually set the IRQ line if updating the currently selected drive. */
904 if (s == &pCtl->aIfs[pCtl->iSelectedIf])
905 {
906 /** @todo experiment with adaptive IRQ delivery: for reads it is
907 * better to wait for IRQ delivery, as it reduces latency. */
908 if (pCtl->irq == 16)
909 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
910 else
911 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
912 }
913 }
914 s->fIrqPending = true;
915}
916
917#endif /* IN_RING3 */
918
919static void ataUnsetIRQ(ATADevState *s)
920{
921 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
922 PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
923
924 if (!(s->uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ))
925 {
926 Log2(("%s: LUN#%d deasserting IRQ\n", __FUNCTION__, s->iLUN));
927 /* Only actually unset the IRQ line if updating the currently selected drive. */
928 if (s == &pCtl->aIfs[pCtl->iSelectedIf])
929 {
930 if (pCtl->irq == 16)
931 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
932 else
933 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
934 }
935 }
936 s->fIrqPending = false;
937}
938
939#ifdef IN_RING3
940
941static void ataPIOTransferStart(ATADevState *s, uint32_t start, uint32_t size)
942{
943 Log2(("%s: LUN#%d start %d size %d\n", __FUNCTION__, s->iLUN, start, size));
944 s->iIOBufferPIODataStart = start;
945 s->iIOBufferPIODataEnd = start + size;
946 ataSetStatus(s, ATA_STAT_DRQ);
947}
948
949
950static void ataPIOTransferStop(ATADevState *s)
951{
952 Log2(("%s: LUN#%d\n", __FUNCTION__, s->iLUN));
953 if (s->fATAPITransfer)
954 {
955 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
956 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
957 ataSetIRQ(s);
958 s->fATAPITransfer = false;
959 }
960 s->cbTotalTransfer = 0;
961 s->cbElementaryTransfer = 0;
962 s->iIOBufferPIODataStart = 0;
963 s->iIOBufferPIODataEnd = 0;
964 s->iBeginTransfer = ATAFN_BT_NULL;
965 s->iSourceSink = ATAFN_SS_NULL;
966}
967
968
969static void ataPIOTransferLimitATAPI(ATADevState *s)
970{
971 uint32_t cbLimit, cbTransfer;
972
973 cbLimit = s->uATARegLCyl | (s->uATARegHCyl << 8);
974 /* Use maximum transfer size if the guest requested 0. Avoids a hang. */
975 if (cbLimit == 0)
976 cbLimit = 0xfffe;
977 Log2(("%s: byte count limit=%d\n", __FUNCTION__, cbLimit));
978 if (cbLimit == 0xffff)
979 cbLimit--;
980 cbTransfer = RT_MIN(s->cbTotalTransfer, s->iIOBufferEnd - s->iIOBufferCur);
981 if (cbTransfer > cbLimit)
982 {
983 /* Byte count limit for clipping must be even in this case */
984 if (cbLimit & 1)
985 cbLimit--;
986 cbTransfer = cbLimit;
987 }
988 s->uATARegLCyl = cbTransfer;
989 s->uATARegHCyl = cbTransfer >> 8;
990 s->cbElementaryTransfer = cbTransfer;
991}
992
993
994static uint32_t ataGetNSectors(ATADevState *s)
995{
996 /* 0 means either 256 (LBA28) or 65536 (LBA48) sectors. */
997 if (s->fLBA48)
998 {
999 if (!s->uATARegNSector && !s->uATARegNSectorHOB)
1000 return 65536;
1001 else
1002 return s->uATARegNSectorHOB << 8 | s->uATARegNSector;
1003 }
1004 else
1005 {
1006 if (!s->uATARegNSector)
1007 return 256;
1008 else
1009 return s->uATARegNSector;
1010 }
1011}
1012
1013
1014static void ataPadString(uint8_t *pbDst, const char *pbSrc, uint32_t cbSize)
1015{
1016 for (uint32_t i = 0; i < cbSize; i++)
1017 {
1018 if (*pbSrc)
1019 pbDst[i ^ 1] = *pbSrc++;
1020 else
1021 pbDst[i ^ 1] = ' ';
1022 }
1023}
1024
1025
1026static void ataSCSIPadStr(uint8_t *pbDst, const char *pbSrc, uint32_t cbSize)
1027{
1028 for (uint32_t i = 0; i < cbSize; i++)
1029 {
1030 if (*pbSrc)
1031 pbDst[i] = *pbSrc++;
1032 else
1033 pbDst[i] = ' ';
1034 }
1035}
1036
1037
1038DECLINLINE(void) ataH2BE_U16(uint8_t *pbBuf, uint16_t val)
1039{
1040 pbBuf[0] = val >> 8;
1041 pbBuf[1] = val;
1042}
1043
1044
1045DECLINLINE(void) ataH2BE_U24(uint8_t *pbBuf, uint32_t val)
1046{
1047 pbBuf[0] = val >> 16;
1048 pbBuf[1] = val >> 8;
1049 pbBuf[2] = val;
1050}
1051
1052
1053DECLINLINE(void) ataH2BE_U32(uint8_t *pbBuf, uint32_t val)
1054{
1055 pbBuf[0] = val >> 24;
1056 pbBuf[1] = val >> 16;
1057 pbBuf[2] = val >> 8;
1058 pbBuf[3] = val;
1059}
1060
1061
1062DECLINLINE(uint16_t) ataBE2H_U16(const uint8_t *pbBuf)
1063{
1064 return (pbBuf[0] << 8) | pbBuf[1];
1065}
1066
1067
1068DECLINLINE(uint32_t) ataBE2H_U24(const uint8_t *pbBuf)
1069{
1070 return (pbBuf[0] << 16) | (pbBuf[1] << 8) | pbBuf[2];
1071}
1072
1073
1074DECLINLINE(uint32_t) ataBE2H_U32(const uint8_t *pbBuf)
1075{
1076 return (pbBuf[0] << 24) | (pbBuf[1] << 16) | (pbBuf[2] << 8) | pbBuf[3];
1077}
1078
1079
1080DECLINLINE(void) ataLBA2MSF(uint8_t *pbBuf, uint32_t iATAPILBA)
1081{
1082 iATAPILBA += 150;
1083 pbBuf[0] = (iATAPILBA / 75) / 60;
1084 pbBuf[1] = (iATAPILBA / 75) % 60;
1085 pbBuf[2] = iATAPILBA % 75;
1086}
1087
1088
1089DECLINLINE(uint32_t) ataMSF2LBA(const uint8_t *pbBuf)
1090{
1091 return (pbBuf[0] * 60 + pbBuf[1]) * 75 + pbBuf[2];
1092}
1093
1094
1095static void ataCmdOK(ATADevState *s, uint8_t status)
1096{
1097 s->uATARegError = 0; /* Not needed by ATA spec, but cannot hurt. */
1098 ataSetStatusValue(s, ATA_STAT_READY | status);
1099}
1100
1101
1102static void ataCmdError(ATADevState *s, uint8_t uErrorCode)
1103{
1104 Log(("%s: code=%#x\n", __FUNCTION__, uErrorCode));
1105 s->uATARegError = uErrorCode;
1106 ataSetStatusValue(s, ATA_STAT_READY | ATA_STAT_ERR);
1107 s->cbTotalTransfer = 0;
1108 s->cbElementaryTransfer = 0;
1109 s->iIOBufferCur = 0;
1110 s->iIOBufferEnd = 0;
1111 s->uTxDir = PDMBLOCKTXDIR_NONE;
1112 s->iBeginTransfer = ATAFN_BT_NULL;
1113 s->iSourceSink = ATAFN_SS_NULL;
1114}
1115
1116
1117static bool ataIdentifySS(ATADevState *s)
1118{
1119 uint16_t *p;
1120
1121 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1122 Assert(s->cbElementaryTransfer == 512);
1123
1124 p = (uint16_t *)s->CTX_SUFF(pbIOBuffer);
1125 memset(p, 0, 512);
1126 p[0] = RT_H2LE_U16(0x0040);
1127 p[1] = RT_H2LE_U16(RT_MIN(s->PCHSGeometry.cCylinders, 16383));
1128 p[3] = RT_H2LE_U16(s->PCHSGeometry.cHeads);
1129 /* Block size; obsolete, but required for the BIOS. */
1130 p[5] = RT_H2LE_U16(512);
1131 p[6] = RT_H2LE_U16(s->PCHSGeometry.cSectors);
1132 ataPadString((uint8_t *)(p + 10), s->szSerialNumber, ATA_SERIAL_NUMBER_LENGTH); /* serial number */
1133 p[20] = RT_H2LE_U16(3); /* XXX: retired, cache type */
1134 p[21] = RT_H2LE_U16(512); /* XXX: retired, cache size in sectors */
1135 p[22] = RT_H2LE_U16(0); /* ECC bytes per sector */
1136 ataPadString((uint8_t *)(p + 23), s->szFirmwareRevision, ATA_FIRMWARE_REVISION_LENGTH); /* firmware version */
1137 ataPadString((uint8_t *)(p + 27), s->szModelNumber, ATA_MODEL_NUMBER_LENGTH); /* model */
1138#if ATA_MAX_MULT_SECTORS > 1
1139 p[47] = RT_H2LE_U16(0x8000 | ATA_MAX_MULT_SECTORS);
1140#endif
1141 p[48] = RT_H2LE_U16(1); /* dword I/O, used by the BIOS */
1142 p[49] = RT_H2LE_U16(1 << 11 | 1 << 9 | 1 << 8); /* DMA and LBA supported */
1143 p[50] = RT_H2LE_U16(1 << 14); /* No drive specific standby timer minimum */
1144 p[51] = RT_H2LE_U16(240); /* PIO transfer cycle */
1145 p[52] = RT_H2LE_U16(240); /* DMA transfer cycle */
1146 p[53] = RT_H2LE_U16(1 | 1 << 1 | 1 << 2); /* words 54-58,64-70,88 valid */
1147 p[54] = RT_H2LE_U16(RT_MIN(s->PCHSGeometry.cCylinders, 16383));
1148 p[55] = RT_H2LE_U16(s->PCHSGeometry.cHeads);
1149 p[56] = RT_H2LE_U16(s->PCHSGeometry.cSectors);
1150 p[57] = RT_H2LE_U16( RT_MIN(s->PCHSGeometry.cCylinders, 16383)
1151 * s->PCHSGeometry.cHeads
1152 * s->PCHSGeometry.cSectors);
1153 p[58] = RT_H2LE_U16( RT_MIN(s->PCHSGeometry.cCylinders, 16383)
1154 * s->PCHSGeometry.cHeads
1155 * s->PCHSGeometry.cSectors >> 16);
1156 if (s->cMultSectors)
1157 p[59] = RT_H2LE_U16(0x100 | s->cMultSectors);
1158 if (s->cTotalSectors <= (1 << 28) - 1)
1159 {
1160 p[60] = RT_H2LE_U16(s->cTotalSectors);
1161 p[61] = RT_H2LE_U16(s->cTotalSectors >> 16);
1162 }
1163 else
1164 {
1165 /* Report maximum number of sectors possible with LBA28 */
1166 p[60] = RT_H2LE_U16(((1 << 28) - 1) & 0xffff);
1167 p[61] = RT_H2LE_U16(((1 << 28) - 1) >> 16);
1168 }
1169 p[63] = RT_H2LE_U16(ATA_TRANSFER_ID(ATA_MODE_MDMA, ATA_MDMA_MODE_MAX, s->uATATransferMode)); /* MDMA modes supported / mode enabled */
1170 p[64] = RT_H2LE_U16(ATA_PIO_MODE_MAX > 2 ? (1 << (ATA_PIO_MODE_MAX - 2)) - 1 : 0); /* PIO modes beyond PIO2 supported */
1171 p[65] = RT_H2LE_U16(120); /* minimum DMA multiword tx cycle time */
1172 p[66] = RT_H2LE_U16(120); /* recommended DMA multiword tx cycle time */
1173 p[67] = RT_H2LE_U16(120); /* minimum PIO cycle time without flow control */
1174 p[68] = RT_H2LE_U16(120); /* minimum PIO cycle time with IORDY flow control */
1175 p[80] = RT_H2LE_U16(0x7e); /* support everything up to ATA/ATAPI-6 */
1176 p[81] = RT_H2LE_U16(0x22); /* conforms to ATA/ATAPI-6 */
1177 p[82] = RT_H2LE_U16(1 << 3 | 1 << 5 | 1 << 6); /* supports power management, write cache and look-ahead */
1178 if (s->cTotalSectors <= (1 << 28) - 1)
1179 p[83] = RT_H2LE_U16(1 << 14 | 1 << 12); /* supports FLUSH CACHE */
1180 else
1181 p[83] = RT_H2LE_U16(1 << 14 | 1 << 10 | 1 << 12 | 1 << 13); /* supports LBA48, FLUSH CACHE and FLUSH CACHE EXT */
1182 p[84] = RT_H2LE_U16(1 << 14);
1183 p[85] = RT_H2LE_U16(1 << 3 | 1 << 5 | 1 << 6); /* enabled power management, write cache and look-ahead */
1184 if (s->cTotalSectors <= (1 << 28) - 1)
1185 p[86] = RT_H2LE_U16(1 << 12); /* enabled FLUSH CACHE */
1186 else
1187 p[86] = RT_H2LE_U16(1 << 10 | 1 << 12 | 1 << 13); /* enabled LBA48, FLUSH CACHE and FLUSH CACHE EXT */
1188 p[87] = RT_H2LE_U16(1 << 14);
1189 p[88] = RT_H2LE_U16(ATA_TRANSFER_ID(ATA_MODE_UDMA, ATA_UDMA_MODE_MAX, s->uATATransferMode)); /* UDMA modes supported / mode enabled */
1190 p[93] = RT_H2LE_U16((1 | 1 << 1) << ((s->iLUN & 1) == 0 ? 0 : 8) | 1 << 13 | 1 << 14);
1191 if (s->cTotalSectors > (1 << 28) - 1)
1192 {
1193 p[100] = RT_H2LE_U16(s->cTotalSectors);
1194 p[101] = RT_H2LE_U16(s->cTotalSectors >> 16);
1195 p[102] = RT_H2LE_U16(s->cTotalSectors >> 32);
1196 p[103] = RT_H2LE_U16(s->cTotalSectors >> 48);
1197 }
1198 s->iSourceSink = ATAFN_SS_NULL;
1199 ataCmdOK(s, ATA_STAT_SEEK);
1200 return false;
1201}
1202
1203
1204static bool ataFlushSS(ATADevState *s)
1205{
1206 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1207 int rc;
1208
1209 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE);
1210 Assert(!s->cbElementaryTransfer);
1211
1212 PDMCritSectLeave(&pCtl->lock);
1213
1214 STAM_PROFILE_START(&s->StatFlushes, f);
1215 rc = s->pDrvBlock->pfnFlush(s->pDrvBlock);
1216 AssertRC(rc);
1217 STAM_PROFILE_STOP(&s->StatFlushes, f);
1218
1219 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1220 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1221 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1222 ataCmdOK(s, 0);
1223 return false;
1224}
1225
1226
1227static bool atapiIdentifySS(ATADevState *s)
1228{
1229 uint16_t *p;
1230
1231 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1232 Assert(s->cbElementaryTransfer == 512);
1233
1234 p = (uint16_t *)s->CTX_SUFF(pbIOBuffer);
1235 memset(p, 0, 512);
1236 /* Removable CDROM, 50us response, 12 byte packets */
1237 p[0] = RT_H2LE_U16(2 << 14 | 5 << 8 | 1 << 7 | 2 << 5 | 0 << 0);
1238 ataPadString((uint8_t *)(p + 10), s->szSerialNumber, ATA_SERIAL_NUMBER_LENGTH); /* serial number */
1239 p[20] = RT_H2LE_U16(3); /* XXX: retired, cache type */
1240 p[21] = RT_H2LE_U16(512); /* XXX: retired, cache size in sectors */
1241 ataPadString((uint8_t *)(p + 23), s->szFirmwareRevision, ATA_FIRMWARE_REVISION_LENGTH); /* firmware version */
1242 ataPadString((uint8_t *)(p + 27), s->szModelNumber, ATA_MODEL_NUMBER_LENGTH); /* model */
1243 p[49] = RT_H2LE_U16(1 << 11 | 1 << 9 | 1 << 8); /* DMA and LBA supported */
1244 p[50] = RT_H2LE_U16(1 << 14); /* No drive specific standby timer minimum */
1245 p[51] = RT_H2LE_U16(240); /* PIO transfer cycle */
1246 p[52] = RT_H2LE_U16(240); /* DMA transfer cycle */
1247 p[53] = RT_H2LE_U16(1 << 1 | 1 << 2); /* words 64-70,88 are valid */
1248 p[63] = RT_H2LE_U16(ATA_TRANSFER_ID(ATA_MODE_MDMA, ATA_MDMA_MODE_MAX, s->uATATransferMode)); /* MDMA modes supported / mode enabled */
1249 p[64] = RT_H2LE_U16(ATA_PIO_MODE_MAX > 2 ? (1 << (ATA_PIO_MODE_MAX - 2)) - 1 : 0); /* PIO modes beyond PIO2 supported */
1250 p[65] = RT_H2LE_U16(120); /* minimum DMA multiword tx cycle time */
1251 p[66] = RT_H2LE_U16(120); /* recommended DMA multiword tx cycle time */
1252 p[67] = RT_H2LE_U16(120); /* minimum PIO cycle time without flow control */
1253 p[68] = RT_H2LE_U16(120); /* minimum PIO cycle time with IORDY flow control */
1254 p[73] = RT_H2LE_U16(0x003e); /* ATAPI CDROM major */
1255 p[74] = RT_H2LE_U16(9); /* ATAPI CDROM minor */
1256 p[75] = RT_H2LE_U16(1); /* queue depth 1 */
1257 p[80] = RT_H2LE_U16(0x7e); /* support everything up to ATA/ATAPI-6 */
1258 p[81] = RT_H2LE_U16(0x22); /* conforms to ATA/ATAPI-6 */
1259 p[82] = RT_H2LE_U16(1 << 4 | 1 << 9); /* supports packet command set and DEVICE RESET */
1260 p[83] = RT_H2LE_U16(1 << 14);
1261 p[84] = RT_H2LE_U16(1 << 14);
1262 p[85] = RT_H2LE_U16(1 << 4 | 1 << 9); /* enabled packet command set and DEVICE RESET */
1263 p[86] = RT_H2LE_U16(0);
1264 p[87] = RT_H2LE_U16(1 << 14);
1265 p[88] = RT_H2LE_U16(ATA_TRANSFER_ID(ATA_MODE_UDMA, ATA_UDMA_MODE_MAX, s->uATATransferMode)); /* UDMA modes supported / mode enabled */
1266 p[93] = RT_H2LE_U16((1 | 1 << 1) << ((s->iLUN & 1) == 0 ? 0 : 8) | 1 << 13 | 1 << 14);
1267 s->iSourceSink = ATAFN_SS_NULL;
1268 ataCmdOK(s, ATA_STAT_SEEK);
1269 return false;
1270}
1271
1272
1273static void ataSetSignature(ATADevState *s)
1274{
1275 s->uATARegSelect &= 0xf0; /* clear head */
1276 /* put signature */
1277 s->uATARegNSector = 1;
1278 s->uATARegSector = 1;
1279 if (s->fATAPI)
1280 {
1281 s->uATARegLCyl = 0x14;
1282 s->uATARegHCyl = 0xeb;
1283 }
1284 else if (s->pDrvBlock)
1285 {
1286 s->uATARegLCyl = 0;
1287 s->uATARegHCyl = 0;
1288 }
1289 else
1290 {
1291 s->uATARegLCyl = 0xff;
1292 s->uATARegHCyl = 0xff;
1293 }
1294}
1295
1296
1297static uint64_t ataGetSector(ATADevState *s)
1298{
1299 uint64_t iLBA;
1300 if (s->uATARegSelect & 0x40)
1301 {
1302 /* any LBA variant */
1303 if (s->fLBA48)
1304 {
1305 /* LBA48 */
1306 iLBA = ((uint64_t)s->uATARegHCylHOB << 40) |
1307 ((uint64_t)s->uATARegLCylHOB << 32) |
1308 ((uint64_t)s->uATARegSectorHOB << 24) |
1309 ((uint64_t)s->uATARegHCyl << 16) |
1310 ((uint64_t)s->uATARegLCyl << 8) |
1311 s->uATARegSector;
1312 }
1313 else
1314 {
1315 /* LBA */
1316 iLBA = ((s->uATARegSelect & 0x0f) << 24) | (s->uATARegHCyl << 16) |
1317 (s->uATARegLCyl << 8) | s->uATARegSector;
1318 }
1319 }
1320 else
1321 {
1322 /* CHS */
1323 iLBA = ((s->uATARegHCyl << 8) | s->uATARegLCyl) * s->PCHSGeometry.cHeads * s->PCHSGeometry.cSectors +
1324 (s->uATARegSelect & 0x0f) * s->PCHSGeometry.cSectors +
1325 (s->uATARegSector - 1);
1326 }
1327 return iLBA;
1328}
1329
1330static void ataSetSector(ATADevState *s, uint64_t iLBA)
1331{
1332 uint32_t cyl, r;
1333 if (s->uATARegSelect & 0x40)
1334 {
1335 /* any LBA variant */
1336 if (s->fLBA48)
1337 {
1338 /* LBA48 */
1339 s->uATARegHCylHOB = iLBA >> 40;
1340 s->uATARegLCylHOB = iLBA >> 32;
1341 s->uATARegSectorHOB = iLBA >> 24;
1342 s->uATARegHCyl = iLBA >> 16;
1343 s->uATARegLCyl = iLBA >> 8;
1344 s->uATARegSector = iLBA;
1345 }
1346 else
1347 {
1348 /* LBA */
1349 s->uATARegSelect = (s->uATARegSelect & 0xf0) | (iLBA >> 24);
1350 s->uATARegHCyl = (iLBA >> 16);
1351 s->uATARegLCyl = (iLBA >> 8);
1352 s->uATARegSector = (iLBA);
1353 }
1354 }
1355 else
1356 {
1357 /* CHS */
1358 cyl = iLBA / (s->PCHSGeometry.cHeads * s->PCHSGeometry.cSectors);
1359 r = iLBA % (s->PCHSGeometry.cHeads * s->PCHSGeometry.cSectors);
1360 s->uATARegHCyl = cyl >> 8;
1361 s->uATARegLCyl = cyl;
1362 s->uATARegSelect = (s->uATARegSelect & 0xf0) | ((r / s->PCHSGeometry.cSectors) & 0x0f);
1363 s->uATARegSector = (r % s->PCHSGeometry.cSectors) + 1;
1364 }
1365}
1366
1367
1368static void ataWarningDiskFull(PPDMDEVINS pDevIns)
1369{
1370 int rc;
1371 LogRel(("PIIX3 ATA: Host disk full\n"));
1372 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),
1373 false, "DevATA_DISKFULL",
1374 N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space"));
1375 AssertRC(rc);
1376}
1377
1378static void ataWarningFileTooBig(PPDMDEVINS pDevIns)
1379{
1380 int rc;
1381 LogRel(("PIIX3 ATA: File too big\n"));
1382 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),
1383 false, "DevATA_FILETOOBIG",
1384 N_("Host system reported that the file size limit of the host file system has been exceeded. VM execution is suspended. You need to move your virtual hard disk to a filesystem which allows bigger files"));
1385 AssertRC(rc);
1386}
1387
1388static void ataWarningISCSI(PPDMDEVINS pDevIns)
1389{
1390 int rc;
1391 LogRel(("PIIX3 ATA: iSCSI target unavailable\n"));
1392 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),
1393 false, "DevATA_ISCSIDOWN",
1394 N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again"));
1395 AssertRC(rc);
1396}
1397
1398/**
1399 * Suspend I/O operations on a controller. Also suspends EMT, because it's
1400 * waiting for I/O to make progress. The next attempt to perform an I/O
1401 * operation will be made when EMT is resumed up again (as the resume
1402 * callback below restarts I/O).
1403 *
1404 * @param pCtl Controller for which to suspend I/O.
1405 */
1406static void ataSuspendRedo(PATACONTROLLER pCtl)
1407{
1408 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
1409 PVMREQ pReq;
1410 int rc;
1411
1412 pCtl->fRedoIdle = true;
1413 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT,
1414 (PFNRT)PDMDevHlpVMSuspend, 1, pDevIns);
1415 AssertReleaseRC(rc);
1416 VMR3ReqFree(pReq);
1417}
1418
1419bool ataIsRedoSetWarning(ATADevState *s, int rc)
1420{
1421 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1422 Assert(!PDMCritSectIsOwner(&pCtl->lock));
1423 if (rc == VERR_DISK_FULL)
1424 {
1425 ataWarningDiskFull(ATADEVSTATE_2_DEVINS(s));
1426 ataSuspendRedo(pCtl);
1427 return true;
1428 }
1429 if (rc == VERR_FILE_TOO_BIG)
1430 {
1431 ataWarningFileTooBig(ATADEVSTATE_2_DEVINS(s));
1432 ataSuspendRedo(pCtl);
1433 return true;
1434 }
1435 if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED)
1436 {
1437 /* iSCSI connection abort (first error) or failure to reestablish
1438 * connection (second error). Pause VM. On resume we'll retry. */
1439 ataWarningISCSI(ATADEVSTATE_2_DEVINS(s));
1440 ataSuspendRedo(pCtl);
1441 return true;
1442 }
1443 return false;
1444}
1445
1446
1447static int ataReadSectors(ATADevState *s, uint64_t u64Sector, void *pvBuf, uint32_t cSectors, bool *fRedo)
1448{
1449 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1450 int rc;
1451
1452 PDMCritSectLeave(&pCtl->lock);
1453
1454 STAM_PROFILE_ADV_START(&s->StatReads, r);
1455 s->Led.Asserted.s.fReading = s->Led.Actual.s.fReading = 1;
1456 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, u64Sector * 512, pvBuf, cSectors * 512);
1457 s->Led.Actual.s.fReading = 0;
1458 STAM_PROFILE_ADV_STOP(&s->StatReads, r);
1459
1460 STAM_REL_COUNTER_ADD(&s->StatBytesRead, cSectors * 512);
1461
1462 if (RT_SUCCESS(rc))
1463 *fRedo = false;
1464 else
1465 *fRedo = ataIsRedoSetWarning(s, rc);
1466
1467 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1468 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1469 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1470 return rc;
1471}
1472
1473
1474static int ataWriteSectors(ATADevState *s, uint64_t u64Sector, const void *pvBuf, uint32_t cSectors, bool *fRedo)
1475{
1476 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1477 int rc;
1478
1479 PDMCritSectLeave(&pCtl->lock);
1480
1481 STAM_PROFILE_ADV_START(&s->StatWrites, w);
1482 s->Led.Asserted.s.fWriting = s->Led.Actual.s.fWriting = 1;
1483#ifdef VBOX_INSTRUMENT_DMA_WRITES
1484 if (s->fDMA)
1485 STAM_PROFILE_ADV_START(&s->StatInstrVDWrites, vw);
1486#endif
1487 rc = s->pDrvBlock->pfnWrite(s->pDrvBlock, u64Sector * 512, pvBuf, cSectors * 512);
1488#ifdef VBOX_INSTRUMENT_DMA_WRITES
1489 if (s->fDMA)
1490 STAM_PROFILE_ADV_STOP(&s->StatInstrVDWrites, vw);
1491#endif
1492 s->Led.Actual.s.fWriting = 0;
1493 STAM_PROFILE_ADV_STOP(&s->StatWrites, w);
1494
1495 STAM_REL_COUNTER_ADD(&s->StatBytesWritten, cSectors * 512);
1496
1497 if (RT_SUCCESS(rc))
1498 *fRedo = false;
1499 else
1500 *fRedo = ataIsRedoSetWarning(s, rc);
1501
1502 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1503 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1504 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1505 return rc;
1506}
1507
1508
1509static void ataReadWriteSectorsBT(ATADevState *s)
1510{
1511 uint32_t cSectors;
1512
1513 cSectors = s->cbTotalTransfer / 512;
1514 if (cSectors > s->cSectorsPerIRQ)
1515 s->cbElementaryTransfer = s->cSectorsPerIRQ * 512;
1516 else
1517 s->cbElementaryTransfer = cSectors * 512;
1518 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
1519 ataCmdOK(s, 0);
1520}
1521
1522
1523static bool ataReadSectorsSS(ATADevState *s)
1524{
1525 int rc;
1526 uint32_t cSectors;
1527 uint64_t iLBA;
1528 bool fRedo;
1529
1530 cSectors = s->cbElementaryTransfer / 512;
1531 Assert(cSectors);
1532 iLBA = ataGetSector(s);
1533 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, iLBA));
1534 rc = ataReadSectors(s, iLBA, s->CTX_SUFF(pbIOBuffer), cSectors, &fRedo);
1535 if (RT_SUCCESS(rc))
1536 {
1537 ataSetSector(s, iLBA + cSectors);
1538 if (s->cbElementaryTransfer == s->cbTotalTransfer)
1539 s->iSourceSink = ATAFN_SS_NULL;
1540 ataCmdOK(s, ATA_STAT_SEEK);
1541 }
1542 else
1543 {
1544 if (fRedo)
1545 return fRedo;
1546 if (s->cErrors++ < MAX_LOG_REL_ERRORS)
1547 LogRel(("PIIX3 ATA: LUN#%d: disk read error (rc=%Rrc iSector=%#RX64 cSectors=%#RX32)\n",
1548 s->iLUN, rc, iLBA, cSectors));
1549
1550 /*
1551 * Check if we got interrupted. We don't need to set status variables
1552 * because the request was aborted.
1553 */
1554 if (rc != VERR_INTERRUPTED)
1555 ataCmdError(s, ID_ERR);
1556 }
1557 return false;
1558}
1559
1560
1561static bool ataWriteSectorsSS(ATADevState *s)
1562{
1563 int rc;
1564 uint32_t cSectors;
1565 uint64_t iLBA;
1566 bool fRedo;
1567
1568 cSectors = s->cbElementaryTransfer / 512;
1569 Assert(cSectors);
1570 iLBA = ataGetSector(s);
1571 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, iLBA));
1572 rc = ataWriteSectors(s, iLBA, s->CTX_SUFF(pbIOBuffer), cSectors, &fRedo);
1573 if (RT_SUCCESS(rc))
1574 {
1575 ataSetSector(s, iLBA + cSectors);
1576 if (!s->cbTotalTransfer)
1577 s->iSourceSink = ATAFN_SS_NULL;
1578 ataCmdOK(s, ATA_STAT_SEEK);
1579 }
1580 else
1581 {
1582 if (fRedo)
1583 return fRedo;
1584 if (s->cErrors++ < MAX_LOG_REL_ERRORS)
1585 LogRel(("PIIX3 ATA: LUN#%d: disk write error (rc=%Rrc iSector=%#RX64 cSectors=%#RX32)\n",
1586 s->iLUN, rc, iLBA, cSectors));
1587
1588 /*
1589 * Check if we got interrupted. We don't need to set status variables
1590 * because the request was aborted.
1591 */
1592 if (rc != VERR_INTERRUPTED)
1593 ataCmdError(s, ID_ERR);
1594 }
1595 return false;
1596}
1597
1598
1599static void atapiCmdOK(ATADevState *s)
1600{
1601 s->uATARegError = 0;
1602 ataSetStatusValue(s, ATA_STAT_READY);
1603 s->uATARegNSector = (s->uATARegNSector & ~7)
1604 | ((s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE) ? ATAPI_INT_REASON_IO : 0)
1605 | (!s->cbTotalTransfer ? ATAPI_INT_REASON_CD : 0);
1606 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
1607
1608 memset(s->abATAPISense, '\0', sizeof(s->abATAPISense));
1609 s->abATAPISense[0] = 0x70 | (1 << 7);
1610 s->abATAPISense[7] = 10;
1611}
1612
1613
1614static void atapiCmdError(ATADevState *s, const uint8_t *pabATAPISense, size_t cbATAPISense)
1615{
1616 Log(("%s: sense=%#x (%s) asc=%#x ascq=%#x (%s)\n", __FUNCTION__, pabATAPISense[2] & 0x0f, SCSISenseText(pabATAPISense[2] & 0x0f),
1617 pabATAPISense[12], pabATAPISense[13], SCSISenseExtText(pabATAPISense[12], pabATAPISense[13])));
1618 s->uATARegError = pabATAPISense[2] << 4;
1619 ataSetStatusValue(s, ATA_STAT_READY | ATA_STAT_ERR);
1620 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1621 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
1622 memset(s->abATAPISense, '\0', sizeof(s->abATAPISense));
1623 memcpy(s->abATAPISense, pabATAPISense, RT_MIN(cbATAPISense, sizeof(s->abATAPISense)));
1624 s->cbTotalTransfer = 0;
1625 s->cbElementaryTransfer = 0;
1626 s->iIOBufferCur = 0;
1627 s->iIOBufferEnd = 0;
1628 s->uTxDir = PDMBLOCKTXDIR_NONE;
1629 s->iBeginTransfer = ATAFN_BT_NULL;
1630 s->iSourceSink = ATAFN_SS_NULL;
1631}
1632
1633
1634/** @todo deprecated function - doesn't provide enough info. Replace by direct
1635 * calls to atapiCmdError() with full data. */
1636static void atapiCmdErrorSimple(ATADevState *s, uint8_t uATAPISenseKey, uint8_t uATAPIASC)
1637{
1638 uint8_t abATAPISense[ATAPI_SENSE_SIZE];
1639 memset(abATAPISense, '\0', sizeof(abATAPISense));
1640 abATAPISense[0] = 0x70 | (1 << 7);
1641 abATAPISense[2] = uATAPISenseKey & 0x0f;
1642 abATAPISense[7] = 10;
1643 abATAPISense[12] = uATAPIASC;
1644 atapiCmdError(s, abATAPISense, sizeof(abATAPISense));
1645}
1646
1647
1648static void atapiCmdBT(ATADevState *s)
1649{
1650 s->fATAPITransfer = true;
1651 s->cbElementaryTransfer = s->cbTotalTransfer;
1652 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
1653 atapiCmdOK(s);
1654}
1655
1656
1657static void atapiPassthroughCmdBT(ATADevState *s)
1658{
1659 /* @todo implement an algorithm for correctly determining the read and
1660 * write sector size without sending additional commands to the drive.
1661 * This should be doable by saving processing the configuration requests
1662 * and replies. */
1663#if 0
1664 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
1665 {
1666 uint8_t cmd = s->aATAPICmd[0];
1667 if (cmd == SCSI_WRITE_10 || cmd == SCSI_WRITE_12 || cmd == SCSI_WRITE_AND_VERIFY_10)
1668 {
1669 uint8_t aModeSenseCmd[10];
1670 uint8_t aModeSenseResult[16];
1671 uint8_t uDummySense;
1672 uint32_t cbTransfer;
1673 int rc;
1674
1675 cbTransfer = sizeof(aModeSenseResult);
1676 aModeSenseCmd[0] = SCSI_MODE_SENSE_10;
1677 aModeSenseCmd[1] = 0x08; /* disable block descriptor = 1 */
1678 aModeSenseCmd[2] = (SCSI_PAGECONTROL_CURRENT << 6) | SCSI_MODEPAGE_WRITE_PARAMETER;
1679 aModeSenseCmd[3] = 0; /* subpage code */
1680 aModeSenseCmd[4] = 0; /* reserved */
1681 aModeSenseCmd[5] = 0; /* reserved */
1682 aModeSenseCmd[6] = 0; /* reserved */
1683 aModeSenseCmd[7] = cbTransfer >> 8;
1684 aModeSenseCmd[8] = cbTransfer & 0xff;
1685 aModeSenseCmd[9] = 0; /* control */
1686 rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, aModeSenseCmd, PDMBLOCKTXDIR_FROM_DEVICE, aModeSenseResult, &cbTransfer, &uDummySense, 500);
1687 if (RT_FAILURE(rc))
1688 {
1689 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_NONE);
1690 return;
1691 }
1692 /* Select sector size based on the current data block type. */
1693 switch (aModeSenseResult[12] & 0x0f)
1694 {
1695 case 0:
1696 s->cbATAPISector = 2352;
1697 break;
1698 case 1:
1699 s->cbATAPISector = 2368;
1700 break;
1701 case 2:
1702 case 3:
1703 s->cbATAPISector = 2448;
1704 break;
1705 case 8:
1706 case 10:
1707 s->cbATAPISector = 2048;
1708 break;
1709 case 9:
1710 s->cbATAPISector = 2336;
1711 break;
1712 case 11:
1713 s->cbATAPISector = 2056;
1714 break;
1715 case 12:
1716 s->cbATAPISector = 2324;
1717 break;
1718 case 13:
1719 s->cbATAPISector = 2332;
1720 break;
1721 default:
1722 s->cbATAPISector = 0;
1723 }
1724 Log2(("%s: sector size %d\n", __FUNCTION__, s->cbATAPISector));
1725 s->cbTotalTransfer *= s->cbATAPISector;
1726 if (s->cbTotalTransfer == 0)
1727 s->uTxDir = PDMBLOCKTXDIR_NONE;
1728 }
1729 }
1730#endif
1731 atapiCmdBT(s);
1732}
1733
1734
1735static bool atapiReadSS(ATADevState *s)
1736{
1737 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1738 int rc = VINF_SUCCESS;
1739 uint32_t cbTransfer, cSectors;
1740
1741 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1742 cbTransfer = RT_MIN(s->cbTotalTransfer, s->cbIOBuffer);
1743 cSectors = cbTransfer / s->cbATAPISector;
1744 Assert(cSectors * s->cbATAPISector <= cbTransfer);
1745 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, s->iATAPILBA));
1746
1747 PDMCritSectLeave(&pCtl->lock);
1748
1749 STAM_PROFILE_ADV_START(&s->StatReads, r);
1750 s->Led.Asserted.s.fReading = s->Led.Actual.s.fReading = 1;
1751 switch (s->cbATAPISector)
1752 {
1753 case 2048:
1754 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, (uint64_t)s->iATAPILBA * s->cbATAPISector, s->CTX_SUFF(pbIOBuffer), s->cbATAPISector * cSectors);
1755 break;
1756 case 2352:
1757 {
1758 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1759
1760 for (uint32_t i = s->iATAPILBA; i < s->iATAPILBA + cSectors; i++)
1761 {
1762 /* Sync bytes, see 4.2.3.8 CD Main Channel Block Formats */
1763 *pbBuf++ = 0x00;
1764 memset(pbBuf, 0xff, 10);
1765 pbBuf += 10;
1766 *pbBuf++ = 0x00;
1767 /* MSF */
1768 ataLBA2MSF(pbBuf, i);
1769 pbBuf += 3;
1770 *pbBuf++ = 0x01; /* mode 1 data */
1771 /* data */
1772 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, (uint64_t)i * 2048, pbBuf, 2048);
1773 if (RT_FAILURE(rc))
1774 break;
1775 pbBuf += 2048;
1776 /**
1777 * @todo: maybe compute ECC and parity, layout is:
1778 * 2072 4 EDC
1779 * 2076 172 P parity symbols
1780 * 2248 104 Q parity symbols
1781 */
1782 memset(pbBuf, 0, 280);
1783 pbBuf += 280;
1784 }
1785 }
1786 break;
1787 default:
1788 break;
1789 }
1790 STAM_PROFILE_ADV_STOP(&s->StatReads, r);
1791
1792 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1793 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1794 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1795
1796 if (RT_SUCCESS(rc))
1797 {
1798 s->Led.Actual.s.fReading = 0;
1799 STAM_REL_COUNTER_ADD(&s->StatBytesRead, s->cbATAPISector * cSectors);
1800
1801 /* The initial buffer end value has been set up based on the total
1802 * transfer size. But the I/O buffer size limits what can actually be
1803 * done in one transfer, so set the actual value of the buffer end. */
1804 s->cbElementaryTransfer = cbTransfer;
1805 if (cbTransfer >= s->cbTotalTransfer)
1806 s->iSourceSink = ATAFN_SS_NULL;
1807 atapiCmdOK(s);
1808 s->iATAPILBA += cSectors;
1809 }
1810 else
1811 {
1812 if (s->cErrors++ < MAX_LOG_REL_ERRORS)
1813 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM read error, %d sectors at LBA %d\n", s->iLUN, cSectors, s->iATAPILBA));
1814
1815 /*
1816 * Check if we got interrupted. We don't need to set status variables
1817 * because the request was aborted.
1818 */
1819 if (rc != VERR_INTERRUPTED)
1820 atapiCmdErrorSimple(s, SCSI_SENSE_MEDIUM_ERROR, SCSI_ASC_READ_ERROR);
1821 }
1822 return false;
1823}
1824
1825
1826static bool atapiPassthroughSS(ATADevState *s)
1827{
1828 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1829 int rc = VINF_SUCCESS;
1830 uint8_t abATAPISense[ATAPI_SENSE_SIZE];
1831 uint32_t cbTransfer;
1832 PSTAMPROFILEADV pProf = NULL;
1833
1834 cbTransfer = s->cbElementaryTransfer;
1835
1836 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
1837 Log3(("ATAPI PT data write (%d): %.*Rhxs\n", cbTransfer, cbTransfer, s->CTX_SUFF(pbIOBuffer)));
1838
1839 /* Simple heuristics: if there is at least one sector of data
1840 * to transfer, it's worth updating the LEDs. */
1841 if (cbTransfer >= 2048)
1842 {
1843 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
1844 {
1845 s->Led.Asserted.s.fReading = s->Led.Actual.s.fReading = 1;
1846 pProf = &s->StatReads;
1847 }
1848 else
1849 {
1850 s->Led.Asserted.s.fWriting = s->Led.Actual.s.fWriting = 1;
1851 pProf = &s->StatWrites;
1852 }
1853 }
1854
1855 PDMCritSectLeave(&pCtl->lock);
1856
1857 if (pProf) { STAM_PROFILE_ADV_START(pProf, b); }
1858 if (cbTransfer > SCSI_MAX_BUFFER_SIZE)
1859 {
1860 /* Linux accepts commands with up to 100KB of data, but expects
1861 * us to handle commands with up to 128KB of data. The usual
1862 * imbalance of powers. */
1863 uint8_t aATAPICmd[ATAPI_PACKET_SIZE];
1864 uint32_t iATAPILBA, cSectors, cReqSectors, cbCurrTX;
1865 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1866
1867 switch (s->aATAPICmd[0])
1868 {
1869 case SCSI_READ_10:
1870 case SCSI_WRITE_10:
1871 case SCSI_WRITE_AND_VERIFY_10:
1872 iATAPILBA = ataBE2H_U32(s->aATAPICmd + 2);
1873 cSectors = ataBE2H_U16(s->aATAPICmd + 7);
1874 break;
1875 case SCSI_READ_12:
1876 case SCSI_WRITE_12:
1877 iATAPILBA = ataBE2H_U32(s->aATAPICmd + 2);
1878 cSectors = ataBE2H_U32(s->aATAPICmd + 6);
1879 break;
1880 case SCSI_READ_CD:
1881 iATAPILBA = ataBE2H_U32(s->aATAPICmd + 2);
1882 cSectors = ataBE2H_U24(s->aATAPICmd + 6) / s->cbATAPISector;
1883 break;
1884 case SCSI_READ_CD_MSF:
1885 iATAPILBA = ataMSF2LBA(s->aATAPICmd + 3);
1886 cSectors = ataMSF2LBA(s->aATAPICmd + 6) - iATAPILBA;
1887 break;
1888 default:
1889 AssertMsgFailed(("Don't know how to split command %#04x\n", s->aATAPICmd[0]));
1890 if (s->cErrors++ < MAX_LOG_REL_ERRORS)
1891 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough split error\n", s->iLUN));
1892 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
1893 {
1894 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1895 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1896 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1897 }
1898 return false;
1899 }
1900 memcpy(aATAPICmd, s->aATAPICmd, ATAPI_PACKET_SIZE);
1901 cReqSectors = 0;
1902 for (uint32_t i = cSectors; i > 0; i -= cReqSectors)
1903 {
1904 if (i * s->cbATAPISector > SCSI_MAX_BUFFER_SIZE)
1905 cReqSectors = SCSI_MAX_BUFFER_SIZE / s->cbATAPISector;
1906 else
1907 cReqSectors = i;
1908 cbCurrTX = s->cbATAPISector * cReqSectors;
1909 switch (s->aATAPICmd[0])
1910 {
1911 case SCSI_READ_10:
1912 case SCSI_WRITE_10:
1913 case SCSI_WRITE_AND_VERIFY_10:
1914 ataH2BE_U32(aATAPICmd + 2, iATAPILBA);
1915 ataH2BE_U16(aATAPICmd + 7, cReqSectors);
1916 break;
1917 case SCSI_READ_12:
1918 case SCSI_WRITE_12:
1919 ataH2BE_U32(aATAPICmd + 2, iATAPILBA);
1920 ataH2BE_U32(aATAPICmd + 6, cReqSectors);
1921 break;
1922 case SCSI_READ_CD:
1923 ataH2BE_U32(s->aATAPICmd + 2, iATAPILBA);
1924 ataH2BE_U24(s->aATAPICmd + 6, cbCurrTX);
1925 break;
1926 case SCSI_READ_CD_MSF:
1927 ataLBA2MSF(aATAPICmd + 3, iATAPILBA);
1928 ataLBA2MSF(aATAPICmd + 6, iATAPILBA + cReqSectors);
1929 break;
1930 }
1931 rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, pbBuf, &cbCurrTX, abATAPISense, sizeof(abATAPISense), 30000 /**< @todo timeout */);
1932 if (rc != VINF_SUCCESS)
1933 break;
1934 iATAPILBA += cReqSectors;
1935 pbBuf += s->cbATAPISector * cReqSectors;
1936 }
1937 }
1938 else
1939 rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, s->aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, s->CTX_SUFF(pbIOBuffer), &cbTransfer, abATAPISense, sizeof(abATAPISense), 30000 /**< @todo timeout */);
1940 if (pProf) { STAM_PROFILE_ADV_STOP(pProf, b); }
1941
1942 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1943 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1944 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1945
1946 /* Update the LEDs and the read/write statistics. */
1947 if (cbTransfer >= 2048)
1948 {
1949 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
1950 {
1951 s->Led.Actual.s.fReading = 0;
1952 STAM_REL_COUNTER_ADD(&s->StatBytesRead, cbTransfer);
1953 }
1954 else
1955 {
1956 s->Led.Actual.s.fWriting = 0;
1957 STAM_REL_COUNTER_ADD(&s->StatBytesWritten, cbTransfer);
1958 }
1959 }
1960
1961 if (RT_SUCCESS(rc))
1962 {
1963 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
1964 {
1965 Assert(cbTransfer <= s->cbTotalTransfer);
1966 /* Reply with the same amount of data as the real drive. */
1967 s->cbTotalTransfer = cbTransfer;
1968 /* The initial buffer end value has been set up based on the total
1969 * transfer size. But the I/O buffer size limits what can actually be
1970 * done in one transfer, so set the actual value of the buffer end. */
1971 s->cbElementaryTransfer = cbTransfer;
1972 if (s->aATAPICmd[0] == SCSI_INQUIRY)
1973 {
1974 /* Make sure that the real drive cannot be identified.
1975 * Motivation: changing the VM configuration should be as
1976 * invisible as possible to the guest. */
1977 Log3(("ATAPI PT inquiry data before (%d): %.*Rhxs\n", cbTransfer, cbTransfer, s->CTX_SUFF(pbIOBuffer)));
1978 ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 8, "VBOX", 8);
1979 ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 16, "CD-ROM", 16);
1980 ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 32, "1.0", 4);
1981 }
1982 if (cbTransfer)
1983 Log3(("ATAPI PT data read (%d): %.*Rhxs\n", cbTransfer, cbTransfer, s->CTX_SUFF(pbIOBuffer)));
1984 }
1985 s->iSourceSink = ATAFN_SS_NULL;
1986 atapiCmdOK(s);
1987 }
1988 else
1989 {
1990 if (s->cErrors < MAX_LOG_REL_ERRORS)
1991 {
1992 uint8_t u8Cmd = s->aATAPICmd[0];
1993 do
1994 {
1995 /* don't log superflous errors */
1996 if ( rc == VERR_DEV_IO_ERROR
1997 && ( u8Cmd == SCSI_TEST_UNIT_READY
1998 || u8Cmd == SCSI_READ_CAPACITY
1999 || u8Cmd == SCSI_READ_DVD_STRUCTURE
2000 || u8Cmd == SCSI_READ_TOC_PMA_ATIP))
2001 break;
2002 s->cErrors++;
2003 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough cmd=%#04x sense=%d ASC=%#02x ASCQ=%#02x %Rrc\n",
2004 s->iLUN, u8Cmd, abATAPISense[2] & 0x0f, abATAPISense[12], abATAPISense[13], rc));
2005 } while (0);
2006 }
2007 atapiCmdError(s, abATAPISense, sizeof(abATAPISense));
2008 }
2009 return false;
2010}
2011
2012/** @todo: Revise ASAP. */
2013static bool atapiReadDVDStructureSS(ATADevState *s)
2014{
2015 uint8_t *buf = s->CTX_SUFF(pbIOBuffer);
2016 int media = s->aATAPICmd[1];
2017 int format = s->aATAPICmd[7];
2018
2019 uint16_t max_len = ataBE2H_U16(&s->aATAPICmd[8]);
2020
2021 memset(buf, 0, max_len);
2022
2023 switch (format) {
2024 case 0x00:
2025 case 0x01:
2026 case 0x02:
2027 case 0x03:
2028 case 0x04:
2029 case 0x05:
2030 case 0x06:
2031 case 0x07:
2032 case 0x08:
2033 case 0x09:
2034 case 0x0a:
2035 case 0x0b:
2036 case 0x0c:
2037 case 0x0d:
2038 case 0x0e:
2039 case 0x0f:
2040 case 0x10:
2041 case 0x11:
2042 case 0x30:
2043 case 0x31:
2044 case 0xff:
2045 if (media == 0)
2046 {
2047 int uASC = SCSI_ASC_NONE;
2048
2049 switch (format)
2050 {
2051 case 0x0: /* Physical format information */
2052 {
2053 int layer = s->aATAPICmd[6];
2054 uint64_t total_sectors;
2055
2056 if (layer != 0)
2057 {
2058 uASC = -SCSI_ASC_INV_FIELD_IN_CMD_PACKET;
2059 break;
2060 }
2061
2062 total_sectors = s->cTotalSectors;
2063 total_sectors >>= 2;
2064 if (total_sectors == 0)
2065 {
2066 uASC = -SCSI_ASC_MEDIUM_NOT_PRESENT;
2067 break;
2068 }
2069
2070 buf[4] = 1; /* DVD-ROM, part version 1 */
2071 buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
2072 buf[6] = 1; /* one layer, read-only (per MMC-2 spec) */
2073 buf[7] = 0; /* default densities */
2074
2075 /* FIXME: 0x30000 per spec? */
2076 ataH2BE_U32(buf + 8, 0); /* start sector */
2077 ataH2BE_U32(buf + 12, total_sectors - 1); /* end sector */
2078 ataH2BE_U32(buf + 16, total_sectors - 1); /* l0 end sector */
2079
2080 /* Size of buffer, not including 2 byte size field */
2081 ataH2BE_U32(&buf[0], 2048 + 2);
2082
2083 /* 2k data + 4 byte header */
2084 uASC = (2048 + 4);
2085 }
2086 break;
2087 case 0x01: /* DVD copyright information */
2088 buf[4] = 0; /* no copyright data */
2089 buf[5] = 0; /* no region restrictions */
2090
2091 /* Size of buffer, not including 2 byte size field */
2092 ataH2BE_U16(buf, 4 + 2);
2093
2094 /* 4 byte header + 4 byte data */
2095 uASC = (4 + 4);
2096
2097 case 0x03: /* BCA information - invalid field for no BCA info */
2098 uASC = -SCSI_ASC_INV_FIELD_IN_CMD_PACKET;
2099 break;
2100
2101 case 0x04: /* DVD disc manufacturing information */
2102 /* Size of buffer, not including 2 byte size field */
2103 ataH2BE_U16(buf, 2048 + 2);
2104
2105 /* 2k data + 4 byte header */
2106 uASC = (2048 + 4);
2107 break;
2108 case 0xff:
2109 /*
2110 * This lists all the command capabilities above. Add new ones
2111 * in order and update the length and buffer return values.
2112 */
2113
2114 buf[4] = 0x00; /* Physical format */
2115 buf[5] = 0x40; /* Not writable, is readable */
2116 ataH2BE_U16((buf + 6), 2048 + 4);
2117
2118 buf[8] = 0x01; /* Copyright info */
2119 buf[9] = 0x40; /* Not writable, is readable */
2120 ataH2BE_U16((buf + 10), 4 + 4);
2121
2122 buf[12] = 0x03; /* BCA info */
2123 buf[13] = 0x40; /* Not writable, is readable */
2124 ataH2BE_U16((buf + 14), 188 + 4);
2125
2126 buf[16] = 0x04; /* Manufacturing info */
2127 buf[17] = 0x40; /* Not writable, is readable */
2128 ataH2BE_U16((buf + 18), 2048 + 4);
2129
2130 /* Size of buffer, not including 2 byte size field */
2131 ataH2BE_U16(buf, 16 + 2);
2132
2133 /* data written + 4 byte header */
2134 uASC = (16 + 4);
2135 break;
2136 default: /* TODO: formats beyond DVD-ROM requires */
2137 uASC = -SCSI_ASC_INV_FIELD_IN_CMD_PACKET;
2138 }
2139
2140 if (uASC < 0)
2141 {
2142 s->iSourceSink = ATAFN_SS_NULL;
2143 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, -uASC);
2144 return false;
2145 }
2146 break;
2147 }
2148 /* TODO: BD support, fall through for now */
2149
2150 /* Generic disk structures */
2151 case 0x80: /* TODO: AACS volume identifier */
2152 case 0x81: /* TODO: AACS media serial number */
2153 case 0x82: /* TODO: AACS media identifier */
2154 case 0x83: /* TODO: AACS media key block */
2155 case 0x90: /* TODO: List of recognized format layers */
2156 case 0xc0: /* TODO: Write protection status */
2157 default:
2158 s->iSourceSink = ATAFN_SS_NULL;
2159 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST,
2160 SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2161 return false;
2162 }
2163
2164 s->iSourceSink = ATAFN_SS_NULL;
2165 atapiCmdOK(s);
2166 return false;
2167}
2168
2169static bool atapiReadSectors(ATADevState *s, uint32_t iATAPILBA, uint32_t cSectors, uint32_t cbSector)
2170{
2171 Assert(cSectors > 0);
2172 s->iATAPILBA = iATAPILBA;
2173 s->cbATAPISector = cbSector;
2174 ataStartTransfer(s, cSectors * cbSector, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ, true);
2175 return false;
2176}
2177
2178
2179static bool atapiReadCapacitySS(ATADevState *s)
2180{
2181 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2182
2183 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2184 Assert(s->cbElementaryTransfer <= 8);
2185 ataH2BE_U32(pbBuf, s->cTotalSectors - 1);
2186 ataH2BE_U32(pbBuf + 4, 2048);
2187 s->iSourceSink = ATAFN_SS_NULL;
2188 atapiCmdOK(s);
2189 return false;
2190}
2191
2192
2193static bool atapiReadDiscInformationSS(ATADevState *s)
2194{
2195 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2196
2197 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2198 Assert(s->cbElementaryTransfer <= 34);
2199 memset(pbBuf, '\0', 34);
2200 ataH2BE_U16(pbBuf, 32);
2201 pbBuf[2] = (0 << 4) | (3 << 2) | (2 << 0); /* not erasable, complete session, complete disc */
2202 pbBuf[3] = 1; /* number of first track */
2203 pbBuf[4] = 1; /* number of sessions (LSB) */
2204 pbBuf[5] = 1; /* first track number in last session (LSB) */
2205 pbBuf[6] = 1; /* last track number in last session (LSB) */
2206 pbBuf[7] = (0 << 7) | (0 << 6) | (1 << 5) | (0 << 2) | (0 << 0); /* disc id not valid, disc bar code not valid, unrestricted use, not dirty, not RW medium */
2207 pbBuf[8] = 0; /* disc type = CD-ROM */
2208 pbBuf[9] = 0; /* number of sessions (MSB) */
2209 pbBuf[10] = 0; /* number of sessions (MSB) */
2210 pbBuf[11] = 0; /* number of sessions (MSB) */
2211 ataH2BE_U32(pbBuf + 16, 0x00ffffff); /* last session lead-in start time is not available */
2212 ataH2BE_U32(pbBuf + 20, 0x00ffffff); /* last possible start time for lead-out is not available */
2213 s->iSourceSink = ATAFN_SS_NULL;
2214 atapiCmdOK(s);
2215 return false;
2216}
2217
2218
2219static bool atapiReadTrackInformationSS(ATADevState *s)
2220{
2221 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2222
2223 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2224 Assert(s->cbElementaryTransfer <= 36);
2225 /* Accept address/number type of 1 only, and only track 1 exists. */
2226 if ((s->aATAPICmd[1] & 0x03) != 1 || ataBE2H_U32(&s->aATAPICmd[2]) != 1)
2227 {
2228 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2229 return false;
2230 }
2231 memset(pbBuf, '\0', 36);
2232 ataH2BE_U16(pbBuf, 34);
2233 pbBuf[2] = 1; /* track number (LSB) */
2234 pbBuf[3] = 1; /* session number (LSB) */
2235 pbBuf[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */
2236 pbBuf[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */
2237 pbBuf[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */
2238 ataH2BE_U32(pbBuf + 8, 0); /* track start address is 0 */
2239 ataH2BE_U32(pbBuf + 24, s->cTotalSectors); /* track size */
2240 pbBuf[32] = 0; /* track number (MSB) */
2241 pbBuf[33] = 0; /* session number (MSB) */
2242 s->iSourceSink = ATAFN_SS_NULL;
2243 atapiCmdOK(s);
2244 return false;
2245}
2246
2247
2248static bool atapiGetConfigurationSS(ATADevState *s)
2249{
2250 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2251 uint16_t u16Sfn = ataBE2H_U16(&s->aATAPICmd[2]);
2252
2253 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2254 Assert(s->cbElementaryTransfer <= 32);
2255 /* Accept valid request types only, and only starting feature 0. */
2256 if ((s->aATAPICmd[1] & 0x03) == 3 || u16Sfn != 0)
2257 {
2258 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2259 return false;
2260 }
2261 memset(pbBuf, '\0', 32);
2262 ataH2BE_U32(pbBuf, 16);
2263 /** @todo implement switching between CD-ROM and DVD-ROM profile (the only
2264 * way to differentiate them right now is based on the image size). Also
2265 * implement signalling "no current profile" if no medium is loaded. */
2266 ataH2BE_U16(pbBuf + 6, 0x08); /* current profile: read-only CD */
2267
2268 ataH2BE_U16(pbBuf + 8, 0); /* feature 0: list of profiles supported */
2269 pbBuf[10] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
2270 pbBuf[11] = 8; /* additional bytes for profiles */
2271 /* The MMC-3 spec says that DVD-ROM read capability should be reported
2272 * before CD-ROM read capability. */
2273 ataH2BE_U16(pbBuf + 12, 0x10); /* profile: read-only DVD */
2274 pbBuf[14] = (0 << 0); /* NOT current profile */
2275 ataH2BE_U16(pbBuf + 16, 0x08); /* profile: read only CD */
2276 pbBuf[18] = (1 << 0); /* current profile */
2277 /* Other profiles we might want to add in the future: 0x40 (BD-ROM) and 0x50 (HDDVD-ROM) */
2278 s->iSourceSink = ATAFN_SS_NULL;
2279 atapiCmdOK(s);
2280 return false;
2281}
2282
2283
2284static bool atapiGetEventStatusNotificationSS(ATADevState *s)
2285{
2286 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2287
2288 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2289 Assert(s->cbElementaryTransfer <= 8);
2290
2291 if (!(s->aATAPICmd[1] & 1))
2292 {
2293 /* no asynchronous operation supported */
2294 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2295 return false;
2296 }
2297
2298 uint32_t OldStatus, NewStatus;
2299 do
2300 {
2301 OldStatus = ASMAtomicReadU32(&s->MediaEventStatus);
2302 NewStatus = ATA_EVENT_STATUS_UNCHANGED;
2303 switch (OldStatus)
2304 {
2305 case ATA_EVENT_STATUS_MEDIA_NEW:
2306 /* mount */
2307 ataH2BE_U16(pbBuf + 0, 6);
2308 pbBuf[2] = 0x04;
2309 pbBuf[3] = 0x5e;
2310 pbBuf[4] = 0x02;
2311 pbBuf[5] = 0x02;
2312 pbBuf[6] = 0x00;
2313 pbBuf[7] = 0x00;
2314 break;
2315
2316 case ATA_EVENT_STATUS_MEDIA_CHANGED:
2317 case ATA_EVENT_STATUS_MEDIA_REMOVED:
2318 /* umount */
2319 ataH2BE_U16(pbBuf + 0, 6);
2320 pbBuf[2] = 0x04;
2321 pbBuf[3] = 0x5e;
2322 pbBuf[4] = 0x03;
2323 pbBuf[5] = 0x00;
2324 pbBuf[6] = 0x00;
2325 pbBuf[7] = 0x00;
2326 if (OldStatus == ATA_EVENT_STATUS_MEDIA_CHANGED)
2327 NewStatus = ATA_EVENT_STATUS_MEDIA_NEW;
2328 break;
2329
2330 case ATA_EVENT_STATUS_UNCHANGED:
2331 default:
2332 ataH2BE_U16(pbBuf + 0, 6);
2333 pbBuf[2] = 0x01;
2334 pbBuf[3] = 0x5e;
2335 pbBuf[4] = 0x00;
2336 pbBuf[5] = 0x00;
2337 pbBuf[6] = 0x00;
2338 pbBuf[7] = 0x00;
2339 break;
2340 }
2341 } while (!ASMAtomicCmpXchgU32(&s->MediaEventStatus, NewStatus, OldStatus));
2342
2343 s->iSourceSink = ATAFN_SS_NULL;
2344 atapiCmdOK(s);
2345 return false;
2346}
2347
2348
2349static bool atapiInquirySS(ATADevState *s)
2350{
2351 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2352
2353 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2354 Assert(s->cbElementaryTransfer <= 36);
2355 pbBuf[0] = 0x05; /* CD-ROM */
2356 pbBuf[1] = 0x80; /* removable */
2357#if 1/*ndef VBOX*/ /** @todo implement MESN + AENC. (async notification on removal and stuff.) */
2358 pbBuf[2] = 0x00; /* ISO */
2359 pbBuf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
2360#else
2361 pbBuf[2] = 0x00; /* ISO */
2362 pbBuf[3] = 0x91; /* format 1, MESN=1, AENC=9 ??? */
2363#endif
2364 pbBuf[4] = 31; /* additional length */
2365 pbBuf[5] = 0; /* reserved */
2366 pbBuf[6] = 0; /* reserved */
2367 pbBuf[7] = 0; /* reserved */
2368 ataSCSIPadStr(pbBuf + 8, "VBOX", 8);
2369 ataSCSIPadStr(pbBuf + 16, "CD-ROM", 16);
2370 ataSCSIPadStr(pbBuf + 32, "1.0", 4);
2371 s->iSourceSink = ATAFN_SS_NULL;
2372 atapiCmdOK(s);
2373 return false;
2374}
2375
2376
2377static bool atapiModeSenseErrorRecoverySS(ATADevState *s)
2378{
2379 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2380
2381 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2382 Assert(s->cbElementaryTransfer <= 16);
2383 ataH2BE_U16(&pbBuf[0], 16 + 6);
2384 pbBuf[2] = 0x70;
2385 pbBuf[3] = 0;
2386 pbBuf[4] = 0;
2387 pbBuf[5] = 0;
2388 pbBuf[6] = 0;
2389 pbBuf[7] = 0;
2390
2391 pbBuf[8] = 0x01;
2392 pbBuf[9] = 0x06;
2393 pbBuf[10] = 0x00;
2394 pbBuf[11] = 0x05;
2395 pbBuf[12] = 0x00;
2396 pbBuf[13] = 0x00;
2397 pbBuf[14] = 0x00;
2398 pbBuf[15] = 0x00;
2399 s->iSourceSink = ATAFN_SS_NULL;
2400 atapiCmdOK(s);
2401 return false;
2402}
2403
2404
2405static bool atapiModeSenseCDStatusSS(ATADevState *s)
2406{
2407 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2408
2409 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2410 Assert(s->cbElementaryTransfer <= 40);
2411 ataH2BE_U16(&pbBuf[0], 38);
2412 pbBuf[2] = 0x70;
2413 pbBuf[3] = 0;
2414 pbBuf[4] = 0;
2415 pbBuf[5] = 0;
2416 pbBuf[6] = 0;
2417 pbBuf[7] = 0;
2418
2419 pbBuf[8] = 0x2a;
2420 pbBuf[9] = 30; /* page length */
2421 pbBuf[10] = 0x08; /* DVD-ROM read support */
2422 pbBuf[11] = 0x00; /* no write support */
2423 /* The following claims we support audio play. This is obviously false,
2424 * but the Linux generic CDROM support makes many features depend on this
2425 * capability. If it's not set, this causes many things to be disabled. */
2426 pbBuf[12] = 0x71; /* multisession support, mode 2 form 1/2 support, audio play */
2427 pbBuf[13] = 0x00; /* no subchannel reads supported */
2428 pbBuf[14] = (1 << 0) | (1 << 3) | (1 << 5); /* lock supported, eject supported, tray type loading mechanism */
2429 if (s->pDrvMount->pfnIsLocked(s->pDrvMount))
2430 pbBuf[14] |= 1 << 1; /* report lock state */
2431 pbBuf[15] = 0; /* no subchannel reads supported, no separate audio volume control, no changer etc. */
2432 ataH2BE_U16(&pbBuf[16], 5632); /* (obsolete) claim 32x speed support */
2433 ataH2BE_U16(&pbBuf[18], 2); /* number of audio volume levels */
2434 ataH2BE_U16(&pbBuf[20], s->cbIOBuffer / _1K); /* buffer size supported in Kbyte */
2435 ataH2BE_U16(&pbBuf[22], 5632); /* (obsolete) current read speed 32x */
2436 pbBuf[24] = 0; /* reserved */
2437 pbBuf[25] = 0; /* reserved for digital audio (see idx 15) */
2438 ataH2BE_U16(&pbBuf[26], 0); /* (obsolete) maximum write speed */
2439 ataH2BE_U16(&pbBuf[28], 0); /* (obsolete) current write speed */
2440 ataH2BE_U16(&pbBuf[30], 0); /* copy management revision supported 0=no CSS */
2441 pbBuf[32] = 0; /* reserved */
2442 pbBuf[33] = 0; /* reserved */
2443 pbBuf[34] = 0; /* reserved */
2444 pbBuf[35] = 1; /* rotation control CAV */
2445 ataH2BE_U16(&pbBuf[36], 0); /* current write speed */
2446 ataH2BE_U16(&pbBuf[38], 0); /* number of write speed performance descriptors */
2447 s->iSourceSink = ATAFN_SS_NULL;
2448 atapiCmdOK(s);
2449 return false;
2450}
2451
2452
2453static bool atapiRequestSenseSS(ATADevState *s)
2454{
2455 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2456
2457 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2458 memset(pbBuf, '\0', s->cbElementaryTransfer);
2459 memcpy(pbBuf, s->abATAPISense, RT_MIN(s->cbElementaryTransfer, sizeof(s->abATAPISense)));
2460 s->iSourceSink = ATAFN_SS_NULL;
2461 atapiCmdOK(s);
2462 return false;
2463}
2464
2465
2466static bool atapiMechanismStatusSS(ATADevState *s)
2467{
2468 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2469
2470 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2471 Assert(s->cbElementaryTransfer <= 8);
2472 ataH2BE_U16(pbBuf, 0);
2473 /* no current LBA */
2474 pbBuf[2] = 0;
2475 pbBuf[3] = 0;
2476 pbBuf[4] = 0;
2477 pbBuf[5] = 1;
2478 ataH2BE_U16(pbBuf + 6, 0);
2479 s->iSourceSink = ATAFN_SS_NULL;
2480 atapiCmdOK(s);
2481 return false;
2482}
2483
2484
2485static bool atapiReadTOCNormalSS(ATADevState *s)
2486{
2487 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer), *q, iStartTrack;
2488 bool fMSF;
2489 uint32_t cbSize;
2490
2491 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2492 fMSF = (s->aATAPICmd[1] >> 1) & 1;
2493 iStartTrack = s->aATAPICmd[6];
2494 if (iStartTrack > 1 && iStartTrack != 0xaa)
2495 {
2496 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2497 return false;
2498 }
2499 q = pbBuf + 2;
2500 *q++ = 1; /* first session */
2501 *q++ = 1; /* last session */
2502 if (iStartTrack <= 1)
2503 {
2504 *q++ = 0; /* reserved */
2505 *q++ = 0x14; /* ADR, control */
2506 *q++ = 1; /* track number */
2507 *q++ = 0; /* reserved */
2508 if (fMSF)
2509 {
2510 *q++ = 0; /* reserved */
2511 ataLBA2MSF(q, 0);
2512 q += 3;
2513 }
2514 else
2515 {
2516 /* sector 0 */
2517 ataH2BE_U32(q, 0);
2518 q += 4;
2519 }
2520 }
2521 /* lead out track */
2522 *q++ = 0; /* reserved */
2523 *q++ = 0x14; /* ADR, control */
2524 *q++ = 0xaa; /* track number */
2525 *q++ = 0; /* reserved */
2526 if (fMSF)
2527 {
2528 *q++ = 0; /* reserved */
2529 ataLBA2MSF(q, s->cTotalSectors);
2530 q += 3;
2531 }
2532 else
2533 {
2534 ataH2BE_U32(q, s->cTotalSectors);
2535 q += 4;
2536 }
2537 cbSize = q - pbBuf;
2538 ataH2BE_U16(pbBuf, cbSize - 2);
2539 if (cbSize < s->cbTotalTransfer)
2540 s->cbTotalTransfer = cbSize;
2541 s->iSourceSink = ATAFN_SS_NULL;
2542 atapiCmdOK(s);
2543 return false;
2544}
2545
2546
2547static bool atapiReadTOCMultiSS(ATADevState *s)
2548{
2549 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
2550 bool fMSF;
2551
2552 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2553 Assert(s->cbElementaryTransfer <= 12);
2554 fMSF = (s->aATAPICmd[1] >> 1) & 1;
2555 /* multi session: only a single session defined */
2556/** @todo double-check this stuff against what a real drive says for a CD-ROM (not a CD-R) with only a single data session. Maybe solve the problem with "cdrdao read-toc" not being able to figure out whether numbers are in BCD or hex. */
2557 memset(pbBuf, 0, 12);
2558 pbBuf[1] = 0x0a;
2559 pbBuf[2] = 0x01;
2560 pbBuf[3] = 0x01;
2561 pbBuf[5] = 0x14; /* ADR, control */
2562 pbBuf[6] = 1; /* first track in last complete session */
2563 if (fMSF)
2564 {
2565 pbBuf[8] = 0; /* reserved */
2566 ataLBA2MSF(&pbBuf[9], 0);
2567 }
2568 else
2569 {
2570 /* sector 0 */
2571 ataH2BE_U32(pbBuf + 8, 0);
2572 }
2573 s->iSourceSink = ATAFN_SS_NULL;
2574 atapiCmdOK(s);
2575 return false;
2576}
2577
2578
2579static bool atapiReadTOCRawSS(ATADevState *s)
2580{
2581 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer), *q, iStartTrack;
2582 bool fMSF;
2583 uint32_t cbSize;
2584
2585 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2586 fMSF = (s->aATAPICmd[1] >> 1) & 1;
2587 iStartTrack = s->aATAPICmd[6];
2588
2589 q = pbBuf + 2;
2590 *q++ = 1; /* first session */
2591 *q++ = 1; /* last session */
2592
2593 *q++ = 1; /* session number */
2594 *q++ = 0x14; /* data track */
2595 *q++ = 0; /* track number */
2596 *q++ = 0xa0; /* first track in program area */
2597 *q++ = 0; /* min */
2598 *q++ = 0; /* sec */
2599 *q++ = 0; /* frame */
2600 *q++ = 0;
2601 *q++ = 1; /* first track */
2602 *q++ = 0x00; /* disk type CD-DA or CD data */
2603 *q++ = 0;
2604
2605 *q++ = 1; /* session number */
2606 *q++ = 0x14; /* data track */
2607 *q++ = 0; /* track number */
2608 *q++ = 0xa1; /* last track in program area */
2609 *q++ = 0; /* min */
2610 *q++ = 0; /* sec */
2611 *q++ = 0; /* frame */
2612 *q++ = 0;
2613 *q++ = 1; /* last track */
2614 *q++ = 0;
2615 *q++ = 0;
2616
2617 *q++ = 1; /* session number */
2618 *q++ = 0x14; /* data track */
2619 *q++ = 0; /* track number */
2620 *q++ = 0xa2; /* lead-out */
2621 *q++ = 0; /* min */
2622 *q++ = 0; /* sec */
2623 *q++ = 0; /* frame */
2624 if (fMSF)
2625 {
2626 *q++ = 0; /* reserved */
2627 ataLBA2MSF(q, s->cTotalSectors);
2628 q += 3;
2629 }
2630 else
2631 {
2632 ataH2BE_U32(q, s->cTotalSectors);
2633 q += 4;
2634 }
2635
2636 *q++ = 1; /* session number */
2637 *q++ = 0x14; /* ADR, control */
2638 *q++ = 0; /* track number */
2639 *q++ = 1; /* point */
2640 *q++ = 0; /* min */
2641 *q++ = 0; /* sec */
2642 *q++ = 0; /* frame */
2643 if (fMSF)
2644 {
2645 *q++ = 0; /* reserved */
2646 ataLBA2MSF(q, 0);
2647 q += 3;
2648 }
2649 else
2650 {
2651 /* sector 0 */
2652 ataH2BE_U32(q, 0);
2653 q += 4;
2654 }
2655
2656 cbSize = q - pbBuf;
2657 ataH2BE_U16(pbBuf, cbSize - 2);
2658 if (cbSize < s->cbTotalTransfer)
2659 s->cbTotalTransfer = cbSize;
2660 s->iSourceSink = ATAFN_SS_NULL;
2661 atapiCmdOK(s);
2662 return false;
2663}
2664
2665
2666static void atapiParseCmdVirtualATAPI(ATADevState *s)
2667{
2668 const uint8_t *pbPacket;
2669 uint8_t *pbBuf;
2670 uint32_t cbMax;
2671
2672 pbPacket = s->aATAPICmd;
2673 pbBuf = s->CTX_SUFF(pbIOBuffer);
2674 switch (pbPacket[0])
2675 {
2676 case SCSI_TEST_UNIT_READY:
2677 if (s->cNotifiedMediaChange > 0)
2678 {
2679 if (s->cNotifiedMediaChange-- > 2)
2680 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2681 else
2682 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2683 }
2684 else if (s->pDrvMount->pfnIsMounted(s->pDrvMount))
2685 atapiCmdOK(s);
2686 else
2687 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2688 break;
2689 case SCSI_GET_EVENT_STATUS_NOTIFICATION:
2690 cbMax = ataBE2H_U16(pbPacket + 7);
2691 ataStartTransfer(s, RT_MIN(cbMax, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_EVENT_STATUS_NOTIFICATION, true);
2692 break;
2693 case SCSI_MODE_SENSE_10:
2694 {
2695 uint8_t uPageControl, uPageCode;
2696 cbMax = ataBE2H_U16(pbPacket + 7);
2697 uPageControl = pbPacket[2] >> 6;
2698 uPageCode = pbPacket[2] & 0x3f;
2699 switch (uPageControl)
2700 {
2701 case SCSI_PAGECONTROL_CURRENT:
2702 switch (uPageCode)
2703 {
2704 case SCSI_MODEPAGE_ERROR_RECOVERY:
2705 ataStartTransfer(s, RT_MIN(cbMax, 16), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_ERROR_RECOVERY, true);
2706 break;
2707 case SCSI_MODEPAGE_CD_STATUS:
2708 ataStartTransfer(s, RT_MIN(cbMax, 40), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS, true);
2709 break;
2710 default:
2711 goto error_cmd;
2712 }
2713 break;
2714 case SCSI_PAGECONTROL_CHANGEABLE:
2715 goto error_cmd;
2716 case SCSI_PAGECONTROL_DEFAULT:
2717 goto error_cmd;
2718 default:
2719 case SCSI_PAGECONTROL_SAVED:
2720 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
2721 break;
2722 }
2723 }
2724 break;
2725 case SCSI_REQUEST_SENSE:
2726 cbMax = pbPacket[4];
2727 ataStartTransfer(s, RT_MIN(cbMax, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
2728 break;
2729 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
2730 if (s->pDrvMount->pfnIsMounted(s->pDrvMount))
2731 {
2732 if (pbPacket[4] & 1)
2733 s->pDrvMount->pfnLock(s->pDrvMount);
2734 else
2735 s->pDrvMount->pfnUnlock(s->pDrvMount);
2736 atapiCmdOK(s);
2737 }
2738 else
2739 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2740 break;
2741 case SCSI_READ_10:
2742 case SCSI_READ_12:
2743 {
2744 uint32_t cSectors, iATAPILBA;
2745
2746 if (s->cNotifiedMediaChange > 0)
2747 {
2748 s->cNotifiedMediaChange-- ;
2749 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2750 break;
2751 }
2752 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2753 {
2754 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2755 break;
2756 }
2757 if (pbPacket[0] == SCSI_READ_10)
2758 cSectors = ataBE2H_U16(pbPacket + 7);
2759 else
2760 cSectors = ataBE2H_U32(pbPacket + 6);
2761 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2762 if (cSectors == 0)
2763 {
2764 atapiCmdOK(s);
2765 break;
2766 }
2767 if ((uint64_t)iATAPILBA + cSectors > s->cTotalSectors)
2768 {
2769 /* Rate limited logging, one log line per second. For
2770 * guests that insist on reading from places outside the
2771 * valid area this often generates too many release log
2772 * entries otherwise. */
2773 static uint64_t uLastLogTS = 0;
2774 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2775 {
2776 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (READ)\n", s->iLUN, (uint64_t)iATAPILBA + cSectors));
2777 uLastLogTS = RTTimeMilliTS();
2778 }
2779 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2780 break;
2781 }
2782 atapiReadSectors(s, iATAPILBA, cSectors, 2048);
2783 }
2784 break;
2785 case SCSI_READ_CD:
2786 {
2787 uint32_t cSectors, iATAPILBA;
2788
2789 if (s->cNotifiedMediaChange > 0)
2790 {
2791 s->cNotifiedMediaChange-- ;
2792 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2793 break;
2794 }
2795 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2796 {
2797 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2798 break;
2799 }
2800 cSectors = (pbPacket[6] << 16) | (pbPacket[7] << 8) | pbPacket[8];
2801 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2802 if (cSectors == 0)
2803 {
2804 atapiCmdOK(s);
2805 break;
2806 }
2807 if ((uint64_t)iATAPILBA + cSectors > s->cTotalSectors)
2808 {
2809 /* Rate limited logging, one log line per second. For
2810 * guests that insist on reading from places outside the
2811 * valid area this often generates too many release log
2812 * entries otherwise. */
2813 static uint64_t uLastLogTS = 0;
2814 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2815 {
2816 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (READ CD)\n", s->iLUN, (uint64_t)iATAPILBA + cSectors));
2817 uLastLogTS = RTTimeMilliTS();
2818 }
2819 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2820 break;
2821 }
2822 switch (pbPacket[9] & 0xf8)
2823 {
2824 case 0x00:
2825 /* nothing */
2826 atapiCmdOK(s);
2827 break;
2828 case 0x10:
2829 /* normal read */
2830 atapiReadSectors(s, iATAPILBA, cSectors, 2048);
2831 break;
2832 case 0xf8:
2833 /* read all data */
2834 atapiReadSectors(s, iATAPILBA, cSectors, 2352);
2835 break;
2836 default:
2837 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM sector format not supported (%#x)\n", s->iLUN, pbPacket[9] & 0xf8));
2838 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2839 break;
2840 }
2841 }
2842 break;
2843 case SCSI_SEEK_10:
2844 {
2845 uint32_t iATAPILBA;
2846 if (s->cNotifiedMediaChange > 0)
2847 {
2848 s->cNotifiedMediaChange-- ;
2849 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2850 break;
2851 }
2852 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2853 {
2854 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2855 break;
2856 }
2857 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2858 if (iATAPILBA > s->cTotalSectors)
2859 {
2860 /* Rate limited logging, one log line per second. For
2861 * guests that insist on seeking to places outside the
2862 * valid area this often generates too many release log
2863 * entries otherwise. */
2864 static uint64_t uLastLogTS = 0;
2865 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2866 {
2867 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (SEEK)\n", s->iLUN, (uint64_t)iATAPILBA));
2868 uLastLogTS = RTTimeMilliTS();
2869 }
2870 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2871 break;
2872 }
2873 atapiCmdOK(s);
2874 ataSetStatus(s, ATA_STAT_SEEK); /* Linux expects this. */
2875 }
2876 break;
2877 case SCSI_START_STOP_UNIT:
2878 {
2879 int rc = VINF_SUCCESS;
2880 switch (pbPacket[4] & 3)
2881 {
2882 case 0: /* 00 - Stop motor */
2883 case 1: /* 01 - Start motor */
2884 break;
2885 case 2: /* 10 - Eject media */
2886 /* This must be done from EMT. */
2887 {
2888 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
2889 PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
2890 PVMREQ pReq;
2891
2892 PDMCritSectLeave(&pCtl->lock);
2893 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT,
2894 (PFNRT)s->pDrvMount->pfnUnmount, 2, s->pDrvMount, false);
2895 AssertReleaseRC(rc);
2896 VMR3ReqFree(pReq);
2897 {
2898 STAM_PROFILE_START(&pCtl->StatLockWait, a);
2899 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
2900 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
2901 }
2902 }
2903 break;
2904 case 3: /* 11 - Load media */
2905 /** @todo rc = s->pDrvMount->pfnLoadMedia(s->pDrvMount) */
2906 break;
2907 }
2908 if (RT_SUCCESS(rc))
2909 atapiCmdOK(s);
2910 else
2911 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIA_LOAD_OR_EJECT_FAILED);
2912 }
2913 break;
2914 case SCSI_MECHANISM_STATUS:
2915 {
2916 cbMax = ataBE2H_U16(pbPacket + 8);
2917 ataStartTransfer(s, RT_MIN(cbMax, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MECHANISM_STATUS, true);
2918 }
2919 break;
2920 case SCSI_READ_TOC_PMA_ATIP:
2921 {
2922 uint8_t format;
2923
2924 if (s->cNotifiedMediaChange > 0)
2925 {
2926 s->cNotifiedMediaChange-- ;
2927 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2928 break;
2929 }
2930 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2931 {
2932 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2933 break;
2934 }
2935 cbMax = ataBE2H_U16(pbPacket + 7);
2936 /* SCSI MMC-3 spec says format is at offset 2 (lower 4 bits),
2937 * but Linux kernel uses offset 9 (topmost 2 bits). Hope that
2938 * the other field is clear... */
2939 format = (pbPacket[2] & 0xf) | (pbPacket[9] >> 6);
2940 switch (format)
2941 {
2942 case 0:
2943 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_NORMAL, true);
2944 break;
2945 case 1:
2946 ataStartTransfer(s, RT_MIN(cbMax, 12), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_MULTI, true);
2947 break;
2948 case 2:
2949 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_RAW, true);
2950 break;
2951 default:
2952 error_cmd:
2953 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2954 break;
2955 }
2956 }
2957 break;
2958 case SCSI_READ_CAPACITY:
2959 if (s->cNotifiedMediaChange > 0)
2960 {
2961 s->cNotifiedMediaChange-- ;
2962 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2963 break;
2964 }
2965 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2966 {
2967 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2968 break;
2969 }
2970 ataStartTransfer(s, 8, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_CAPACITY, true);
2971 break;
2972 case SCSI_READ_DISC_INFORMATION:
2973 if (s->cNotifiedMediaChange > 0)
2974 {
2975 s->cNotifiedMediaChange-- ;
2976 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2977 break;
2978 }
2979 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2980 {
2981 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2982 break;
2983 }
2984 cbMax = ataBE2H_U16(pbPacket + 7);
2985 ataStartTransfer(s, RT_MIN(cbMax, 34), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DISC_INFORMATION, true);
2986 break;
2987 case SCSI_READ_TRACK_INFORMATION:
2988 if (s->cNotifiedMediaChange > 0)
2989 {
2990 s->cNotifiedMediaChange-- ;
2991 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2992 break;
2993 }
2994 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2995 {
2996 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2997 break;
2998 }
2999 cbMax = ataBE2H_U16(pbPacket + 7);
3000 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TRACK_INFORMATION, true);
3001 break;
3002 case SCSI_GET_CONFIGURATION:
3003 /* No media change stuff here, it can confuse Linux guests. */
3004 cbMax = ataBE2H_U16(pbPacket + 7);
3005 ataStartTransfer(s, RT_MIN(cbMax, 32), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
3006 break;
3007 case SCSI_INQUIRY:
3008 cbMax = ataBE2H_U16(pbPacket + 3);
3009 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_INQUIRY, true);
3010 break;
3011 case SCSI_READ_DVD_STRUCTURE:
3012 {
3013 /* Only available for ICH6 for now. */
3014 PCIATAState *pDevice = PDMINS_2_DATA(s->CTX_SUFF(pDevIns), PCIATAState *);
3015
3016 if ( (PCIDevGetVendorId(&pDevice->dev) == 0x8086)
3017 && (PCIDevGetDeviceId(&pDevice->dev) == 0x269e))
3018 {
3019 cbMax = ataBE2H_U16(pbPacket + 8);
3020 ataStartTransfer(s, RT_MIN(cbMax, 4), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DVD_STRUCTURE, true);
3021 }
3022 else
3023 {
3024 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
3025 }
3026 break;
3027 }
3028 default:
3029 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
3030 break;
3031 }
3032}
3033
3034
3035/*
3036 * Parse ATAPI commands, passing them directly to the CD/DVD drive.
3037 */
3038static void atapiParseCmdPassthrough(ATADevState *s)
3039{
3040 const uint8_t *pbPacket;
3041 uint8_t *pbBuf;
3042 uint32_t cSectors, iATAPILBA;
3043 uint32_t cbTransfer = 0;
3044 PDMBLOCKTXDIR uTxDir = PDMBLOCKTXDIR_NONE;
3045
3046 pbPacket = s->aATAPICmd;
3047 pbBuf = s->CTX_SUFF(pbIOBuffer);
3048 switch (pbPacket[0])
3049 {
3050 case SCSI_BLANK:
3051 goto sendcmd;
3052 case SCSI_CLOSE_TRACK_SESSION:
3053 goto sendcmd;
3054 case SCSI_ERASE_10:
3055 iATAPILBA = ataBE2H_U32(pbPacket + 2);
3056 cbTransfer = ataBE2H_U16(pbPacket + 7);
3057 Log2(("ATAPI PT: lba %d\n", iATAPILBA));
3058 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3059 goto sendcmd;
3060 case SCSI_FORMAT_UNIT:
3061 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
3062 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3063 goto sendcmd;
3064 case SCSI_GET_CONFIGURATION:
3065 cbTransfer = ataBE2H_U16(pbPacket + 7);
3066 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3067 goto sendcmd;
3068 case SCSI_GET_EVENT_STATUS_NOTIFICATION:
3069 cbTransfer = ataBE2H_U16(pbPacket + 7);
3070 if (ASMAtomicReadU32(&s->MediaEventStatus) != ATA_EVENT_STATUS_UNCHANGED)
3071 {
3072 ataStartTransfer(s, RT_MIN(cbTransfer, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_EVENT_STATUS_NOTIFICATION, true);
3073 break;
3074 }
3075 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3076 goto sendcmd;
3077 case SCSI_GET_PERFORMANCE:
3078 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
3079 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3080 goto sendcmd;
3081 case SCSI_INQUIRY:
3082 cbTransfer = ataBE2H_U16(pbPacket + 3);
3083 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3084 goto sendcmd;
3085 case SCSI_LOAD_UNLOAD_MEDIUM:
3086 goto sendcmd;
3087 case SCSI_MECHANISM_STATUS:
3088 cbTransfer = ataBE2H_U16(pbPacket + 8);
3089 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3090 goto sendcmd;
3091 case SCSI_MODE_SELECT_10:
3092 cbTransfer = ataBE2H_U16(pbPacket + 7);
3093 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3094 goto sendcmd;
3095 case SCSI_MODE_SENSE_10:
3096 cbTransfer = ataBE2H_U16(pbPacket + 7);
3097 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3098 goto sendcmd;
3099 case SCSI_PAUSE_RESUME:
3100 goto sendcmd;
3101 case SCSI_PLAY_AUDIO_10:
3102 goto sendcmd;
3103 case SCSI_PLAY_AUDIO_12:
3104 goto sendcmd;
3105 case SCSI_PLAY_AUDIO_MSF:
3106 goto sendcmd;
3107 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
3108 /** @todo do not forget to unlock when a VM is shut down */
3109 goto sendcmd;
3110 case SCSI_READ_10:
3111 iATAPILBA = ataBE2H_U32(pbPacket + 2);
3112 cSectors = ataBE2H_U16(pbPacket + 7);
3113 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
3114 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
3115 cbTransfer = cSectors * s->cbATAPISector;
3116 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3117 goto sendcmd;
3118 case SCSI_READ_12:
3119 iATAPILBA = ataBE2H_U32(pbPacket + 2);
3120 cSectors = ataBE2H_U32(pbPacket + 6);
3121 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
3122 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
3123 cbTransfer = cSectors * s->cbATAPISector;
3124 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3125 goto sendcmd;
3126 case SCSI_READ_BUFFER:
3127 cbTransfer = ataBE2H_U24(pbPacket + 6);
3128 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3129 goto sendcmd;
3130 case SCSI_READ_BUFFER_CAPACITY:
3131 cbTransfer = ataBE2H_U16(pbPacket + 7);
3132 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3133 goto sendcmd;
3134 case SCSI_READ_CAPACITY:
3135 cbTransfer = 8;
3136 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3137 goto sendcmd;
3138 case SCSI_READ_CD:
3139 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
3140 cbTransfer = ataBE2H_U24(pbPacket + 6) / s->cbATAPISector * s->cbATAPISector;
3141 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3142 goto sendcmd;
3143 case SCSI_READ_CD_MSF:
3144 cSectors = ataMSF2LBA(pbPacket + 6) - ataMSF2LBA(pbPacket + 3);
3145 if (cSectors > 32)
3146 cSectors = 32; /* Limit transfer size to 64~74K. Safety first. In any case this can only harm software doing CDDA extraction. */
3147 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
3148 cbTransfer = cSectors * s->cbATAPISector;
3149 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3150 goto sendcmd;
3151 case SCSI_READ_DISC_INFORMATION:
3152 cbTransfer = ataBE2H_U16(pbPacket + 7);
3153 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3154 goto sendcmd;
3155 case SCSI_READ_DVD_STRUCTURE:
3156 cbTransfer = ataBE2H_U16(pbPacket + 8);
3157 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3158 goto sendcmd;
3159 case SCSI_READ_FORMAT_CAPACITIES:
3160 cbTransfer = ataBE2H_U16(pbPacket + 7);
3161 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3162 goto sendcmd;
3163 case SCSI_READ_SUBCHANNEL:
3164 cbTransfer = ataBE2H_U16(pbPacket + 7);
3165 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3166 goto sendcmd;
3167 case SCSI_READ_TOC_PMA_ATIP:
3168 cbTransfer = ataBE2H_U16(pbPacket + 7);
3169 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3170 goto sendcmd;
3171 case SCSI_READ_TRACK_INFORMATION:
3172 cbTransfer = ataBE2H_U16(pbPacket + 7);
3173 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3174 goto sendcmd;
3175 case SCSI_REPAIR_TRACK:
3176 goto sendcmd;
3177 case SCSI_REPORT_KEY:
3178 cbTransfer = ataBE2H_U16(pbPacket + 8);
3179 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3180 goto sendcmd;
3181 case SCSI_REQUEST_SENSE:
3182 cbTransfer = pbPacket[4];
3183 if ((s->abATAPISense[2] & 0x0f) != SCSI_SENSE_NONE)
3184 {
3185 ataStartTransfer(s, RT_MIN(cbTransfer, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
3186 break;
3187 }
3188 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3189 goto sendcmd;
3190 case SCSI_RESERVE_TRACK:
3191 goto sendcmd;
3192 case SCSI_SCAN:
3193 goto sendcmd;
3194 case SCSI_SEEK_10:
3195 goto sendcmd;
3196 case SCSI_SEND_CUE_SHEET:
3197 cbTransfer = ataBE2H_U24(pbPacket + 6);
3198 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3199 goto sendcmd;
3200 case SCSI_SEND_DVD_STRUCTURE:
3201 cbTransfer = ataBE2H_U16(pbPacket + 8);
3202 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3203 goto sendcmd;
3204 case SCSI_SEND_EVENT:
3205 cbTransfer = ataBE2H_U16(pbPacket + 8);
3206 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3207 goto sendcmd;
3208 case SCSI_SEND_KEY:
3209 cbTransfer = ataBE2H_U16(pbPacket + 8);
3210 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3211 goto sendcmd;
3212 case SCSI_SEND_OPC_INFORMATION:
3213 cbTransfer = ataBE2H_U16(pbPacket + 7);
3214 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3215 goto sendcmd;
3216 case SCSI_SET_CD_SPEED:
3217 goto sendcmd;
3218 case SCSI_SET_READ_AHEAD:
3219 goto sendcmd;
3220 case SCSI_SET_STREAMING:
3221 cbTransfer = ataBE2H_U16(pbPacket + 9);
3222 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3223 goto sendcmd;
3224 case SCSI_START_STOP_UNIT:
3225 goto sendcmd;
3226 case SCSI_STOP_PLAY_SCAN:
3227 goto sendcmd;
3228 case SCSI_SYNCHRONIZE_CACHE:
3229 goto sendcmd;
3230 case SCSI_TEST_UNIT_READY:
3231 goto sendcmd;
3232 case SCSI_VERIFY_10:
3233 goto sendcmd;
3234 case SCSI_WRITE_10:
3235 iATAPILBA = ataBE2H_U32(pbPacket + 2);
3236 cSectors = ataBE2H_U16(pbPacket + 7);
3237 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
3238#if 0
3239 /* The sector size is determined by the async I/O thread. */
3240 s->cbATAPISector = 0;
3241 /* Preliminary, will be corrected once the sector size is known. */
3242 cbTransfer = cSectors;
3243#else
3244 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
3245 cbTransfer = cSectors * s->cbATAPISector;
3246#endif
3247 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3248 goto sendcmd;
3249 case SCSI_WRITE_12:
3250 iATAPILBA = ataBE2H_U32(pbPacket + 2);
3251 cSectors = ataBE2H_U32(pbPacket + 6);
3252 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
3253#if 0
3254 /* The sector size is determined by the async I/O thread. */
3255 s->cbATAPISector = 0;
3256 /* Preliminary, will be corrected once the sector size is known. */
3257 cbTransfer = cSectors;
3258#else
3259 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
3260 cbTransfer = cSectors * s->cbATAPISector;
3261#endif
3262 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3263 goto sendcmd;
3264 case SCSI_WRITE_AND_VERIFY_10:
3265 iATAPILBA = ataBE2H_U32(pbPacket + 2);
3266 cSectors = ataBE2H_U16(pbPacket + 7);
3267 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
3268 /* The sector size is determined by the async I/O thread. */
3269 s->cbATAPISector = 0;
3270 /* Preliminary, will be corrected once the sector size is known. */
3271 cbTransfer = cSectors;
3272 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3273 goto sendcmd;
3274 case SCSI_WRITE_BUFFER:
3275 switch (pbPacket[1] & 0x1f)
3276 {
3277 case 0x04: /* download microcode */
3278 case 0x05: /* download microcode and save */
3279 case 0x06: /* download microcode with offsets */
3280 case 0x07: /* download microcode with offsets and save */
3281 case 0x0e: /* download microcode with offsets and defer activation */
3282 case 0x0f: /* activate deferred microcode */
3283 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command attempted to update firmware, blocked\n", s->iLUN));
3284 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
3285 break;
3286 default:
3287 cbTransfer = ataBE2H_U16(pbPacket + 6);
3288 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
3289 goto sendcmd;
3290 }
3291 break;
3292 case SCSI_REPORT_LUNS: /* Not part of MMC-3, but used by Windows. */
3293 cbTransfer = ataBE2H_U32(pbPacket + 6);
3294 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
3295 goto sendcmd;
3296 case SCSI_REZERO_UNIT:
3297 /* Obsolete command used by cdrecord. What else would one expect?
3298 * This command is not sent to the drive, it is handled internally,
3299 * as the Linux kernel doesn't like it (message "scsi: unknown
3300 * opcode 0x01" in syslog) and replies with a sense code of 0,
3301 * which sends cdrecord to an endless loop. */
3302 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
3303 break;
3304 default:
3305 LogRel(("PIIX3 ATA: LUN#%d: passthrough unimplemented for command %#x\n", s->iLUN, pbPacket[0]));
3306 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
3307 break;
3308 sendcmd:
3309 /* Send a command to the drive, passing data in/out as required. */
3310 Log2(("ATAPI PT: max size %d\n", cbTransfer));
3311 Assert(cbTransfer <= s->cbIOBuffer);
3312 if (cbTransfer == 0)
3313 uTxDir = PDMBLOCKTXDIR_NONE;
3314 ataStartTransfer(s, cbTransfer, uTxDir, ATAFN_BT_ATAPI_PASSTHROUGH_CMD, ATAFN_SS_ATAPI_PASSTHROUGH, true);
3315 }
3316}
3317
3318
3319static void atapiParseCmd(ATADevState *s)
3320{
3321 const uint8_t *pbPacket;
3322
3323 pbPacket = s->aATAPICmd;
3324#ifdef DEBUG
3325 Log(("%s: LUN#%d DMA=%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0], SCSICmdText(pbPacket[0])));
3326#else /* !DEBUG */
3327 Log(("%s: LUN#%d DMA=%d CMD=%#04x\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0]));
3328#endif /* !DEBUG */
3329 Log2(("%s: limit=%#x packet: %.*Rhxs\n", __FUNCTION__, s->uATARegLCyl | (s->uATARegHCyl << 8), ATAPI_PACKET_SIZE, pbPacket));
3330
3331 if (s->fATAPIPassthrough)
3332 atapiParseCmdPassthrough(s);
3333 else
3334 atapiParseCmdVirtualATAPI(s);
3335}
3336
3337
3338static bool ataPacketSS(ATADevState *s)
3339{
3340 s->fDMA = !!(s->uATARegFeature & 1);
3341 memcpy(s->aATAPICmd, s->CTX_SUFF(pbIOBuffer), ATAPI_PACKET_SIZE);
3342 s->uTxDir = PDMBLOCKTXDIR_NONE;
3343 s->cbTotalTransfer = 0;
3344 s->cbElementaryTransfer = 0;
3345 atapiParseCmd(s);
3346 return false;
3347}
3348
3349
3350/**
3351 * SCSI_GET_EVENT_STATUS_NOTIFICATION should return "medium removed" event
3352 * from now on, regardless if there was a medium inserted or not.
3353 */
3354static void ataMediumRemoved(ATADevState *s)
3355{
3356 ASMAtomicWriteU32(&s->MediaEventStatus, ATA_EVENT_STATUS_MEDIA_REMOVED);
3357}
3358
3359
3360/**
3361 * SCSI_GET_EVENT_STATUS_NOTIFICATION should return "medium inserted". If
3362 * there was already a medium inserted, don't forget to send the "medium
3363 * removed" event first.
3364 */
3365static void ataMediumInserted(ATADevState *s)
3366{
3367 uint32_t OldStatus, NewStatus;
3368 do
3369 {
3370 OldStatus = ASMAtomicReadU32(&s->MediaEventStatus);
3371 switch (OldStatus)
3372 {
3373 case ATA_EVENT_STATUS_MEDIA_CHANGED:
3374 case ATA_EVENT_STATUS_MEDIA_REMOVED:
3375 /* no change, we will send "medium removed" + "medium inserted" */
3376 NewStatus = ATA_EVENT_STATUS_MEDIA_CHANGED;
3377 break;
3378 default:
3379 NewStatus = ATA_EVENT_STATUS_MEDIA_NEW;
3380 break;
3381 }
3382 } while (!ASMAtomicCmpXchgU32(&s->MediaEventStatus, NewStatus, OldStatus));
3383}
3384
3385
3386/**
3387 * Called when a media is mounted.
3388 *
3389 * @param pInterface Pointer to the interface structure containing the called function pointer.
3390 */
3391static DECLCALLBACK(void) ataMountNotify(PPDMIMOUNTNOTIFY pInterface)
3392{
3393 ATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
3394 Log(("%s: changing LUN#%d\n", __FUNCTION__, pIf->iLUN));
3395
3396 /* Ignore the call if we're called while being attached. */
3397 if (!pIf->pDrvBlock)
3398 return;
3399
3400 if (pIf->fATAPI)
3401 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
3402 else
3403 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
3404
3405 /* Report media changed in TEST UNIT and other (probably incorrect) places. */
3406 if (pIf->cNotifiedMediaChange < 2)
3407 pIf->cNotifiedMediaChange = 2;
3408 ataMediumInserted(pIf);
3409}
3410
3411/**
3412 * Called when a media is unmounted
3413 * @param pInterface Pointer to the interface structure containing the called function pointer.
3414 */
3415static DECLCALLBACK(void) ataUnmountNotify(PPDMIMOUNTNOTIFY pInterface)
3416{
3417 ATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
3418 Log(("%s:\n", __FUNCTION__));
3419 pIf->cTotalSectors = 0;
3420
3421 /*
3422 * Whatever I do, XP will not use the GET MEDIA STATUS nor the EVENT stuff.
3423 * However, it will respond to TEST UNIT with a 0x6 0x28 (media changed) sense code.
3424 * So, we'll give it 4 TEST UNIT command to catch up, two which the media is not
3425 * present and 2 in which it is changed.
3426 */
3427 pIf->cNotifiedMediaChange = 4;
3428 ataMediumRemoved(pIf);
3429}
3430
3431static void ataPacketBT(ATADevState *s)
3432{
3433 s->cbElementaryTransfer = s->cbTotalTransfer;
3434 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_CD;
3435 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
3436 ataSetStatusValue(s, ATA_STAT_READY);
3437}
3438
3439
3440static void ataResetDevice(ATADevState *s)
3441{
3442 s->cMultSectors = ATA_MAX_MULT_SECTORS;
3443 s->cNotifiedMediaChange = 0;
3444 ASMAtomicWriteU32(&s->MediaEventStatus, ATA_EVENT_STATUS_UNCHANGED);
3445 ataUnsetIRQ(s);
3446
3447 s->uATARegSelect = 0x20;
3448 ataSetStatusValue(s, ATA_STAT_READY);
3449 ataSetSignature(s);
3450 s->cbTotalTransfer = 0;
3451 s->cbElementaryTransfer = 0;
3452 s->iIOBufferPIODataStart = 0;
3453 s->iIOBufferPIODataEnd = 0;
3454 s->iBeginTransfer = ATAFN_BT_NULL;
3455 s->iSourceSink = ATAFN_SS_NULL;
3456 s->fATAPITransfer = false;
3457 s->uATATransferMode = ATA_MODE_UDMA | 2; /* PIIX3 supports only up to UDMA2 */
3458
3459 s->uATARegFeature = 0;
3460}
3461
3462
3463static bool ataExecuteDeviceDiagnosticSS(ATADevState *s)
3464{
3465 ataSetSignature(s);
3466 if (s->fATAPI)
3467 ataSetStatusValue(s, 0); /* NOTE: READY is _not_ set */
3468 else
3469 ataSetStatusValue(s, ATA_STAT_READY);
3470 s->uATARegError = 0x01;
3471 return false;
3472}
3473
3474
3475static void ataParseCmd(ATADevState *s, uint8_t cmd)
3476{
3477#ifdef DEBUG
3478 Log(("%s: LUN#%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, cmd, ATACmdText(cmd)));
3479#else /* !DEBUG */
3480 Log(("%s: LUN#%d CMD=%#04x\n", __FUNCTION__, s->iLUN, cmd));
3481#endif /* !DEBUG */
3482 s->fLBA48 = false;
3483 s->fDMA = false;
3484 if (cmd == ATA_IDLE_IMMEDIATE)
3485 {
3486 /* Detect Linux timeout recovery, first tries IDLE IMMEDIATE (which
3487 * would overwrite the failing command unfortunately), then RESET. */
3488 int32_t uCmdWait = -1;
3489 uint64_t uNow = RTTimeNanoTS();
3490 if (s->u64CmdTS)
3491 uCmdWait = (uNow - s->u64CmdTS) / 1000;
3492 LogRel(("PIIX3 ATA: LUN#%d: IDLE IMMEDIATE, CmdIf=%#04x (%d usec ago)\n",
3493 s->iLUN, s->uATARegCommand, uCmdWait));
3494 }
3495 s->uATARegCommand = cmd;
3496 switch (cmd)
3497 {
3498 case ATA_IDENTIFY_DEVICE:
3499 if (s->pDrvBlock && !s->fATAPI)
3500 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_IDENTIFY, false);
3501 else
3502 {
3503 if (s->fATAPI)
3504 ataSetSignature(s);
3505 ataCmdError(s, ABRT_ERR);
3506 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3507 }
3508 break;
3509 case ATA_INITIALIZE_DEVICE_PARAMETERS:
3510 case ATA_RECALIBRATE:
3511 ataCmdOK(s, ATA_STAT_SEEK);
3512 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3513 break;
3514 case ATA_SET_MULTIPLE_MODE:
3515 if ( s->uATARegNSector != 0
3516 && ( s->uATARegNSector > ATA_MAX_MULT_SECTORS
3517 || (s->uATARegNSector & (s->uATARegNSector - 1)) != 0))
3518 {
3519 ataCmdError(s, ABRT_ERR);
3520 }
3521 else
3522 {
3523 Log2(("%s: set multi sector count to %d\n", __FUNCTION__, s->uATARegNSector));
3524 s->cMultSectors = s->uATARegNSector;
3525 ataCmdOK(s, 0);
3526 }
3527 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3528 break;
3529 case ATA_READ_VERIFY_SECTORS_EXT:
3530 s->fLBA48 = true;
3531 case ATA_READ_VERIFY_SECTORS:
3532 case ATA_READ_VERIFY_SECTORS_WITHOUT_RETRIES:
3533 /* do sector number check ? */
3534 ataCmdOK(s, 0);
3535 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3536 break;
3537 case ATA_READ_SECTORS_EXT:
3538 s->fLBA48 = true;
3539 case ATA_READ_SECTORS:
3540 case ATA_READ_SECTORS_WITHOUT_RETRIES:
3541 if (!s->pDrvBlock)
3542 goto abort_cmd;
3543 s->cSectorsPerIRQ = 1;
3544 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
3545 break;
3546 case ATA_WRITE_SECTORS_EXT:
3547 s->fLBA48 = true;
3548 case ATA_WRITE_SECTORS:
3549 case ATA_WRITE_SECTORS_WITHOUT_RETRIES:
3550 s->cSectorsPerIRQ = 1;
3551 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
3552 break;
3553 case ATA_READ_MULTIPLE_EXT:
3554 s->fLBA48 = true;
3555 case ATA_READ_MULTIPLE:
3556 if (!s->cMultSectors)
3557 goto abort_cmd;
3558 s->cSectorsPerIRQ = s->cMultSectors;
3559 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
3560 break;
3561 case ATA_WRITE_MULTIPLE_EXT:
3562 s->fLBA48 = true;
3563 case ATA_WRITE_MULTIPLE:
3564 if (!s->cMultSectors)
3565 goto abort_cmd;
3566 s->cSectorsPerIRQ = s->cMultSectors;
3567 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
3568 break;
3569 case ATA_READ_DMA_EXT:
3570 s->fLBA48 = true;
3571 case ATA_READ_DMA:
3572 case ATA_READ_DMA_WITHOUT_RETRIES:
3573 if (!s->pDrvBlock)
3574 goto abort_cmd;
3575 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
3576 s->fDMA = true;
3577 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
3578 break;
3579 case ATA_WRITE_DMA_EXT:
3580 s->fLBA48 = true;
3581 case ATA_WRITE_DMA:
3582 case ATA_WRITE_DMA_WITHOUT_RETRIES:
3583 if (!s->pDrvBlock)
3584 goto abort_cmd;
3585 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
3586 s->fDMA = true;
3587 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
3588 break;
3589 case ATA_READ_NATIVE_MAX_ADDRESS_EXT:
3590 s->fLBA48 = true;
3591 ataSetSector(s, s->cTotalSectors - 1);
3592 ataCmdOK(s, 0);
3593 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3594 break;
3595 case ATA_SEEK: /* Used by the SCO OpenServer. Command is marked as obsolete */
3596 ataCmdOK(s, 0);
3597 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3598 break;
3599 case ATA_READ_NATIVE_MAX_ADDRESS:
3600 ataSetSector(s, RT_MIN(s->cTotalSectors, 1 << 28) - 1);
3601 ataCmdOK(s, 0);
3602 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3603 break;
3604 case ATA_CHECK_POWER_MODE:
3605 s->uATARegNSector = 0xff; /* drive active or idle */
3606 ataCmdOK(s, 0);
3607 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3608 break;
3609 case ATA_SET_FEATURES:
3610 Log2(("%s: feature=%#x\n", __FUNCTION__, s->uATARegFeature));
3611 if (!s->pDrvBlock)
3612 goto abort_cmd;
3613 switch (s->uATARegFeature)
3614 {
3615 case 0x02: /* write cache enable */
3616 Log2(("%s: write cache enable\n", __FUNCTION__));
3617 ataCmdOK(s, ATA_STAT_SEEK);
3618 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3619 break;
3620 case 0xaa: /* read look-ahead enable */
3621 Log2(("%s: read look-ahead enable\n", __FUNCTION__));
3622 ataCmdOK(s, ATA_STAT_SEEK);
3623 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3624 break;
3625 case 0x55: /* read look-ahead disable */
3626 Log2(("%s: read look-ahead disable\n", __FUNCTION__));
3627 ataCmdOK(s, ATA_STAT_SEEK);
3628 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3629 break;
3630 case 0xcc: /* reverting to power-on defaults enable */
3631 Log2(("%s: revert to power-on defaults enable\n", __FUNCTION__));
3632 ataCmdOK(s, ATA_STAT_SEEK);
3633 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3634 break;
3635 case 0x66: /* reverting to power-on defaults disable */
3636 Log2(("%s: revert to power-on defaults disable\n", __FUNCTION__));
3637 ataCmdOK(s, ATA_STAT_SEEK);
3638 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3639 break;
3640 case 0x82: /* write cache disable */
3641 Log2(("%s: write cache disable\n", __FUNCTION__));
3642 /* As per the ATA/ATAPI-6 specs, a write cache disable
3643 * command MUST flush the write buffers to disc. */
3644 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
3645 break;
3646 case 0x03: { /* set transfer mode */
3647 Log2(("%s: transfer mode %#04x\n", __FUNCTION__, s->uATARegNSector));
3648 switch (s->uATARegNSector & 0xf8)
3649 {
3650 case 0x00: /* PIO default */
3651 case 0x08: /* PIO mode */
3652 break;
3653 case ATA_MODE_MDMA: /* MDMA mode */
3654 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_MDMA_MODE_MAX);
3655 break;
3656 case ATA_MODE_UDMA: /* UDMA mode */
3657 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_UDMA_MODE_MAX);
3658 break;
3659 default:
3660 goto abort_cmd;
3661 }
3662 ataCmdOK(s, ATA_STAT_SEEK);
3663 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3664 break;
3665 }
3666 default:
3667 goto abort_cmd;
3668 }
3669 /*
3670 * OS/2 workarond:
3671 * The OS/2 IDE driver from MCP2 appears to rely on the feature register being
3672 * reset here. According to the specification, this is a driver bug as the register
3673 * contents are undefined after the call. This means we can just as well reset it.
3674 */
3675 s->uATARegFeature = 0;
3676 break;
3677 case ATA_FLUSH_CACHE_EXT:
3678 case ATA_FLUSH_CACHE:
3679 if (!s->pDrvBlock || s->fATAPI)
3680 goto abort_cmd;
3681 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
3682 break;
3683 case ATA_STANDBY_IMMEDIATE:
3684 ataCmdOK(s, 0);
3685 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3686 break;
3687 case ATA_IDLE_IMMEDIATE:
3688 LogRel(("PIIX3 ATA: LUN#%d: aborting current command\n", s->iLUN));
3689 ataAbortCurrentCommand(s, false);
3690 break;
3691 /* ATAPI commands */
3692 case ATA_IDENTIFY_PACKET_DEVICE:
3693 if (s->fATAPI)
3694 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_ATAPI_IDENTIFY, false);
3695 else
3696 {
3697 ataCmdError(s, ABRT_ERR);
3698 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3699 }
3700 break;
3701 case ATA_EXECUTE_DEVICE_DIAGNOSTIC:
3702 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC, false);
3703 break;
3704 case ATA_DEVICE_RESET:
3705 if (!s->fATAPI)
3706 goto abort_cmd;
3707 LogRel(("PIIX3 ATA: LUN#%d: performing device RESET\n", s->iLUN));
3708 ataAbortCurrentCommand(s, true);
3709 break;
3710 case ATA_PACKET:
3711 if (!s->fATAPI)
3712 goto abort_cmd;
3713 /* overlapping commands not supported */
3714 if (s->uATARegFeature & 0x02)
3715 goto abort_cmd;
3716 ataStartTransfer(s, ATAPI_PACKET_SIZE, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_PACKET, ATAFN_SS_PACKET, false);
3717 break;
3718 default:
3719 abort_cmd:
3720 ataCmdError(s, ABRT_ERR);
3721 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3722 break;
3723 }
3724}
3725
3726
3727/**
3728 * Waits for a particular async I/O thread to complete whatever it
3729 * is doing at the moment.
3730 *
3731 * @returns true on success.
3732 * @returns false when the thread is still processing.
3733 * @param pThis Pointer to the controller data.
3734 * @param cMillies How long to wait (total).
3735 */
3736static bool ataWaitForAsyncIOIsIdle(PATACONTROLLER pCtl, unsigned cMillies)
3737{
3738 uint64_t u64Start;
3739
3740 /*
3741 * Wait for any pending async operation to finish
3742 */
3743 u64Start = RTTimeMilliTS();
3744 for (;;)
3745 {
3746 if (ataAsyncIOIsIdle(pCtl, false))
3747 return true;
3748 if (RTTimeMilliTS() - u64Start >= cMillies)
3749 break;
3750
3751 /* Sleep for a bit. */
3752 RTThreadSleep(100);
3753 }
3754
3755 return false;
3756}
3757
3758#endif /* IN_RING3 */
3759
3760static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3761{
3762 Log2(("%s: write addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3763 addr &= 7;
3764 switch (addr)
3765 {
3766 case 0:
3767 break;
3768 case 1: /* feature register */
3769 /* NOTE: data is written to the two drives */
3770 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3771 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3772 pCtl->aIfs[0].uATARegFeatureHOB = pCtl->aIfs[0].uATARegFeature;
3773 pCtl->aIfs[1].uATARegFeatureHOB = pCtl->aIfs[1].uATARegFeature;
3774 pCtl->aIfs[0].uATARegFeature = val;
3775 pCtl->aIfs[1].uATARegFeature = val;
3776 break;
3777 case 2: /* sector count */
3778 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3779 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3780 pCtl->aIfs[0].uATARegNSectorHOB = pCtl->aIfs[0].uATARegNSector;
3781 pCtl->aIfs[1].uATARegNSectorHOB = pCtl->aIfs[1].uATARegNSector;
3782 pCtl->aIfs[0].uATARegNSector = val;
3783 pCtl->aIfs[1].uATARegNSector = val;
3784 break;
3785 case 3: /* sector number */
3786 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3787 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3788 pCtl->aIfs[0].uATARegSectorHOB = pCtl->aIfs[0].uATARegSector;
3789 pCtl->aIfs[1].uATARegSectorHOB = pCtl->aIfs[1].uATARegSector;
3790 pCtl->aIfs[0].uATARegSector = val;
3791 pCtl->aIfs[1].uATARegSector = val;
3792 break;
3793 case 4: /* cylinder low */
3794 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3795 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3796 pCtl->aIfs[0].uATARegLCylHOB = pCtl->aIfs[0].uATARegLCyl;
3797 pCtl->aIfs[1].uATARegLCylHOB = pCtl->aIfs[1].uATARegLCyl;
3798 pCtl->aIfs[0].uATARegLCyl = val;
3799 pCtl->aIfs[1].uATARegLCyl = val;
3800 break;
3801 case 5: /* cylinder high */
3802 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3803 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3804 pCtl->aIfs[0].uATARegHCylHOB = pCtl->aIfs[0].uATARegHCyl;
3805 pCtl->aIfs[1].uATARegHCylHOB = pCtl->aIfs[1].uATARegHCyl;
3806 pCtl->aIfs[0].uATARegHCyl = val;
3807 pCtl->aIfs[1].uATARegHCyl = val;
3808 break;
3809 case 6: /* drive/head */
3810 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0;
3811 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0;
3812 if (((val >> 4) & 1) != pCtl->iSelectedIf)
3813 {
3814 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3815
3816 /* select another drive */
3817 pCtl->iSelectedIf = (val >> 4) & 1;
3818 /* The IRQ line is multiplexed between the two drives, so
3819 * update the state when switching to another drive. Only need
3820 * to update interrupt line if it is enabled and there is a
3821 * state change. */
3822 if ( !(pCtl->aIfs[pCtl->iSelectedIf].uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ)
3823 && ( pCtl->aIfs[pCtl->iSelectedIf].fIrqPending
3824 != pCtl->aIfs[pCtl->iSelectedIf ^ 1].fIrqPending))
3825 {
3826 if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
3827 {
3828 Log2(("%s: LUN#%d asserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3829 /* The BMDMA unit unconditionally sets BM_STATUS_INT if
3830 * the interrupt line is asserted. It monitors the line
3831 * for a rising edge. */
3832 pCtl->BmDma.u8Status |= BM_STATUS_INT;
3833 if (pCtl->irq == 16)
3834 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
3835 else
3836 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
3837 }
3838 else
3839 {
3840 Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3841 if (pCtl->irq == 16)
3842 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
3843 else
3844 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
3845 }
3846 }
3847 }
3848 break;
3849 default:
3850 case 7: /* command */
3851 /* ignore commands to non existant slave */
3852 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
3853 break;
3854#ifndef IN_RING3
3855 /* Don't do anything complicated in GC */
3856 return VINF_IOM_HC_IOPORT_WRITE;
3857#else /* IN_RING3 */
3858 ataParseCmd(&pCtl->aIfs[pCtl->iSelectedIf], val);
3859#endif /* !IN_RING3 */
3860 }
3861 return VINF_SUCCESS;
3862}
3863
3864
3865static int ataIOPortReadU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32)
3866{
3867 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3868 uint32_t val;
3869 bool fHOB;
3870
3871 fHOB = !!(s->uATARegDevCtl & (1 << 7));
3872 switch (addr & 7)
3873 {
3874 case 0: /* data register */
3875 val = 0xff;
3876 break;
3877 case 1: /* error register */
3878 /* The ATA specification is very terse when it comes to specifying
3879 * the precise effects of reading back the error/feature register.
3880 * The error register (read-only) shares the register number with
3881 * the feature register (write-only), so it seems that it's not
3882 * necessary to support the usual HOB readback here. */
3883 if (!s->pDrvBlock)
3884 val = 0;
3885 else
3886 val = s->uATARegError;
3887 break;
3888 case 2: /* sector count */
3889 if (!s->pDrvBlock)
3890 val = 0;
3891 else if (fHOB)
3892 val = s->uATARegNSectorHOB;
3893 else
3894 val = s->uATARegNSector;
3895 break;
3896 case 3: /* sector number */
3897 if (!s->pDrvBlock)
3898 val = 0;
3899 else if (fHOB)
3900 val = s->uATARegSectorHOB;
3901 else
3902 val = s->uATARegSector;
3903 break;
3904 case 4: /* cylinder low */
3905 if (!s->pDrvBlock)
3906 val = 0;
3907 else if (fHOB)
3908 val = s->uATARegLCylHOB;
3909 else
3910 val = s->uATARegLCyl;
3911 break;
3912 case 5: /* cylinder high */
3913 if (!s->pDrvBlock)
3914 val = 0;
3915 else if (fHOB)
3916 val = s->uATARegHCylHOB;
3917 else
3918 val = s->uATARegHCyl;
3919 break;
3920 case 6: /* drive/head */
3921 /* This register must always work as long as there is at least
3922 * one drive attached to the controller. It is common between
3923 * both drives anyway (completely identical content). */
3924 if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
3925 val = 0;
3926 else
3927 val = s->uATARegSelect;
3928 break;
3929 default:
3930 case 7: /* primary status */
3931 {
3932 /* Counter for number of busy status seen in GC in a row. */
3933 static unsigned cBusy = 0;
3934
3935 if (!s->pDrvBlock)
3936 val = 0;
3937 else
3938 val = s->uATARegStatus;
3939
3940 /* Give the async I/O thread an opportunity to make progress,
3941 * don't let it starve by guests polling frequently. EMT has a
3942 * lower priority than the async I/O thread, but sometimes the
3943 * host OS doesn't care. With some guests we are only allowed to
3944 * be busy for about 5 milliseconds in some situations. Note that
3945 * this is no guarantee for any other VBox thread getting
3946 * scheduled, so this just lowers the CPU load a bit when drives
3947 * are busy. It cannot help with timing problems. */
3948 if (val & ATA_STAT_BUSY)
3949 {
3950#ifdef IN_RING3
3951 cBusy = 0;
3952 PDMCritSectLeave(&pCtl->lock);
3953
3954#ifndef RT_OS_WINDOWS
3955 /*
3956 * The thread might be stuck in an I/O operation
3957 * due to a high I/O load on the host. (see @bugref{3301})
3958 * To perform the reset successfully
3959 * we interrupt the operation by sending a signal to the thread
3960 * if the thread didn't responded in 10ms.
3961 * This works only on POSIX hosts (Windows has a CancelSynchronousIo function which
3962 * does the same but it was introduced with Vista) but so far
3963 * this hang was only observed on Linux and Mac OS X.
3964 *
3965 * This is a workaround and needs to be solved properly.
3966 */
3967 if (pCtl->fReset)
3968 {
3969 uint64_t u64ResetTimeStop = RTTimeMilliTS();
3970
3971 if ((u64ResetTimeStop - pCtl->u64ResetTime) >= 10)
3972 {
3973 LogRel(("PIIX3 ATA: Async I/O thread probably stuck in operation, interrupting\n"));
3974 pCtl->u64ResetTime = u64ResetTimeStop;
3975 RTThreadPoke(pCtl->AsyncIOThread);
3976 }
3977 }
3978#endif
3979
3980 RTThreadYield();
3981
3982 {
3983 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3984 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3985 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3986 }
3987
3988 val = s->uATARegStatus;
3989#else /* !IN_RING3 */
3990 /* Cannot yield CPU in guest context. And switching to host
3991 * context for each and every busy status is too costly,
3992 * especially on SMP systems where we don't gain much by
3993 * yielding the CPU to someone else. */
3994 if (++cBusy >= 20)
3995 {
3996 cBusy = 0;
3997 return VINF_IOM_HC_IOPORT_READ;
3998 }
3999#endif /* !IN_RING3 */
4000 }
4001 else
4002 cBusy = 0;
4003 ataUnsetIRQ(s);
4004 break;
4005 }
4006 }
4007 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
4008 *pu32 = val;
4009 return VINF_SUCCESS;
4010}
4011
4012
4013static uint32_t ataStatusRead(PATACONTROLLER pCtl, uint32_t addr)
4014{
4015 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4016 uint32_t val;
4017
4018 if ((!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock) ||
4019 (pCtl->iSelectedIf == 1 && !s->pDrvBlock))
4020 val = 0;
4021 else
4022 val = s->uATARegStatus;
4023 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
4024 return val;
4025}
4026
4027static int ataControlWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4028{
4029#ifndef IN_RING3
4030 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_RESET)
4031 return VINF_IOM_HC_IOPORT_WRITE; /* The RESET stuff is too complicated for GC. */
4032#endif /* !IN_RING3 */
4033
4034 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
4035 /* RESET is common for both drives attached to a controller. */
4036 if (!(pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
4037 (val & ATA_DEVCTL_RESET))
4038 {
4039#ifdef IN_RING3
4040 /* Software RESET low to high */
4041 int32_t uCmdWait0 = -1, uCmdWait1 = -1;
4042 uint64_t uNow = RTTimeNanoTS();
4043 if (pCtl->aIfs[0].u64CmdTS)
4044 uCmdWait0 = (uNow - pCtl->aIfs[0].u64CmdTS) / 1000;
4045 if (pCtl->aIfs[1].u64CmdTS)
4046 uCmdWait1 = (uNow - pCtl->aIfs[1].u64CmdTS) / 1000;
4047 LogRel(("PIIX3 ATA: Ctl#%d: RESET, DevSel=%d AIOIf=%d CmdIf0=%#04x (%d usec ago) CmdIf1=%#04x (%d usec ago)\n",
4048 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
4049 pCtl->aIfs[0].uATARegCommand, uCmdWait0,
4050 pCtl->aIfs[1].uATARegCommand, uCmdWait1));
4051 pCtl->fReset = true;
4052 /* Everything must be done after the reset flag is set, otherwise
4053 * there are unavoidable races with the currently executing request
4054 * (which might just finish in the mean time). */
4055 pCtl->fChainedTransfer = false;
4056 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4057 {
4058 ataResetDevice(&pCtl->aIfs[i]);
4059 /* The following cannot be done using ataSetStatusValue() since the
4060 * reset flag is already set, which suppresses all status changes. */
4061 pCtl->aIfs[i].uATARegStatus = ATA_STAT_BUSY | ATA_STAT_SEEK;
4062 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, pCtl->aIfs[i].iLUN, pCtl->aIfs[i].uATARegStatus));
4063 pCtl->aIfs[i].uATARegError = 0x01;
4064 }
4065 ataAsyncIOClearRequests(pCtl);
4066 Log2(("%s: Ctl#%d: message to async I/O thread, resetA\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4067 if (val & ATA_DEVCTL_HOB)
4068 {
4069 val &= ~ATA_DEVCTL_HOB;
4070 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
4071 }
4072
4073 /* Save the timestamp we started the reset. */
4074 pCtl->u64ResetTime = RTTimeMilliTS();
4075
4076 /* Issue the reset request now. */
4077 ataAsyncIOPutRequest(pCtl, &ataResetARequest);
4078#else /* !IN_RING3 */
4079 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
4080#endif /* IN_RING3 */
4081 }
4082 else if ((pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
4083 !(val & ATA_DEVCTL_RESET))
4084 {
4085#ifdef IN_RING3
4086 /* Software RESET high to low */
4087 Log(("%s: deasserting RESET\n", __FUNCTION__));
4088 Log2(("%s: Ctl#%d: message to async I/O thread, resetC\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4089 if (val & ATA_DEVCTL_HOB)
4090 {
4091 val &= ~ATA_DEVCTL_HOB;
4092 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
4093 }
4094 ataAsyncIOPutRequest(pCtl, &ataResetCRequest);
4095#else /* !IN_RING3 */
4096 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
4097#endif /* IN_RING3 */
4098 }
4099
4100 /* Change of interrupt disable flag. Update interrupt line if interrupt
4101 * is pending on the current interface. */
4102 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_DISABLE_IRQ
4103 && pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
4104 {
4105 if (!(val & ATA_DEVCTL_DISABLE_IRQ))
4106 {
4107 Log2(("%s: LUN#%d asserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4108 /* The BMDMA unit unconditionally sets BM_STATUS_INT if the
4109 * interrupt line is asserted. It monitors the line for a rising
4110 * edge. */
4111 pCtl->BmDma.u8Status |= BM_STATUS_INT;
4112 if (pCtl->irq == 16)
4113 PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 1);
4114 else
4115 PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 1);
4116 }
4117 else
4118 {
4119 Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4120 if (pCtl->irq == 16)
4121 PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 0);
4122 else
4123 PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 0);
4124 }
4125 }
4126
4127 if (val & ATA_DEVCTL_HOB)
4128 Log2(("%s: set HOB\n", __FUNCTION__));
4129
4130 pCtl->aIfs[0].uATARegDevCtl = val;
4131 pCtl->aIfs[1].uATARegDevCtl = val;
4132
4133 return VINF_SUCCESS;
4134}
4135
4136#ifdef IN_RING3
4137
4138static void ataPIOTransfer(PATACONTROLLER pCtl)
4139{
4140 ATADevState *s;
4141
4142 s = &pCtl->aIfs[pCtl->iAIOIf];
4143 Log3(("%s: if=%p\n", __FUNCTION__, s));
4144
4145 if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
4146 {
4147 LogRel(("PIIX3 ATA: LUN#%d: %s data in the middle of a PIO transfer - VERY SLOW\n", s->iLUN, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "loading" : "storing"));
4148 /* Any guest OS that triggers this case has a pathetic ATA driver.
4149 * In a real system it would block the CPU via IORDY, here we do it
4150 * very similarly by not continuing with the current instruction
4151 * until the transfer to/from the storage medium is completed. */
4152 if (s->iSourceSink != ATAFN_SS_NULL)
4153 {
4154 bool fRedo;
4155 uint8_t status = s->uATARegStatus;
4156 ataSetStatusValue(s, ATA_STAT_BUSY);
4157 Log2(("%s: calling source/sink function\n", __FUNCTION__));
4158 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4159 pCtl->fRedo = fRedo;
4160 if (RT_UNLIKELY(fRedo))
4161 return;
4162 ataSetStatusValue(s, status);
4163 s->iIOBufferCur = 0;
4164 s->iIOBufferEnd = s->cbElementaryTransfer;
4165 }
4166 }
4167 if (s->cbTotalTransfer)
4168 {
4169 if (s->fATAPITransfer)
4170 ataPIOTransferLimitATAPI(s);
4171
4172 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
4173 s->cbElementaryTransfer = s->cbTotalTransfer;
4174
4175 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
4176 __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
4177 s->cbTotalTransfer, s->cbElementaryTransfer,
4178 s->iIOBufferCur, s->iIOBufferEnd));
4179 ataPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
4180 s->cbTotalTransfer -= s->cbElementaryTransfer;
4181 s->iIOBufferCur += s->cbElementaryTransfer;
4182
4183 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
4184 s->cbElementaryTransfer = s->cbTotalTransfer;
4185 }
4186 else
4187 ataPIOTransferStop(s);
4188}
4189
4190
4191DECLINLINE(void) ataPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
4192{
4193 /* Do not interfere with RESET processing if the PIO transfer finishes
4194 * while the RESET line is asserted. */
4195 if (pCtl->fReset)
4196 {
4197 Log2(("%s: Ctl#%d: suppressed continuing PIO transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4198 return;
4199 }
4200
4201 if ( s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE
4202 || ( s->iSourceSink != ATAFN_SS_NULL
4203 && s->iIOBufferCur >= s->iIOBufferEnd))
4204 {
4205 /* Need to continue the transfer in the async I/O thread. This is
4206 * the case for write operations or generally for not yet finished
4207 * transfers (some data might need to be read). */
4208 ataUnsetStatus(s, ATA_STAT_READY | ATA_STAT_DRQ);
4209 ataSetStatus(s, ATA_STAT_BUSY);
4210
4211 Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4212 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
4213 }
4214 else
4215 {
4216 /* Either everything finished (though some data might still be pending)
4217 * or some data is pending before the next read is due. */
4218
4219 /* Continue a previously started transfer. */
4220 ataUnsetStatus(s, ATA_STAT_DRQ);
4221 ataSetStatus(s, ATA_STAT_READY);
4222
4223 if (s->cbTotalTransfer)
4224 {
4225 /* There is more to transfer, happens usually for large ATAPI
4226 * reads - the protocol limits the chunk size to 65534 bytes. */
4227 ataPIOTransfer(pCtl);
4228 ataSetIRQ(s);
4229 }
4230 else
4231 {
4232 Log2(("%s: Ctl#%d: skipping message to async I/O thread, ending PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4233 /* Finish PIO transfer. */
4234 ataPIOTransfer(pCtl);
4235 Assert(!pCtl->fRedo);
4236 }
4237 }
4238}
4239
4240#endif /* IN_RING3 */
4241
4242static int ataDataWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf)
4243{
4244 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4245 uint8_t *p;
4246
4247 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
4248 {
4249 Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE);
4250 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
4251#ifndef IN_RING3
4252 /* All but the last transfer unit is simple enough for GC, but
4253 * sending a request to the async IO thread is too complicated. */
4254 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
4255 {
4256 memcpy(p, pbBuf, cbSize);
4257 s->iIOBufferPIODataStart += cbSize;
4258 }
4259 else
4260 return VINF_IOM_HC_IOPORT_WRITE;
4261#else /* IN_RING3 */
4262 memcpy(p, pbBuf, cbSize);
4263 s->iIOBufferPIODataStart += cbSize;
4264 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4265 ataPIOTransferFinish(pCtl, s);
4266#endif /* !IN_RING3 */
4267 }
4268 else
4269 Log2(("%s: DUMMY data\n", __FUNCTION__));
4270 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
4271 return VINF_SUCCESS;
4272}
4273
4274static int ataDataRead(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, uint8_t *pbBuf)
4275{
4276 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4277 uint8_t *p;
4278
4279 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
4280 {
4281 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
4282 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
4283#ifndef IN_RING3
4284 /* All but the last transfer unit is simple enough for GC, but
4285 * sending a request to the async IO thread is too complicated. */
4286 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
4287 {
4288 memcpy(pbBuf, p, cbSize);
4289 s->iIOBufferPIODataStart += cbSize;
4290 }
4291 else
4292 return VINF_IOM_HC_IOPORT_READ;
4293#else /* IN_RING3 */
4294 memcpy(pbBuf, p, cbSize);
4295 s->iIOBufferPIODataStart += cbSize;
4296 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4297 ataPIOTransferFinish(pCtl, s);
4298#endif /* !IN_RING3 */
4299 }
4300 else
4301 {
4302 Log2(("%s: DUMMY data\n", __FUNCTION__));
4303 memset(pbBuf, '\xff', cbSize);
4304 }
4305 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
4306 return VINF_SUCCESS;
4307}
4308
4309#ifdef IN_RING3
4310
4311static void ataDMATransferStop(ATADevState *s)
4312{
4313 s->cbTotalTransfer = 0;
4314 s->cbElementaryTransfer = 0;
4315 s->iBeginTransfer = ATAFN_BT_NULL;
4316 s->iSourceSink = ATAFN_SS_NULL;
4317}
4318
4319
4320/**
4321 * Perform the entire DMA transfer in one go (unless a source/sink operation
4322 * has to be redone or a RESET comes in between). Unlike the PIO counterpart
4323 * this function cannot handle empty transfers.
4324 *
4325 * @param pCtl Controller for which to perform the transfer.
4326 */
4327static void ataDMATransfer(PATACONTROLLER pCtl)
4328{
4329 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
4330 ATADevState *s = &pCtl->aIfs[pCtl->iAIOIf];
4331 bool fRedo;
4332 RTGCPHYS32 pDesc;
4333 uint32_t cbTotalTransfer, cbElementaryTransfer;
4334 uint32_t iIOBufferCur, iIOBufferEnd;
4335 uint32_t dmalen;
4336 PDMBLOCKTXDIR uTxDir;
4337 bool fLastDesc = false;
4338
4339 Assert(sizeof(BMDMADesc) == 8);
4340
4341 fRedo = pCtl->fRedo;
4342 if (RT_LIKELY(!fRedo))
4343 Assert(s->cbTotalTransfer);
4344 uTxDir = (PDMBLOCKTXDIR)s->uTxDir;
4345 cbTotalTransfer = s->cbTotalTransfer;
4346 cbElementaryTransfer = s->cbElementaryTransfer;
4347 iIOBufferCur = s->iIOBufferCur;
4348 iIOBufferEnd = s->iIOBufferEnd;
4349
4350 /* The DMA loop is designed to hold the lock only when absolutely
4351 * necessary. This avoids long freezes should the guest access the
4352 * ATA registers etc. for some reason. */
4353 PDMCritSectLeave(&pCtl->lock);
4354
4355 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
4356 __FUNCTION__, uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
4357 cbTotalTransfer, cbElementaryTransfer,
4358 iIOBufferCur, iIOBufferEnd));
4359 for (pDesc = pCtl->pFirstDMADesc; pDesc <= pCtl->pLastDMADesc; pDesc += sizeof(BMDMADesc))
4360 {
4361 BMDMADesc DMADesc;
4362 RTGCPHYS32 pBuffer;
4363 uint32_t cbBuffer;
4364
4365 if (RT_UNLIKELY(fRedo))
4366 {
4367 pBuffer = pCtl->pRedoDMABuffer;
4368 cbBuffer = pCtl->cbRedoDMABuffer;
4369 fLastDesc = pCtl->fRedoDMALastDesc;
4370 }
4371 else
4372 {
4373 PDMDevHlpPhysRead(pDevIns, pDesc, &DMADesc, sizeof(BMDMADesc));
4374 pBuffer = RT_LE2H_U32(DMADesc.pBuffer);
4375 cbBuffer = RT_LE2H_U32(DMADesc.cbBuffer);
4376 fLastDesc = !!(cbBuffer & 0x80000000);
4377 cbBuffer &= 0xfffe;
4378 if (cbBuffer == 0)
4379 cbBuffer = 0x10000;
4380 if (cbBuffer > cbTotalTransfer)
4381 cbBuffer = cbTotalTransfer;
4382 }
4383
4384 while (RT_UNLIKELY(fRedo) || (cbBuffer && cbTotalTransfer))
4385 {
4386 if (RT_LIKELY(!fRedo))
4387 {
4388 dmalen = RT_MIN(cbBuffer, iIOBufferEnd - iIOBufferCur);
4389 Log2(("%s: DMA desc %#010x: addr=%#010x size=%#010x\n", __FUNCTION__,
4390 (int)pDesc, pBuffer, cbBuffer));
4391 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
4392 PDMDevHlpPhysWrite(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
4393 else
4394 PDMDevHlpPhysRead(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
4395 iIOBufferCur += dmalen;
4396 cbTotalTransfer -= dmalen;
4397 cbBuffer -= dmalen;
4398 pBuffer += dmalen;
4399 }
4400 if ( iIOBufferCur == iIOBufferEnd
4401 && (uTxDir == PDMBLOCKTXDIR_TO_DEVICE || cbTotalTransfer))
4402 {
4403 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
4404 cbElementaryTransfer = cbTotalTransfer;
4405
4406 {
4407 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4408 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4409 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4410 }
4411
4412 /* The RESET handler could have cleared the DMA transfer
4413 * state (since we didn't hold the lock until just now
4414 * the guest can continue in parallel). If so, the state
4415 * is already set up so the loop is exited immediately. */
4416 if (s->iSourceSink != ATAFN_SS_NULL)
4417 {
4418 s->iIOBufferCur = iIOBufferCur;
4419 s->iIOBufferEnd = iIOBufferEnd;
4420 s->cbElementaryTransfer = cbElementaryTransfer;
4421 s->cbTotalTransfer = cbTotalTransfer;
4422 Log2(("%s: calling source/sink function\n", __FUNCTION__));
4423 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4424 if (RT_UNLIKELY(fRedo))
4425 {
4426 pCtl->pFirstDMADesc = pDesc;
4427 pCtl->pRedoDMABuffer = pBuffer;
4428 pCtl->cbRedoDMABuffer = cbBuffer;
4429 pCtl->fRedoDMALastDesc = fLastDesc;
4430 }
4431 else
4432 {
4433 cbTotalTransfer = s->cbTotalTransfer;
4434 cbElementaryTransfer = s->cbElementaryTransfer;
4435
4436 if (uTxDir == PDMBLOCKTXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
4437 cbElementaryTransfer = cbTotalTransfer;
4438 iIOBufferCur = 0;
4439 iIOBufferEnd = cbElementaryTransfer;
4440 }
4441 pCtl->fRedo = fRedo;
4442 }
4443 else
4444 {
4445 /* This forces the loop to exit immediately. */
4446 pDesc = pCtl->pLastDMADesc + 1;
4447 }
4448
4449 PDMCritSectLeave(&pCtl->lock);
4450 if (RT_UNLIKELY(fRedo))
4451 break;
4452 }
4453 }
4454
4455 if (RT_UNLIKELY(fRedo))
4456 break;
4457
4458 /* end of transfer */
4459 if (!cbTotalTransfer || fLastDesc)
4460 break;
4461
4462 {
4463 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4464 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4465 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4466 }
4467
4468 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset)
4469 {
4470 LogRel(("PIIX3 ATA: Ctl#%d: ABORT DMA%s\n", ATACONTROLLER_IDX(pCtl), pCtl->fReset ? " due to RESET" : ""));
4471 if (!pCtl->fReset)
4472 ataDMATransferStop(s);
4473 /* This forces the loop to exit immediately. */
4474 pDesc = pCtl->pLastDMADesc + 1;
4475 }
4476
4477 PDMCritSectLeave(&pCtl->lock);
4478 }
4479
4480 {
4481 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4482 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4483 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4484 }
4485
4486 if (RT_UNLIKELY(fRedo))
4487 return;
4488
4489 if (fLastDesc)
4490 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
4491 s->cbTotalTransfer = cbTotalTransfer;
4492 s->cbElementaryTransfer = cbElementaryTransfer;
4493 s->iIOBufferCur = iIOBufferCur;
4494 s->iIOBufferEnd = iIOBufferEnd;
4495}
4496
4497
4498/** Asynch I/O thread for an interface. Once upon a time this was readable
4499 * code with several loops and a different semaphore for each purpose. But
4500 * then came the "how can one save the state in the middle of a PIO transfer"
4501 * question. The solution was to use an ASM, which is what's there now. */
4502static DECLCALLBACK(int) ataAsyncIOLoop(RTTHREAD ThreadSelf, void *pvUser)
4503{
4504 const ATARequest *pReq;
4505 uint64_t u64TS = 0; /* shut up gcc */
4506 uint64_t uWait;
4507 int rc = VINF_SUCCESS;
4508 PATACONTROLLER pCtl = (PATACONTROLLER)pvUser;
4509 ATADevState *s;
4510
4511 pReq = NULL;
4512 pCtl->fChainedTransfer = false;
4513 while (!pCtl->fShutdown)
4514 {
4515 /* Keep this thread from doing anything as long as EMT is suspended. */
4516 while (pCtl->fRedoIdle)
4517 {
4518 rc = RTSemEventWait(pCtl->SuspendIOSem, RT_INDEFINITE_WAIT);
4519 /* Continue if we got a signal by RTThreadPoke().
4520 * We will get notified if there is a request to process.
4521 */
4522 if (RT_UNLIKELY(rc == VERR_INTERRUPTED))
4523 continue;
4524 if (RT_FAILURE(rc) || pCtl->fShutdown)
4525 break;
4526
4527 pCtl->fRedoIdle = false;
4528 }
4529
4530 /* Wait for work. */
4531 while (pReq == NULL)
4532 {
4533 LogBird(("ata: %x: going to sleep...\n", pCtl->IOPortBase1));
4534 rc = RTSemEventWait(pCtl->AsyncIOSem, RT_INDEFINITE_WAIT);
4535 LogBird(("ata: %x: waking up\n", pCtl->IOPortBase1));
4536 /* Continue if we got a signal by RTThreadPoke().
4537 * We will get notified if there is a request to process.
4538 */
4539 if (RT_UNLIKELY(rc == VERR_INTERRUPTED))
4540 continue;
4541 if (RT_FAILURE(rc) || RT_UNLIKELY(pCtl->fShutdown))
4542 break;
4543
4544 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4545 }
4546
4547 if (RT_FAILURE(rc) || pCtl->fShutdown)
4548 break;
4549
4550 if (pReq == NULL)
4551 continue;
4552
4553 ATAAIO ReqType = pReq->ReqType;
4554
4555 Log2(("%s: Ctl#%d: state=%d, req=%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->uAsyncIOState, ReqType));
4556 if (pCtl->uAsyncIOState != ReqType)
4557 {
4558 /* The new state is not the state that was expected by the normal
4559 * state changes. This is either a RESET/ABORT or there's something
4560 * really strange going on. */
4561 if ( (pCtl->uAsyncIOState == ATA_AIO_PIO || pCtl->uAsyncIOState == ATA_AIO_DMA)
4562 && (ReqType == ATA_AIO_PIO || ReqType == ATA_AIO_DMA))
4563 {
4564 /* Incorrect sequence of PIO/DMA states. Dump request queue. */
4565 ataAsyncIODumpRequests(pCtl);
4566 }
4567 AssertReleaseMsg(ReqType == ATA_AIO_RESET_ASSERTED || ReqType == ATA_AIO_RESET_CLEARED || ReqType == ATA_AIO_ABORT || pCtl->uAsyncIOState == ReqType, ("I/O state inconsistent: state=%d request=%d\n", pCtl->uAsyncIOState, ReqType));
4568 }
4569
4570 /* Do our work. */
4571 {
4572 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4573 LogBird(("ata: %x: entering critsect\n", pCtl->IOPortBase1));
4574 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4575 LogBird(("ata: %x: entered\n", pCtl->IOPortBase1));
4576 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4577 }
4578
4579 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4580 {
4581 u64TS = RTTimeNanoTS();
4582#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4583 STAM_PROFILE_ADV_START(&pCtl->StatAsyncTime, a);
4584#endif /* DEBUG || VBOX_WITH_STATISTICS */
4585 }
4586
4587 switch (ReqType)
4588 {
4589 case ATA_AIO_NEW:
4590
4591 pCtl->iAIOIf = pReq->u.t.iIf;
4592 s = &pCtl->aIfs[pCtl->iAIOIf];
4593 s->cbTotalTransfer = pReq->u.t.cbTotalTransfer;
4594 s->uTxDir = pReq->u.t.uTxDir;
4595 s->iBeginTransfer = pReq->u.t.iBeginTransfer;
4596 s->iSourceSink = pReq->u.t.iSourceSink;
4597 s->iIOBufferEnd = 0;
4598 s->u64CmdTS = u64TS;
4599
4600 if (s->fATAPI)
4601 {
4602 if (pCtl->fChainedTransfer)
4603 {
4604 /* Only count the actual transfers, not the PIO
4605 * transfer of the ATAPI command bytes. */
4606 if (s->fDMA)
4607 STAM_REL_COUNTER_INC(&s->StatATAPIDMA);
4608 else
4609 STAM_REL_COUNTER_INC(&s->StatATAPIPIO);
4610 }
4611 }
4612 else
4613 {
4614 if (s->fDMA)
4615 STAM_REL_COUNTER_INC(&s->StatATADMA);
4616 else
4617 STAM_REL_COUNTER_INC(&s->StatATAPIO);
4618 }
4619
4620 pCtl->fChainedTransfer = false;
4621
4622 if (s->iBeginTransfer != ATAFN_BT_NULL)
4623 {
4624 Log2(("%s: Ctl#%d: calling begin transfer function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4625 g_apfnBeginTransFuncs[s->iBeginTransfer](s);
4626 s->iBeginTransfer = ATAFN_BT_NULL;
4627 if (s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4628 s->iIOBufferEnd = s->cbElementaryTransfer;
4629 }
4630 else
4631 {
4632 s->cbElementaryTransfer = s->cbTotalTransfer;
4633 s->iIOBufferEnd = s->cbTotalTransfer;
4634 }
4635 s->iIOBufferCur = 0;
4636
4637 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4638 {
4639 if (s->iSourceSink != ATAFN_SS_NULL)
4640 {
4641 bool fRedo;
4642 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4643 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4644 pCtl->fRedo = fRedo;
4645 if (RT_UNLIKELY(fRedo))
4646 {
4647 /* Operation failed at the initial transfer, restart
4648 * everything from scratch by resending the current
4649 * request. Occurs very rarely, not worth optimizing. */
4650 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4651 ataAsyncIOPutRequest(pCtl, pReq);
4652 break;
4653 }
4654 }
4655 else
4656 ataCmdOK(s, 0);
4657 s->iIOBufferEnd = s->cbElementaryTransfer;
4658
4659 }
4660
4661 /* Do not go into the transfer phase if RESET is asserted.
4662 * The CritSect is released while waiting for the host OS
4663 * to finish the I/O, thus RESET is possible here. Most
4664 * important: do not change uAsyncIOState. */
4665 if (pCtl->fReset)
4666 break;
4667
4668 if (s->fDMA)
4669 {
4670 if (s->cbTotalTransfer)
4671 {
4672 ataSetStatus(s, ATA_STAT_DRQ);
4673
4674 pCtl->uAsyncIOState = ATA_AIO_DMA;
4675 /* If BMDMA is already started, do the transfer now. */
4676 if (pCtl->BmDma.u8Cmd & BM_CMD_START)
4677 {
4678 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4679 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4680 }
4681 }
4682 else
4683 {
4684 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4685 /* Finish DMA transfer. */
4686 ataDMATransferStop(s);
4687 ataSetIRQ(s);
4688 pCtl->uAsyncIOState = ATA_AIO_NEW;
4689 }
4690 }
4691 else
4692 {
4693 if (s->cbTotalTransfer)
4694 {
4695 ataPIOTransfer(pCtl);
4696 Assert(!pCtl->fRedo);
4697 if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4698 ataSetIRQ(s);
4699
4700 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
4701 {
4702 /* Write operations and not yet finished transfers
4703 * must be completed in the async I/O thread. */
4704 pCtl->uAsyncIOState = ATA_AIO_PIO;
4705 }
4706 else
4707 {
4708 /* Finished read operation can be handled inline
4709 * in the end of PIO transfer handling code. Linux
4710 * depends on this, as it waits only briefly for
4711 * devices to become ready after incoming data
4712 * transfer. Cannot find anything in the ATA spec
4713 * that backs this assumption, but as all kernels
4714 * are affected (though most of the time it does
4715 * not cause any harm) this must work. */
4716 pCtl->uAsyncIOState = ATA_AIO_NEW;
4717 }
4718 }
4719 else
4720 {
4721 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4722 /* Finish PIO transfer. */
4723 ataPIOTransfer(pCtl);
4724 Assert(!pCtl->fRedo);
4725 if (!s->fATAPITransfer)
4726 ataSetIRQ(s);
4727 pCtl->uAsyncIOState = ATA_AIO_NEW;
4728 }
4729 }
4730 break;
4731
4732 case ATA_AIO_DMA:
4733 {
4734 BMDMAState *bm = &pCtl->BmDma;
4735 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4736 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */
4737
4738 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
4739 AssertRelease(bm->u8Cmd & BM_CMD_WRITE);
4740 else
4741 AssertRelease(!(bm->u8Cmd & BM_CMD_WRITE));
4742
4743 if (RT_LIKELY(!pCtl->fRedo))
4744 {
4745 /* The specs say that the descriptor table must not cross a
4746 * 4K boundary. */
4747 pCtl->pFirstDMADesc = bm->pvAddr;
4748 pCtl->pLastDMADesc = RT_ALIGN_32(bm->pvAddr + 1, _4K) - sizeof(BMDMADesc);
4749 }
4750 ataDMATransfer(pCtl);
4751
4752 if (RT_UNLIKELY(pCtl->fRedo))
4753 {
4754 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl)));
4755 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4756 break;
4757 }
4758
4759 /* The infamous delay IRQ hack. */
4760 if ( iOriginalSourceSink == ATAFN_SS_WRITE_SECTORS
4761 && s->cbTotalTransfer == 0
4762 && pCtl->DelayIRQMillies)
4763 {
4764 /* Delay IRQ for writing. Required to get the Win2K
4765 * installation work reliably (otherwise it crashes,
4766 * usually during component install). So far no better
4767 * solution has been found. */
4768 Log(("%s: delay IRQ hack\n", __FUNCTION__));
4769 PDMCritSectLeave(&pCtl->lock);
4770 RTThreadSleep(pCtl->DelayIRQMillies);
4771 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4772 }
4773
4774 ataUnsetStatus(s, ATA_STAT_DRQ);
4775 Assert(!pCtl->fChainedTransfer);
4776 Assert(s->iSourceSink == ATAFN_SS_NULL);
4777 if (s->fATAPITransfer)
4778 {
4779 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
4780 Log2(("%s: Ctl#%d: interrupt reason %#04x\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegNSector));
4781 s->fATAPITransfer = false;
4782 }
4783 ataSetIRQ(s);
4784 pCtl->uAsyncIOState = ATA_AIO_NEW;
4785 break;
4786 }
4787
4788 case ATA_AIO_PIO:
4789 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4790
4791 if (s->iSourceSink != ATAFN_SS_NULL)
4792 {
4793 bool fRedo;
4794 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4795 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4796 pCtl->fRedo = fRedo;
4797 if (RT_UNLIKELY(fRedo))
4798 {
4799 LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl)));
4800 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
4801 ataSuspendRedo(pCtl);
4802 break;
4803 }
4804 s->iIOBufferCur = 0;
4805 s->iIOBufferEnd = s->cbElementaryTransfer;
4806 }
4807 else
4808 {
4809 /* Continue a previously started transfer. */
4810 ataUnsetStatus(s, ATA_STAT_BUSY);
4811 ataSetStatus(s, ATA_STAT_READY);
4812 }
4813
4814 /* It is possible that the drives on this controller get RESET
4815 * during the above call to the source/sink function. If that's
4816 * the case, don't restart the transfer and don't finish it the
4817 * usual way. RESET handling took care of all that already.
4818 * Most important: do not change uAsyncIOState. */
4819 if (pCtl->fReset)
4820 break;
4821
4822 if (s->cbTotalTransfer)
4823 {
4824 ataPIOTransfer(pCtl);
4825 ataSetIRQ(s);
4826
4827 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
4828 {
4829 /* Write operations and not yet finished transfers
4830 * must be completed in the async I/O thread. */
4831 pCtl->uAsyncIOState = ATA_AIO_PIO;
4832 }
4833 else
4834 {
4835 /* Finished read operation can be handled inline
4836 * in the end of PIO transfer handling code. Linux
4837 * depends on this, as it waits only briefly for
4838 * devices to become ready after incoming data
4839 * transfer. Cannot find anything in the ATA spec
4840 * that backs this assumption, but as all kernels
4841 * are affected (though most of the time it does
4842 * not cause any harm) this must work. */
4843 pCtl->uAsyncIOState = ATA_AIO_NEW;
4844 }
4845 }
4846 else
4847 {
4848 /* Finish PIO transfer. */
4849 ataPIOTransfer(pCtl);
4850 if ( !pCtl->fChainedTransfer
4851 && !s->fATAPITransfer
4852 && s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4853 {
4854 ataSetIRQ(s);
4855 }
4856 pCtl->uAsyncIOState = ATA_AIO_NEW;
4857 }
4858 break;
4859
4860 case ATA_AIO_RESET_ASSERTED:
4861 pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED;
4862 ataPIOTransferStop(&pCtl->aIfs[0]);
4863 ataPIOTransferStop(&pCtl->aIfs[1]);
4864 /* Do not change the DMA registers, they are not affected by the
4865 * ATA controller reset logic. It should be sufficient to issue a
4866 * new command, which is now possible as the state is cleared. */
4867 break;
4868
4869 case ATA_AIO_RESET_CLEARED:
4870 pCtl->uAsyncIOState = ATA_AIO_NEW;
4871 pCtl->fReset = false;
4872 LogRel(("PIIX3 ATA: Ctl#%d: finished processing RESET\n",
4873 ATACONTROLLER_IDX(pCtl)));
4874 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4875 {
4876 if (pCtl->aIfs[i].fATAPI)
4877 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
4878 else
4879 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
4880 ataSetSignature(&pCtl->aIfs[i]);
4881 }
4882 break;
4883
4884 case ATA_AIO_ABORT:
4885 /* Abort the current command only if it operates on the same interface. */
4886 if (pCtl->iAIOIf == pReq->u.a.iIf)
4887 {
4888 s = &pCtl->aIfs[pCtl->iAIOIf];
4889
4890 pCtl->uAsyncIOState = ATA_AIO_NEW;
4891 /* Do not change the DMA registers, they are not affected by the
4892 * ATA controller reset logic. It should be sufficient to issue a
4893 * new command, which is now possible as the state is cleared. */
4894 if (pReq->u.a.fResetDrive)
4895 {
4896 ataResetDevice(s);
4897 ataExecuteDeviceDiagnosticSS(s);
4898 }
4899 else
4900 {
4901 ataPIOTransferStop(s);
4902 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
4903 ataSetStatus(s, ATA_STAT_READY);
4904 ataSetIRQ(s);
4905 }
4906 }
4907 break;
4908
4909 default:
4910 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
4911 }
4912
4913 ataAsyncIORemoveCurrentRequest(pCtl, ReqType);
4914 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4915
4916 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4917 {
4918#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4919 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
4920#endif /* DEBUG || VBOX_WITH_STATISTICS */
4921
4922 u64TS = RTTimeNanoTS() - u64TS;
4923 uWait = u64TS / 1000;
4924 Log(("%s: Ctl#%d: LUN#%d finished I/O transaction in %d microseconds\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->aIfs[pCtl->iAIOIf].iLUN, (uint32_t)(uWait)));
4925 /* Mark command as finished. */
4926 pCtl->aIfs[pCtl->iAIOIf].u64CmdTS = 0;
4927
4928 /*
4929 * Release logging of command execution times depends on the
4930 * command type. ATAPI commands often take longer (due to CD/DVD
4931 * spin up time etc.) so the threshold is different.
4932 */
4933 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
4934 {
4935 if (uWait > 8 * 1000 * 1000)
4936 {
4937 /*
4938 * Command took longer than 8 seconds. This is close
4939 * enough or over the guest's command timeout, so place
4940 * an entry in the release log to allow tracking such
4941 * timing errors (which are often caused by the host).
4942 */
4943 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
4944 }
4945 }
4946 else
4947 {
4948 if (uWait > 20 * 1000 * 1000)
4949 {
4950 /*
4951 * Command took longer than 20 seconds. This is close
4952 * enough or over the guest's command timeout, so place
4953 * an entry in the release log to allow tracking such
4954 * timing errors (which are often caused by the host).
4955 */
4956 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
4957 }
4958 }
4959
4960#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4961 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
4962 pCtl->StatAsyncMinWait = uWait;
4963 if (uWait > pCtl->StatAsyncMaxWait)
4964 pCtl->StatAsyncMaxWait = uWait;
4965
4966 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
4967 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
4968#endif /* DEBUG || VBOX_WITH_STATISTICS */
4969 }
4970
4971 LogBird(("ata: %x: leaving critsect\n", pCtl->IOPortBase1));
4972 PDMCritSectLeave(&pCtl->lock);
4973 }
4974
4975 /* Cleanup the state. */
4976 if (pCtl->AsyncIOSem)
4977 {
4978 RTSemEventDestroy(pCtl->AsyncIOSem);
4979 pCtl->AsyncIOSem = NIL_RTSEMEVENT;
4980 }
4981 if (pCtl->SuspendIOSem)
4982 {
4983 RTSemEventDestroy(pCtl->SuspendIOSem);
4984 pCtl->SuspendIOSem = NIL_RTSEMEVENT;
4985 }
4986 /* Do not destroy request mutex yet, still needed for proper shutdown. */
4987 pCtl->fShutdown = false;
4988 /* This must be last, as it also signals thread exit to EMT. */
4989 pCtl->AsyncIOThread = NIL_RTTHREAD;
4990
4991 Log2(("%s: Ctl#%d: return %Rrc\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), rc));
4992 return rc;
4993}
4994
4995#endif /* IN_RING3 */
4996
4997static uint32_t ataBMDMACmdReadB(PATACONTROLLER pCtl, uint32_t addr)
4998{
4999 uint32_t val = pCtl->BmDma.u8Cmd;
5000 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5001 return val;
5002}
5003
5004
5005static void ataBMDMACmdWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5006{
5007 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5008 if (!(val & BM_CMD_START))
5009 {
5010 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
5011 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5012 }
5013 else
5014 {
5015#ifdef IN_RING3
5016 /* Check whether the guest OS wants to change DMA direction in
5017 * mid-flight. Not allowed, according to the PIIX3 specs. */
5018 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
5019 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
5020 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5021
5022 /* Do not continue DMA transfers while the RESET line is asserted. */
5023 if (pCtl->fReset)
5024 {
5025 Log2(("%s: Ctl#%d: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5026 return;
5027 }
5028
5029 /* Do not start DMA transfers if there's a PIO transfer going on. */
5030 if (!pCtl->aIfs[pCtl->iSelectedIf].fDMA)
5031 return;
5032
5033 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
5034 {
5035 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5036 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
5037 }
5038#else /* !IN_RING3 */
5039 AssertMsgFailed(("DMA START handling is too complicated for GC\n"));
5040#endif /* IN_RING3 */
5041 }
5042}
5043
5044static uint32_t ataBMDMAStatusReadB(PATACONTROLLER pCtl, uint32_t addr)
5045{
5046 uint32_t val = pCtl->BmDma.u8Status;
5047 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5048 return val;
5049}
5050
5051static void ataBMDMAStatusWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5052{
5053 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5054 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
5055 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
5056 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
5057}
5058
5059static uint32_t ataBMDMAAddrReadL(PATACONTROLLER pCtl, uint32_t addr)
5060{
5061 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
5062 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5063 return val;
5064}
5065
5066static void ataBMDMAAddrWriteL(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5067{
5068 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5069 pCtl->BmDma.pvAddr = val & ~3;
5070}
5071
5072static void ataBMDMAAddrWriteLowWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5073{
5074 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5075 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
5076
5077}
5078
5079static void ataBMDMAAddrWriteHighWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5080{
5081 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5082 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
5083}
5084
5085#define VAL(port, size) ( ((port) & 7) | ((size) << 3) )
5086
5087/**
5088 * Port I/O Handler for bus master DMA IN operations.
5089 * @see FNIOMIOPORTIN for details.
5090 */
5091PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5092{
5093 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5094 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5095 PATACONTROLLER pCtl = &pThis->aCts[i];
5096 int rc;
5097
5098 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5099 if (rc != VINF_SUCCESS)
5100 return rc;
5101 switch (VAL(Port, cb))
5102 {
5103 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
5104 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
5105 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
5106 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
5107 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
5108 case VAL(0, 4):
5109 /* The SCO OpenServer tries to read 4 bytes starting from offset 0. */
5110 *pu32 = ataBMDMACmdReadB(pCtl, Port) | (ataBMDMAStatusReadB(pCtl, Port) << 16);
5111 break;
5112 default:
5113 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb));
5114 PDMCritSectLeave(&pCtl->lock);
5115 return VERR_IOM_IOPORT_UNUSED;
5116 }
5117 PDMCritSectLeave(&pCtl->lock);
5118 return rc;
5119}
5120
5121/**
5122 * Port I/O Handler for bus master DMA OUT operations.
5123 * @see FNIOMIOPORTOUT for details.
5124 */
5125PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5126{
5127 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5128 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5129 PATACONTROLLER pCtl = &pThis->aCts[i];
5130 int rc;
5131
5132 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5133 if (rc != VINF_SUCCESS)
5134 return rc;
5135 switch (VAL(Port, cb))
5136 {
5137 case VAL(0, 1):
5138#ifndef IN_RING3
5139 if (u32 & BM_CMD_START)
5140 {
5141 rc = VINF_IOM_HC_IOPORT_WRITE;
5142 break;
5143 }
5144#endif /* !IN_RING3 */
5145 ataBMDMACmdWriteB(pCtl, Port, u32);
5146 break;
5147 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
5148 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
5149 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
5150 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
5151 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break;
5152 }
5153 PDMCritSectLeave(&pCtl->lock);
5154 return rc;
5155}
5156
5157#undef VAL
5158
5159#ifdef IN_RING3
5160
5161/**
5162 * Callback function for mapping an PCI I/O region.
5163 *
5164 * @return VBox status code.
5165 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
5166 * @param iRegion The region number.
5167 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
5168 * I/O port, else it's a physical address.
5169 * This address is *NOT* relative to pci_mem_base like earlier!
5170 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
5171 */
5172static DECLCALLBACK(int) ataBMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
5173{
5174 PCIATAState *pThis = PCIDEV_2_PCIATASTATE(pPciDev);
5175 int rc = VINF_SUCCESS;
5176 Assert(enmType == PCI_ADDRESS_SPACE_IO);
5177 Assert(iRegion == 4);
5178 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
5179
5180 /* Register the port range. */
5181 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5182 {
5183 int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
5184 (RTHCPTR)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL, NULL, "ATA Bus Master DMA");
5185 AssertRC(rc2);
5186 if (rc2 < rc)
5187 rc = rc2;
5188
5189 if (pThis->fGCEnabled)
5190 {
5191 rc2 = PDMDevHlpIOPortRegisterGC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
5192 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
5193 AssertRC(rc2);
5194 if (rc2 < rc)
5195 rc = rc2;
5196 }
5197 if (pThis->fR0Enabled)
5198 {
5199 rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
5200 (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
5201 AssertRC(rc2);
5202 if (rc2 < rc)
5203 rc = rc2;
5204 }
5205 }
5206 return rc;
5207}
5208
5209
5210/**
5211 * Reset notification.
5212 *
5213 * @returns VBox status.
5214 * @param pDevIns The device instance data.
5215 */
5216static DECLCALLBACK(void) ataReset(PPDMDEVINS pDevIns)
5217{
5218 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5219
5220 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5221 {
5222 pThis->aCts[i].iSelectedIf = 0;
5223 pThis->aCts[i].iAIOIf = 0;
5224 pThis->aCts[i].BmDma.u8Cmd = 0;
5225 /* Report that both drives present on the bus are in DMA mode. This
5226 * pretends that there is a BIOS that has set it up. Normal reset
5227 * default is 0x00. */
5228 pThis->aCts[i].BmDma.u8Status = (pThis->aCts[i].aIfs[0].pDrvBase != NULL ? BM_STATUS_D0DMA : 0)
5229 | (pThis->aCts[i].aIfs[1].pDrvBase != NULL ? BM_STATUS_D1DMA : 0);
5230 pThis->aCts[i].BmDma.pvAddr = 0;
5231
5232 pThis->aCts[i].fReset = true;
5233 pThis->aCts[i].fRedo = false;
5234 pThis->aCts[i].fRedoIdle = false;
5235 ataAsyncIOClearRequests(&pThis->aCts[i]);
5236 Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i));
5237 ataAsyncIOPutRequest(&pThis->aCts[i], &ataResetARequest);
5238 ataAsyncIOPutRequest(&pThis->aCts[i], &ataResetCRequest);
5239 if (!ataWaitForAsyncIOIsIdle(&pThis->aCts[i], 30000))
5240 {
5241 VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),
5242 false, "DevATA_ASYNCBUSY",
5243 N_("The IDE async I/O thread remained busy after a reset, usually a host filesystem performance problem\n"));
5244 AssertMsgFailed(("Async I/O thread busy after reset\n"));
5245 }
5246
5247 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
5248 ataResetDevice(&pThis->aCts[i].aIfs[j]);
5249 }
5250}
5251
5252
5253/* -=-=-=-=-=- PCIATAState::IBase -=-=-=-=-=- */
5254
5255/**
5256 * Queries an interface to the driver.
5257 *
5258 * @returns Pointer to interface.
5259 * @returns NULL if the interface was not supported by the device.
5260 * @param pInterface Pointer to ATADevState::IBase.
5261 * @param enmInterface The requested interface identification.
5262 */
5263static DECLCALLBACK(void *) ataStatus_QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
5264{
5265 PCIATAState *pThis = PDMIBASE_2_PCIATASTATE(pInterface);
5266 switch (enmInterface)
5267 {
5268 case PDMINTERFACE_BASE:
5269 return &pThis->IBase;
5270 case PDMINTERFACE_LED_PORTS:
5271 return &pThis->ILeds;
5272 default:
5273 return NULL;
5274 }
5275}
5276
5277
5278/* -=-=-=-=-=- PCIATAState::ILeds -=-=-=-=-=- */
5279
5280/**
5281 * Gets the pointer to the status LED of a unit.
5282 *
5283 * @returns VBox status code.
5284 * @param pInterface Pointer to the interface structure containing the called function pointer.
5285 * @param iLUN The unit which status LED we desire.
5286 * @param ppLed Where to store the LED pointer.
5287 */
5288static DECLCALLBACK(int) ataStatus_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
5289{
5290 PCIATAState *pThis = PDMILEDPORTS_2_PCIATASTATE(pInterface);
5291 if (iLUN < 4)
5292 {
5293 switch (iLUN)
5294 {
5295 case 0: *ppLed = &pThis->aCts[0].aIfs[0].Led; break;
5296 case 1: *ppLed = &pThis->aCts[0].aIfs[1].Led; break;
5297 case 2: *ppLed = &pThis->aCts[1].aIfs[0].Led; break;
5298 case 3: *ppLed = &pThis->aCts[1].aIfs[1].Led; break;
5299 }
5300 Assert((*ppLed)->u32Magic == PDMLED_MAGIC);
5301 return VINF_SUCCESS;
5302 }
5303 return VERR_PDM_LUN_NOT_FOUND;
5304}
5305
5306
5307/* -=-=-=-=-=- ATADevState::IBase -=-=-=-=-=- */
5308
5309/**
5310 * Queries an interface to the driver.
5311 *
5312 * @returns Pointer to interface.
5313 * @returns NULL if the interface was not supported by the device.
5314 * @param pInterface Pointer to ATADevState::IBase.
5315 * @param enmInterface The requested interface identification.
5316 */
5317static DECLCALLBACK(void *) ataQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
5318{
5319 ATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
5320 switch (enmInterface)
5321 {
5322 case PDMINTERFACE_BASE:
5323 return &pIf->IBase;
5324 case PDMINTERFACE_BLOCK_PORT:
5325 return &pIf->IPort;
5326 case PDMINTERFACE_MOUNT_NOTIFY:
5327 return &pIf->IMountNotify;
5328 default:
5329 return NULL;
5330 }
5331}
5332
5333#endif /* IN_RING3 */
5334
5335
5336/* -=-=-=-=-=- Wrappers -=-=-=-=-=- */
5337
5338/**
5339 * Port I/O Handler for primary port range OUT operations.
5340 * @see FNIOMIOPORTOUT for details.
5341 */
5342PDMBOTHCBDECL(int) ataIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5343{
5344 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5345 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5346 PATACONTROLLER pCtl = &pThis->aCts[i];
5347 int rc = VINF_SUCCESS;
5348
5349 Assert(i < 2);
5350
5351 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5352 if (rc != VINF_SUCCESS)
5353 return rc;
5354 if (cb == 1)
5355 rc = ataIOPortWriteU8(pCtl, Port, u32);
5356 else if (Port == pCtl->IOPortBase1)
5357 {
5358 Assert(cb == 2 || cb == 4);
5359 rc = ataDataWrite(pCtl, Port, cb, (const uint8_t *)&u32);
5360 }
5361 else
5362 AssertMsgFailed(("ataIOPortWrite1: unsupported write to port %x val=%x size=%d\n", Port, u32, cb));
5363 LogBird(("ata: leaving critsect\n"));
5364 PDMCritSectLeave(&pCtl->lock);
5365 LogBird(("ata: left critsect\n"));
5366 return rc;
5367}
5368
5369
5370/**
5371 * Port I/O Handler for primary port range IN operations.
5372 * @see FNIOMIOPORTIN for details.
5373 */
5374PDMBOTHCBDECL(int) ataIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5375{
5376 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5377 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5378 PATACONTROLLER pCtl = &pThis->aCts[i];
5379 int rc = VINF_SUCCESS;
5380
5381 Assert(i < 2);
5382
5383 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5384 if (rc != VINF_SUCCESS)
5385 return rc;
5386 if (cb == 1)
5387 {
5388 rc = ataIOPortReadU8(pCtl, Port, pu32);
5389 }
5390 else if (Port == pCtl->IOPortBase1)
5391 {
5392 Assert(cb == 2 || cb == 4);
5393 rc = ataDataRead(pCtl, Port, cb, (uint8_t *)pu32);
5394 if (cb == 2)
5395 *pu32 &= 0xffff;
5396 }
5397 else
5398 {
5399 AssertMsgFailed(("ataIOPortRead1: unsupported read from port %x size=%d\n", Port, cb));
5400 rc = VERR_IOM_IOPORT_UNUSED;
5401 }
5402 PDMCritSectLeave(&pCtl->lock);
5403 return rc;
5404}
5405
5406#ifndef IN_RING0
5407/**
5408 * Port I/O Handler for primary port range IN string operations.
5409 * @see FNIOMIOPORTINSTRING for details.
5410 */
5411PDMBOTHCBDECL(int) ataIOPortReadStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb)
5412{
5413 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5414 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5415 PATACONTROLLER pCtl = &pThis->aCts[i];
5416 int rc = VINF_SUCCESS;
5417
5418 Assert(i < 2);
5419
5420 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5421 if (rc != VINF_SUCCESS)
5422 return rc;
5423 if (Port == pCtl->IOPortBase1)
5424 {
5425 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
5426 RTGCPTR GCDst = *pGCPtrDst;
5427 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
5428 Assert(cb == 2 || cb == 4);
5429
5430 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
5431#ifndef IN_RING3
5432 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
5433 cTransAvailable--;
5434#endif /* !IN_RING3 */
5435 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
5436 * They are not performance-critical and generally shouldn't occur at all. */
5437 if (cTransAvailable > cTransfer)
5438 cTransAvailable = cTransfer;
5439 cbTransfer = cTransAvailable * cb;
5440
5441#ifdef IN_RC
5442 for (uint32_t i = 0; i < cbTransfer; i += cb)
5443 MMGCRamWriteNoTrapHandler((char *)GCDst + i, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, cb);
5444#else /* !IN_RC */
5445 rc = PGMPhysSimpleDirtyWriteGCPtr(PDMDevHlpGetVM(pDevIns), GCDst, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
5446 Assert(rc == VINF_SUCCESS);
5447#endif /* IN_RC */
5448
5449 if (cbTransfer)
5450 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
5451 s->iIOBufferPIODataStart += cbTransfer;
5452 *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
5453 *pcTransfer = cTransfer - cTransAvailable;
5454#ifdef IN_RING3
5455 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
5456 ataPIOTransferFinish(pCtl, s);
5457#endif /* IN_RING3 */
5458 }
5459 PDMCritSectLeave(&pCtl->lock);
5460 return rc;
5461}
5462
5463
5464/**
5465 * Port I/O Handler for primary port range OUT string operations.
5466 * @see FNIOMIOPORTOUTSTRING for details.
5467 */
5468PDMBOTHCBDECL(int) ataIOPortWriteStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)
5469{
5470 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5471 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5472 PATACONTROLLER pCtl = &pThis->aCts[i];
5473 int rc;
5474
5475 Assert(i < 2);
5476
5477 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5478 if (rc != VINF_SUCCESS)
5479 return rc;
5480 if (Port == pCtl->IOPortBase1)
5481 {
5482 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
5483 RTGCPTR GCSrc = *pGCPtrSrc;
5484 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
5485 Assert(cb == 2 || cb == 4);
5486
5487 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
5488#ifndef IN_RING3
5489 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
5490 cTransAvailable--;
5491#endif /* !IN_RING3 */
5492 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
5493 * They are not performance-critical and generally shouldn't occur at all. */
5494 if (cTransAvailable > cTransfer)
5495 cTransAvailable = cTransfer;
5496 cbTransfer = cTransAvailable * cb;
5497
5498#ifdef IN_RC
5499 for (uint32_t i = 0; i < cbTransfer; i += cb)
5500 MMGCRamReadNoTrapHandler(s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, (char *)GCSrc + i, cb);
5501#else /* !IN_RC */
5502 rc = PGMPhysSimpleReadGCPtr(PDMDevHlpGetVM(pDevIns), s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
5503 Assert(rc == VINF_SUCCESS);
5504#endif /* IN_RC */
5505
5506 if (cbTransfer)
5507 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
5508 s->iIOBufferPIODataStart += cbTransfer;
5509 *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
5510 *pcTransfer = cTransfer - cTransAvailable;
5511#ifdef IN_RING3
5512 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
5513 ataPIOTransferFinish(pCtl, s);
5514#endif /* IN_RING3 */
5515 }
5516 PDMCritSectLeave(&pCtl->lock);
5517 return rc;
5518}
5519#endif /* !IN_RING0 */
5520
5521/**
5522 * Port I/O Handler for secondary port range OUT operations.
5523 * @see FNIOMIOPORTOUT for details.
5524 */
5525PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5526{
5527 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5528 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5529 PATACONTROLLER pCtl = &pThis->aCts[i];
5530 int rc;
5531
5532 Assert(i < 2);
5533
5534 if (cb != 1)
5535 return VINF_SUCCESS;
5536 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5537 if (rc != VINF_SUCCESS)
5538 return rc;
5539 rc = ataControlWrite(pCtl, Port, u32);
5540 PDMCritSectLeave(&pCtl->lock);
5541 return rc;
5542}
5543
5544
5545/**
5546 * Port I/O Handler for secondary port range IN operations.
5547 * @see FNIOMIOPORTIN for details.
5548 */
5549PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5550{
5551 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5552 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5553 PATACONTROLLER pCtl = &pThis->aCts[i];
5554 int rc;
5555
5556 Assert(i < 2);
5557
5558 if (cb != 1)
5559 return VERR_IOM_IOPORT_UNUSED;
5560
5561 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5562 if (rc != VINF_SUCCESS)
5563 return rc;
5564 *pu32 = ataStatusRead(pCtl, Port);
5565 PDMCritSectLeave(&pCtl->lock);
5566 return VINF_SUCCESS;
5567}
5568
5569#ifdef IN_RING3
5570
5571/**
5572 * Waits for all async I/O threads to complete whatever they
5573 * are doing at the moment.
5574 *
5575 * @returns true on success.
5576 * @returns false when one or more threads is still processing.
5577 * @param pThis Pointer to the instance data.
5578 * @param cMillies How long to wait (total).
5579 */
5580static bool ataWaitForAllAsyncIOIsIdle(PPDMDEVINS pDevIns, unsigned cMillies)
5581{
5582 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5583 bool fVMLocked;
5584 uint64_t u64Start;
5585 PATACONTROLLER pCtl;
5586 bool fAllIdle = false;
5587
5588 /* The only way to deal cleanly with the VM lock is to check whether
5589 * it is owned now (it always is owned by EMT, which is the current
5590 * thread). Since this function is called several times during VM
5591 * shutdown, and the VM lock is only held for the first call (which
5592 * can be either from ataPowerOff or ataSuspend), there is no other
5593 * reasonable solution. */
5594 fVMLocked = VMMR3LockIsOwner(PDMDevHlpGetVM(pDevIns));
5595
5596 if (fVMLocked)
5597 pDevIns->pDevHlpR3->pfnUnlockVM(pDevIns);
5598 /*
5599 * Wait for any pending async operation to finish
5600 */
5601 u64Start = RTTimeMilliTS();
5602 for (;;)
5603 {
5604 /* Check all async I/O threads. */
5605 fAllIdle = true;
5606 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5607 {
5608 pCtl = &pThis->aCts[i];
5609
5610 /*
5611 * Only check if the thread is idling if the request mutex is set up.
5612 * It is possible that the creation of the first controller failed and that
5613 * the request mutex is not initialized on the second one yet
5614 * But it would be called without the following check.
5615 */
5616 if (pCtl->AsyncIORequestMutex != NIL_RTSEMEVENT)
5617 {
5618 fAllIdle &= ataAsyncIOIsIdle(pCtl, false);
5619 if (!fAllIdle)
5620 break;
5621 }
5622 }
5623 if ( fAllIdle
5624 || RTTimeMilliTS() - u64Start >= cMillies)
5625 break;
5626
5627 /* Sleep for a bit. */
5628 RTThreadSleep(100);
5629 }
5630
5631 if (fVMLocked)
5632 pDevIns->pDevHlpR3->pfnLockVM(pDevIns);
5633
5634 if (!fAllIdle)
5635 LogRel(("PIIX3 ATA: Ctl#%d is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",
5636 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
5637 pCtl->aIfs[0].uATARegCommand, pCtl->aIfs[1].uATARegCommand));
5638
5639 return fAllIdle;
5640}
5641
5642
5643DECLINLINE(void) ataRelocBuffer(PPDMDEVINS pDevIns, ATADevState *s)
5644{
5645 if (s->pbIOBufferR3)
5646 s->pbIOBufferRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), s->pbIOBufferR3);
5647}
5648
5649
5650/**
5651 * @copydoc FNPDMDEVRELOCATE
5652 */
5653static DECLCALLBACK(void) ataRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
5654{
5655 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5656
5657 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5658 {
5659 pThis->aCts[i].pDevInsRC += offDelta;
5660 pThis->aCts[i].aIfs[0].pDevInsRC += offDelta;
5661 pThis->aCts[i].aIfs[0].pControllerRC += offDelta;
5662 ataRelocBuffer(pDevIns, &pThis->aCts[i].aIfs[0]);
5663 pThis->aCts[i].aIfs[1].pDevInsRC += offDelta;
5664 pThis->aCts[i].aIfs[1].pControllerRC += offDelta;
5665 ataRelocBuffer(pDevIns, &pThis->aCts[i].aIfs[1]);
5666 }
5667}
5668
5669
5670/**
5671 * Destroy a driver instance.
5672 *
5673 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
5674 * resources can be freed correctly.
5675 *
5676 * @param pDevIns The device instance data.
5677 */
5678static DECLCALLBACK(int) ataDestruct(PPDMDEVINS pDevIns)
5679{
5680 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5681 int rc;
5682
5683 Log(("%s:\n", __FUNCTION__));
5684
5685 /*
5686 * Terminate all async helper threads
5687 */
5688 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5689 {
5690 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5691 {
5692 ASMAtomicXchgU32(&pThis->aCts[i].fShutdown, true);
5693 rc = RTSemEventSignal(pThis->aCts[i].AsyncIOSem);
5694 AssertRC(rc);
5695 }
5696 }
5697
5698 /*
5699 * Wait for them to complete whatever they are doing and then
5700 * for them to terminate.
5701 */
5702 if (ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5703 {
5704 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5705 {
5706 rc = RTThreadWait(pThis->aCts[i].AsyncIOThread, 30000 /* 30 s*/, NULL);
5707 AssertMsgRC(rc || rc == VERR_INVALID_HANDLE, ("rc=%Rrc i=%d\n", rc, i));
5708 }
5709 }
5710 else
5711 AssertMsgFailed(("Async I/O is still busy!\n"));
5712
5713 /*
5714 * Now the request mutexes are no longer needed. Free resources.
5715 */
5716 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5717 {
5718 if (pThis->aCts[i].AsyncIORequestMutex != NIL_RTSEMEVENT)
5719 {
5720 RTSemMutexDestroy(pThis->aCts[i].AsyncIORequestMutex);
5721 pThis->aCts[i].AsyncIORequestMutex = NIL_RTSEMEVENT;
5722 }
5723 }
5724 return VINF_SUCCESS;
5725}
5726
5727
5728/**
5729 * Detach notification.
5730 *
5731 * The DVD drive has been unplugged.
5732 *
5733 * @param pDevIns The device instance.
5734 * @param iLUN The logical unit which is being detached.
5735 */
5736static DECLCALLBACK(void) ataDetach(PPDMDEVINS pDevIns, unsigned iLUN)
5737{
5738 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5739 PATACONTROLLER pCtl;
5740 ATADevState *pIf;
5741 unsigned iController;
5742 unsigned iInterface;
5743
5744 /*
5745 * Locate the controller and stuff.
5746 */
5747 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5748 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5749 pCtl = &pThis->aCts[iController];
5750
5751 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5752 pIf = &pCtl->aIfs[iInterface];
5753
5754 /*
5755 * Zero some important members.
5756 */
5757 pIf->pDrvBase = NULL;
5758 pIf->pDrvBlock = NULL;
5759 pIf->pDrvBlockBios = NULL;
5760 pIf->pDrvMount = NULL;
5761
5762 /*
5763 * In case there was a medium inserted.
5764 */
5765 ataMediumRemoved(pIf);
5766}
5767
5768
5769/**
5770 * Configure a LUN.
5771 *
5772 * @returns VBox status code.
5773 * @param pDevIns The device instance.
5774 * @param pIf The ATA unit state.
5775 */
5776static int ataConfigLun(PPDMDEVINS pDevIns, ATADevState *pIf)
5777{
5778 int rc = VINF_SUCCESS;
5779 PDMBLOCKTYPE enmType;
5780
5781 /*
5782 * Query Block, Bios and Mount interfaces.
5783 */
5784 pIf->pDrvBlock = (PDMIBLOCK *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK);
5785 if (!pIf->pDrvBlock)
5786 {
5787 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
5788 return VERR_PDM_MISSING_INTERFACE;
5789 }
5790
5791 /** @todo implement the BIOS invisible code path. */
5792 pIf->pDrvBlockBios = (PDMIBLOCKBIOS *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK_BIOS);
5793 if (!pIf->pDrvBlockBios)
5794 {
5795 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pIf->iLUN));
5796 return VERR_PDM_MISSING_INTERFACE;
5797 }
5798 pIf->pDrvMount = (PDMIMOUNT *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_MOUNT);
5799
5800 /*
5801 * Validate type.
5802 */
5803 enmType = pIf->pDrvBlock->pfnGetType(pIf->pDrvBlock);
5804 if ( enmType != PDMBLOCKTYPE_CDROM
5805 && enmType != PDMBLOCKTYPE_DVD
5806 && enmType != PDMBLOCKTYPE_HARD_DISK)
5807 {
5808 AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
5809 return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
5810 }
5811 if ( ( enmType == PDMBLOCKTYPE_DVD
5812 || enmType == PDMBLOCKTYPE_CDROM)
5813 && !pIf->pDrvMount)
5814 {
5815 AssertMsgFailed(("Internal error: cdrom without a mountable interface, WTF???!\n"));
5816 return VERR_INTERNAL_ERROR;
5817 }
5818 pIf->fATAPI = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM;
5819 pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvBlock->pfnSendCmd != NULL) : false;
5820
5821 /*
5822 * Allocate I/O buffer.
5823 */
5824 PVM pVM = PDMDevHlpGetVM(pDevIns);
5825 if (pIf->cbIOBuffer)
5826 {
5827 /* Buffer is (probably) already allocated. Validate the fields,
5828 * because memory corruption can also overwrite pIf->cbIOBuffer. */
5829 if (pIf->fATAPI)
5830 AssertRelease(pIf->cbIOBuffer == _128K);
5831 else
5832 AssertRelease(pIf->cbIOBuffer == ATA_MAX_MULT_SECTORS * 512);
5833 Assert(pIf->pbIOBufferR3);
5834 Assert(pIf->pbIOBufferR0 == MMHyperR3ToR0(pVM, pIf->pbIOBufferR3));
5835 Assert(pIf->pbIOBufferRC == MMHyperR3ToRC(pVM, pIf->pbIOBufferR3));
5836 }
5837 else
5838 {
5839 if (pIf->fATAPI)
5840 pIf->cbIOBuffer = _128K;
5841 else
5842 pIf->cbIOBuffer = ATA_MAX_MULT_SECTORS * 512;
5843 Assert(!pIf->pbIOBufferR3);
5844 rc = MMR3HyperAllocOnceNoRel(pVM, pIf->cbIOBuffer, 0, MM_TAG_PDM_DEVICE_USER, (void **)&pIf->pbIOBufferR3);
5845 if (RT_FAILURE(rc))
5846 return VERR_NO_MEMORY;
5847 pIf->pbIOBufferR0 = MMHyperR3ToR0(pVM, pIf->pbIOBufferR3);
5848 pIf->pbIOBufferRC = MMHyperR3ToRC(pVM, pIf->pbIOBufferR3);
5849 }
5850
5851 /*
5852 * Init geometry (only for non-CD/DVD media).
5853 */
5854 if (pIf->fATAPI)
5855 {
5856 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
5857 pIf->PCHSGeometry.cCylinders = 0; /* dummy */
5858 pIf->PCHSGeometry.cHeads = 0; /* dummy */
5859 pIf->PCHSGeometry.cSectors = 0; /* dummy */
5860 LogRel(("PIIX3 ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));
5861 }
5862 else
5863 {
5864 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
5865 rc = pIf->pDrvBlockBios->pfnGetPCHSGeometry(pIf->pDrvBlockBios,
5866 &pIf->PCHSGeometry);
5867 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
5868 {
5869 pIf->PCHSGeometry.cCylinders = 0;
5870 pIf->PCHSGeometry.cHeads = 16; /*??*/
5871 pIf->PCHSGeometry.cSectors = 63; /*??*/
5872 }
5873 else if (rc == VERR_PDM_GEOMETRY_NOT_SET)
5874 {
5875 pIf->PCHSGeometry.cCylinders = 0; /* autodetect marker */
5876 rc = VINF_SUCCESS;
5877 }
5878 AssertRC(rc);
5879
5880 if ( pIf->PCHSGeometry.cCylinders == 0
5881 || pIf->PCHSGeometry.cHeads == 0
5882 || pIf->PCHSGeometry.cSectors == 0
5883 )
5884 {
5885 uint64_t cCylinders = pIf->cTotalSectors / (16 * 63);
5886 pIf->PCHSGeometry.cCylinders = RT_MAX(RT_MIN(cCylinders, 16383), 1);
5887 pIf->PCHSGeometry.cHeads = 16;
5888 pIf->PCHSGeometry.cSectors = 63;
5889 /* Set the disk geometry information. Ignore errors. */
5890 pIf->pDrvBlockBios->pfnSetPCHSGeometry(pIf->pDrvBlockBios,
5891 &pIf->PCHSGeometry);
5892 rc = VINF_SUCCESS;
5893 }
5894 LogRel(("PIIX3 ATA: LUN#%d: disk, PCHS=%u/%u/%u, total number of sectors %Ld\n", pIf->iLUN, pIf->PCHSGeometry.cCylinders, pIf->PCHSGeometry.cHeads, pIf->PCHSGeometry.cSectors, pIf->cTotalSectors));
5895 }
5896 return rc;
5897}
5898
5899
5900/**
5901 * Attach command.
5902 *
5903 * This is called when we change block driver for the DVD drive.
5904 *
5905 * @returns VBox status code.
5906 * @param pDevIns The device instance.
5907 * @param iLUN The logical unit which is being detached.
5908 */
5909static DECLCALLBACK(int) ataAttach(PPDMDEVINS pDevIns, unsigned iLUN)
5910{
5911 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5912 PATACONTROLLER pCtl;
5913 ATADevState *pIf;
5914 int rc;
5915 unsigned iController;
5916 unsigned iInterface;
5917
5918 /*
5919 * Locate the controller and stuff.
5920 */
5921 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5922 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5923 pCtl = &pThis->aCts[iController];
5924
5925 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5926 pIf = &pCtl->aIfs[iInterface];
5927
5928 /* the usual paranoia */
5929 AssertRelease(!pIf->pDrvBase);
5930 AssertRelease(!pIf->pDrvBlock);
5931 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
5932 Assert(pIf->iLUN == iLUN);
5933
5934 /*
5935 * Try attach the block device and get the interfaces,
5936 * required as well as optional.
5937 */
5938 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
5939 if (RT_SUCCESS(rc))
5940 {
5941 rc = ataConfigLun(pDevIns, pIf);
5942 /*
5943 * In case there is a medium inserted.
5944 */
5945 ataMediumInserted(pIf);
5946 }
5947 else
5948 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Rrc\n", pIf->iLUN, rc));
5949
5950 if (RT_FAILURE(rc))
5951 {
5952 pIf->pDrvBase = NULL;
5953 pIf->pDrvBlock = NULL;
5954 }
5955 return rc;
5956}
5957
5958
5959/**
5960 * Suspend notification.
5961 *
5962 * @returns VBox status.
5963 * @param pDevIns The device instance data.
5964 */
5965static DECLCALLBACK(void) ataSuspend(PPDMDEVINS pDevIns)
5966{
5967 Log(("%s:\n", __FUNCTION__));
5968 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5969 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5970 return;
5971}
5972
5973
5974/**
5975 * Resume notification.
5976 *
5977 * @returns VBox status.
5978 * @param pDevIns The device instance data.
5979 */
5980static DECLCALLBACK(void) ataResume(PPDMDEVINS pDevIns)
5981{
5982 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5983 int rc;
5984
5985 Log(("%s:\n", __FUNCTION__));
5986 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5987 {
5988 if (pThis->aCts[i].fRedo && pThis->aCts[i].fRedoIdle)
5989 {
5990 rc = RTSemEventSignal(pThis->aCts[i].SuspendIOSem);
5991 AssertRC(rc);
5992 }
5993 }
5994 return;
5995}
5996
5997
5998/**
5999 * Power Off notification.
6000 *
6001 * @returns VBox status.
6002 * @param pDevIns The device instance data.
6003 */
6004static DECLCALLBACK(void) ataPowerOff(PPDMDEVINS pDevIns)
6005{
6006 Log(("%s:\n", __FUNCTION__));
6007 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
6008 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
6009 return;
6010}
6011
6012
6013/**
6014 * Prepare state save and load operation.
6015 *
6016 * @returns VBox status code.
6017 * @param pDevIns Device instance of the device which registered the data unit.
6018 * @param pSSM SSM operation handle.
6019 */
6020static DECLCALLBACK(int) ataSaveLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
6021{
6022 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6023
6024 /* sanity - the suspend notification will wait on the async stuff. */
6025 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6026 {
6027 Assert(ataAsyncIOIsIdle(&pThis->aCts[i], false));
6028 if (!ataAsyncIOIsIdle(&pThis->aCts[i], false))
6029 return VERR_SSM_IDE_ASYNC_TIMEOUT;
6030 }
6031 return VINF_SUCCESS;
6032}
6033
6034
6035/**
6036 * Saves a state of the ATA device.
6037 *
6038 * @returns VBox status code.
6039 * @param pDevIns The device instance.
6040 * @param pSSMHandle The handle to save the state to.
6041 */
6042static DECLCALLBACK(int) ataSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
6043{
6044 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6045
6046 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6047 {
6048 SSMR3PutU8(pSSMHandle, pThis->aCts[i].iSelectedIf);
6049 SSMR3PutU8(pSSMHandle, pThis->aCts[i].iAIOIf);
6050 SSMR3PutU8(pSSMHandle, pThis->aCts[i].uAsyncIOState);
6051 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fChainedTransfer);
6052 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fReset);
6053 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fRedo);
6054 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fRedoIdle);
6055 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fRedoDMALastDesc);
6056 SSMR3PutMem(pSSMHandle, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
6057 SSMR3PutGCPhys32(pSSMHandle, pThis->aCts[i].pFirstDMADesc);
6058 SSMR3PutGCPhys32(pSSMHandle, pThis->aCts[i].pLastDMADesc);
6059 SSMR3PutGCPhys32(pSSMHandle, pThis->aCts[i].pRedoDMABuffer);
6060 SSMR3PutU32(pSSMHandle, pThis->aCts[i].cbRedoDMABuffer);
6061
6062 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6063 {
6064 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fLBA48);
6065 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fATAPI);
6066 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fIrqPending);
6067 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].cMultSectors);
6068 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
6069 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
6070 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
6071 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
6072 SSMR3PutU64(pSSMHandle, pThis->aCts[i].aIfs[j].cTotalSectors);
6073 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegFeature);
6074 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
6075 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegError);
6076 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegNSector);
6077 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
6078 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegSector);
6079 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegSectorHOB);
6080 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegLCyl);
6081 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegLCylHOB);
6082 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegHCyl);
6083 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegHCylHOB);
6084 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegSelect);
6085 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegStatus);
6086 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegCommand);
6087 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegDevCtl);
6088 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATATransferMode);
6089 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uTxDir);
6090 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].iBeginTransfer);
6091 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].iSourceSink);
6092 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fDMA);
6093 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fATAPITransfer);
6094 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cbTotalTransfer);
6095 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cbElementaryTransfer);
6096 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iIOBufferCur);
6097 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iIOBufferEnd);
6098 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
6099 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
6100 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iATAPILBA);
6101 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cbATAPISector);
6102 SSMR3PutMem(pSSMHandle, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
6103 SSMR3PutMem(pSSMHandle, &pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6104 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
6105 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].MediaEventStatus);
6106 SSMR3PutMem(pSSMHandle, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
6107 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cbIOBuffer);
6108 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
6109 SSMR3PutMem(pSSMHandle, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
6110 else
6111 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
6112 }
6113 }
6114 SSMR3PutU8(pSSMHandle, pThis->u8Type);
6115
6116 return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
6117}
6118
6119
6120/**
6121 * Loads a saved ATA device state.
6122 *
6123 * @returns VBox status code.
6124 * @param pDevIns The device instance.
6125 * @param pSSMHandle The handle to the saved state.
6126 * @param u32Version The data unit version number.
6127 */
6128static DECLCALLBACK(int) ataLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
6129{
6130 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6131 int rc;
6132 uint32_t u32;
6133
6134 if ( u32Version != ATA_SAVED_STATE_VERSION
6135 && u32Version != ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE
6136 && u32Version != ATA_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS
6137 && u32Version != ATA_SAVED_STATE_VERSION_WITH_BOOL_TYPE)
6138 {
6139 AssertMsgFailed(("u32Version=%d\n", u32Version));
6140 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
6141 }
6142
6143 /*
6144 * Restore valid parts of the PCIATAState structure
6145 */
6146 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6147 {
6148 /* integrity check */
6149 if (!ataAsyncIOIsIdle(&pThis->aCts[i], false))
6150 {
6151 AssertMsgFailed(("Async I/O for controller %d is active\n", i));
6152 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
6153 return rc;
6154 }
6155
6156 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].iSelectedIf);
6157 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].iAIOIf);
6158 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].uAsyncIOState);
6159 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].fChainedTransfer);
6160 SSMR3GetBool(pSSMHandle, (bool *)&pThis->aCts[i].fReset);
6161 SSMR3GetBool(pSSMHandle, (bool *)&pThis->aCts[i].fRedo);
6162 SSMR3GetBool(pSSMHandle, (bool *)&pThis->aCts[i].fRedoIdle);
6163 SSMR3GetBool(pSSMHandle, (bool *)&pThis->aCts[i].fRedoDMALastDesc);
6164 SSMR3GetMem(pSSMHandle, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
6165 SSMR3GetGCPhys32(pSSMHandle, &pThis->aCts[i].pFirstDMADesc);
6166 SSMR3GetGCPhys32(pSSMHandle, &pThis->aCts[i].pLastDMADesc);
6167 SSMR3GetGCPhys32(pSSMHandle, &pThis->aCts[i].pRedoDMABuffer);
6168 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].cbRedoDMABuffer);
6169
6170 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6171 {
6172 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fLBA48);
6173 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fATAPI);
6174 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fIrqPending);
6175 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].cMultSectors);
6176 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
6177 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
6178 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
6179 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
6180 SSMR3GetU64(pSSMHandle, &pThis->aCts[i].aIfs[j].cTotalSectors);
6181 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegFeature);
6182 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
6183 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegError);
6184 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegNSector);
6185 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
6186 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegSector);
6187 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegSectorHOB);
6188 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegLCyl);
6189 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegLCylHOB);
6190 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegHCyl);
6191 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegHCylHOB);
6192 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegSelect);
6193 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegStatus);
6194 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegCommand);
6195 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegDevCtl);
6196 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATATransferMode);
6197 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uTxDir);
6198 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].iBeginTransfer);
6199 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].iSourceSink);
6200 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fDMA);
6201 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fATAPITransfer);
6202 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cbTotalTransfer);
6203 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cbElementaryTransfer);
6204 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iIOBufferCur);
6205 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iIOBufferEnd);
6206 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
6207 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
6208 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iATAPILBA);
6209 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cbATAPISector);
6210 SSMR3GetMem(pSSMHandle, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
6211 if (u32Version > ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE)
6212 {
6213 SSMR3GetMem(pSSMHandle, pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6214 }
6215 else
6216 {
6217 uint8_t uATAPISenseKey, uATAPIASC;
6218 memset(pThis->aCts[i].aIfs[j].abATAPISense, '\0', sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6219 pThis->aCts[i].aIfs[j].abATAPISense[0] = 0x70 | (1 << 7);
6220 pThis->aCts[i].aIfs[j].abATAPISense[7] = 10;
6221 SSMR3GetU8(pSSMHandle, &uATAPISenseKey);
6222 SSMR3GetU8(pSSMHandle, &uATAPIASC);
6223 pThis->aCts[i].aIfs[j].abATAPISense[2] = uATAPISenseKey & 0x0f;
6224 pThis->aCts[i].aIfs[j].abATAPISense[12] = uATAPIASC;
6225 }
6226 /** @todo triple-check this hack after passthrough is working */
6227 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
6228 if (u32Version > ATA_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS)
6229 SSMR3GetU32(pSSMHandle, (uint32_t*)&pThis->aCts[i].aIfs[j].MediaEventStatus);
6230 else
6231 pThis->aCts[i].aIfs[j].MediaEventStatus = ATA_EVENT_STATUS_UNCHANGED;
6232 SSMR3GetMem(pSSMHandle, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
6233 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cbIOBuffer);
6234 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
6235 {
6236 if (pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer))
6237 SSMR3GetMem(pSSMHandle, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
6238 else
6239 {
6240 LogRel(("ATA: No buffer for %d/%d\n", i, j));
6241 if (SSMR3HandleGetAfter(pSSMHandle) != SSMAFTER_DEBUG_IT)
6242 return VERR_SSM_LOAD_CONFIG_MISMATCH;
6243
6244 /* skip the buffer if we're loading for the debugger / animator. */
6245 uint8_t u8Ignored;
6246 size_t cbLeft = pThis->aCts[i].aIfs[j].cbIOBuffer;
6247 while (cbLeft-- > 0)
6248 SSMR3GetU8(pSSMHandle, &u8Ignored);
6249 }
6250 }
6251 else
6252 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
6253 }
6254 }
6255 SSMR3GetU8(pSSMHandle, &pThis->u8Type);
6256
6257 rc = SSMR3GetU32(pSSMHandle, &u32);
6258 if (RT_FAILURE(rc))
6259 return rc;
6260 if (u32 != ~0U)
6261 {
6262 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
6263 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
6264 return rc;
6265 }
6266
6267 return VINF_SUCCESS;
6268}
6269
6270/**
6271 * Convert config value to DEVPCBIOSBOOT.
6272 *
6273 * @returns VBox status code.
6274 * @param pDevIns The device instance data.
6275 * @param pCfgHandle Configuration handle.
6276 * @param penmChipset Where to store the chipset type.
6277 */
6278static int ataControllerFromCfg(PPDMDEVINS pDevIns, PCFGMNODE pCfgHandle, CHIPSET *penmChipset)
6279{
6280 char szType[20];
6281
6282 int rc = CFGMR3QueryStringDef(pCfgHandle, "Type", &szType[0], sizeof(szType), "PIIX4");
6283 if (RT_FAILURE(rc))
6284 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
6285 N_("Configuration error: Querying \"Type\" as a string failed"));
6286 if (!strcmp(szType, "PIIX3"))
6287 *penmChipset = CHIPSET_PIIX3;
6288 else if (!strcmp(szType, "PIIX4"))
6289 *penmChipset = CHIPSET_PIIX4;
6290 else if (!strcmp(szType, "ICH6"))
6291 *penmChipset = CHIPSET_ICH6;
6292 else
6293 {
6294 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
6295 N_("Configuration error: The \"Type\" value \"%s\" is unknown"),
6296 szType);
6297 rc = VERR_INTERNAL_ERROR;
6298 }
6299 return rc;
6300}
6301
6302
6303/**
6304 * Construct a device instance for a VM.
6305 *
6306 * @returns VBox status.
6307 * @param pDevIns The device instance data.
6308 * If the registration structure is needed, pDevIns->pDevReg points to it.
6309 * @param iInstance Instance number. Use this to figure out which registers and such to use.
6310 * The device number is also found in pDevIns->iInstance, but since it's
6311 * likely to be freqently used PDM passes it as parameter.
6312 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
6313 * of the device instance. It's also found in pDevIns->pCfgHandle, but like
6314 * iInstance it's expected to be used a bit in this function.
6315 */
6316static DECLCALLBACK(int) ataConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
6317{
6318 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6319 PPDMIBASE pBase;
6320 int rc;
6321 bool fGCEnabled;
6322 bool fR0Enabled;
6323 uint32_t DelayIRQMillies;
6324
6325 Assert(iInstance == 0);
6326
6327 /*
6328 * Initialize NIL handle values (for the destructor).
6329 */
6330 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6331 {
6332 pThis->aCts[i].AsyncIOSem = NIL_RTSEMEVENT;
6333 pThis->aCts[i].SuspendIOSem = NIL_RTSEMEVENT;
6334 pThis->aCts[i].AsyncIORequestMutex = NIL_RTSEMEVENT;
6335 }
6336
6337 /*
6338 * Validate and read configuration.
6339 */
6340 if (!CFGMR3AreValuesValid(pCfgHandle, "GCEnabled\0IRQDelay\0R0Enabled\0Type\0"))
6341 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
6342 N_("PIIX3 configuration error: unknown option specified"));
6343
6344 rc = CFGMR3QueryBoolDef(pCfgHandle, "GCEnabled", &fGCEnabled, true);
6345 if (RT_FAILURE(rc))
6346 return PDMDEV_SET_ERROR(pDevIns, rc,
6347 N_("PIIX3 configuration error: failed to read GCEnabled as boolean"));
6348 Log(("%s: fGCEnabled=%d\n", __FUNCTION__, fGCEnabled));
6349
6350 rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &fR0Enabled, true);
6351 if (RT_FAILURE(rc))
6352 return PDMDEV_SET_ERROR(pDevIns, rc,
6353 N_("PIIX3 configuration error: failed to read R0Enabled as boolean"));
6354 Log(("%s: fR0Enabled=%d\n", __FUNCTION__, fR0Enabled));
6355
6356 rc = CFGMR3QueryU32Def(pCfgHandle, "IRQDelay", &DelayIRQMillies, 0);
6357 if (RT_FAILURE(rc))
6358 return PDMDEV_SET_ERROR(pDevIns, rc,
6359 N_("PIIX3 configuration error: failed to read IRQDelay as integer"));
6360 Log(("%s: DelayIRQMillies=%d\n", __FUNCTION__, DelayIRQMillies));
6361 Assert(DelayIRQMillies < 50);
6362
6363 CHIPSET enmChipset = CHIPSET_PIIX3;
6364 rc = ataControllerFromCfg(pDevIns, pCfgHandle, &enmChipset);
6365 if (RT_FAILURE(rc))
6366 return rc;
6367 pThis->u8Type = (uint8_t)enmChipset;
6368
6369 /*
6370 * Initialize data (most of it anyway).
6371 */
6372 /* Status LUN. */
6373 pThis->IBase.pfnQueryInterface = ataStatus_QueryInterface;
6374 pThis->ILeds.pfnQueryStatusLed = ataStatus_QueryStatusLed;
6375
6376 /* PCI configuration space. */
6377 PCIDevSetVendorId(&pThis->dev, 0x8086); /* Intel */
6378
6379 /*
6380 * When adding more IDE chipsets, don't forget to update pci_bios_init_device()
6381 * as it explicitly checks for PCI id for IDE controllers.
6382 */
6383 switch (pThis->u8Type)
6384 {
6385 case CHIPSET_ICH6:
6386 PCIDevSetDeviceId(&pThis->dev, 0x269e); /* ICH6 IDE */
6387 /** @todo: do we need it? Do we need anything else? */
6388 pThis->dev.config[0x48] = 0x00; /* UDMACTL */
6389 pThis->dev.config[0x4A] = 0x00; /* UDMATIM */
6390 pThis->dev.config[0x4B] = 0x00;
6391 {
6392 /*
6393 * See www.intel.com/Assets/PDF/manual/298600.pdf p. 30
6394 * Report
6395 * WR_Ping-Pong_EN: must be set
6396 * PCR0, PCR1: 80-pin primary cable reporting for both disks
6397 * SCR0, SCR1: 80-pin secondary cable reporting for both disks
6398 */
6399 uint16_t u16Config = (1<<10) | (1<<7) | (1<<6) | (1<<5) | (1<<4) ;
6400 pThis->dev.config[0x54] = u16Config & 0xff;
6401 pThis->dev.config[0x55] = u16Config >> 8;
6402 }
6403 break;
6404 case CHIPSET_PIIX4:
6405 PCIDevSetDeviceId(&pThis->dev, 0x7111); /* PIIX4 IDE */
6406 PCIDevSetRevisionId(&pThis->dev, 0x01); /* PIIX4E */
6407 pThis->dev.config[0x48] = 0x00; /* UDMACTL */
6408 pThis->dev.config[0x4A] = 0x00; /* UDMATIM */
6409 pThis->dev.config[0x4B] = 0x00;
6410 break;
6411 case CHIPSET_PIIX3:
6412 PCIDevSetDeviceId(&pThis->dev, 0x7010); /* PIIX3 IDE */
6413 break;
6414 default:
6415 AssertMsgFailed(("Unsupported IDE chipset type: %d\n", pThis->u8Type));
6416 }
6417
6418 PCIDevSetCommand( &pThis->dev, PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER);
6419 PCIDevSetClassProg( &pThis->dev, 0x8a); /* programming interface = PCI_IDE bus master is supported */
6420 PCIDevSetClassSub( &pThis->dev, 0x01); /* class_sub = PCI_IDE */
6421 PCIDevSetClassBase( &pThis->dev, 0x01); /* class_base = PCI_mass_storage */
6422 PCIDevSetHeaderType(&pThis->dev, 0x00);
6423
6424 pThis->pDevIns = pDevIns;
6425 pThis->fGCEnabled = fGCEnabled;
6426 pThis->fR0Enabled = fR0Enabled;
6427 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6428 {
6429 pThis->aCts[i].pDevInsR3 = pDevIns;
6430 pThis->aCts[i].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
6431 pThis->aCts[i].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
6432 pThis->aCts[i].DelayIRQMillies = (uint32_t)DelayIRQMillies;
6433 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6434 {
6435 ATADevState *pIf = &pThis->aCts[i].aIfs[j];
6436
6437 pIf->iLUN = i * RT_ELEMENTS(pThis->aCts) + j;
6438 pIf->pDevInsR3 = pDevIns;
6439 pIf->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
6440 pIf->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
6441 pIf->pControllerR3 = &pThis->aCts[i];
6442 pIf->pControllerR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
6443 pIf->pControllerRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
6444 pIf->IBase.pfnQueryInterface = ataQueryInterface;
6445 pIf->IMountNotify.pfnMountNotify = ataMountNotify;
6446 pIf->IMountNotify.pfnUnmountNotify = ataUnmountNotify;
6447 pIf->Led.u32Magic = PDMLED_MAGIC;
6448 }
6449 }
6450
6451 Assert(RT_ELEMENTS(pThis->aCts) == 2);
6452 pThis->aCts[0].irq = 14;
6453 pThis->aCts[0].IOPortBase1 = 0x1f0;
6454 pThis->aCts[0].IOPortBase2 = 0x3f6;
6455 pThis->aCts[1].irq = 15;
6456 pThis->aCts[1].IOPortBase1 = 0x170;
6457 pThis->aCts[1].IOPortBase2 = 0x376;
6458
6459 /*
6460 * Register the PCI device.
6461 * N.B. There's a hack in the PIIX3 PCI bridge device to assign this
6462 * device the slot next to itself.
6463 */
6464 rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev);
6465 if (RT_FAILURE(rc))
6466 return PDMDEV_SET_ERROR(pDevIns, rc,
6467 N_("PIIX3 cannot register PCI device"));
6468 AssertMsg(pThis->dev.devfn == 9 || iInstance != 0, ("pThis->dev.devfn=%d\n", pThis->dev.devfn));
6469 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataBMDMAIORangeMap);
6470 if (RT_FAILURE(rc))
6471 return PDMDEV_SET_ERROR(pDevIns, rc,
6472 N_("PIIX3 cannot register PCI I/O region for BMDMA"));
6473
6474 /*
6475 * Register the I/O ports.
6476 * The ports are all hardcoded and enforced by the PIIX3 host bridge controller.
6477 */
6478 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6479 {
6480 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTHCPTR)i,
6481 ataIOPortWrite1, ataIOPortRead1, ataIOPortWriteStr1, ataIOPortReadStr1, "ATA I/O Base 1");
6482 if (RT_FAILURE(rc))
6483 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers"));
6484
6485 if (fGCEnabled)
6486 {
6487 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTGCPTR)i,
6488 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
6489 if (RT_FAILURE(rc))
6490 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers (GC)"));
6491 }
6492
6493 if (fR0Enabled)
6494 {
6495#if 1
6496 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
6497 "ataIOPortWrite1", "ataIOPortRead1", NULL, NULL, "ATA I/O Base 1");
6498#else
6499 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
6500 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
6501#endif
6502 if (RT_FAILURE(rc))
6503 return PDMDEV_SET_ERROR(pDevIns, rc, "PIIX3 cannot register I/O handlers (R0).");
6504 }
6505
6506 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTHCPTR)i,
6507 ataIOPortWrite2, ataIOPortRead2, NULL, NULL, "ATA I/O Base 2");
6508 if (RT_FAILURE(rc))
6509 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers"));
6510
6511 if (fGCEnabled)
6512 {
6513 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTGCPTR)i,
6514 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
6515 if (RT_FAILURE(rc))
6516 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (GC)"));
6517 }
6518 if (fR0Enabled)
6519 {
6520 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTR0PTR)i,
6521 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
6522 if (RT_FAILURE(rc))
6523 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (R0)"));
6524 }
6525
6526 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6527 {
6528 ATADevState *pIf = &pThis->aCts[i].aIfs[j];
6529 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATADMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATA DMA transfers.", "/Devices/ATA%d/Unit%d/DMA", i, j);
6530 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATA PIO transfers.", "/Devices/ATA%d/Unit%d/PIO", i, j);
6531 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIDMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATAPI DMA transfers.", "/Devices/ATA%d/Unit%d/AtapiDMA", i, j);
6532 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATAPI PIO transfers.", "/Devices/ATA%d/Unit%d/AtapiPIO", i, j);
6533#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
6534 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatReads, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of the read operations.", "/Devices/ATA%d/Unit%d/Reads", i, j);
6535#endif
6536 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesRead, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data read.", "/Devices/ATA%d/Unit%d/ReadBytes", i, j);
6537#ifdef VBOX_INSTRUMENT_DMA_WRITES
6538 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatInstrVDWrites,STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of the VD DMA write operations.","/Devices/ATA%d/Unit%d/InstrVDWrites", i, j);
6539#endif
6540#ifdef VBOX_WITH_STATISTICS
6541 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatWrites, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of the write operations.","/Devices/ATA%d/Unit%d/Writes", i, j);
6542#endif
6543 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data written.", "/Devices/ATA%d/Unit%d/WrittenBytes", i, j);
6544#ifdef VBOX_WITH_STATISTICS
6545 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatFlushes, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of the flush operations.","/Devices/ATA%d/Unit%d/Flushes", i, j);
6546#endif
6547 }
6548#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
6549 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncOps, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "The number of async operations.", "/Devices/ATA%d/Async/Operations", i);
6550 /** @todo STAMUNIT_MICROSECS */
6551 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMinWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Minimum wait in microseconds.", "/Devices/ATA%d/Async/MinWait", i);
6552 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMaxWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Maximum wait in microseconds.", "/Devices/ATA%d/Async/MaxWait", i);
6553 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncTimeUS, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Total time spent in microseconds.","/Devices/ATA%d/Async/TotalTimeUS", i);
6554 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncTime, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of async operations.", "/Devices/ATA%d/Async/Time", i);
6555 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatLockWait, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of locks.", "/Devices/ATA%d/Async/LockWait", i);
6556#endif /* VBOX_WITH_STATISTICS */
6557
6558 /* Initialize per-controller critical section */
6559 char szName[24];
6560 RTStrPrintf(szName, sizeof(szName), "ATA%d", i);
6561 rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].lock, szName);
6562 if (RT_FAILURE(rc))
6563 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot initialize critical section"));
6564 }
6565
6566 /*
6567 * Attach status driver (optional).
6568 */
6569 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pBase, "Status Port");
6570 if (RT_SUCCESS(rc))
6571 pThis->pLedsConnector = (PDMILEDCONNECTORS *)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS);
6572 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
6573 {
6574 AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc));
6575 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot attach to status driver"));
6576 }
6577
6578 /*
6579 * Attach the units.
6580 */
6581 uint32_t cbTotalBuffer = 0;
6582 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6583 {
6584 PATACONTROLLER pCtl = &pThis->aCts[i];
6585
6586 /*
6587 * Start the worker thread.
6588 */
6589 pCtl->uAsyncIOState = ATA_AIO_NEW;
6590 rc = RTSemEventCreate(&pCtl->AsyncIOSem);
6591 AssertRC(rc);
6592 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
6593 AssertRC(rc);
6594 rc = RTSemMutexCreate(&pCtl->AsyncIORequestMutex);
6595 AssertRC(rc);
6596 ataAsyncIOClearRequests(pCtl);
6597 rc = RTThreadCreateF(&pCtl->AsyncIOThread, ataAsyncIOLoop, (void *)pCtl, 128*1024, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "ATA-%u", i);
6598 AssertRC(rc);
6599 Assert(pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->AsyncIOSem != NIL_RTSEMEVENT && pCtl->SuspendIOSem != NIL_RTSEMEVENT && pCtl->AsyncIORequestMutex != NIL_RTSEMMUTEX);
6600 Log(("%s: controller %d AIO thread id %#x; sem %p susp_sem %p mutex %p\n", __FUNCTION__, i, pCtl->AsyncIOThread, pCtl->AsyncIOSem, pCtl->SuspendIOSem, pCtl->AsyncIORequestMutex));
6601
6602 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
6603 {
6604 static const char *s_apszDescs[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
6605 {
6606 { "Primary Master", "Primary Slave" },
6607 { "Secondary Master", "Secondary Slave" }
6608 };
6609
6610 /*
6611 * Try attach the block device and get the interfaces,
6612 * required as well as optional.
6613 */
6614 ATADevState *pIf = &pCtl->aIfs[j];
6615
6616 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, s_apszDescs[i][j]);
6617 if (RT_SUCCESS(rc))
6618 {
6619 rc = ataConfigLun(pDevIns, pIf);
6620 if (RT_SUCCESS(rc))
6621 {
6622 /*
6623 * Init vendor product data.
6624 */
6625 static const char *s_apszCFGMKeys[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
6626 {
6627 { "PrimaryMaster", "PrimarySlave" },
6628 { "SecondaryMaster", "SecondarySlave" }
6629 };
6630
6631 /* Generate a default serial number. */
6632 char szSerial[ATA_SERIAL_NUMBER_LENGTH+1];
6633 RTUUID Uuid;
6634 if (pIf->pDrvBlock)
6635 rc = pIf->pDrvBlock->pfnGetUuid(pIf->pDrvBlock, &Uuid);
6636 else
6637 RTUuidClear(&Uuid);
6638
6639 if (RT_FAILURE(rc) || RTUuidIsNull(&Uuid))
6640 {
6641 /* Generate a predictable serial for drives which don't have a UUID. */
6642 RTStrPrintf(szSerial, sizeof(szSerial), "VB%x-%04x%04x",
6643 pIf->iLUN + pDevIns->iInstance * 32,
6644 pThis->aCts[i].IOPortBase1, pThis->aCts[i].IOPortBase2);
6645 }
6646 else
6647 RTStrPrintf(szSerial, sizeof(szSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
6648
6649 /* Get user config if present using defaults otherwise. */
6650 PCFGMNODE pCfgNode = CFGMR3GetChild(pCfgHandle, s_apszCFGMKeys[i][j]);
6651 rc = CFGMR3QueryStringDef(pCfgNode, "SerialNumber", pIf->szSerialNumber, sizeof(pIf->szSerialNumber),
6652 szSerial);
6653 if (RT_FAILURE(rc))
6654 {
6655 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
6656 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
6657 N_("PIIX3 configuration error: \"SerialNumber\" is longer than 20 bytes"));
6658 return PDMDEV_SET_ERROR(pDevIns, rc,
6659 N_("PIIX3 configuration error: failed to read \"SerialNumber\" as string"));
6660 }
6661
6662 rc = CFGMR3QueryStringDef(pCfgNode, "FirmwareRevision", pIf->szFirmwareRevision, sizeof(pIf->szFirmwareRevision),
6663 "1.0");
6664 if (RT_FAILURE(rc))
6665 {
6666 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
6667 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
6668 N_("PIIX3 configuration error: \"FirmwareRevision\" is longer than 8 bytes"));
6669 return PDMDEV_SET_ERROR(pDevIns, rc,
6670 N_("PIIX3 configuration error: failed to read \"FirmwareRevision\" as string"));
6671 }
6672
6673 rc = CFGMR3QueryStringDef(pCfgNode, "ModelNumber", pIf->szModelNumber, sizeof(pIf->szModelNumber),
6674 pIf->fATAPI ? "VBOX CD-ROM" : "VBOX HARDDISK");
6675 if (RT_FAILURE(rc))
6676 {
6677 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
6678 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
6679 N_("PIIX3 configuration error: \"ModelNumber\" is longer than 40 bytes"));
6680 return PDMDEV_SET_ERROR(pDevIns, rc,
6681 N_("PIIX3 configuration error: failed to read \"ModelNumber\" as string"));
6682 }
6683 }
6684
6685 }
6686 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
6687 {
6688 pIf->pDrvBase = NULL;
6689 pIf->pDrvBlock = NULL;
6690 pIf->cbIOBuffer = 0;
6691 pIf->pbIOBufferR3 = NULL;
6692 pIf->pbIOBufferR0 = NIL_RTR0PTR;
6693 pIf->pbIOBufferRC = NIL_RTGCPTR;
6694 LogRel(("PIIX3 ATA: LUN#%d: no unit\n", pIf->iLUN));
6695 }
6696 else
6697 {
6698 switch (rc)
6699 {
6700 case VERR_ACCESS_DENIED:
6701 /* Error already catched by DrvHostBase */
6702 return rc;
6703 default:
6704 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
6705 N_("PIIX3 cannot attach drive to the %s"),
6706 s_apszDescs[i][j]);
6707 }
6708 }
6709 cbTotalBuffer += pIf->cbIOBuffer;
6710 }
6711 }
6712
6713 rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance,
6714 ATA_SAVED_STATE_VERSION, sizeof(*pThis) + cbTotalBuffer,
6715 ataSaveLoadPrep, ataSaveExec, NULL,
6716 ataSaveLoadPrep, ataLoadExec, NULL);
6717 if (RT_FAILURE(rc))
6718 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register save state handlers"));
6719
6720 /*
6721 * Initialize the device state.
6722 */
6723 ataReset(pDevIns);
6724
6725 return VINF_SUCCESS;
6726}
6727
6728
6729/**
6730 * The device registration structure.
6731 */
6732const PDMDEVREG g_DevicePIIX3IDE =
6733{
6734 /* u32Version */
6735 PDM_DEVREG_VERSION,
6736 /* szDeviceName */
6737 "piix3ide",
6738 /* szRCMod */
6739 "VBoxDDGC.gc",
6740 /* szR0Mod */
6741 "VBoxDDR0.r0",
6742 /* pszDescription */
6743 "Intel PIIX3 ATA controller.\n"
6744 " LUN #0 is primary master.\n"
6745 " LUN #1 is primary slave.\n"
6746 " LUN #2 is secondary master.\n"
6747 " LUN #3 is secondary slave.\n"
6748 " LUN #999 is the LED/Status connector.",
6749 /* fFlags */
6750 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
6751 PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION,
6752 /* fClass */
6753 PDM_DEVREG_CLASS_STORAGE,
6754 /* cMaxInstances */
6755 1,
6756 /* cbInstance */
6757 sizeof(PCIATAState),
6758 /* pfnConstruct */
6759 ataConstruct,
6760 /* pfnDestruct */
6761 ataDestruct,
6762 /* pfnRelocate */
6763 ataRelocate,
6764 /* pfnIOCtl */
6765 NULL,
6766 /* pfnPowerOn */
6767 NULL,
6768 /* pfnReset */
6769 ataReset,
6770 /* pfnSuspend */
6771 ataSuspend,
6772 /* pfnResume */
6773 ataResume,
6774 /* pfnAttach */
6775 ataAttach,
6776 /* pfnDetach */
6777 ataDetach,
6778 /* pfnQueryInterface. */
6779 NULL,
6780 /* pfnInitComplete */
6781 NULL,
6782 /* pfnPowerOff */
6783 ataPowerOff,
6784 /* pfnSoftReset */
6785 NULL,
6786 /* u32VersionEnd */
6787 PDM_DEVREG_VERSION
6788};
6789#endif /* IN_RING3 */
6790#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
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