VirtualBox

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

Last change on this file since 81839 was 81839, checked in by vboxsync, 5 years ago

DevATA: Buffer paranoia and preperations for static alloc. bugref:9218

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