VirtualBox

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

Last change on this file since 40912 was 40841, checked in by vboxsync, 13 years ago

Storage/ATA: Fix CD/DVD passthrough and Session At Once (SAO) recording by saving the CUE sheet and determining the correct sector sizes during recording

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