VirtualBox

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

Last change on this file since 72589 was 72589, checked in by vboxsync, 7 years ago

DevATA: Register statistics profiling the yields. bugref:1960

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

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