VirtualBox

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

Last change on this file since 36337 was 36337, checked in by vboxsync, 14 years ago

DevATA: Disable feature list for now because it breaks at least Windows XP

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

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