VirtualBox

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

Last change on this file since 71564 was 70776, checked in by vboxsync, 7 years ago

Devices/Storage/DevATA.cpp: Implement MODE SENSE (6) command to be on the same level as the VSCSI implementation and what we allow in the passthrough code

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