VirtualBox

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

Last change on this file since 56400 was 56400, checked in by vboxsync, 10 years ago

DevATA: Use the R3 infix to clarify in which context things are executed.

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

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