VirtualBox

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

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

DevATA: Optimize the suspend and poweroff pendig I/O waits so they won't wait in 100ms chunks but block on the thread semaphore and get woken up by the I/O thread when it is idle. Combined the per-controller waiting with the wait for both controllers, sacrifying the timeout a bit in the latter case (but it's not all that important, so who cares). Made the constructor return on semaphore and thread creation failures. Moved the semaphore cleanup to the constructor and simplified the waiting there to just wait for the threads. Made the I/O thread stop setting its handle to NIL_RTTHREAD before quitting and causing a thread handle leak (IPRT internal handle).

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

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