VirtualBox

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

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

Devices: Use PDMDEVINS_2_DATA and PDMDEVINS_2_DATA. bugref:9218

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

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