VirtualBox

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

Last change on this file since 24761 was 24761, checked in by vboxsync, 15 years ago

Storage/ATA: clear pending DMA on controller reset (and on command abort), since restarting such a transfer will cause a vm crash (I/O state inconsistent: state=0 request=1)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 267.2 KB
Line 
1/* $Id: DevATA.cpp 24761 2009-11-18 16:11:58Z 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.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * 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 finished\n"));
779 break;
780 case ATA_AIO_PIO:
781 LogRel(("pio transfer finished\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))
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))
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))
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 LogRel(("PIIX3 ATA: Ctl#%d: finished processing RESET\n",
4878 ATACONTROLLER_IDX(pCtl)));
4879 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4880 {
4881 if (pCtl->aIfs[i].fATAPI)
4882 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
4883 else
4884 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
4885 ataSetSignature(&pCtl->aIfs[i]);
4886 }
4887 break;
4888
4889 case ATA_AIO_ABORT:
4890 /* Abort the current command only if it operates on the same interface. */
4891 if (pCtl->iAIOIf == pReq->u.a.iIf)
4892 {
4893 s = &pCtl->aIfs[pCtl->iAIOIf];
4894
4895 pCtl->uAsyncIOState = ATA_AIO_NEW;
4896 /* Do not change the DMA registers, they are not affected by the
4897 * ATA controller reset logic. It should be sufficient to issue a
4898 * new command, which is now possible as the state is cleared. */
4899 if (pReq->u.a.fResetDrive)
4900 {
4901 ataResetDevice(s);
4902 ataExecuteDeviceDiagnosticSS(s);
4903 }
4904 else
4905 {
4906 /* Stop any pending DMA transfer. */
4907 s->fDMA = false;
4908 ataPIOTransferStop(s);
4909 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
4910 ataSetStatus(s, ATA_STAT_READY);
4911 ataSetIRQ(s);
4912 }
4913 }
4914 break;
4915
4916 default:
4917 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
4918 }
4919
4920 ataAsyncIORemoveCurrentRequest(pCtl, ReqType);
4921 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4922
4923 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4924 {
4925#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4926 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
4927#endif /* DEBUG || VBOX_WITH_STATISTICS */
4928
4929 u64TS = RTTimeNanoTS() - u64TS;
4930 uWait = u64TS / 1000;
4931 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)));
4932 /* Mark command as finished. */
4933 pCtl->aIfs[pCtl->iAIOIf].u64CmdTS = 0;
4934
4935 /*
4936 * Release logging of command execution times depends on the
4937 * command type. ATAPI commands often take longer (due to CD/DVD
4938 * spin up time etc.) so the threshold is different.
4939 */
4940 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
4941 {
4942 if (uWait > 8 * 1000 * 1000)
4943 {
4944 /*
4945 * Command took longer than 8 seconds. This is close
4946 * enough or over the guest's command timeout, so place
4947 * an entry in the release log to allow tracking such
4948 * timing errors (which are often caused by the host).
4949 */
4950 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
4951 }
4952 }
4953 else
4954 {
4955 if (uWait > 20 * 1000 * 1000)
4956 {
4957 /*
4958 * Command took longer than 20 seconds. This is close
4959 * enough or over the guest's command timeout, so place
4960 * an entry in the release log to allow tracking such
4961 * timing errors (which are often caused by the host).
4962 */
4963 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
4964 }
4965 }
4966
4967#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4968 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
4969 pCtl->StatAsyncMinWait = uWait;
4970 if (uWait > pCtl->StatAsyncMaxWait)
4971 pCtl->StatAsyncMaxWait = uWait;
4972
4973 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
4974 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
4975#endif /* DEBUG || VBOX_WITH_STATISTICS */
4976 }
4977
4978 PDMCritSectLeave(&pCtl->lock);
4979 }
4980
4981 /* Signal the ultimate idleness. */
4982 RTThreadUserSignal(pCtl->AsyncIOThread);
4983 if (pCtl->fSignalIdle)
4984 PDMDevHlpAsyncNotificationCompleted(pCtl->pDevInsR3);
4985
4986 /* Cleanup the state. */
4987 /* Do not destroy request mutex yet, still needed for proper shutdown. */
4988 pCtl->fShutdown = false;
4989
4990 Log2(("%s: Ctl#%d: return %Rrc\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), rc));
4991 return rc;
4992}
4993
4994#endif /* IN_RING3 */
4995
4996static uint32_t ataBMDMACmdReadB(PATACONTROLLER pCtl, uint32_t addr)
4997{
4998 uint32_t val = pCtl->BmDma.u8Cmd;
4999 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5000 return val;
5001}
5002
5003
5004static void ataBMDMACmdWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5005{
5006 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5007 if (!(val & BM_CMD_START))
5008 {
5009 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
5010 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5011 }
5012 else
5013 {
5014#ifdef IN_RING3
5015 /* Check whether the guest OS wants to change DMA direction in
5016 * mid-flight. Not allowed, according to the PIIX3 specs. */
5017 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
5018 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
5019 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5020
5021 /* Do not continue DMA transfers while the RESET line is asserted. */
5022 if (pCtl->fReset)
5023 {
5024 Log2(("%s: Ctl#%d: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5025 return;
5026 }
5027
5028 /* Do not start DMA transfers if there's a PIO transfer going on. */
5029 if (!pCtl->aIfs[pCtl->iSelectedIf].fDMA)
5030 return;
5031
5032 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
5033 {
5034 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5035 ataAsyncIOPutRequest(pCtl, &g_ataDMARequest);
5036 }
5037#else /* !IN_RING3 */
5038 AssertMsgFailed(("DMA START handling is too complicated for GC\n"));
5039#endif /* IN_RING3 */
5040 }
5041}
5042
5043static uint32_t ataBMDMAStatusReadB(PATACONTROLLER pCtl, uint32_t addr)
5044{
5045 uint32_t val = pCtl->BmDma.u8Status;
5046 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5047 return val;
5048}
5049
5050static void ataBMDMAStatusWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5051{
5052 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5053 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
5054 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
5055 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
5056}
5057
5058static uint32_t ataBMDMAAddrReadL(PATACONTROLLER pCtl, uint32_t addr)
5059{
5060 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
5061 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5062 return val;
5063}
5064
5065static void ataBMDMAAddrWriteL(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5066{
5067 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5068 pCtl->BmDma.pvAddr = val & ~3;
5069}
5070
5071static void ataBMDMAAddrWriteLowWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5072{
5073 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5074 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
5075
5076}
5077
5078static void ataBMDMAAddrWriteHighWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5079{
5080 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5081 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
5082}
5083
5084#define VAL(port, size) ( ((port) & 7) | ((size) << 3) )
5085
5086/**
5087 * Port I/O Handler for bus master DMA IN operations.
5088 * @see FNIOMIOPORTIN for details.
5089 */
5090PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5091{
5092 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5093 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5094 PATACONTROLLER pCtl = &pThis->aCts[i];
5095 int rc;
5096
5097 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5098 if (rc != VINF_SUCCESS)
5099 return rc;
5100 switch (VAL(Port, cb))
5101 {
5102 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
5103 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
5104 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
5105 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
5106 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
5107 case VAL(0, 4):
5108 /* The SCO OpenServer tries to read 4 bytes starting from offset 0. */
5109 *pu32 = ataBMDMACmdReadB(pCtl, Port) | (ataBMDMAStatusReadB(pCtl, Port) << 16);
5110 break;
5111 default:
5112 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb));
5113 PDMCritSectLeave(&pCtl->lock);
5114 return VERR_IOM_IOPORT_UNUSED;
5115 }
5116 PDMCritSectLeave(&pCtl->lock);
5117 return rc;
5118}
5119
5120/**
5121 * Port I/O Handler for bus master DMA OUT operations.
5122 * @see FNIOMIOPORTOUT for details.
5123 */
5124PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5125{
5126 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5127 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5128 PATACONTROLLER pCtl = &pThis->aCts[i];
5129 int rc;
5130
5131 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5132 if (rc != VINF_SUCCESS)
5133 return rc;
5134 switch (VAL(Port, cb))
5135 {
5136 case VAL(0, 1):
5137#ifndef IN_RING3
5138 if (u32 & BM_CMD_START)
5139 {
5140 rc = VINF_IOM_HC_IOPORT_WRITE;
5141 break;
5142 }
5143#endif /* !IN_RING3 */
5144 ataBMDMACmdWriteB(pCtl, Port, u32);
5145 break;
5146 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
5147 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
5148 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
5149 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
5150 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break;
5151 }
5152 PDMCritSectLeave(&pCtl->lock);
5153 return rc;
5154}
5155
5156#undef VAL
5157
5158#ifdef IN_RING3
5159
5160/**
5161 * Callback function for mapping an PCI I/O region.
5162 *
5163 * @return VBox status code.
5164 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
5165 * @param iRegion The region number.
5166 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
5167 * I/O port, else it's a physical address.
5168 * This address is *NOT* relative to pci_mem_base like earlier!
5169 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
5170 */
5171static DECLCALLBACK(int) ataBMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
5172{
5173 PCIATAState *pThis = PCIDEV_2_PCIATASTATE(pPciDev);
5174 int rc = VINF_SUCCESS;
5175 Assert(enmType == PCI_ADDRESS_SPACE_IO);
5176 Assert(iRegion == 4);
5177 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
5178
5179 /* Register the port range. */
5180 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5181 {
5182 int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
5183 (RTHCPTR)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL, NULL, "ATA Bus Master DMA");
5184 AssertRC(rc2);
5185 if (rc2 < rc)
5186 rc = rc2;
5187
5188 if (pThis->fGCEnabled)
5189 {
5190 rc2 = PDMDevHlpIOPortRegisterGC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
5191 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
5192 AssertRC(rc2);
5193 if (rc2 < rc)
5194 rc = rc2;
5195 }
5196 if (pThis->fR0Enabled)
5197 {
5198 rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
5199 (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
5200 AssertRC(rc2);
5201 if (rc2 < rc)
5202 rc = rc2;
5203 }
5204 }
5205 return rc;
5206}
5207
5208
5209/* -=-=-=-=-=- PCIATAState::IBase -=-=-=-=-=- */
5210
5211/**
5212 * Queries an interface to the driver.
5213 *
5214 * @returns Pointer to interface.
5215 * @returns NULL if the interface was not supported by the device.
5216 * @param pInterface Pointer to ATADevState::IBase.
5217 * @param enmInterface The requested interface identification.
5218 */
5219static DECLCALLBACK(void *) ataStatus_QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
5220{
5221 PCIATAState *pThis = PDMIBASE_2_PCIATASTATE(pInterface);
5222 switch (enmInterface)
5223 {
5224 case PDMINTERFACE_BASE:
5225 return &pThis->IBase;
5226 case PDMINTERFACE_LED_PORTS:
5227 return &pThis->ILeds;
5228 default:
5229 return NULL;
5230 }
5231}
5232
5233
5234/* -=-=-=-=-=- PCIATAState::ILeds -=-=-=-=-=- */
5235
5236/**
5237 * Gets the pointer to the status LED of a unit.
5238 *
5239 * @returns VBox status code.
5240 * @param pInterface Pointer to the interface structure containing the called function pointer.
5241 * @param iLUN The unit which status LED we desire.
5242 * @param ppLed Where to store the LED pointer.
5243 */
5244static DECLCALLBACK(int) ataStatus_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
5245{
5246 PCIATAState *pThis = PDMILEDPORTS_2_PCIATASTATE(pInterface);
5247 if (iLUN < 4)
5248 {
5249 switch (iLUN)
5250 {
5251 case 0: *ppLed = &pThis->aCts[0].aIfs[0].Led; break;
5252 case 1: *ppLed = &pThis->aCts[0].aIfs[1].Led; break;
5253 case 2: *ppLed = &pThis->aCts[1].aIfs[0].Led; break;
5254 case 3: *ppLed = &pThis->aCts[1].aIfs[1].Led; break;
5255 }
5256 Assert((*ppLed)->u32Magic == PDMLED_MAGIC);
5257 return VINF_SUCCESS;
5258 }
5259 return VERR_PDM_LUN_NOT_FOUND;
5260}
5261
5262
5263/* -=-=-=-=-=- ATADevState::IBase -=-=-=-=-=- */
5264
5265/**
5266 * Queries an interface to the driver.
5267 *
5268 * @returns Pointer to interface.
5269 * @returns NULL if the interface was not supported by the device.
5270 * @param pInterface Pointer to ATADevState::IBase.
5271 * @param enmInterface The requested interface identification.
5272 */
5273static DECLCALLBACK(void *) ataQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
5274{
5275 ATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
5276 switch (enmInterface)
5277 {
5278 case PDMINTERFACE_BASE:
5279 return &pIf->IBase;
5280 case PDMINTERFACE_BLOCK_PORT:
5281 return &pIf->IPort;
5282 case PDMINTERFACE_MOUNT_NOTIFY:
5283 return &pIf->IMountNotify;
5284 default:
5285 return NULL;
5286 }
5287}
5288
5289#endif /* IN_RING3 */
5290
5291
5292/* -=-=-=-=-=- Wrappers -=-=-=-=-=- */
5293
5294/**
5295 * Port I/O Handler for primary port range OUT operations.
5296 * @see FNIOMIOPORTOUT for details.
5297 */
5298PDMBOTHCBDECL(int) ataIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5299{
5300 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5301 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5302 PATACONTROLLER pCtl = &pThis->aCts[i];
5303 int rc = VINF_SUCCESS;
5304
5305 Assert(i < 2);
5306
5307 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5308 if (rc != VINF_SUCCESS)
5309 return rc;
5310 if (cb == 1)
5311 rc = ataIOPortWriteU8(pCtl, Port, u32);
5312 else if (Port == pCtl->IOPortBase1)
5313 {
5314 Assert(cb == 2 || cb == 4);
5315 rc = ataDataWrite(pCtl, Port, cb, (const uint8_t *)&u32);
5316 }
5317 else
5318 AssertMsgFailed(("ataIOPortWrite1: unsupported write to port %x val=%x size=%d\n", Port, u32, cb));
5319 PDMCritSectLeave(&pCtl->lock);
5320 return rc;
5321}
5322
5323
5324/**
5325 * Port I/O Handler for primary port range IN operations.
5326 * @see FNIOMIOPORTIN for details.
5327 */
5328PDMBOTHCBDECL(int) ataIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5329{
5330 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5331 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5332 PATACONTROLLER pCtl = &pThis->aCts[i];
5333 int rc = VINF_SUCCESS;
5334
5335 Assert(i < 2);
5336
5337 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5338 if (rc != VINF_SUCCESS)
5339 return rc;
5340 if (cb == 1)
5341 {
5342 rc = ataIOPortReadU8(pCtl, Port, pu32);
5343 }
5344 else if (Port == pCtl->IOPortBase1)
5345 {
5346 Assert(cb == 2 || cb == 4);
5347 rc = ataDataRead(pCtl, Port, cb, (uint8_t *)pu32);
5348 if (cb == 2)
5349 *pu32 &= 0xffff;
5350 }
5351 else
5352 {
5353 AssertMsgFailed(("ataIOPortRead1: unsupported read from port %x size=%d\n", Port, cb));
5354 rc = VERR_IOM_IOPORT_UNUSED;
5355 }
5356 PDMCritSectLeave(&pCtl->lock);
5357 return rc;
5358}
5359
5360#ifndef IN_RING0 /** @todo do this in ring-0 as well. */
5361/**
5362 * Port I/O Handler for primary port range IN string operations.
5363 * @see FNIOMIOPORTINSTRING for details.
5364 */
5365PDMBOTHCBDECL(int) ataIOPortReadStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb)
5366{
5367 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5368 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5369 PATACONTROLLER pCtl = &pThis->aCts[i];
5370 int rc = VINF_SUCCESS;
5371
5372 Assert(i < 2);
5373
5374 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5375 if (rc != VINF_SUCCESS)
5376 return rc;
5377 if (Port == pCtl->IOPortBase1)
5378 {
5379 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
5380 RTGCPTR GCDst = *pGCPtrDst;
5381 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
5382 Assert(cb == 2 || cb == 4);
5383
5384 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
5385#ifndef IN_RING3
5386 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
5387 cTransAvailable--;
5388#endif /* !IN_RING3 */
5389 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
5390 * They are not performance-critical and generally shouldn't occur at all. */
5391 if (cTransAvailable > cTransfer)
5392 cTransAvailable = cTransfer;
5393 cbTransfer = cTransAvailable * cb;
5394
5395 rc = PGMPhysSimpleDirtyWriteGCPtr(PDMDevHlpGetVMCPU(pDevIns), GCDst, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
5396 Assert(rc == VINF_SUCCESS);
5397
5398 if (cbTransfer)
5399 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
5400 s->iIOBufferPIODataStart += cbTransfer;
5401 *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
5402 *pcTransfer = cTransfer - cTransAvailable;
5403#ifdef IN_RING3
5404 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
5405 ataPIOTransferFinish(pCtl, s);
5406#endif /* IN_RING3 */
5407 }
5408 PDMCritSectLeave(&pCtl->lock);
5409 return rc;
5410}
5411
5412
5413/**
5414 * Port I/O Handler for primary port range OUT string operations.
5415 * @see FNIOMIOPORTOUTSTRING for details.
5416 */
5417PDMBOTHCBDECL(int) ataIOPortWriteStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)
5418{
5419 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5420 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5421 PATACONTROLLER pCtl = &pThis->aCts[i];
5422 int rc;
5423
5424 Assert(i < 2);
5425
5426 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5427 if (rc != VINF_SUCCESS)
5428 return rc;
5429 if (Port == pCtl->IOPortBase1)
5430 {
5431 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
5432 RTGCPTR GCSrc = *pGCPtrSrc;
5433 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
5434 Assert(cb == 2 || cb == 4);
5435
5436 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
5437#ifndef IN_RING3
5438 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
5439 cTransAvailable--;
5440#endif /* !IN_RING3 */
5441 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
5442 * They are not performance-critical and generally shouldn't occur at all. */
5443 if (cTransAvailable > cTransfer)
5444 cTransAvailable = cTransfer;
5445 cbTransfer = cTransAvailable * cb;
5446
5447 rc = PGMPhysSimpleReadGCPtr(PDMDevHlpGetVMCPU(pDevIns), s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
5448 Assert(rc == VINF_SUCCESS);
5449
5450 if (cbTransfer)
5451 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
5452 s->iIOBufferPIODataStart += cbTransfer;
5453 *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
5454 *pcTransfer = cTransfer - cTransAvailable;
5455#ifdef IN_RING3
5456 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
5457 ataPIOTransferFinish(pCtl, s);
5458#endif /* IN_RING3 */
5459 }
5460 PDMCritSectLeave(&pCtl->lock);
5461 return rc;
5462}
5463#endif /* !IN_RING0 */
5464
5465/**
5466 * Port I/O Handler for secondary port range OUT operations.
5467 * @see FNIOMIOPORTOUT for details.
5468 */
5469PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5470{
5471 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5472 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5473 PATACONTROLLER pCtl = &pThis->aCts[i];
5474 int rc;
5475
5476 Assert(i < 2);
5477
5478 if (cb != 1)
5479 return VINF_SUCCESS;
5480 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5481 if (rc != VINF_SUCCESS)
5482 return rc;
5483 rc = ataControlWrite(pCtl, Port, u32);
5484 PDMCritSectLeave(&pCtl->lock);
5485 return rc;
5486}
5487
5488
5489/**
5490 * Port I/O Handler for secondary port range IN operations.
5491 * @see FNIOMIOPORTIN for details.
5492 */
5493PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5494{
5495 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5496 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5497 PATACONTROLLER pCtl = &pThis->aCts[i];
5498 int rc;
5499
5500 Assert(i < 2);
5501
5502 if (cb != 1)
5503 return VERR_IOM_IOPORT_UNUSED;
5504
5505 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5506 if (rc != VINF_SUCCESS)
5507 return rc;
5508 *pu32 = ataStatusRead(pCtl, Port);
5509 PDMCritSectLeave(&pCtl->lock);
5510 return VINF_SUCCESS;
5511}
5512
5513#ifdef IN_RING3
5514
5515
5516DECLINLINE(void) ataRelocBuffer(PPDMDEVINS pDevIns, ATADevState *s)
5517{
5518 if (s->pbIOBufferR3)
5519 s->pbIOBufferRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), s->pbIOBufferR3);
5520}
5521
5522
5523/**
5524 * @copydoc FNPDMDEVRELOCATE
5525 */
5526static DECLCALLBACK(void) ataR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
5527{
5528 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5529
5530 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5531 {
5532 pThis->aCts[i].pDevInsRC += offDelta;
5533 pThis->aCts[i].aIfs[0].pDevInsRC += offDelta;
5534 pThis->aCts[i].aIfs[0].pControllerRC += offDelta;
5535 ataRelocBuffer(pDevIns, &pThis->aCts[i].aIfs[0]);
5536 pThis->aCts[i].aIfs[1].pDevInsRC += offDelta;
5537 pThis->aCts[i].aIfs[1].pControllerRC += offDelta;
5538 ataRelocBuffer(pDevIns, &pThis->aCts[i].aIfs[1]);
5539 }
5540}
5541
5542
5543/**
5544 * Destroy a driver instance.
5545 *
5546 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
5547 * resources can be freed correctly.
5548 *
5549 * @param pDevIns The device instance data.
5550 */
5551static DECLCALLBACK(int) ataR3Destruct(PPDMDEVINS pDevIns)
5552{
5553 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5554 int rc;
5555
5556 Log(("ataR3Destruct\n"));
5557
5558 /*
5559 * Tell the async I/O threads to terminate.
5560 */
5561 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5562 {
5563 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5564 {
5565 ASMAtomicWriteU32(&pThis->aCts[i].fShutdown, true);
5566 rc = RTSemEventSignal(pThis->aCts[i].AsyncIOSem);
5567 AssertRC(rc);
5568 }
5569 }
5570
5571 /*
5572 * Wait for the threads to terminate before destroying their resources.
5573 */
5574 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5575 {
5576 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5577 {
5578 rc = RTThreadWait(pThis->aCts[i].AsyncIOThread, 30000 /* 30 s*/, NULL);
5579 if (RT_SUCCESS(rc))
5580 pThis->aCts[i].AsyncIOThread = NIL_RTTHREAD;
5581 else
5582 LogRel(("PIIX3 ATA Dtor: Ctl#%u is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x rc=%Rrc\n",
5583 i, pThis->aCts[i].iSelectedIf, pThis->aCts[i].iAIOIf,
5584 pThis->aCts[i].aIfs[0].uATARegCommand, pThis->aCts[i].aIfs[1].uATARegCommand, rc));
5585 }
5586 }
5587
5588 /*
5589 * Free resources.
5590 */
5591 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5592 {
5593 if (pThis->aCts[i].AsyncIORequestMutex != NIL_RTSEMMUTEX)
5594 {
5595 RTSemMutexDestroy(pThis->aCts[i].AsyncIORequestMutex);
5596 pThis->aCts[i].AsyncIORequestMutex = NIL_RTSEMMUTEX;
5597 }
5598 if (pThis->aCts[i].AsyncIOSem != NIL_RTSEMEVENT)
5599 {
5600 RTSemEventDestroy(pThis->aCts[i].AsyncIOSem);
5601 pThis->aCts[i].AsyncIOSem = NIL_RTSEMEVENT;
5602 }
5603 if (pThis->aCts[i].SuspendIOSem != NIL_RTSEMEVENT)
5604 {
5605 RTSemEventDestroy(pThis->aCts[i].SuspendIOSem);
5606 pThis->aCts[i].SuspendIOSem = NIL_RTSEMEVENT;
5607 }
5608
5609 /* try one final time */
5610 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5611 {
5612 rc = RTThreadWait(pThis->aCts[i].AsyncIOThread, 1 /*ms*/, NULL);
5613 if (RT_SUCCESS(rc))
5614 {
5615 pThis->aCts[i].AsyncIOThread = NIL_RTTHREAD;
5616 LogRel(("PIIX3 ATA Dtor: Ctl#%u actually completed.\n", i));
5617 }
5618 }
5619 }
5620
5621 return VINF_SUCCESS;
5622}
5623
5624
5625/**
5626 * Detach notification.
5627 *
5628 * The DVD drive has been unplugged.
5629 *
5630 * @param pDevIns The device instance.
5631 * @param iLUN The logical unit which is being detached.
5632 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
5633 */
5634static DECLCALLBACK(void) ataR3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
5635{
5636 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5637 PATACONTROLLER pCtl;
5638 ATADevState *pIf;
5639 unsigned iController;
5640 unsigned iInterface;
5641
5642 AssertMsg(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
5643 ("PIIX3IDE: Device does not support hotplugging\n"));
5644
5645 /*
5646 * Locate the controller and stuff.
5647 */
5648 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5649 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5650 pCtl = &pThis->aCts[iController];
5651
5652 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5653 pIf = &pCtl->aIfs[iInterface];
5654
5655 /*
5656 * Zero some important members.
5657 */
5658 pIf->pDrvBase = NULL;
5659 pIf->pDrvBlock = NULL;
5660 pIf->pDrvBlockBios = NULL;
5661 pIf->pDrvMount = NULL;
5662
5663 /*
5664 * In case there was a medium inserted.
5665 */
5666 ataMediumRemoved(pIf);
5667}
5668
5669
5670/**
5671 * Configure a LUN.
5672 *
5673 * @returns VBox status code.
5674 * @param pDevIns The device instance.
5675 * @param pIf The ATA unit state.
5676 */
5677static int ataConfigLun(PPDMDEVINS pDevIns, ATADevState *pIf)
5678{
5679 int rc = VINF_SUCCESS;
5680 PDMBLOCKTYPE enmType;
5681
5682 /*
5683 * Query Block, Bios and Mount interfaces.
5684 */
5685 pIf->pDrvBlock = (PDMIBLOCK *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK);
5686 if (!pIf->pDrvBlock)
5687 {
5688 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
5689 return VERR_PDM_MISSING_INTERFACE;
5690 }
5691
5692 /** @todo implement the BIOS invisible code path. */
5693 pIf->pDrvBlockBios = (PDMIBLOCKBIOS *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK_BIOS);
5694 if (!pIf->pDrvBlockBios)
5695 {
5696 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pIf->iLUN));
5697 return VERR_PDM_MISSING_INTERFACE;
5698 }
5699 pIf->pDrvMount = (PDMIMOUNT *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_MOUNT);
5700
5701 /*
5702 * Validate type.
5703 */
5704 enmType = pIf->pDrvBlock->pfnGetType(pIf->pDrvBlock);
5705 if ( enmType != PDMBLOCKTYPE_CDROM
5706 && enmType != PDMBLOCKTYPE_DVD
5707 && enmType != PDMBLOCKTYPE_HARD_DISK)
5708 {
5709 AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
5710 return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
5711 }
5712 if ( ( enmType == PDMBLOCKTYPE_DVD
5713 || enmType == PDMBLOCKTYPE_CDROM)
5714 && !pIf->pDrvMount)
5715 {
5716 AssertMsgFailed(("Internal error: cdrom without a mountable interface, WTF???!\n"));
5717 return VERR_INTERNAL_ERROR;
5718 }
5719 pIf->fATAPI = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM;
5720 pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvBlock->pfnSendCmd != NULL) : false;
5721
5722 /*
5723 * Allocate I/O buffer.
5724 */
5725 PVM pVM = PDMDevHlpGetVM(pDevIns);
5726 if (pIf->cbIOBuffer)
5727 {
5728 /* Buffer is (probably) already allocated. Validate the fields,
5729 * because memory corruption can also overwrite pIf->cbIOBuffer. */
5730 if (pIf->fATAPI)
5731 AssertRelease(pIf->cbIOBuffer == _128K);
5732 else
5733 AssertRelease(pIf->cbIOBuffer == ATA_MAX_MULT_SECTORS * 512);
5734 Assert(pIf->pbIOBufferR3);
5735 Assert(pIf->pbIOBufferR0 == MMHyperR3ToR0(pVM, pIf->pbIOBufferR3));
5736 Assert(pIf->pbIOBufferRC == MMHyperR3ToRC(pVM, pIf->pbIOBufferR3));
5737 }
5738 else
5739 {
5740 if (pIf->fATAPI)
5741 pIf->cbIOBuffer = _128K;
5742 else
5743 pIf->cbIOBuffer = ATA_MAX_MULT_SECTORS * 512;
5744 Assert(!pIf->pbIOBufferR3);
5745 rc = MMR3HyperAllocOnceNoRel(pVM, pIf->cbIOBuffer, 0, MM_TAG_PDM_DEVICE_USER, (void **)&pIf->pbIOBufferR3);
5746 if (RT_FAILURE(rc))
5747 return VERR_NO_MEMORY;
5748 pIf->pbIOBufferR0 = MMHyperR3ToR0(pVM, pIf->pbIOBufferR3);
5749 pIf->pbIOBufferRC = MMHyperR3ToRC(pVM, pIf->pbIOBufferR3);
5750 }
5751
5752 /*
5753 * Init geometry (only for non-CD/DVD media).
5754 */
5755 if (pIf->fATAPI)
5756 {
5757 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
5758 pIf->PCHSGeometry.cCylinders = 0; /* dummy */
5759 pIf->PCHSGeometry.cHeads = 0; /* dummy */
5760 pIf->PCHSGeometry.cSectors = 0; /* dummy */
5761 LogRel(("PIIX3 ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));
5762 }
5763 else
5764 {
5765 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
5766 rc = pIf->pDrvBlockBios->pfnGetPCHSGeometry(pIf->pDrvBlockBios,
5767 &pIf->PCHSGeometry);
5768 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
5769 {
5770 pIf->PCHSGeometry.cCylinders = 0;
5771 pIf->PCHSGeometry.cHeads = 16; /*??*/
5772 pIf->PCHSGeometry.cSectors = 63; /*??*/
5773 }
5774 else if (rc == VERR_PDM_GEOMETRY_NOT_SET)
5775 {
5776 pIf->PCHSGeometry.cCylinders = 0; /* autodetect marker */
5777 rc = VINF_SUCCESS;
5778 }
5779 AssertRC(rc);
5780
5781 if ( pIf->PCHSGeometry.cCylinders == 0
5782 || pIf->PCHSGeometry.cHeads == 0
5783 || pIf->PCHSGeometry.cSectors == 0
5784 )
5785 {
5786 uint64_t cCylinders = pIf->cTotalSectors / (16 * 63);
5787 pIf->PCHSGeometry.cCylinders = RT_MAX(RT_MIN(cCylinders, 16383), 1);
5788 pIf->PCHSGeometry.cHeads = 16;
5789 pIf->PCHSGeometry.cSectors = 63;
5790 /* Set the disk geometry information. Ignore errors. */
5791 pIf->pDrvBlockBios->pfnSetPCHSGeometry(pIf->pDrvBlockBios,
5792 &pIf->PCHSGeometry);
5793 rc = VINF_SUCCESS;
5794 }
5795 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));
5796 }
5797 return rc;
5798}
5799
5800
5801/**
5802 * Attach command.
5803 *
5804 * This is called when we change block driver for the DVD drive.
5805 *
5806 * @returns VBox status code.
5807 * @param pDevIns The device instance.
5808 * @param iLUN The logical unit which is being detached.
5809 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
5810 */
5811static DECLCALLBACK(int) ataR3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
5812{
5813 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5814 PATACONTROLLER pCtl;
5815 ATADevState *pIf;
5816 int rc;
5817 unsigned iController;
5818 unsigned iInterface;
5819
5820 AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
5821 ("PIIX3IDE: Device does not support hotplugging\n"),
5822 VERR_INVALID_PARAMETER);
5823
5824 /*
5825 * Locate the controller and stuff.
5826 */
5827 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5828 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5829 pCtl = &pThis->aCts[iController];
5830
5831 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5832 pIf = &pCtl->aIfs[iInterface];
5833
5834 /* the usual paranoia */
5835 AssertRelease(!pIf->pDrvBase);
5836 AssertRelease(!pIf->pDrvBlock);
5837 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
5838 Assert(pIf->iLUN == iLUN);
5839
5840 /*
5841 * Try attach the block device and get the interfaces,
5842 * required as well as optional.
5843 */
5844 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
5845 if (RT_SUCCESS(rc))
5846 {
5847 rc = ataConfigLun(pDevIns, pIf);
5848 /*
5849 * In case there is a medium inserted.
5850 */
5851 ataMediumInserted(pIf);
5852 }
5853 else
5854 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Rrc\n", pIf->iLUN, rc));
5855
5856 if (RT_FAILURE(rc))
5857 {
5858 pIf->pDrvBase = NULL;
5859 pIf->pDrvBlock = NULL;
5860 }
5861 return rc;
5862}
5863
5864
5865/**
5866 * Resume notification.
5867 *
5868 * @returns VBox status.
5869 * @param pDevIns The device instance data.
5870 */
5871static DECLCALLBACK(void) ataR3Resume(PPDMDEVINS pDevIns)
5872{
5873 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5874 int rc;
5875
5876 Log(("%s:\n", __FUNCTION__));
5877 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5878 {
5879 if (pThis->aCts[i].fRedo && pThis->aCts[i].fRedoIdle)
5880 {
5881 rc = RTSemEventSignal(pThis->aCts[i].SuspendIOSem);
5882 AssertRC(rc);
5883 }
5884 }
5885 return;
5886}
5887
5888
5889/**
5890 * Checks if all (both) the async I/O threads have quiesced.
5891 *
5892 * @returns true on success.
5893 * @returns false when one or more threads is still processing.
5894 * @param pThis Pointer to the instance data.
5895 */
5896static bool ataR3AllAsyncIOIsIdle(PPDMDEVINS pDevIns)
5897{
5898 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5899
5900 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5901 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5902 {
5903 bool fRc = ataAsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/);
5904 if (!fRc)
5905 {
5906 /* Make it signal PDM & itself when its done */
5907 RTSemMutexRequest(pThis->aCts[i].AsyncIORequestMutex, RT_INDEFINITE_WAIT);
5908 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, true);
5909 RTSemMutexRelease(pThis->aCts[i].AsyncIORequestMutex);
5910 fRc = ataAsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/);
5911 if (!fRc)
5912 {
5913#if 0 /** @todo Need to do some time tracking here... */
5914 LogRel(("PIIX3 ATA: Ctl#%u is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",
5915 i, pThis->aCts[i].iSelectedIf, pThis->aCts[i].iAIOIf,
5916 pThis->aCts[i].aIfs[0].uATARegCommand, pThis->aCts[i].aIfs[1].uATARegCommand));
5917#endif
5918 return false;
5919 }
5920 }
5921 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, false);
5922 }
5923 return true;
5924}
5925
5926
5927/**
5928 * Callback employed by ataSuspend and ataR3PowerOff.
5929 *
5930 * @returns true if we've quiesced, false if we're still working.
5931 * @param pDevIns The device instance.
5932 */
5933static DECLCALLBACK(bool) ataR3IsAsyncSuspendOrPowerOffDone(PPDMDEVINS pDevIns)
5934{
5935 return ataR3AllAsyncIOIsIdle(pDevIns);
5936}
5937
5938
5939/**
5940 * Common worker for ataSuspend and ataR3PowerOff.
5941 */
5942static void ataR3SuspendOrPowerOff(PPDMDEVINS pDevIns)
5943{
5944 if (!ataR3AllAsyncIOIsIdle(pDevIns))
5945 PDMDevHlpSetAsyncNotification(pDevIns, ataR3IsAsyncSuspendOrPowerOffDone);
5946}
5947
5948
5949/**
5950 * Power Off notification.
5951 *
5952 * @returns VBox status.
5953 * @param pDevIns The device instance data.
5954 */
5955static DECLCALLBACK(void) ataR3PowerOff(PPDMDEVINS pDevIns)
5956{
5957 Log(("%s:\n", __FUNCTION__));
5958 ataR3SuspendOrPowerOff(pDevIns);
5959}
5960
5961
5962/**
5963 * Suspend notification.
5964 *
5965 * @returns VBox status.
5966 * @param pDevIns The device instance data.
5967 */
5968static DECLCALLBACK(void) ataR3Suspend(PPDMDEVINS pDevIns)
5969{
5970 Log(("%s:\n", __FUNCTION__));
5971 ataR3SuspendOrPowerOff(pDevIns);
5972}
5973
5974
5975/**
5976 * Callback employed by ataR3Reset.
5977 *
5978 * @returns true if we've quiesced, false if we're still working.
5979 * @param pDevIns The device instance.
5980 */
5981static DECLCALLBACK(bool) ataR3IsAsyncResetDone(PPDMDEVINS pDevIns)
5982{
5983 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5984
5985 if (!ataR3AllAsyncIOIsIdle(pDevIns))
5986 return false;
5987
5988 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5989 {
5990 PDMCritSectEnter(&pThis->aCts[i].lock, VERR_INTERNAL_ERROR);
5991 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
5992 ataResetDevice(&pThis->aCts[i].aIfs[j]);
5993 PDMCritSectLeave(&pThis->aCts[i].lock);
5994 }
5995 return true;
5996}
5997
5998
5999/**
6000 * Common reset worker for ataR3Reset and ataR3Construct.
6001 *
6002 * @returns VBox status.
6003 * @param pDevIns The device instance data.
6004 * @param fConstruct Indicates who is calling.
6005 */
6006static int ataR3ResetCommon(PPDMDEVINS pDevIns, bool fConstruct)
6007{
6008 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6009
6010 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6011 {
6012 PDMCritSectEnter(&pThis->aCts[i].lock, VERR_INTERNAL_ERROR);
6013
6014 pThis->aCts[i].iSelectedIf = 0;
6015 pThis->aCts[i].iAIOIf = 0;
6016 pThis->aCts[i].BmDma.u8Cmd = 0;
6017 /* Report that both drives present on the bus are in DMA mode. This
6018 * pretends that there is a BIOS that has set it up. Normal reset
6019 * default is 0x00. */
6020 pThis->aCts[i].BmDma.u8Status = (pThis->aCts[i].aIfs[0].pDrvBase != NULL ? BM_STATUS_D0DMA : 0)
6021 | (pThis->aCts[i].aIfs[1].pDrvBase != NULL ? BM_STATUS_D1DMA : 0);
6022 pThis->aCts[i].BmDma.pvAddr = 0;
6023
6024 pThis->aCts[i].fReset = true;
6025 pThis->aCts[i].fRedo = false;
6026 pThis->aCts[i].fRedoIdle = false;
6027 ataAsyncIOClearRequests(&pThis->aCts[i]);
6028 Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i));
6029 ataAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetARequest);
6030 ataAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetCRequest);
6031
6032 PDMCritSectLeave(&pThis->aCts[i].lock);
6033 }
6034
6035 int rcRet = VINF_SUCCESS;
6036 if (!fConstruct)
6037 {
6038 /*
6039 * Setup asynchronous notification compmletion if the requests haven't
6040 * completed yet.
6041 */
6042 if (!ataR3IsAsyncResetDone(pDevIns))
6043 PDMDevHlpSetAsyncNotification(pDevIns, ataR3IsAsyncResetDone);
6044 }
6045 else
6046 {
6047 /*
6048 * Wait for the requests for complete.
6049 *
6050 * Would be real nice if we could do it all from EMT(0) and not
6051 * involve the worker threads, then we could dispense with all the
6052 * waiting and semaphore ping-pong here...
6053 */
6054 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6055 {
6056 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
6057 {
6058 int rc = RTSemMutexRequest(pThis->aCts[i].AsyncIORequestMutex, RT_INDEFINITE_WAIT);
6059 AssertRC(rc);
6060
6061 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, true);
6062 rc = RTThreadUserReset(pThis->aCts[i].AsyncIOThread);
6063 AssertRC(rc);
6064
6065 rc = RTSemMutexRelease(pThis->aCts[i].AsyncIORequestMutex);
6066 AssertRC(rc);
6067
6068 if (!ataAsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/))
6069 {
6070 rc = RTThreadUserWait(pThis->aCts[i].AsyncIOThread, 30*1000 /*ms*/);
6071 if (RT_FAILURE(rc))
6072 rc = RTThreadUserWait(pThis->aCts[i].AsyncIOThread, 1000 /*ms*/);
6073 if (RT_FAILURE(rc))
6074 {
6075 AssertRC(rc);
6076 rcRet = rc;
6077 }
6078 }
6079 }
6080 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, false);
6081 }
6082 if (RT_SUCCESS(rcRet))
6083 {
6084 rcRet = ataR3IsAsyncResetDone(pDevIns) ? VINF_SUCCESS : VERR_INTERNAL_ERROR;
6085 AssertRC(rcRet);
6086 }
6087 }
6088 return rcRet;
6089}
6090
6091
6092/**
6093 * Reset notification.
6094 *
6095 * @param pDevIns The device instance data.
6096 */
6097static DECLCALLBACK(void) ataR3Reset(PPDMDEVINS pDevIns)
6098{
6099 ataR3ResetCommon(pDevIns, false /*fConstruct*/);
6100}
6101
6102
6103/**
6104 * Prepare state save and load operation.
6105 *
6106 * @returns VBox status code.
6107 * @param pDevIns Device instance of the device which registered the data unit.
6108 * @param pSSM SSM operation handle.
6109 */
6110static DECLCALLBACK(int) ataSaveLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
6111{
6112 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6113
6114 /* sanity - the suspend notification will wait on the async stuff. */
6115 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6116 AssertLogRelMsgReturn(ataAsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/),
6117 ("i=%u\n", i),
6118 VERR_SSM_IDE_ASYNC_TIMEOUT);
6119 return VINF_SUCCESS;
6120}
6121
6122/**
6123 * @copydoc FNSSMDEVLIVEEXEC
6124 */
6125static DECLCALLBACK(int) ataLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
6126{
6127 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6128
6129 SSMR3PutU8(pSSM, pThis->u8Type);
6130 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6131 {
6132 SSMR3PutBool(pSSM, true); /* For controller enabled / disabled. */
6133 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6134 {
6135 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].pDrvBase != NULL);
6136 SSMR3PutStrZ(pSSM, pThis->aCts[i].aIfs[j].szSerialNumber);
6137 SSMR3PutStrZ(pSSM, pThis->aCts[i].aIfs[j].szFirmwareRevision);
6138 SSMR3PutStrZ(pSSM, pThis->aCts[i].aIfs[j].szModelNumber);
6139 }
6140 }
6141
6142 return VINF_SSM_DONT_CALL_AGAIN;
6143}
6144
6145
6146/**
6147 * @copydoc FNSSMDEVSAVEEXEC
6148 */
6149static DECLCALLBACK(int) ataSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
6150{
6151 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6152
6153 ataLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
6154
6155 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6156 {
6157 SSMR3PutU8(pSSM, pThis->aCts[i].iSelectedIf);
6158 SSMR3PutU8(pSSM, pThis->aCts[i].iAIOIf);
6159 SSMR3PutU8(pSSM, pThis->aCts[i].uAsyncIOState);
6160 SSMR3PutBool(pSSM, pThis->aCts[i].fChainedTransfer);
6161 SSMR3PutBool(pSSM, pThis->aCts[i].fReset);
6162 SSMR3PutBool(pSSM, pThis->aCts[i].fRedo);
6163 SSMR3PutBool(pSSM, pThis->aCts[i].fRedoIdle);
6164 SSMR3PutBool(pSSM, pThis->aCts[i].fRedoDMALastDesc);
6165 SSMR3PutMem(pSSM, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
6166 SSMR3PutGCPhys32(pSSM, pThis->aCts[i].pFirstDMADesc);
6167 SSMR3PutGCPhys32(pSSM, pThis->aCts[i].pLastDMADesc);
6168 SSMR3PutGCPhys32(pSSM, pThis->aCts[i].pRedoDMABuffer);
6169 SSMR3PutU32(pSSM, pThis->aCts[i].cbRedoDMABuffer);
6170
6171 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6172 {
6173 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fLBA48);
6174 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fATAPI);
6175 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fIrqPending);
6176 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].cMultSectors);
6177 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
6178 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
6179 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
6180 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
6181 SSMR3PutU64(pSSM, pThis->aCts[i].aIfs[j].cTotalSectors);
6182 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegFeature);
6183 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
6184 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegError);
6185 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegNSector);
6186 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
6187 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegSector);
6188 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegSectorHOB);
6189 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegLCyl);
6190 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegLCylHOB);
6191 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegHCyl);
6192 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegHCylHOB);
6193 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegSelect);
6194 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegStatus);
6195 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegCommand);
6196 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegDevCtl);
6197 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATATransferMode);
6198 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uTxDir);
6199 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].iBeginTransfer);
6200 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].iSourceSink);
6201 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fDMA);
6202 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fATAPITransfer);
6203 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbTotalTransfer);
6204 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbElementaryTransfer);
6205 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferCur);
6206 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferEnd);
6207 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
6208 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
6209 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iATAPILBA);
6210 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbATAPISector);
6211 SSMR3PutMem(pSSM, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
6212 SSMR3PutMem(pSSM, &pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6213 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
6214 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].MediaEventStatus);
6215 SSMR3PutMem(pSSM, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
6216 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbIOBuffer);
6217 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
6218 SSMR3PutMem(pSSM, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
6219 else
6220 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
6221 }
6222 }
6223
6224 return SSMR3PutU32(pSSM, ~0); /* sanity/terminator */
6225}
6226
6227/**
6228 * Converts the LUN number into a message string.
6229 */
6230static const char *ataStringifyLun(unsigned iLun)
6231{
6232 switch (iLun)
6233 {
6234 case 0: return "primary master";
6235 case 1: return "primary slave";
6236 case 2: return "secondary master";
6237 case 3: return "secondary slave";
6238 default: AssertFailedReturn("unknown lun");
6239 }
6240}
6241
6242/**
6243 * FNSSMDEVLOADEXEC
6244 */
6245static DECLCALLBACK(int) ataLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
6246{
6247 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6248 int rc;
6249 uint32_t u32;
6250
6251 if ( uVersion != ATA_SAVED_STATE_VERSION
6252 && uVersion != ATA_SAVED_STATE_VERSION_VBOX_30
6253 && uVersion != ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE
6254 && uVersion != ATA_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS
6255 && uVersion != ATA_SAVED_STATE_VERSION_WITH_BOOL_TYPE)
6256 {
6257 AssertMsgFailed(("uVersion=%d\n", uVersion));
6258 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
6259 }
6260
6261 /*
6262 * Verify the configuration.
6263 */
6264 if (uVersion > ATA_SAVED_STATE_VERSION_VBOX_30)
6265 {
6266 uint8_t u8Type;
6267 rc = SSMR3GetU8(pSSM, &u8Type);
6268 AssertRCReturn(rc, rc);
6269 if (u8Type != pThis->u8Type)
6270 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch: u8Type - saved=%u config=%u"), u8Type, pThis->u8Type);
6271
6272 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6273 {
6274 bool fEnabled;
6275 rc = SSMR3GetBool(pSSM, &fEnabled);
6276 AssertRCReturn(rc, rc);
6277 if (!fEnabled)
6278 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Ctr#%u onfig mismatch: fEnabled != true"), i);
6279
6280 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6281 {
6282 ATADevState const *pIf = &pThis->aCts[i].aIfs[j];
6283
6284 bool fInUse;
6285 rc = SSMR3GetBool(pSSM, &fInUse);
6286 AssertRCReturn(rc, rc);
6287 if (fInUse != (pIf->pDrvBase != NULL))
6288 return SSMR3SetCfgError(pSSM, RT_SRC_POS,
6289 N_("The %s VM is missing a %s device. Please make sure the source and target VMs have compatible storage configurations"),
6290 fInUse ? "target" : "source", ataStringifyLun(pIf->iLUN) );
6291
6292 char szSerialNumber[ATA_SERIAL_NUMBER_LENGTH+1];
6293 rc = SSMR3GetStrZ(pSSM, szSerialNumber, sizeof(szSerialNumber));
6294 AssertRCReturn(rc, rc);
6295 if (strcmp(szSerialNumber, pIf->szSerialNumber))
6296 LogRel(("PIIX3 ATA: LUN#%u config mismatch: Serial number - saved='%s' config='%s'\n",
6297 pIf->iLUN, szSerialNumber, pIf->szSerialNumber));
6298
6299 char szFirmwareRevision[ATA_FIRMWARE_REVISION_LENGTH+1];
6300 rc = SSMR3GetStrZ(pSSM, szFirmwareRevision, sizeof(szFirmwareRevision));
6301 AssertRCReturn(rc, rc);
6302 if (strcmp(szFirmwareRevision, pIf->szFirmwareRevision))
6303 LogRel(("PIIX3 ATA: LUN#%u config mismatch: Firmware revision - saved='%s' config='%s'\n",
6304 pIf->iLUN, szFirmwareRevision, pIf->szFirmwareRevision));
6305
6306 char szModelNumber[ATA_MODEL_NUMBER_LENGTH+1];
6307 rc = SSMR3GetStrZ(pSSM, szModelNumber, sizeof(szModelNumber));
6308 AssertRCReturn(rc, rc);
6309 if (strcmp(szModelNumber, pIf->szModelNumber))
6310 LogRel(("PIIX3 ATA: LUN#%u config mismatch: Model number - saved='%s' config='%s'\n",
6311 pIf->iLUN, szModelNumber, pIf->szModelNumber));
6312 }
6313 }
6314 }
6315 if (uPass != SSM_PASS_FINAL)
6316 return VINF_SUCCESS;
6317
6318 /*
6319 * Restore valid parts of the PCIATAState structure
6320 */
6321 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6322 {
6323 /* integrity check */
6324 if (!ataAsyncIOIsIdle(&pThis->aCts[i], false))
6325 {
6326 AssertMsgFailed(("Async I/O for controller %d is active\n", i));
6327 return VERR_INTERNAL_ERROR_4;
6328 }
6329
6330 SSMR3GetU8(pSSM, &pThis->aCts[i].iSelectedIf);
6331 SSMR3GetU8(pSSM, &pThis->aCts[i].iAIOIf);
6332 SSMR3GetU8(pSSM, &pThis->aCts[i].uAsyncIOState);
6333 SSMR3GetBool(pSSM, &pThis->aCts[i].fChainedTransfer);
6334 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fReset);
6335 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fRedo);
6336 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fRedoIdle);
6337 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fRedoDMALastDesc);
6338 SSMR3GetMem(pSSM, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
6339 SSMR3GetGCPhys32(pSSM, &pThis->aCts[i].pFirstDMADesc);
6340 SSMR3GetGCPhys32(pSSM, &pThis->aCts[i].pLastDMADesc);
6341 SSMR3GetGCPhys32(pSSM, &pThis->aCts[i].pRedoDMABuffer);
6342 SSMR3GetU32(pSSM, &pThis->aCts[i].cbRedoDMABuffer);
6343
6344 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6345 {
6346 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fLBA48);
6347 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fATAPI);
6348 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fIrqPending);
6349 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].cMultSectors);
6350 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
6351 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
6352 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
6353 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
6354 SSMR3GetU64(pSSM, &pThis->aCts[i].aIfs[j].cTotalSectors);
6355 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegFeature);
6356 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
6357 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegError);
6358 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegNSector);
6359 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
6360 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegSector);
6361 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegSectorHOB);
6362 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegLCyl);
6363 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegLCylHOB);
6364 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegHCyl);
6365 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegHCylHOB);
6366 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegSelect);
6367 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegStatus);
6368 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegCommand);
6369 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegDevCtl);
6370 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATATransferMode);
6371 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uTxDir);
6372 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].iBeginTransfer);
6373 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].iSourceSink);
6374 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fDMA);
6375 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fATAPITransfer);
6376 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbTotalTransfer);
6377 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbElementaryTransfer);
6378 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferCur);
6379 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferEnd);
6380 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
6381 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
6382 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iATAPILBA);
6383 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbATAPISector);
6384 SSMR3GetMem(pSSM, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
6385 if (uVersion > ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE)
6386 {
6387 SSMR3GetMem(pSSM, pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6388 }
6389 else
6390 {
6391 uint8_t uATAPISenseKey, uATAPIASC;
6392 memset(pThis->aCts[i].aIfs[j].abATAPISense, '\0', sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6393 pThis->aCts[i].aIfs[j].abATAPISense[0] = 0x70 | (1 << 7);
6394 pThis->aCts[i].aIfs[j].abATAPISense[7] = 10;
6395 SSMR3GetU8(pSSM, &uATAPISenseKey);
6396 SSMR3GetU8(pSSM, &uATAPIASC);
6397 pThis->aCts[i].aIfs[j].abATAPISense[2] = uATAPISenseKey & 0x0f;
6398 pThis->aCts[i].aIfs[j].abATAPISense[12] = uATAPIASC;
6399 }
6400 /** @todo triple-check this hack after passthrough is working */
6401 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
6402 if (uVersion > ATA_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS)
6403 SSMR3GetU32(pSSM, (uint32_t*)&pThis->aCts[i].aIfs[j].MediaEventStatus);
6404 else
6405 pThis->aCts[i].aIfs[j].MediaEventStatus = ATA_EVENT_STATUS_UNCHANGED;
6406 SSMR3GetMem(pSSM, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
6407 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbIOBuffer);
6408 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
6409 {
6410 if (pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer))
6411 SSMR3GetMem(pSSM, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
6412 else
6413 {
6414 LogRel(("ATA: No buffer for %d/%d\n", i, j));
6415 if (SSMR3HandleGetAfter(pSSM) != SSMAFTER_DEBUG_IT)
6416 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("No buffer for %d/%d"), i, j);
6417
6418 /* skip the buffer if we're loading for the debugger / animator. */
6419 uint8_t u8Ignored;
6420 size_t cbLeft = pThis->aCts[i].aIfs[j].cbIOBuffer;
6421 while (cbLeft-- > 0)
6422 SSMR3GetU8(pSSM, &u8Ignored);
6423 }
6424 }
6425 else
6426 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
6427 }
6428 }
6429 if (uVersion <= ATA_SAVED_STATE_VERSION_VBOX_30)
6430 SSMR3GetU8(pSSM, &pThis->u8Type);
6431
6432 rc = SSMR3GetU32(pSSM, &u32);
6433 if (RT_FAILURE(rc))
6434 return rc;
6435 if (u32 != ~0U)
6436 {
6437 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
6438 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
6439 return rc;
6440 }
6441
6442 return VINF_SUCCESS;
6443}
6444
6445/**
6446 * Convert config value to DEVPCBIOSBOOT.
6447 *
6448 * @returns VBox status code.
6449 * @param pDevIns The device instance data.
6450 * @param pCfgHandle Configuration handle.
6451 * @param penmChipset Where to store the chipset type.
6452 */
6453static int ataControllerFromCfg(PPDMDEVINS pDevIns, PCFGMNODE pCfgHandle, CHIPSET *penmChipset)
6454{
6455 char szType[20];
6456
6457 int rc = CFGMR3QueryStringDef(pCfgHandle, "Type", &szType[0], sizeof(szType), "PIIX4");
6458 if (RT_FAILURE(rc))
6459 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
6460 N_("Configuration error: Querying \"Type\" as a string failed"));
6461 if (!strcmp(szType, "PIIX3"))
6462 *penmChipset = CHIPSET_PIIX3;
6463 else if (!strcmp(szType, "PIIX4"))
6464 *penmChipset = CHIPSET_PIIX4;
6465 else if (!strcmp(szType, "ICH6"))
6466 *penmChipset = CHIPSET_ICH6;
6467 else
6468 {
6469 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
6470 N_("Configuration error: The \"Type\" value \"%s\" is unknown"),
6471 szType);
6472 rc = VERR_INTERNAL_ERROR;
6473 }
6474 return rc;
6475}
6476
6477
6478/**
6479 * Construct a device instance for a VM.
6480 *
6481 * @returns VBox status.
6482 * @param pDevIns The device instance data.
6483 * If the registration structure is needed, pDevIns->pDevReg points to it.
6484 * @param iInstance Instance number. Use this to figure out which registers and such to use.
6485 * The device number is also found in pDevIns->iInstance, but since it's
6486 * likely to be freqently used PDM passes it as parameter.
6487 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
6488 * of the device instance. It's also found in pDevIns->pCfgHandle, but like
6489 * iInstance it's expected to be used a bit in this function.
6490 */
6491static DECLCALLBACK(int) ataR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
6492{
6493 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6494 PPDMIBASE pBase;
6495 int rc;
6496 bool fGCEnabled;
6497 bool fR0Enabled;
6498 uint32_t DelayIRQMillies;
6499
6500 Assert(iInstance == 0);
6501
6502 /*
6503 * Initialize NIL handle values (for the destructor).
6504 */
6505 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6506 {
6507 pThis->aCts[i].AsyncIOSem = NIL_RTSEMEVENT;
6508 pThis->aCts[i].SuspendIOSem = NIL_RTSEMEVENT;
6509 pThis->aCts[i].AsyncIORequestMutex = NIL_RTSEMMUTEX;
6510 pThis->aCts[i].AsyncIOThread = NIL_RTTHREAD;
6511 }
6512
6513 /*
6514 * Validate and read configuration.
6515 */
6516 if (!CFGMR3AreValuesValid(pCfgHandle,
6517 "GCEnabled\0"
6518 "R0Enabled\0"
6519 "IRQDelay\0"
6520 "Type\0")
6521 /** @todo || invalid keys */)
6522 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
6523 N_("PIIX3 configuration error: unknown option specified"));
6524
6525 rc = CFGMR3QueryBoolDef(pCfgHandle, "GCEnabled", &fGCEnabled, true);
6526 if (RT_FAILURE(rc))
6527 return PDMDEV_SET_ERROR(pDevIns, rc,
6528 N_("PIIX3 configuration error: failed to read GCEnabled as boolean"));
6529 Log(("%s: fGCEnabled=%d\n", __FUNCTION__, fGCEnabled));
6530
6531 rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &fR0Enabled, true);
6532 if (RT_FAILURE(rc))
6533 return PDMDEV_SET_ERROR(pDevIns, rc,
6534 N_("PIIX3 configuration error: failed to read R0Enabled as boolean"));
6535 Log(("%s: fR0Enabled=%d\n", __FUNCTION__, fR0Enabled));
6536
6537 rc = CFGMR3QueryU32Def(pCfgHandle, "IRQDelay", &DelayIRQMillies, 0);
6538 if (RT_FAILURE(rc))
6539 return PDMDEV_SET_ERROR(pDevIns, rc,
6540 N_("PIIX3 configuration error: failed to read IRQDelay as integer"));
6541 Log(("%s: DelayIRQMillies=%d\n", __FUNCTION__, DelayIRQMillies));
6542 Assert(DelayIRQMillies < 50);
6543
6544 CHIPSET enmChipset = CHIPSET_PIIX3;
6545 rc = ataControllerFromCfg(pDevIns, pCfgHandle, &enmChipset);
6546 if (RT_FAILURE(rc))
6547 return rc;
6548 pThis->u8Type = (uint8_t)enmChipset;
6549
6550 /*
6551 * Initialize data (most of it anyway).
6552 */
6553 /* Status LUN. */
6554 pThis->IBase.pfnQueryInterface = ataStatus_QueryInterface;
6555 pThis->ILeds.pfnQueryStatusLed = ataStatus_QueryStatusLed;
6556
6557 /* PCI configuration space. */
6558 PCIDevSetVendorId(&pThis->dev, 0x8086); /* Intel */
6559
6560 /*
6561 * When adding more IDE chipsets, don't forget to update pci_bios_init_device()
6562 * as it explicitly checks for PCI id for IDE controllers.
6563 */
6564 switch (pThis->u8Type)
6565 {
6566 case CHIPSET_ICH6:
6567 PCIDevSetDeviceId(&pThis->dev, 0x269e); /* ICH6 IDE */
6568 /** @todo: do we need it? Do we need anything else? */
6569 pThis->dev.config[0x48] = 0x00; /* UDMACTL */
6570 pThis->dev.config[0x4A] = 0x00; /* UDMATIM */
6571 pThis->dev.config[0x4B] = 0x00;
6572 {
6573 /*
6574 * See www.intel.com/Assets/PDF/manual/298600.pdf p. 30
6575 * Report
6576 * WR_Ping-Pong_EN: must be set
6577 * PCR0, PCR1: 80-pin primary cable reporting for both disks
6578 * SCR0, SCR1: 80-pin secondary cable reporting for both disks
6579 */
6580 uint16_t u16Config = (1<<10) | (1<<7) | (1<<6) | (1<<5) | (1<<4) ;
6581 pThis->dev.config[0x54] = u16Config & 0xff;
6582 pThis->dev.config[0x55] = u16Config >> 8;
6583 }
6584 break;
6585 case CHIPSET_PIIX4:
6586 PCIDevSetDeviceId(&pThis->dev, 0x7111); /* PIIX4 IDE */
6587 PCIDevSetRevisionId(&pThis->dev, 0x01); /* PIIX4E */
6588 pThis->dev.config[0x48] = 0x00; /* UDMACTL */
6589 pThis->dev.config[0x4A] = 0x00; /* UDMATIM */
6590 pThis->dev.config[0x4B] = 0x00;
6591 break;
6592 case CHIPSET_PIIX3:
6593 PCIDevSetDeviceId(&pThis->dev, 0x7010); /* PIIX3 IDE */
6594 break;
6595 default:
6596 AssertMsgFailed(("Unsupported IDE chipset type: %d\n", pThis->u8Type));
6597 }
6598
6599 PCIDevSetCommand( &pThis->dev, PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER);
6600 PCIDevSetClassProg( &pThis->dev, 0x8a); /* programming interface = PCI_IDE bus master is supported */
6601 PCIDevSetClassSub( &pThis->dev, 0x01); /* class_sub = PCI_IDE */
6602 PCIDevSetClassBase( &pThis->dev, 0x01); /* class_base = PCI_mass_storage */
6603 PCIDevSetHeaderType(&pThis->dev, 0x00);
6604
6605 pThis->pDevIns = pDevIns;
6606 pThis->fGCEnabled = fGCEnabled;
6607 pThis->fR0Enabled = fR0Enabled;
6608 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6609 {
6610 pThis->aCts[i].pDevInsR3 = pDevIns;
6611 pThis->aCts[i].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
6612 pThis->aCts[i].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
6613 pThis->aCts[i].DelayIRQMillies = (uint32_t)DelayIRQMillies;
6614 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6615 {
6616 ATADevState *pIf = &pThis->aCts[i].aIfs[j];
6617
6618 pIf->iLUN = i * RT_ELEMENTS(pThis->aCts) + j;
6619 pIf->pDevInsR3 = pDevIns;
6620 pIf->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
6621 pIf->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
6622 pIf->pControllerR3 = &pThis->aCts[i];
6623 pIf->pControllerR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
6624 pIf->pControllerRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
6625 pIf->IBase.pfnQueryInterface = ataQueryInterface;
6626 pIf->IMountNotify.pfnMountNotify = ataMountNotify;
6627 pIf->IMountNotify.pfnUnmountNotify = ataUnmountNotify;
6628 pIf->Led.u32Magic = PDMLED_MAGIC;
6629 }
6630 }
6631
6632 Assert(RT_ELEMENTS(pThis->aCts) == 2);
6633 pThis->aCts[0].irq = 14;
6634 pThis->aCts[0].IOPortBase1 = 0x1f0;
6635 pThis->aCts[0].IOPortBase2 = 0x3f6;
6636 pThis->aCts[1].irq = 15;
6637 pThis->aCts[1].IOPortBase1 = 0x170;
6638 pThis->aCts[1].IOPortBase2 = 0x376;
6639
6640 /*
6641 * Register the PCI device.
6642 * N.B. There's a hack in the PIIX3 PCI bridge device to assign this
6643 * device the slot next to itself.
6644 */
6645 rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev);
6646 if (RT_FAILURE(rc))
6647 return PDMDEV_SET_ERROR(pDevIns, rc,
6648 N_("PIIX3 cannot register PCI device"));
6649 AssertMsg(pThis->dev.devfn == 9 || iInstance != 0, ("pThis->dev.devfn=%d\n", pThis->dev.devfn));
6650 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataBMDMAIORangeMap);
6651 if (RT_FAILURE(rc))
6652 return PDMDEV_SET_ERROR(pDevIns, rc,
6653 N_("PIIX3 cannot register PCI I/O region for BMDMA"));
6654
6655 /*
6656 * Register the I/O ports.
6657 * The ports are all hardcoded and enforced by the PIIX3 host bridge controller.
6658 */
6659 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6660 {
6661 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTHCPTR)i,
6662 ataIOPortWrite1, ataIOPortRead1, ataIOPortWriteStr1, ataIOPortReadStr1, "ATA I/O Base 1");
6663 if (RT_FAILURE(rc))
6664 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers"));
6665
6666 if (fGCEnabled)
6667 {
6668 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTGCPTR)i,
6669 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
6670 if (RT_FAILURE(rc))
6671 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers (GC)"));
6672 }
6673
6674 if (fR0Enabled)
6675 {
6676#if 1
6677 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
6678 "ataIOPortWrite1", "ataIOPortRead1", NULL, NULL, "ATA I/O Base 1");
6679#else
6680 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
6681 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
6682#endif
6683 if (RT_FAILURE(rc))
6684 return PDMDEV_SET_ERROR(pDevIns, rc, "PIIX3 cannot register I/O handlers (R0).");
6685 }
6686
6687 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTHCPTR)i,
6688 ataIOPortWrite2, ataIOPortRead2, NULL, NULL, "ATA I/O Base 2");
6689 if (RT_FAILURE(rc))
6690 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers"));
6691
6692 if (fGCEnabled)
6693 {
6694 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTGCPTR)i,
6695 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
6696 if (RT_FAILURE(rc))
6697 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (GC)"));
6698 }
6699 if (fR0Enabled)
6700 {
6701 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTR0PTR)i,
6702 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
6703 if (RT_FAILURE(rc))
6704 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (R0)"));
6705 }
6706
6707 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6708 {
6709 ATADevState *pIf = &pThis->aCts[i].aIfs[j];
6710 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATADMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
6711 "Number of ATA DMA transfers.", "/Devices/IDE%d/ATA%d/Unit%d/DMA", iInstance, i, j);
6712 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
6713 "Number of ATA PIO transfers.", "/Devices/IDE%d/ATA%d/Unit%d/PIO", iInstance, i, j);
6714 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIDMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
6715 "Number of ATAPI DMA transfers.", "/Devices/IDE%d/ATA%d/Unit%d/AtapiDMA", iInstance, i, j);
6716 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
6717 "Number of ATAPI PIO transfers.", "/Devices/IDE%d/ATA%d/Unit%d/AtapiPIO", iInstance, i, j);
6718#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
6719 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatReads, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
6720 "Profiling of the read operations.", "/Devices/IDE%d/ATA%d/Unit%d/Reads", iInstance, i, j);
6721#endif
6722 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesRead, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
6723 "Amount of data read.", "/Devices/IDE%d/ATA%d/Unit%d/ReadBytes", iInstance, i, j);
6724#ifdef VBOX_INSTRUMENT_DMA_WRITES
6725 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatInstrVDWrites,STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
6726 "Profiling of the VD DMA write operations.", "/Devices/IDE%d/ATA%d/Unit%d/InstrVDWrites", iInstance, i, j);
6727#endif
6728#ifdef VBOX_WITH_STATISTICS
6729 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatWrites, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
6730 "Profiling of the write operations.", "/Devices/IDE%d/ATA%d/Unit%d/Writes", iInstance, i, j);
6731#endif
6732 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
6733 "Amount of data written.", "/Devices/IDE%d/ATA%d/Unit%d/WrittenBytes", iInstance, i, j);
6734#ifdef VBOX_WITH_STATISTICS
6735 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatFlushes, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
6736 "Profiling of the flush operations.", "/Devices/IDE%d/ATA%d/Unit%d/Flushes", iInstance, i, j);
6737#endif
6738 }
6739#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
6740 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncOps, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
6741 "The number of async operations.", "/Devices/IDE%d/ATA%d/Async/Operations", iInstance, i);
6742 /** @todo STAMUNIT_MICROSECS */
6743 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMinWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
6744 "Minimum wait in microseconds.", "/Devices/IDE%d/ATA%d/Async/MinWait", iInstance, i);
6745 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMaxWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
6746 "Maximum wait in microseconds.", "/Devices/IDE%d/ATA%d/Async/MaxWait", iInstance, i);
6747 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncTimeUS, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
6748 "Total time spent in microseconds.", "/Devices/IDE%d/ATA%d/Async/TotalTimeUS", iInstance, i);
6749 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncTime, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
6750 "Profiling of async operations.", "/Devices/IDE%d/ATA%d/Async/Time", iInstance, i);
6751 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatLockWait, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
6752 "Profiling of locks.", "/Devices/IDE%d/ATA%d/Async/LockWait", iInstance, i);
6753#endif /* VBOX_WITH_STATISTICS */
6754
6755 /* Initialize per-controller critical section */
6756 char szName[24];
6757 RTStrPrintf(szName, sizeof(szName), "ATA%d", i);
6758 rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].lock, szName);
6759 if (RT_FAILURE(rc))
6760 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot initialize critical section"));
6761 }
6762
6763 /*
6764 * Attach status driver (optional).
6765 */
6766 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pBase, "Status Port");
6767 if (RT_SUCCESS(rc))
6768 pThis->pLedsConnector = (PDMILEDCONNECTORS *)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS);
6769 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
6770 {
6771 AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc));
6772 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot attach to status driver"));
6773 }
6774
6775 /*
6776 * Attach the units.
6777 */
6778 uint32_t cbTotalBuffer = 0;
6779 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6780 {
6781 PATACONTROLLER pCtl = &pThis->aCts[i];
6782
6783 /*
6784 * Start the worker thread.
6785 */
6786 pCtl->uAsyncIOState = ATA_AIO_NEW;
6787 rc = RTSemEventCreate(&pCtl->AsyncIOSem);
6788 AssertLogRelRCReturn(rc, rc);
6789 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
6790 AssertLogRelRCReturn(rc, rc);
6791 rc = RTSemMutexCreate(&pCtl->AsyncIORequestMutex);
6792 AssertLogRelRCReturn(rc, rc);
6793 ataAsyncIOClearRequests(pCtl);
6794 rc = RTThreadCreateF(&pCtl->AsyncIOThread, ataAsyncIOLoop, (void *)pCtl, 128*1024 /*cbStack*/,
6795 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "ATA-%u", i);
6796 AssertLogRelRCReturn(rc, rc);
6797 Assert(pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->AsyncIOSem != NIL_RTSEMEVENT && pCtl->SuspendIOSem != NIL_RTSEMEVENT && pCtl->AsyncIORequestMutex != NIL_RTSEMMUTEX);
6798 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));
6799
6800 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
6801 {
6802 static const char *s_apszDescs[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
6803 {
6804 { "Primary Master", "Primary Slave" },
6805 { "Secondary Master", "Secondary Slave" }
6806 };
6807
6808 /*
6809 * Try attach the block device and get the interfaces,
6810 * required as well as optional.
6811 */
6812 ATADevState *pIf = &pCtl->aIfs[j];
6813
6814 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, s_apszDescs[i][j]);
6815 if (RT_SUCCESS(rc))
6816 {
6817 rc = ataConfigLun(pDevIns, pIf);
6818 if (RT_SUCCESS(rc))
6819 {
6820 /*
6821 * Init vendor product data.
6822 */
6823 static const char *s_apszCFGMKeys[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
6824 {
6825 { "PrimaryMaster", "PrimarySlave" },
6826 { "SecondaryMaster", "SecondarySlave" }
6827 };
6828
6829 /* Generate a default serial number. */
6830 char szSerial[ATA_SERIAL_NUMBER_LENGTH+1];
6831 RTUUID Uuid;
6832 if (pIf->pDrvBlock)
6833 rc = pIf->pDrvBlock->pfnGetUuid(pIf->pDrvBlock, &Uuid);
6834 else
6835 RTUuidClear(&Uuid);
6836
6837 if (RT_FAILURE(rc) || RTUuidIsNull(&Uuid))
6838 {
6839 /* Generate a predictable serial for drives which don't have a UUID. */
6840 RTStrPrintf(szSerial, sizeof(szSerial), "VB%x-%04x%04x",
6841 pIf->iLUN + pDevIns->iInstance * 32,
6842 pThis->aCts[i].IOPortBase1, pThis->aCts[i].IOPortBase2);
6843 }
6844 else
6845 RTStrPrintf(szSerial, sizeof(szSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
6846
6847 /* Get user config if present using defaults otherwise. */
6848 PCFGMNODE pCfgNode = CFGMR3GetChild(pCfgHandle, s_apszCFGMKeys[i][j]);
6849 rc = CFGMR3QueryStringDef(pCfgNode, "SerialNumber", pIf->szSerialNumber, sizeof(pIf->szSerialNumber),
6850 szSerial);
6851 if (RT_FAILURE(rc))
6852 {
6853 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
6854 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
6855 N_("PIIX3 configuration error: \"SerialNumber\" is longer than 20 bytes"));
6856 return PDMDEV_SET_ERROR(pDevIns, rc,
6857 N_("PIIX3 configuration error: failed to read \"SerialNumber\" as string"));
6858 }
6859
6860 rc = CFGMR3QueryStringDef(pCfgNode, "FirmwareRevision", pIf->szFirmwareRevision, sizeof(pIf->szFirmwareRevision),
6861 "1.0");
6862 if (RT_FAILURE(rc))
6863 {
6864 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
6865 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
6866 N_("PIIX3 configuration error: \"FirmwareRevision\" is longer than 8 bytes"));
6867 return PDMDEV_SET_ERROR(pDevIns, rc,
6868 N_("PIIX3 configuration error: failed to read \"FirmwareRevision\" as string"));
6869 }
6870
6871 rc = CFGMR3QueryStringDef(pCfgNode, "ModelNumber", pIf->szModelNumber, sizeof(pIf->szModelNumber),
6872 pIf->fATAPI ? "VBOX CD-ROM" : "VBOX HARDDISK");
6873 if (RT_FAILURE(rc))
6874 {
6875 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
6876 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
6877 N_("PIIX3 configuration error: \"ModelNumber\" is longer than 40 bytes"));
6878 return PDMDEV_SET_ERROR(pDevIns, rc,
6879 N_("PIIX3 configuration error: failed to read \"ModelNumber\" as string"));
6880 }
6881
6882 /* There are three other identification strings for CD drives used for INQUIRY */
6883 if (pIf->fATAPI)
6884 {
6885 rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIVendorId", pIf->szInquiryVendorId, sizeof(pIf->szInquiryVendorId),
6886 "VBOX");
6887 if (RT_FAILURE(rc))
6888 {
6889 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
6890 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
6891 N_("PIIX3 configuration error: \"ATAPIVendorId\" is longer than 16 bytes"));
6892 return PDMDEV_SET_ERROR(pDevIns, rc,
6893 N_("PIIX3 configuration error: failed to read \"ATAPIVendorId\" as string"));
6894 }
6895
6896 rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIProductId", pIf->szInquiryProductId, sizeof(pIf->szInquiryProductId),
6897 "CD-ROM");
6898 if (RT_FAILURE(rc))
6899 {
6900 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
6901 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
6902 N_("PIIX3 configuration error: \"ATAPIProductId\" is longer than 16 bytes"));
6903 return PDMDEV_SET_ERROR(pDevIns, rc,
6904 N_("PIIX3 configuration error: failed to read \"ATAPIProductId\" as string"));
6905 }
6906
6907 rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIRevision", pIf->szInquiryRevision, sizeof(pIf->szInquiryRevision),
6908 "1.0");
6909 if (RT_FAILURE(rc))
6910 {
6911 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
6912 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
6913 N_("PIIX3 configuration error: \"ATAPIRevision\" is longer than 4 bytes"));
6914 return PDMDEV_SET_ERROR(pDevIns, rc,
6915 N_("PIIX3 configuration error: failed to read \"ATAPIRevision\" as string"));
6916 }
6917 }
6918 }
6919
6920 }
6921 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
6922 {
6923 pIf->pDrvBase = NULL;
6924 pIf->pDrvBlock = NULL;
6925 pIf->cbIOBuffer = 0;
6926 pIf->pbIOBufferR3 = NULL;
6927 pIf->pbIOBufferR0 = NIL_RTR0PTR;
6928 pIf->pbIOBufferRC = NIL_RTGCPTR;
6929 LogRel(("PIIX3 ATA: LUN#%d: no unit\n", pIf->iLUN));
6930 }
6931 else
6932 {
6933 switch (rc)
6934 {
6935 case VERR_ACCESS_DENIED:
6936 /* Error already catched by DrvHostBase */
6937 return rc;
6938 default:
6939 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
6940 N_("PIIX3 cannot attach drive to the %s"),
6941 s_apszDescs[i][j]);
6942 }
6943 }
6944 cbTotalBuffer += pIf->cbIOBuffer;
6945 }
6946 }
6947
6948 rc = PDMDevHlpSSMRegisterEx(pDevIns, ATA_SAVED_STATE_VERSION, sizeof(*pThis) + cbTotalBuffer, NULL,
6949 NULL, ataLiveExec, NULL,
6950 ataSaveLoadPrep, ataSaveExec, NULL,
6951 ataSaveLoadPrep, ataLoadExec, NULL);
6952 if (RT_FAILURE(rc))
6953 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register save state handlers"));
6954
6955 /*
6956 * Initialize the device state.
6957 */
6958 return ataR3ResetCommon(pDevIns, true /*fConstruct*/);
6959}
6960
6961
6962/**
6963 * The device registration structure.
6964 */
6965const PDMDEVREG g_DevicePIIX3IDE =
6966{
6967 /* u32Version */
6968 PDM_DEVREG_VERSION,
6969 /* szDeviceName */
6970 "piix3ide",
6971 /* szRCMod */
6972 "VBoxDDGC.gc",
6973 /* szR0Mod */
6974 "VBoxDDR0.r0",
6975 /* pszDescription */
6976 "Intel PIIX3 ATA controller.\n"
6977 " LUN #0 is primary master.\n"
6978 " LUN #1 is primary slave.\n"
6979 " LUN #2 is secondary master.\n"
6980 " LUN #3 is secondary slave.\n"
6981 " LUN #999 is the LED/Status connector.",
6982 /* fFlags */
6983 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
6984 PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION,
6985 /* fClass */
6986 PDM_DEVREG_CLASS_STORAGE,
6987 /* cMaxInstances */
6988 1,
6989 /* cbInstance */
6990 sizeof(PCIATAState),
6991 /* pfnConstruct */
6992 ataR3Construct,
6993 /* pfnDestruct */
6994 ataR3Destruct,
6995 /* pfnRelocate */
6996 ataR3Relocate,
6997 /* pfnIOCtl */
6998 NULL,
6999 /* pfnPowerOn */
7000 NULL,
7001 /* pfnReset */
7002 ataR3Reset,
7003 /* pfnSuspend */
7004 ataR3Suspend,
7005 /* pfnResume */
7006 ataR3Resume,
7007 /* pfnAttach */
7008 ataR3Attach,
7009 /* pfnDetach */
7010 ataR3Detach,
7011 /* pfnQueryInterface. */
7012 NULL,
7013 /* pfnInitComplete */
7014 NULL,
7015 /* pfnPowerOff */
7016 ataR3PowerOff,
7017 /* pfnSoftReset */
7018 NULL,
7019 /* u32VersionEnd */
7020 PDM_DEVREG_VERSION
7021};
7022#endif /* IN_RING3 */
7023#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Note: See TracBrowser for help on using the repository browser.

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