VirtualBox

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

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

DevATA: Clear interrupt when command register is written (ATA requirement). Also rely on the internal interrupt pending state more, to avoid unnecessary PDM calls (see bugref:5869).

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

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