VirtualBox

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

最後變更 在這個檔案從23149是 23149,由 vboxsync 提交於 16 年 前

ATA,AHCI: Assertion is to is strict. VERR_PDM_MEDIA_LOCKED is expected if the pfnUnmount is called while the medium is still locked. Will be handled by the device emulation correctly

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette