VirtualBox

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

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

PDM: s/szDeviceName/szName/g - PDMDEVREG & PDMUSBREG.

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

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