VirtualBox

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

最後變更 在這個檔案從62632是 62632,由 vboxsync 提交於 9 年 前

Devices: unused parameter warnings.

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

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