VirtualBox

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

Last change on this file since 63942 was 63690, checked in by vboxsync, 8 years ago

PCI,Devices: Changed range size in FNPCIIOREGIONMAP from uint32_t to RTGCPHYS.

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

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