VirtualBox

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

最後變更 在這個檔案從77579是 77579,由 vboxsync 提交於 6 年 前

DevATA: Added empty bus port handler to simplify logic elsewhere.

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

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