VirtualBox

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

最後變更 在這個檔案從25276是 25192,由 vboxsync 提交於 15 年 前

Storage/DevATA: fix device reset if a transfer redo is pending. Triggered release assertions (which was good, because if that check was missing the guest would have been with a totally unresponsive hard disk) with message "I/O state inconsistent: state=0 request=1". Reproducing is pretty much impossible unless using an iSCSI target which becomes unresponsive at just the right time, i.e. when doing big transfers.

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

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