VirtualBox

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

Last change on this file since 77560 was 77392, checked in by vboxsync, 6 years ago

DevATA: Return bit 7 clear when reading registers on IDE channel with no drives. Avoids 2x35s delay with EFI IDE device detection. See bugref:5869

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

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