VirtualBox

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

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

DevATA: Simplified non-present device port read handling.

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