VirtualBox

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

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

gcc 7: Devices: fall thru

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