VirtualBox

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

Last change on this file since 65075 was 65075, checked in by vboxsync, 8 years ago

Devices/Storage: Move ide.h to include/VBox/ata.h to be consistent with how the headers are layed out for the SCSI bits. Renamed to ata.h to reflect that it belongs to the ATA standard

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

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