VirtualBox

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

Last change on this file since 77329 was 77023, checked in by vboxsync, 6 years ago

DevATA: Added READ CD MSF support (see bugref:5869).

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