VirtualBox

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

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

PDM,Devices: Changed PDM_DEVREG_FLAGS_MSI_X into a registration field giving the max MSI-X vector count config for the device (typically VBOX_MSIX_MAX_ENTRIES). bugref:9218

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

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