VirtualBox

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

Last change on this file since 76565 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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