VirtualBox

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

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

DevATA: Log CHS<->LBA conversions.

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

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