VirtualBox

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

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

For ATAPI devices, fail recalibrate and clear DRDY on aborted commands.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 278.3 KB
Line 
1/* $Id: DevATA.cpp 38664 2011-09-06 16:11:24Z 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
4006static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4007{
4008 Log2(("%s: write addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
4009 addr &= 7;
4010 switch (addr)
4011 {
4012 case 0:
4013 break;
4014 case 1: /* feature register */
4015 /* NOTE: data is written to the two drives */
4016 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4017 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4018 pCtl->aIfs[0].uATARegFeatureHOB = pCtl->aIfs[0].uATARegFeature;
4019 pCtl->aIfs[1].uATARegFeatureHOB = pCtl->aIfs[1].uATARegFeature;
4020 pCtl->aIfs[0].uATARegFeature = val;
4021 pCtl->aIfs[1].uATARegFeature = val;
4022 break;
4023 case 2: /* sector count */
4024 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4025 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4026 pCtl->aIfs[0].uATARegNSectorHOB = pCtl->aIfs[0].uATARegNSector;
4027 pCtl->aIfs[1].uATARegNSectorHOB = pCtl->aIfs[1].uATARegNSector;
4028 pCtl->aIfs[0].uATARegNSector = val;
4029 pCtl->aIfs[1].uATARegNSector = val;
4030 break;
4031 case 3: /* sector number */
4032 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4033 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4034 pCtl->aIfs[0].uATARegSectorHOB = pCtl->aIfs[0].uATARegSector;
4035 pCtl->aIfs[1].uATARegSectorHOB = pCtl->aIfs[1].uATARegSector;
4036 pCtl->aIfs[0].uATARegSector = val;
4037 pCtl->aIfs[1].uATARegSector = val;
4038 break;
4039 case 4: /* cylinder low */
4040 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4041 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4042 pCtl->aIfs[0].uATARegLCylHOB = pCtl->aIfs[0].uATARegLCyl;
4043 pCtl->aIfs[1].uATARegLCylHOB = pCtl->aIfs[1].uATARegLCyl;
4044 pCtl->aIfs[0].uATARegLCyl = val;
4045 pCtl->aIfs[1].uATARegLCyl = val;
4046 break;
4047 case 5: /* cylinder high */
4048 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4049 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
4050 pCtl->aIfs[0].uATARegHCylHOB = pCtl->aIfs[0].uATARegHCyl;
4051 pCtl->aIfs[1].uATARegHCylHOB = pCtl->aIfs[1].uATARegHCyl;
4052 pCtl->aIfs[0].uATARegHCyl = val;
4053 pCtl->aIfs[1].uATARegHCyl = val;
4054 break;
4055 case 6: /* drive/head */
4056 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0;
4057 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0;
4058 if (((val >> 4) & 1) != pCtl->iSelectedIf)
4059 {
4060 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
4061
4062 /* select another drive */
4063 pCtl->iSelectedIf = (val >> 4) & 1;
4064 /* The IRQ line is multiplexed between the two drives, so
4065 * update the state when switching to another drive. Only need
4066 * to update interrupt line if it is enabled and there is a
4067 * state change. */
4068 if ( !(pCtl->aIfs[pCtl->iSelectedIf].uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ)
4069 && ( pCtl->aIfs[pCtl->iSelectedIf].fIrqPending
4070 != pCtl->aIfs[pCtl->iSelectedIf ^ 1].fIrqPending))
4071 {
4072 if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
4073 {
4074 Log2(("%s: LUN#%d asserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4075 /* The BMDMA unit unconditionally sets BM_STATUS_INT if
4076 * the interrupt line is asserted. It monitors the line
4077 * for a rising edge. */
4078 pCtl->BmDma.u8Status |= BM_STATUS_INT;
4079 if (pCtl->irq == 16)
4080 PDMDevHlpPCISetIrq(pDevIns, 0, 1);
4081 else
4082 PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 1);
4083 }
4084 else
4085 {
4086 Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4087 if (pCtl->irq == 16)
4088 PDMDevHlpPCISetIrq(pDevIns, 0, 0);
4089 else
4090 PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 0);
4091 }
4092 }
4093 }
4094 break;
4095 default:
4096 case 7: /* command */
4097 /* ignore commands to non existant slave */
4098 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
4099 break;
4100#ifndef IN_RING3
4101 /* Don't do anything complicated in GC */
4102 return VINF_IOM_HC_IOPORT_WRITE;
4103#else /* IN_RING3 */
4104 ataParseCmd(&pCtl->aIfs[pCtl->iSelectedIf], val);
4105#endif /* !IN_RING3 */
4106 }
4107 return VINF_SUCCESS;
4108}
4109
4110
4111static int ataIOPortReadU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32)
4112{
4113 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4114 uint32_t val;
4115 bool fHOB;
4116
4117 fHOB = !!(s->uATARegDevCtl & (1 << 7));
4118 switch (addr & 7)
4119 {
4120 case 0: /* data register */
4121 val = 0xff;
4122 break;
4123 case 1: /* error register */
4124 /* The ATA specification is very terse when it comes to specifying
4125 * the precise effects of reading back the error/feature register.
4126 * The error register (read-only) shares the register number with
4127 * the feature register (write-only), so it seems that it's not
4128 * necessary to support the usual HOB readback here. */
4129 if (!s->pDrvBlock)
4130 val = 0;
4131 else
4132 val = s->uATARegError;
4133 break;
4134 case 2: /* sector count */
4135 if (!s->pDrvBlock)
4136 val = 0;
4137 else if (fHOB)
4138 val = s->uATARegNSectorHOB;
4139 else
4140 val = s->uATARegNSector;
4141 break;
4142 case 3: /* sector number */
4143 if (!s->pDrvBlock)
4144 val = 0;
4145 else if (fHOB)
4146 val = s->uATARegSectorHOB;
4147 else
4148 val = s->uATARegSector;
4149 break;
4150 case 4: /* cylinder low */
4151 if (!s->pDrvBlock)
4152 val = 0;
4153 else if (fHOB)
4154 val = s->uATARegLCylHOB;
4155 else
4156 val = s->uATARegLCyl;
4157 break;
4158 case 5: /* cylinder high */
4159 if (!s->pDrvBlock)
4160 val = 0;
4161 else if (fHOB)
4162 val = s->uATARegHCylHOB;
4163 else
4164 val = s->uATARegHCyl;
4165 break;
4166 case 6: /* drive/head */
4167 /* This register must always work as long as there is at least
4168 * one drive attached to the controller. It is common between
4169 * both drives anyway (completely identical content). */
4170 if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
4171 val = 0;
4172 else
4173 val = s->uATARegSelect;
4174 break;
4175 default:
4176 case 7: /* primary status */
4177 {
4178 /* Counter for number of busy status seen in GC in a row. */
4179 static unsigned cBusy = 0;
4180
4181 if (!s->pDrvBlock)
4182 val = 0;
4183 else
4184 val = s->uATARegStatus;
4185
4186 /* Give the async I/O thread an opportunity to make progress,
4187 * don't let it starve by guests polling frequently. EMT has a
4188 * lower priority than the async I/O thread, but sometimes the
4189 * host OS doesn't care. With some guests we are only allowed to
4190 * be busy for about 5 milliseconds in some situations. Note that
4191 * this is no guarantee for any other VBox thread getting
4192 * scheduled, so this just lowers the CPU load a bit when drives
4193 * are busy. It cannot help with timing problems. */
4194 if (val & ATA_STAT_BUSY)
4195 {
4196#ifdef IN_RING3
4197 cBusy = 0;
4198 PDMCritSectLeave(&pCtl->lock);
4199
4200#ifndef RT_OS_WINDOWS
4201 /*
4202 * The thread might be stuck in an I/O operation
4203 * due to a high I/O load on the host. (see @bugref{3301})
4204 * To perform the reset successfully
4205 * we interrupt the operation by sending a signal to the thread
4206 * if the thread didn't responded in 10ms.
4207 * This works only on POSIX hosts (Windows has a CancelSynchronousIo function which
4208 * does the same but it was introduced with Vista) but so far
4209 * this hang was only observed on Linux and Mac OS X.
4210 *
4211 * This is a workaround and needs to be solved properly.
4212 */
4213 if (pCtl->fReset)
4214 {
4215 uint64_t u64ResetTimeStop = RTTimeMilliTS();
4216
4217 if ((u64ResetTimeStop - pCtl->u64ResetTime) >= 10)
4218 {
4219 LogRel(("PIIX3 ATA: Async I/O thread probably stuck in operation, interrupting\n"));
4220 pCtl->u64ResetTime = u64ResetTimeStop;
4221 RTThreadPoke(pCtl->AsyncIOThread);
4222 }
4223 }
4224#endif
4225
4226 RTThreadYield();
4227
4228 {
4229 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4230 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4231 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4232 }
4233
4234 val = s->uATARegStatus;
4235#else /* !IN_RING3 */
4236 /* Cannot yield CPU in guest context. And switching to host
4237 * context for each and every busy status is too costly,
4238 * especially on SMP systems where we don't gain much by
4239 * yielding the CPU to someone else. */
4240 if (++cBusy >= 20)
4241 {
4242 cBusy = 0;
4243 return VINF_IOM_HC_IOPORT_READ;
4244 }
4245#endif /* !IN_RING3 */
4246 }
4247 else
4248 cBusy = 0;
4249 ataUnsetIRQ(s);
4250 break;
4251 }
4252 }
4253 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
4254 *pu32 = val;
4255 return VINF_SUCCESS;
4256}
4257
4258
4259static uint32_t ataStatusRead(PATACONTROLLER pCtl, uint32_t addr)
4260{
4261 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4262 uint32_t val;
4263
4264 if ((!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock) ||
4265 (pCtl->iSelectedIf == 1 && !s->pDrvBlock))
4266 val = 0;
4267 else
4268 val = s->uATARegStatus;
4269 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
4270 return val;
4271}
4272
4273static int ataControlWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4274{
4275#ifndef IN_RING3
4276 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_RESET)
4277 return VINF_IOM_HC_IOPORT_WRITE; /* The RESET stuff is too complicated for GC. */
4278#endif /* !IN_RING3 */
4279
4280 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
4281 /* RESET is common for both drives attached to a controller. */
4282 if (!(pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
4283 (val & ATA_DEVCTL_RESET))
4284 {
4285#ifdef IN_RING3
4286 /* Software RESET low to high */
4287 int32_t uCmdWait0 = -1, uCmdWait1 = -1;
4288 uint64_t uNow = RTTimeNanoTS();
4289 if (pCtl->aIfs[0].u64CmdTS)
4290 uCmdWait0 = (uNow - pCtl->aIfs[0].u64CmdTS) / 1000;
4291 if (pCtl->aIfs[1].u64CmdTS)
4292 uCmdWait1 = (uNow - pCtl->aIfs[1].u64CmdTS) / 1000;
4293 LogRel(("PIIX3 ATA: Ctl#%d: RESET, DevSel=%d AIOIf=%d CmdIf0=%#04x (%d usec ago) CmdIf1=%#04x (%d usec ago)\n",
4294 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
4295 pCtl->aIfs[0].uATARegCommand, uCmdWait0,
4296 pCtl->aIfs[1].uATARegCommand, uCmdWait1));
4297 pCtl->fReset = true;
4298 /* Everything must be done after the reset flag is set, otherwise
4299 * there are unavoidable races with the currently executing request
4300 * (which might just finish in the mean time). */
4301 pCtl->fChainedTransfer = false;
4302 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4303 {
4304 ataResetDevice(&pCtl->aIfs[i]);
4305 /* The following cannot be done using ataSetStatusValue() since the
4306 * reset flag is already set, which suppresses all status changes. */
4307 pCtl->aIfs[i].uATARegStatus = ATA_STAT_BUSY | ATA_STAT_SEEK;
4308 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, pCtl->aIfs[i].iLUN, pCtl->aIfs[i].uATARegStatus));
4309 pCtl->aIfs[i].uATARegError = 0x01;
4310 }
4311 ataAsyncIOClearRequests(pCtl);
4312 Log2(("%s: Ctl#%d: message to async I/O thread, resetA\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4313 if (val & ATA_DEVCTL_HOB)
4314 {
4315 val &= ~ATA_DEVCTL_HOB;
4316 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
4317 }
4318
4319 /* Save the timestamp we started the reset. */
4320 pCtl->u64ResetTime = RTTimeMilliTS();
4321
4322 /* Issue the reset request now. */
4323 ataAsyncIOPutRequest(pCtl, &g_ataResetARequest);
4324#else /* !IN_RING3 */
4325 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
4326#endif /* IN_RING3 */
4327 }
4328 else if ((pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
4329 !(val & ATA_DEVCTL_RESET))
4330 {
4331#ifdef IN_RING3
4332 /* Software RESET high to low */
4333 Log(("%s: deasserting RESET\n", __FUNCTION__));
4334 Log2(("%s: Ctl#%d: message to async I/O thread, resetC\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4335 if (val & ATA_DEVCTL_HOB)
4336 {
4337 val &= ~ATA_DEVCTL_HOB;
4338 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
4339 }
4340 ataAsyncIOPutRequest(pCtl, &g_ataResetCRequest);
4341#else /* !IN_RING3 */
4342 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
4343#endif /* IN_RING3 */
4344 }
4345
4346 /* Change of interrupt disable flag. Update interrupt line if interrupt
4347 * is pending on the current interface. */
4348 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_DISABLE_IRQ
4349 && pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
4350 {
4351 if (!(val & ATA_DEVCTL_DISABLE_IRQ))
4352 {
4353 Log2(("%s: LUN#%d asserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4354 /* The BMDMA unit unconditionally sets BM_STATUS_INT if the
4355 * interrupt line is asserted. It monitors the line for a rising
4356 * edge. */
4357 pCtl->BmDma.u8Status |= BM_STATUS_INT;
4358 if (pCtl->irq == 16)
4359 PDMDevHlpPCISetIrq(CONTROLLER_2_DEVINS(pCtl), 0, 1);
4360 else
4361 PDMDevHlpISASetIrq(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 1);
4362 }
4363 else
4364 {
4365 Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
4366 if (pCtl->irq == 16)
4367 PDMDevHlpPCISetIrq(CONTROLLER_2_DEVINS(pCtl), 0, 0);
4368 else
4369 PDMDevHlpISASetIrq(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 0);
4370 }
4371 }
4372
4373 if (val & ATA_DEVCTL_HOB)
4374 Log2(("%s: set HOB\n", __FUNCTION__));
4375
4376 pCtl->aIfs[0].uATARegDevCtl = val;
4377 pCtl->aIfs[1].uATARegDevCtl = val;
4378
4379 return VINF_SUCCESS;
4380}
4381
4382#ifdef IN_RING3
4383
4384static void ataPIOTransfer(PATACONTROLLER pCtl)
4385{
4386 ATADevState *s;
4387
4388 s = &pCtl->aIfs[pCtl->iAIOIf];
4389 Log3(("%s: if=%p\n", __FUNCTION__, s));
4390
4391 if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
4392 {
4393 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"));
4394 /* Any guest OS that triggers this case has a pathetic ATA driver.
4395 * In a real system it would block the CPU via IORDY, here we do it
4396 * very similarly by not continuing with the current instruction
4397 * until the transfer to/from the storage medium is completed. */
4398 if (s->iSourceSink != ATAFN_SS_NULL)
4399 {
4400 bool fRedo;
4401 uint8_t status = s->uATARegStatus;
4402 ataSetStatusValue(s, ATA_STAT_BUSY);
4403 Log2(("%s: calling source/sink function\n", __FUNCTION__));
4404 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4405 pCtl->fRedo = fRedo;
4406 if (RT_UNLIKELY(fRedo))
4407 return;
4408 ataSetStatusValue(s, status);
4409 s->iIOBufferCur = 0;
4410 s->iIOBufferEnd = s->cbElementaryTransfer;
4411 }
4412 }
4413 if (s->cbTotalTransfer)
4414 {
4415 if (s->fATAPITransfer)
4416 ataPIOTransferLimitATAPI(s);
4417
4418 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
4419 s->cbElementaryTransfer = s->cbTotalTransfer;
4420
4421 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
4422 __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
4423 s->cbTotalTransfer, s->cbElementaryTransfer,
4424 s->iIOBufferCur, s->iIOBufferEnd));
4425 ataPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
4426 s->cbTotalTransfer -= s->cbElementaryTransfer;
4427 s->iIOBufferCur += s->cbElementaryTransfer;
4428
4429 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
4430 s->cbElementaryTransfer = s->cbTotalTransfer;
4431 }
4432 else
4433 ataPIOTransferStop(s);
4434}
4435
4436
4437DECLINLINE(void) ataPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
4438{
4439 /* Do not interfere with RESET processing if the PIO transfer finishes
4440 * while the RESET line is asserted. */
4441 if (pCtl->fReset)
4442 {
4443 Log2(("%s: Ctl#%d: suppressed continuing PIO transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4444 return;
4445 }
4446
4447 if ( s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE
4448 || ( s->iSourceSink != ATAFN_SS_NULL
4449 && s->iIOBufferCur >= s->iIOBufferEnd))
4450 {
4451 /* Need to continue the transfer in the async I/O thread. This is
4452 * the case for write operations or generally for not yet finished
4453 * transfers (some data might need to be read). */
4454 ataUnsetStatus(s, ATA_STAT_READY | ATA_STAT_DRQ);
4455 ataSetStatus(s, ATA_STAT_BUSY);
4456
4457 Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4458 ataAsyncIOPutRequest(pCtl, &g_ataPIORequest);
4459 }
4460 else
4461 {
4462 /* Either everything finished (though some data might still be pending)
4463 * or some data is pending before the next read is due. */
4464
4465 /* Continue a previously started transfer. */
4466 ataUnsetStatus(s, ATA_STAT_DRQ);
4467 ataSetStatus(s, ATA_STAT_READY);
4468
4469 if (s->cbTotalTransfer)
4470 {
4471 /* There is more to transfer, happens usually for large ATAPI
4472 * reads - the protocol limits the chunk size to 65534 bytes. */
4473 ataPIOTransfer(pCtl);
4474 ataSetIRQ(s);
4475 }
4476 else
4477 {
4478 Log2(("%s: Ctl#%d: skipping message to async I/O thread, ending PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4479 /* Finish PIO transfer. */
4480 ataPIOTransfer(pCtl);
4481 Assert(!pCtl->fRedo);
4482 }
4483 }
4484}
4485
4486#endif /* IN_RING3 */
4487
4488static int ataDataWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf)
4489{
4490 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4491 uint8_t *p;
4492
4493 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
4494 {
4495 Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE);
4496 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
4497#ifndef IN_RING3
4498 /* All but the last transfer unit is simple enough for GC, but
4499 * sending a request to the async IO thread is too complicated. */
4500 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
4501 {
4502 memcpy(p, pbBuf, cbSize);
4503 s->iIOBufferPIODataStart += cbSize;
4504 }
4505 else
4506 return VINF_IOM_HC_IOPORT_WRITE;
4507#else /* IN_RING3 */
4508 memcpy(p, pbBuf, cbSize);
4509 s->iIOBufferPIODataStart += cbSize;
4510 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4511 ataPIOTransferFinish(pCtl, s);
4512#endif /* !IN_RING3 */
4513 }
4514 else
4515 Log2(("%s: DUMMY data\n", __FUNCTION__));
4516 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
4517 return VINF_SUCCESS;
4518}
4519
4520static int ataDataRead(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, uint8_t *pbBuf)
4521{
4522 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4523 uint8_t *p;
4524
4525 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
4526 {
4527 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
4528 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
4529#ifndef IN_RING3
4530 /* All but the last transfer unit is simple enough for GC, but
4531 * sending a request to the async IO thread is too complicated. */
4532 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
4533 {
4534 memcpy(pbBuf, p, cbSize);
4535 s->iIOBufferPIODataStart += cbSize;
4536 }
4537 else
4538 return VINF_IOM_HC_IOPORT_READ;
4539#else /* IN_RING3 */
4540 memcpy(pbBuf, p, cbSize);
4541 s->iIOBufferPIODataStart += cbSize;
4542 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4543 ataPIOTransferFinish(pCtl, s);
4544#endif /* !IN_RING3 */
4545 }
4546 else
4547 {
4548 Log2(("%s: DUMMY data\n", __FUNCTION__));
4549 memset(pbBuf, '\xff', cbSize);
4550 }
4551 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
4552 return VINF_SUCCESS;
4553}
4554
4555#ifdef IN_RING3
4556
4557static void ataDMATransferStop(ATADevState *s)
4558{
4559 s->cbTotalTransfer = 0;
4560 s->cbElementaryTransfer = 0;
4561 s->iBeginTransfer = ATAFN_BT_NULL;
4562 s->iSourceSink = ATAFN_SS_NULL;
4563}
4564
4565
4566/**
4567 * Perform the entire DMA transfer in one go (unless a source/sink operation
4568 * has to be redone or a RESET comes in between). Unlike the PIO counterpart
4569 * this function cannot handle empty transfers.
4570 *
4571 * @param pCtl Controller for which to perform the transfer.
4572 */
4573static void ataDMATransfer(PATACONTROLLER pCtl)
4574{
4575 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
4576 ATADevState *s = &pCtl->aIfs[pCtl->iAIOIf];
4577 bool fRedo;
4578 RTGCPHYS32 pDesc;
4579 uint32_t cbTotalTransfer, cbElementaryTransfer;
4580 uint32_t iIOBufferCur, iIOBufferEnd;
4581 uint32_t dmalen;
4582 PDMBLOCKTXDIR uTxDir;
4583 bool fLastDesc = false;
4584
4585 Assert(sizeof(BMDMADesc) == 8);
4586
4587 fRedo = pCtl->fRedo;
4588 if (RT_LIKELY(!fRedo))
4589 Assert(s->cbTotalTransfer);
4590 uTxDir = (PDMBLOCKTXDIR)s->uTxDir;
4591 cbTotalTransfer = s->cbTotalTransfer;
4592 cbElementaryTransfer = s->cbElementaryTransfer;
4593 iIOBufferCur = s->iIOBufferCur;
4594 iIOBufferEnd = s->iIOBufferEnd;
4595
4596 /* The DMA loop is designed to hold the lock only when absolutely
4597 * necessary. This avoids long freezes should the guest access the
4598 * ATA registers etc. for some reason. */
4599 PDMCritSectLeave(&pCtl->lock);
4600
4601 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
4602 __FUNCTION__, uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
4603 cbTotalTransfer, cbElementaryTransfer,
4604 iIOBufferCur, iIOBufferEnd));
4605 for (pDesc = pCtl->pFirstDMADesc; pDesc <= pCtl->pLastDMADesc; pDesc += sizeof(BMDMADesc))
4606 {
4607 BMDMADesc DMADesc;
4608 RTGCPHYS32 pBuffer;
4609 uint32_t cbBuffer;
4610
4611 if (RT_UNLIKELY(fRedo))
4612 {
4613 pBuffer = pCtl->pRedoDMABuffer;
4614 cbBuffer = pCtl->cbRedoDMABuffer;
4615 fLastDesc = pCtl->fRedoDMALastDesc;
4616 }
4617 else
4618 {
4619 PDMDevHlpPhysRead(pDevIns, pDesc, &DMADesc, sizeof(BMDMADesc));
4620 pBuffer = RT_LE2H_U32(DMADesc.pBuffer);
4621 cbBuffer = RT_LE2H_U32(DMADesc.cbBuffer);
4622 fLastDesc = !!(cbBuffer & 0x80000000);
4623 cbBuffer &= 0xfffe;
4624 if (cbBuffer == 0)
4625 cbBuffer = 0x10000;
4626 if (cbBuffer > cbTotalTransfer)
4627 cbBuffer = cbTotalTransfer;
4628 }
4629
4630 while (RT_UNLIKELY(fRedo) || (cbBuffer && cbTotalTransfer))
4631 {
4632 if (RT_LIKELY(!fRedo))
4633 {
4634 dmalen = RT_MIN(cbBuffer, iIOBufferEnd - iIOBufferCur);
4635 Log2(("%s: DMA desc %#010x: addr=%#010x size=%#010x\n", __FUNCTION__,
4636 (int)pDesc, pBuffer, cbBuffer));
4637 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
4638 PDMDevHlpPhysWrite(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
4639 else
4640 PDMDevHlpPhysRead(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
4641 iIOBufferCur += dmalen;
4642 cbTotalTransfer -= dmalen;
4643 cbBuffer -= dmalen;
4644 pBuffer += dmalen;
4645 }
4646 if ( iIOBufferCur == iIOBufferEnd
4647 && (uTxDir == PDMBLOCKTXDIR_TO_DEVICE || cbTotalTransfer))
4648 {
4649 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
4650 cbElementaryTransfer = cbTotalTransfer;
4651
4652 {
4653 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4654 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4655 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4656 }
4657
4658 /* The RESET handler could have cleared the DMA transfer
4659 * state (since we didn't hold the lock until just now
4660 * the guest can continue in parallel). If so, the state
4661 * is already set up so the loop is exited immediately. */
4662 if (s->iSourceSink != ATAFN_SS_NULL)
4663 {
4664 s->iIOBufferCur = iIOBufferCur;
4665 s->iIOBufferEnd = iIOBufferEnd;
4666 s->cbElementaryTransfer = cbElementaryTransfer;
4667 s->cbTotalTransfer = cbTotalTransfer;
4668 Log2(("%s: calling source/sink function\n", __FUNCTION__));
4669 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4670 if (RT_UNLIKELY(fRedo))
4671 {
4672 pCtl->pFirstDMADesc = pDesc;
4673 pCtl->pRedoDMABuffer = pBuffer;
4674 pCtl->cbRedoDMABuffer = cbBuffer;
4675 pCtl->fRedoDMALastDesc = fLastDesc;
4676 }
4677 else
4678 {
4679 cbTotalTransfer = s->cbTotalTransfer;
4680 cbElementaryTransfer = s->cbElementaryTransfer;
4681
4682 if (uTxDir == PDMBLOCKTXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
4683 cbElementaryTransfer = cbTotalTransfer;
4684 iIOBufferCur = 0;
4685 iIOBufferEnd = cbElementaryTransfer;
4686 }
4687 pCtl->fRedo = fRedo;
4688 }
4689 else
4690 {
4691 /* This forces the loop to exit immediately. */
4692 pDesc = pCtl->pLastDMADesc + 1;
4693 }
4694
4695 PDMCritSectLeave(&pCtl->lock);
4696 if (RT_UNLIKELY(fRedo))
4697 break;
4698 }
4699 }
4700
4701 if (RT_UNLIKELY(fRedo))
4702 break;
4703
4704 /* end of transfer */
4705 if (!cbTotalTransfer || fLastDesc)
4706 break;
4707
4708 {
4709 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4710 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4711 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4712 }
4713
4714 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset)
4715 {
4716 LogRel(("PIIX3 ATA: Ctl#%d: ABORT DMA%s\n", ATACONTROLLER_IDX(pCtl), pCtl->fReset ? " due to RESET" : ""));
4717 if (!pCtl->fReset)
4718 ataDMATransferStop(s);
4719 /* This forces the loop to exit immediately. */
4720 pDesc = pCtl->pLastDMADesc + 1;
4721 }
4722
4723 PDMCritSectLeave(&pCtl->lock);
4724 }
4725
4726 {
4727 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4728 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4729 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4730 }
4731
4732 if (RT_UNLIKELY(fRedo))
4733 return;
4734
4735 if (fLastDesc)
4736 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
4737 s->cbTotalTransfer = cbTotalTransfer;
4738 s->cbElementaryTransfer = cbElementaryTransfer;
4739 s->iIOBufferCur = iIOBufferCur;
4740 s->iIOBufferEnd = iIOBufferEnd;
4741}
4742
4743/**
4744 * Signal PDM that we're idle (if we actually are).
4745 *
4746 * @param pCtl The controller.
4747 */
4748static void ataR3AsyncSignalIdle(PATACONTROLLER pCtl)
4749{
4750 /*
4751 * Take the mutex here and recheck the idle indicator to avoid
4752 * unnecessary work and racing ataR3WaitForAsyncIOIsIdle.
4753 */
4754 int rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT); AssertRC(rc);
4755
4756 if ( pCtl->fSignalIdle
4757 && ataAsyncIOIsIdle(pCtl, false /*fStrict*/))
4758 {
4759 PDMDevHlpAsyncNotificationCompleted(pCtl->pDevInsR3);
4760 RTThreadUserSignal(pCtl->AsyncIOThread); /* for ataR3Construct/ataR3ResetCommon. */
4761 }
4762
4763 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex); AssertRC(rc);
4764}
4765
4766/** Async I/O thread for an interface. Once upon a time this was readable
4767 * code with several loops and a different semaphore for each purpose. But
4768 * then came the "how can one save the state in the middle of a PIO transfer"
4769 * question. The solution was to use an ASM, which is what's there now. */
4770static DECLCALLBACK(int) ataAsyncIOLoop(RTTHREAD ThreadSelf, void *pvUser)
4771{
4772 const ATARequest *pReq;
4773 uint64_t u64TS = 0; /* shut up gcc */
4774 uint64_t uWait;
4775 int rc = VINF_SUCCESS;
4776 PATACONTROLLER pCtl = (PATACONTROLLER)pvUser;
4777 ATADevState *s;
4778
4779 pReq = NULL;
4780 pCtl->fChainedTransfer = false;
4781 while (!pCtl->fShutdown)
4782 {
4783 /* Keep this thread from doing anything as long as EMT is suspended. */
4784 while (pCtl->fRedoIdle)
4785 {
4786 if (pCtl->fSignalIdle)
4787 ataR3AsyncSignalIdle(pCtl);
4788 rc = RTSemEventWait(pCtl->SuspendIOSem, RT_INDEFINITE_WAIT);
4789 /* Continue if we got a signal by RTThreadPoke().
4790 * We will get notified if there is a request to process.
4791 */
4792 if (RT_UNLIKELY(rc == VERR_INTERRUPTED))
4793 continue;
4794 if (RT_FAILURE(rc) || pCtl->fShutdown)
4795 break;
4796
4797 pCtl->fRedoIdle = false;
4798 }
4799
4800 /* Wait for work. */
4801 while (pReq == NULL)
4802 {
4803 if (pCtl->fSignalIdle)
4804 ataR3AsyncSignalIdle(pCtl);
4805 rc = RTSemEventWait(pCtl->AsyncIOSem, RT_INDEFINITE_WAIT);
4806 /* Continue if we got a signal by RTThreadPoke().
4807 * We will get notified if there is a request to process.
4808 */
4809 if (RT_UNLIKELY(rc == VERR_INTERRUPTED))
4810 continue;
4811 if (RT_FAILURE(rc) || RT_UNLIKELY(pCtl->fShutdown))
4812 break;
4813
4814 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4815 }
4816
4817 if (RT_FAILURE(rc) || pCtl->fShutdown)
4818 break;
4819
4820 if (pReq == NULL)
4821 continue;
4822
4823 ATAAIO ReqType = pReq->ReqType;
4824
4825 Log2(("%s: Ctl#%d: state=%d, req=%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->uAsyncIOState, ReqType));
4826 if (pCtl->uAsyncIOState != ReqType)
4827 {
4828 /* The new state is not the state that was expected by the normal
4829 * state changes. This is either a RESET/ABORT or there's something
4830 * really strange going on. */
4831 if ( (pCtl->uAsyncIOState == ATA_AIO_PIO || pCtl->uAsyncIOState == ATA_AIO_DMA)
4832 && (ReqType == ATA_AIO_PIO || ReqType == ATA_AIO_DMA))
4833 {
4834 /* Incorrect sequence of PIO/DMA states. Dump request queue. */
4835 ataAsyncIODumpRequests(pCtl);
4836 }
4837 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));
4838 }
4839
4840 /* Do our work. */
4841 {
4842 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4843 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4844 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4845 }
4846
4847 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4848 {
4849 u64TS = RTTimeNanoTS();
4850#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4851 STAM_PROFILE_ADV_START(&pCtl->StatAsyncTime, a);
4852#endif /* DEBUG || VBOX_WITH_STATISTICS */
4853 }
4854
4855 switch (ReqType)
4856 {
4857 case ATA_AIO_NEW:
4858
4859 pCtl->iAIOIf = pReq->u.t.iIf;
4860 s = &pCtl->aIfs[pCtl->iAIOIf];
4861 s->cbTotalTransfer = pReq->u.t.cbTotalTransfer;
4862 s->uTxDir = pReq->u.t.uTxDir;
4863 s->iBeginTransfer = pReq->u.t.iBeginTransfer;
4864 s->iSourceSink = pReq->u.t.iSourceSink;
4865 s->iIOBufferEnd = 0;
4866 s->u64CmdTS = u64TS;
4867
4868 if (s->fATAPI)
4869 {
4870 if (pCtl->fChainedTransfer)
4871 {
4872 /* Only count the actual transfers, not the PIO
4873 * transfer of the ATAPI command bytes. */
4874 if (s->fDMA)
4875 STAM_REL_COUNTER_INC(&s->StatATAPIDMA);
4876 else
4877 STAM_REL_COUNTER_INC(&s->StatATAPIPIO);
4878 }
4879 }
4880 else
4881 {
4882 if (s->fDMA)
4883 STAM_REL_COUNTER_INC(&s->StatATADMA);
4884 else
4885 STAM_REL_COUNTER_INC(&s->StatATAPIO);
4886 }
4887
4888 pCtl->fChainedTransfer = false;
4889
4890 if (s->iBeginTransfer != ATAFN_BT_NULL)
4891 {
4892 Log2(("%s: Ctl#%d: calling begin transfer function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4893 g_apfnBeginTransFuncs[s->iBeginTransfer](s);
4894 s->iBeginTransfer = ATAFN_BT_NULL;
4895 if (s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4896 s->iIOBufferEnd = s->cbElementaryTransfer;
4897 }
4898 else
4899 {
4900 s->cbElementaryTransfer = s->cbTotalTransfer;
4901 s->iIOBufferEnd = s->cbTotalTransfer;
4902 }
4903 s->iIOBufferCur = 0;
4904
4905 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4906 {
4907 if (s->iSourceSink != ATAFN_SS_NULL)
4908 {
4909 bool fRedo;
4910 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4911 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4912 pCtl->fRedo = fRedo;
4913 if (RT_UNLIKELY(fRedo && !pCtl->fReset))
4914 {
4915 /* Operation failed at the initial transfer, restart
4916 * everything from scratch by resending the current
4917 * request. Occurs very rarely, not worth optimizing. */
4918 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4919 ataAsyncIOPutRequest(pCtl, pReq);
4920 break;
4921 }
4922 }
4923 else
4924 ataCmdOK(s, 0);
4925 s->iIOBufferEnd = s->cbElementaryTransfer;
4926
4927 }
4928
4929 /* Do not go into the transfer phase if RESET is asserted.
4930 * The CritSect is released while waiting for the host OS
4931 * to finish the I/O, thus RESET is possible here. Most
4932 * important: do not change uAsyncIOState. */
4933 if (pCtl->fReset)
4934 break;
4935
4936 if (s->fDMA)
4937 {
4938 if (s->cbTotalTransfer)
4939 {
4940 ataSetStatus(s, ATA_STAT_DRQ);
4941
4942 pCtl->uAsyncIOState = ATA_AIO_DMA;
4943 /* If BMDMA is already started, do the transfer now. */
4944 if (pCtl->BmDma.u8Cmd & BM_CMD_START)
4945 {
4946 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4947 ataAsyncIOPutRequest(pCtl, &g_ataDMARequest);
4948 }
4949 }
4950 else
4951 {
4952 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4953 /* Finish DMA transfer. */
4954 ataDMATransferStop(s);
4955 ataSetIRQ(s);
4956 pCtl->uAsyncIOState = ATA_AIO_NEW;
4957 }
4958 }
4959 else
4960 {
4961 if (s->cbTotalTransfer)
4962 {
4963 ataPIOTransfer(pCtl);
4964 Assert(!pCtl->fRedo);
4965 if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4966 ataSetIRQ(s);
4967
4968 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
4969 {
4970 /* Write operations and not yet finished transfers
4971 * must be completed in the async I/O thread. */
4972 pCtl->uAsyncIOState = ATA_AIO_PIO;
4973 }
4974 else
4975 {
4976 /* Finished read operation can be handled inline
4977 * in the end of PIO transfer handling code. Linux
4978 * depends on this, as it waits only briefly for
4979 * devices to become ready after incoming data
4980 * transfer. Cannot find anything in the ATA spec
4981 * that backs this assumption, but as all kernels
4982 * are affected (though most of the time it does
4983 * not cause any harm) this must work. */
4984 pCtl->uAsyncIOState = ATA_AIO_NEW;
4985 }
4986 }
4987 else
4988 {
4989 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4990 /* Finish PIO transfer. */
4991 ataPIOTransfer(pCtl);
4992 Assert(!pCtl->fRedo);
4993 if (!s->fATAPITransfer)
4994 ataSetIRQ(s);
4995 pCtl->uAsyncIOState = ATA_AIO_NEW;
4996 }
4997 }
4998 break;
4999
5000 case ATA_AIO_DMA:
5001 {
5002 BMDMAState *bm = &pCtl->BmDma;
5003 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
5004 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */
5005
5006 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
5007 AssertRelease(bm->u8Cmd & BM_CMD_WRITE);
5008 else
5009 AssertRelease(!(bm->u8Cmd & BM_CMD_WRITE));
5010
5011 if (RT_LIKELY(!pCtl->fRedo))
5012 {
5013 /* The specs say that the descriptor table must not cross a
5014 * 4K boundary. */
5015 pCtl->pFirstDMADesc = bm->pvAddr;
5016 pCtl->pLastDMADesc = RT_ALIGN_32(bm->pvAddr + 1, _4K) - sizeof(BMDMADesc);
5017 }
5018 ataDMATransfer(pCtl);
5019
5020 if (RT_UNLIKELY(pCtl->fRedo && !pCtl->fReset))
5021 {
5022 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl)));
5023 ataAsyncIOPutRequest(pCtl, &g_ataDMARequest);
5024 break;
5025 }
5026
5027 /* The infamous delay IRQ hack. */
5028 if ( iOriginalSourceSink == ATAFN_SS_WRITE_SECTORS
5029 && s->cbTotalTransfer == 0
5030 && pCtl->DelayIRQMillies)
5031 {
5032 /* Delay IRQ for writing. Required to get the Win2K
5033 * installation work reliably (otherwise it crashes,
5034 * usually during component install). So far no better
5035 * solution has been found. */
5036 Log(("%s: delay IRQ hack\n", __FUNCTION__));
5037 PDMCritSectLeave(&pCtl->lock);
5038 RTThreadSleep(pCtl->DelayIRQMillies);
5039 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
5040 }
5041
5042 ataUnsetStatus(s, ATA_STAT_DRQ);
5043 Assert(!pCtl->fChainedTransfer);
5044 Assert(s->iSourceSink == ATAFN_SS_NULL);
5045 if (s->fATAPITransfer)
5046 {
5047 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
5048 Log2(("%s: Ctl#%d: interrupt reason %#04x\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegNSector));
5049 s->fATAPITransfer = false;
5050 }
5051 ataSetIRQ(s);
5052 pCtl->uAsyncIOState = ATA_AIO_NEW;
5053 break;
5054 }
5055
5056 case ATA_AIO_PIO:
5057 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
5058
5059 if (s->iSourceSink != ATAFN_SS_NULL)
5060 {
5061 bool fRedo;
5062 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5063 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
5064 pCtl->fRedo = fRedo;
5065 if (RT_UNLIKELY(fRedo && !pCtl->fReset))
5066 {
5067 LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl)));
5068 ataAsyncIOPutRequest(pCtl, &g_ataPIORequest);
5069 break;
5070 }
5071 s->iIOBufferCur = 0;
5072 s->iIOBufferEnd = s->cbElementaryTransfer;
5073 }
5074 else
5075 {
5076 /* Continue a previously started transfer. */
5077 ataUnsetStatus(s, ATA_STAT_BUSY);
5078 ataSetStatus(s, ATA_STAT_READY);
5079 }
5080
5081 /* It is possible that the drives on this controller get RESET
5082 * during the above call to the source/sink function. If that's
5083 * the case, don't restart the transfer and don't finish it the
5084 * usual way. RESET handling took care of all that already.
5085 * Most important: do not change uAsyncIOState. */
5086 if (pCtl->fReset)
5087 break;
5088
5089 if (s->cbTotalTransfer)
5090 {
5091 ataPIOTransfer(pCtl);
5092 ataSetIRQ(s);
5093
5094 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
5095 {
5096 /* Write operations and not yet finished transfers
5097 * must be completed in the async I/O thread. */
5098 pCtl->uAsyncIOState = ATA_AIO_PIO;
5099 }
5100 else
5101 {
5102 /* Finished read operation can be handled inline
5103 * in the end of PIO transfer handling code. Linux
5104 * depends on this, as it waits only briefly for
5105 * devices to become ready after incoming data
5106 * transfer. Cannot find anything in the ATA spec
5107 * that backs this assumption, but as all kernels
5108 * are affected (though most of the time it does
5109 * not cause any harm) this must work. */
5110 pCtl->uAsyncIOState = ATA_AIO_NEW;
5111 }
5112 }
5113 else
5114 {
5115 /* Finish PIO transfer. */
5116 ataPIOTransfer(pCtl);
5117 if ( !pCtl->fChainedTransfer
5118 && !s->fATAPITransfer
5119 && s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
5120 {
5121 ataSetIRQ(s);
5122 }
5123 pCtl->uAsyncIOState = ATA_AIO_NEW;
5124 }
5125 break;
5126
5127 case ATA_AIO_RESET_ASSERTED:
5128 pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED;
5129 ataPIOTransferStop(&pCtl->aIfs[0]);
5130 ataPIOTransferStop(&pCtl->aIfs[1]);
5131 /* Do not change the DMA registers, they are not affected by the
5132 * ATA controller reset logic. It should be sufficient to issue a
5133 * new command, which is now possible as the state is cleared. */
5134 break;
5135
5136 case ATA_AIO_RESET_CLEARED:
5137 pCtl->uAsyncIOState = ATA_AIO_NEW;
5138 pCtl->fReset = false;
5139 /* Ensure that half-completed transfers are not redone. A reset
5140 * cancels the entire transfer, so continuing is wrong. */
5141 pCtl->fRedo = false;
5142 pCtl->fRedoDMALastDesc = false;
5143 LogRel(("PIIX3 ATA: Ctl#%d: finished processing RESET\n",
5144 ATACONTROLLER_IDX(pCtl)));
5145 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
5146 {
5147 if (pCtl->aIfs[i].fATAPI)
5148 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
5149 else
5150 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
5151 ataSetSignature(&pCtl->aIfs[i]);
5152 }
5153 break;
5154
5155 case ATA_AIO_ABORT:
5156 /* Abort the current command no matter what. There cannot be
5157 * any command activity on the other drive otherwise using
5158 * one thread per controller wouldn't work at all. */
5159 s = &pCtl->aIfs[pReq->u.a.iIf];
5160
5161 pCtl->uAsyncIOState = ATA_AIO_NEW;
5162 /* Do not change the DMA registers, they are not affected by the
5163 * ATA controller reset logic. It should be sufficient to issue a
5164 * new command, which is now possible as the state is cleared. */
5165 if (pReq->u.a.fResetDrive)
5166 {
5167 ataResetDevice(s);
5168 ataExecuteDeviceDiagnosticSS(s);
5169 }
5170 else
5171 {
5172 /* Stop any pending DMA transfer. */
5173 s->fDMA = false;
5174 ataPIOTransferStop(s);
5175 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
5176 ataSetStatus(s, ATA_STAT_READY);
5177 ataSetIRQ(s);
5178 }
5179 break;
5180
5181 default:
5182 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
5183 }
5184
5185 ataAsyncIORemoveCurrentRequest(pCtl, ReqType);
5186 pReq = ataAsyncIOGetCurrentRequest(pCtl);
5187
5188 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
5189 {
5190#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
5191 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
5192#endif /* DEBUG || VBOX_WITH_STATISTICS */
5193
5194 u64TS = RTTimeNanoTS() - u64TS;
5195 uWait = u64TS / 1000;
5196 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)));
5197 /* Mark command as finished. */
5198 pCtl->aIfs[pCtl->iAIOIf].u64CmdTS = 0;
5199
5200 /*
5201 * Release logging of command execution times depends on the
5202 * command type. ATAPI commands often take longer (due to CD/DVD
5203 * spin up time etc.) so the threshold is different.
5204 */
5205 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
5206 {
5207 if (uWait > 8 * 1000 * 1000)
5208 {
5209 /*
5210 * Command took longer than 8 seconds. This is close
5211 * enough or over the guest's command timeout, so place
5212 * an entry in the release log to allow tracking such
5213 * timing errors (which are often caused by the host).
5214 */
5215 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
5216 }
5217 }
5218 else
5219 {
5220 if (uWait > 20 * 1000 * 1000)
5221 {
5222 /*
5223 * Command took longer than 20 seconds. This is close
5224 * enough or over the guest's command timeout, so place
5225 * an entry in the release log to allow tracking such
5226 * timing errors (which are often caused by the host).
5227 */
5228 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
5229 }
5230 }
5231
5232#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
5233 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
5234 pCtl->StatAsyncMinWait = uWait;
5235 if (uWait > pCtl->StatAsyncMaxWait)
5236 pCtl->StatAsyncMaxWait = uWait;
5237
5238 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
5239 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
5240#endif /* DEBUG || VBOX_WITH_STATISTICS */
5241 }
5242
5243 PDMCritSectLeave(&pCtl->lock);
5244 }
5245
5246 /* Signal the ultimate idleness. */
5247 RTThreadUserSignal(pCtl->AsyncIOThread);
5248 if (pCtl->fSignalIdle)
5249 PDMDevHlpAsyncNotificationCompleted(pCtl->pDevInsR3);
5250
5251 /* Cleanup the state. */
5252 /* Do not destroy request mutex yet, still needed for proper shutdown. */
5253 pCtl->fShutdown = false;
5254
5255 Log2(("%s: Ctl#%d: return %Rrc\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), rc));
5256 return rc;
5257}
5258
5259#endif /* IN_RING3 */
5260
5261static uint32_t ataBMDMACmdReadB(PATACONTROLLER pCtl, uint32_t addr)
5262{
5263 uint32_t val = pCtl->BmDma.u8Cmd;
5264 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5265 return val;
5266}
5267
5268
5269static void ataBMDMACmdWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5270{
5271 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5272 if (!(val & BM_CMD_START))
5273 {
5274 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
5275 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5276 }
5277 else
5278 {
5279#ifdef IN_RING3
5280 /* Check whether the guest OS wants to change DMA direction in
5281 * mid-flight. Not allowed, according to the PIIX3 specs. */
5282 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
5283 uint8_t uOldBmDmaStatus = pCtl->BmDma.u8Status;
5284 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
5285 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5286
5287 /* Do not continue DMA transfers while the RESET line is asserted. */
5288 if (pCtl->fReset)
5289 {
5290 Log2(("%s: Ctl#%d: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5291 return;
5292 }
5293
5294 /* Do not start DMA transfers if there's a PIO transfer going on,
5295 * or if there is already a transfer started on this controller. */
5296 if ( !pCtl->aIfs[pCtl->iSelectedIf].fDMA
5297 || (uOldBmDmaStatus & BM_STATUS_DMAING))
5298 return;
5299
5300 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
5301 {
5302 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5303 ataAsyncIOPutRequest(pCtl, &g_ataDMARequest);
5304 }
5305#else /* !IN_RING3 */
5306 AssertMsgFailed(("DMA START handling is too complicated for GC\n"));
5307#endif /* IN_RING3 */
5308 }
5309}
5310
5311static uint32_t ataBMDMAStatusReadB(PATACONTROLLER pCtl, uint32_t addr)
5312{
5313 uint32_t val = pCtl->BmDma.u8Status;
5314 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5315 return val;
5316}
5317
5318static void ataBMDMAStatusWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5319{
5320 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5321 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
5322 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
5323 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
5324}
5325
5326static uint32_t ataBMDMAAddrReadL(PATACONTROLLER pCtl, uint32_t addr)
5327{
5328 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
5329 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5330 return val;
5331}
5332
5333static void ataBMDMAAddrWriteL(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5334{
5335 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5336 pCtl->BmDma.pvAddr = val & ~3;
5337}
5338
5339static void ataBMDMAAddrWriteLowWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5340{
5341 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5342 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
5343
5344}
5345
5346static void ataBMDMAAddrWriteHighWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5347{
5348 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
5349 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
5350}
5351
5352#define VAL(port, size) ( ((port) & 7) | ((size) << 3) )
5353
5354/**
5355 * Port I/O Handler for bus master DMA IN operations.
5356 * @see FNIOMIOPORTIN for details.
5357 */
5358PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5359{
5360 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5361 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5362 PATACONTROLLER pCtl = &pThis->aCts[i];
5363 int rc;
5364
5365 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5366 if (rc != VINF_SUCCESS)
5367 return rc;
5368 switch (VAL(Port, cb))
5369 {
5370 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
5371 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
5372 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
5373 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
5374 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
5375 case VAL(0, 4):
5376 /* The SCO OpenServer tries to read 4 bytes starting from offset 0. */
5377 *pu32 = ataBMDMACmdReadB(pCtl, Port) | (ataBMDMAStatusReadB(pCtl, Port) << 16);
5378 break;
5379 default:
5380 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb));
5381 PDMCritSectLeave(&pCtl->lock);
5382 return VERR_IOM_IOPORT_UNUSED;
5383 }
5384 PDMCritSectLeave(&pCtl->lock);
5385 return rc;
5386}
5387
5388/**
5389 * Port I/O Handler for bus master DMA OUT operations.
5390 * @see FNIOMIOPORTOUT for details.
5391 */
5392PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5393{
5394 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5395 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5396 PATACONTROLLER pCtl = &pThis->aCts[i];
5397 int rc;
5398
5399 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5400 if (rc != VINF_SUCCESS)
5401 return rc;
5402 switch (VAL(Port, cb))
5403 {
5404 case VAL(0, 1):
5405#ifndef IN_RING3
5406 if (u32 & BM_CMD_START)
5407 {
5408 rc = VINF_IOM_HC_IOPORT_WRITE;
5409 break;
5410 }
5411#endif /* !IN_RING3 */
5412 ataBMDMACmdWriteB(pCtl, Port, u32);
5413 break;
5414 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
5415 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
5416 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
5417 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
5418 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break;
5419 }
5420 PDMCritSectLeave(&pCtl->lock);
5421 return rc;
5422}
5423
5424#undef VAL
5425
5426#ifdef IN_RING3
5427
5428/**
5429 * Callback function for mapping an PCI I/O region.
5430 *
5431 * @return VBox status code.
5432 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
5433 * @param iRegion The region number.
5434 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
5435 * I/O port, else it's a physical address.
5436 * This address is *NOT* relative to pci_mem_base like earlier!
5437 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
5438 */
5439static DECLCALLBACK(int) ataBMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
5440{
5441 PCIATAState *pThis = PCIDEV_2_PCIATASTATE(pPciDev);
5442 int rc = VINF_SUCCESS;
5443 Assert(enmType == PCI_ADDRESS_SPACE_IO);
5444 Assert(iRegion == 4);
5445 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
5446
5447 /* Register the port range. */
5448 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5449 {
5450 int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
5451 (RTHCPTR)(uintptr_t)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL, NULL, "ATA Bus Master DMA");
5452 AssertRC(rc2);
5453 if (rc2 < rc)
5454 rc = rc2;
5455
5456 if (pThis->fGCEnabled)
5457 {
5458 rc2 = PDMDevHlpIOPortRegisterRC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
5459 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
5460 AssertRC(rc2);
5461 if (rc2 < rc)
5462 rc = rc2;
5463 }
5464 if (pThis->fR0Enabled)
5465 {
5466 rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
5467 (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
5468 AssertRC(rc2);
5469 if (rc2 < rc)
5470 rc = rc2;
5471 }
5472 }
5473 return rc;
5474}
5475
5476
5477/* -=-=-=-=-=- PCIATAState::IBase -=-=-=-=-=- */
5478
5479/**
5480 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
5481 */
5482static DECLCALLBACK(void *) ataStatus_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
5483{
5484 PCIATAState *pThis = PDMIBASE_2_PCIATASTATE(pInterface);
5485 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase);
5486 PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS, &pThis->ILeds);
5487 return NULL;
5488}
5489
5490
5491/* -=-=-=-=-=- PCIATAState::ILeds -=-=-=-=-=- */
5492
5493/**
5494 * Gets the pointer to the status LED of a unit.
5495 *
5496 * @returns VBox status code.
5497 * @param pInterface Pointer to the interface structure containing the called function pointer.
5498 * @param iLUN The unit which status LED we desire.
5499 * @param ppLed Where to store the LED pointer.
5500 */
5501static DECLCALLBACK(int) ataStatus_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
5502{
5503 PCIATAState *pThis = PDMILEDPORTS_2_PCIATASTATE(pInterface);
5504 if (iLUN < 4)
5505 {
5506 switch (iLUN)
5507 {
5508 case 0: *ppLed = &pThis->aCts[0].aIfs[0].Led; break;
5509 case 1: *ppLed = &pThis->aCts[0].aIfs[1].Led; break;
5510 case 2: *ppLed = &pThis->aCts[1].aIfs[0].Led; break;
5511 case 3: *ppLed = &pThis->aCts[1].aIfs[1].Led; break;
5512 }
5513 Assert((*ppLed)->u32Magic == PDMLED_MAGIC);
5514 return VINF_SUCCESS;
5515 }
5516 return VERR_PDM_LUN_NOT_FOUND;
5517}
5518
5519
5520/* -=-=-=-=-=- ATADevState::IBase -=-=-=-=-=- */
5521
5522/**
5523 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
5524 */
5525static DECLCALLBACK(void *) ataQueryInterface(PPDMIBASE pInterface, const char *pszIID)
5526{
5527 ATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
5528 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pIf->IBase);
5529 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKPORT, &pIf->IPort);
5530 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNTNOTIFY, &pIf->IMountNotify);
5531 return NULL;
5532}
5533
5534
5535/* -=-=-=-=-=- ATADevState::IPort -=-=-=-=-=- */
5536
5537/**
5538 * @interface_method_impl{PDMIBLOCKPORT,pfnQueryDeviceLocation}
5539 */
5540static DECLCALLBACK(int) ataR3QueryDeviceLocation(PPDMIBLOCKPORT pInterface, const char **ppcszController,
5541 uint32_t *piInstance, uint32_t *piLUN)
5542{
5543 ATADevState *pIf = PDMIBLOCKPORT_2_ATASTATE(pInterface);
5544 PPDMDEVINS pDevIns = pIf->CTX_SUFF(pDevIns);
5545
5546 AssertPtrReturn(ppcszController, VERR_INVALID_POINTER);
5547 AssertPtrReturn(piInstance, VERR_INVALID_POINTER);
5548 AssertPtrReturn(piLUN, VERR_INVALID_POINTER);
5549
5550 *ppcszController = pDevIns->pReg->szName;
5551 *piInstance = pDevIns->iInstance;
5552 *piLUN = pIf->iLUN;
5553
5554 return VINF_SUCCESS;
5555}
5556#endif /* IN_RING3 */
5557
5558
5559/* -=-=-=-=-=- Wrappers -=-=-=-=-=- */
5560
5561/**
5562 * Port I/O Handler for primary port range OUT operations.
5563 * @see FNIOMIOPORTOUT for details.
5564 */
5565PDMBOTHCBDECL(int) ataIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5566{
5567 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5568 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5569 PATACONTROLLER pCtl = &pThis->aCts[i];
5570 int rc = VINF_SUCCESS;
5571
5572 Assert(i < 2);
5573
5574 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5575 if (rc != VINF_SUCCESS)
5576 return rc;
5577 if (cb == 1)
5578 rc = ataIOPortWriteU8(pCtl, Port, u32);
5579 else if (Port == pCtl->IOPortBase1)
5580 {
5581 Assert(cb == 2 || cb == 4);
5582 rc = ataDataWrite(pCtl, Port, cb, (const uint8_t *)&u32);
5583 }
5584 else
5585 AssertMsgFailed(("ataIOPortWrite1: unsupported write to port %x val=%x size=%d\n", Port, u32, cb));
5586 PDMCritSectLeave(&pCtl->lock);
5587 return rc;
5588}
5589
5590
5591/**
5592 * Port I/O Handler for primary port range IN operations.
5593 * @see FNIOMIOPORTIN for details.
5594 */
5595PDMBOTHCBDECL(int) ataIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5596{
5597 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5598 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5599 PATACONTROLLER pCtl = &pThis->aCts[i];
5600 int rc = VINF_SUCCESS;
5601
5602 Assert(i < 2);
5603
5604 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5605 if (rc != VINF_SUCCESS)
5606 return rc;
5607 if (cb == 1)
5608 {
5609 rc = ataIOPortReadU8(pCtl, Port, pu32);
5610 }
5611 else if (Port == pCtl->IOPortBase1)
5612 {
5613 Assert(cb == 2 || cb == 4);
5614 rc = ataDataRead(pCtl, Port, cb, (uint8_t *)pu32);
5615 if (cb == 2)
5616 *pu32 &= 0xffff;
5617 }
5618 else
5619 {
5620 AssertMsgFailed(("ataIOPortRead1: unsupported read from port %x size=%d\n", Port, cb));
5621 rc = VERR_IOM_IOPORT_UNUSED;
5622 }
5623 PDMCritSectLeave(&pCtl->lock);
5624 return rc;
5625}
5626
5627#ifndef IN_RING0 /** @todo do this in ring-0 as well. */
5628/**
5629 * Port I/O Handler for primary port range IN string operations.
5630 * @see FNIOMIOPORTINSTRING for details.
5631 */
5632PDMBOTHCBDECL(int) ataIOPortReadStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb)
5633{
5634 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5635 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5636 PATACONTROLLER pCtl = &pThis->aCts[i];
5637 int rc = VINF_SUCCESS;
5638
5639 Assert(i < 2);
5640
5641 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5642 if (rc != VINF_SUCCESS)
5643 return rc;
5644 if (Port == pCtl->IOPortBase1)
5645 {
5646 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
5647 RTGCPTR GCDst = *pGCPtrDst;
5648 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
5649 Assert(cb == 2 || cb == 4);
5650
5651 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
5652#ifndef IN_RING3
5653 /* Deal with the unlikely case where no data (or not enough for the read length operation) is available; go back to ring 3. */
5654 if (!cTransAvailable)
5655 {
5656 PDMCritSectLeave(&pCtl->lock);
5657 return VINF_IOM_HC_IOPORT_READ;
5658 }
5659 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
5660 cTransAvailable--;
5661#endif /* !IN_RING3 */
5662 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
5663 * They are not performance-critical and generally shouldn't occur at all. */
5664 if (cTransAvailable > cTransfer)
5665 cTransAvailable = cTransfer;
5666 cbTransfer = cTransAvailable * cb;
5667
5668 rc = PGMPhysSimpleDirtyWriteGCPtr(PDMDevHlpGetVMCPU(pDevIns), GCDst, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
5669#ifndef IN_RING3
5670 /* Paranoia. */
5671 if (RT_FAILURE(rc))
5672 {
5673 PDMCritSectLeave(&pCtl->lock);
5674 AssertFailed();
5675 return VINF_IOM_HC_IOPORT_READ;
5676 }
5677#else
5678 Assert(rc == VINF_SUCCESS);
5679#endif
5680
5681 if (cbTransfer)
5682 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
5683 s->iIOBufferPIODataStart += cbTransfer;
5684 *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
5685 *pcTransfer = cTransfer - cTransAvailable;
5686#ifdef IN_RING3
5687 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
5688 ataPIOTransferFinish(pCtl, s);
5689#endif /* IN_RING3 */
5690 }
5691 PDMCritSectLeave(&pCtl->lock);
5692 return rc;
5693}
5694
5695
5696/**
5697 * Port I/O Handler for primary port range OUT string operations.
5698 * @see FNIOMIOPORTOUTSTRING for details.
5699 */
5700PDMBOTHCBDECL(int) ataIOPortWriteStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)
5701{
5702 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5703 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5704 PATACONTROLLER pCtl = &pThis->aCts[i];
5705 int rc;
5706
5707 Assert(i < 2);
5708
5709 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5710 if (rc != VINF_SUCCESS)
5711 return rc;
5712 if (Port == pCtl->IOPortBase1)
5713 {
5714 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
5715 RTGCPTR GCSrc = *pGCPtrSrc;
5716 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
5717 Assert(cb == 2 || cb == 4);
5718
5719 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
5720#ifndef IN_RING3
5721 /* Deal with the unlikely case where no data (or not enough for the read length operation) is available; go back to ring 3. */
5722 if (!cTransAvailable)
5723 {
5724 PDMCritSectLeave(&pCtl->lock);
5725 return VINF_IOM_HC_IOPORT_WRITE;
5726 }
5727 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
5728 cTransAvailable--;
5729#endif /* !IN_RING3 */
5730 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
5731 * They are not performance-critical and generally shouldn't occur at all. */
5732 if (cTransAvailable > cTransfer)
5733 cTransAvailable = cTransfer;
5734 cbTransfer = cTransAvailable * cb;
5735
5736 rc = PGMPhysSimpleReadGCPtr(PDMDevHlpGetVMCPU(pDevIns), s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
5737#ifndef IN_RING3
5738 /* Paranoia. */
5739 if (RT_FAILURE(rc))
5740 {
5741 PDMCritSectLeave(&pCtl->lock);
5742 AssertFailed();
5743 return VINF_IOM_HC_IOPORT_WRITE;
5744 }
5745#else
5746 Assert(rc == VINF_SUCCESS);
5747#endif
5748
5749 if (cbTransfer)
5750 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
5751 s->iIOBufferPIODataStart += cbTransfer;
5752 *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
5753 *pcTransfer = cTransfer - cTransAvailable;
5754#ifdef IN_RING3
5755 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
5756 ataPIOTransferFinish(pCtl, s);
5757#endif /* IN_RING3 */
5758 }
5759 PDMCritSectLeave(&pCtl->lock);
5760 return rc;
5761}
5762#endif /* !IN_RING0 */
5763
5764/**
5765 * Port I/O Handler for secondary port range OUT operations.
5766 * @see FNIOMIOPORTOUT for details.
5767 */
5768PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5769{
5770 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5771 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5772 PATACONTROLLER pCtl = &pThis->aCts[i];
5773 int rc;
5774
5775 Assert(i < 2);
5776
5777 if (cb != 1)
5778 return VINF_SUCCESS;
5779 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5780 if (rc != VINF_SUCCESS)
5781 return rc;
5782 rc = ataControlWrite(pCtl, Port, u32);
5783 PDMCritSectLeave(&pCtl->lock);
5784 return rc;
5785}
5786
5787
5788/**
5789 * Port I/O Handler for secondary port range IN operations.
5790 * @see FNIOMIOPORTIN for details.
5791 */
5792PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5793{
5794 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5795 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5796 PATACONTROLLER pCtl = &pThis->aCts[i];
5797 int rc;
5798
5799 Assert(i < 2);
5800
5801 if (cb != 1)
5802 return VERR_IOM_IOPORT_UNUSED;
5803
5804 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5805 if (rc != VINF_SUCCESS)
5806 return rc;
5807 *pu32 = ataStatusRead(pCtl, Port);
5808 PDMCritSectLeave(&pCtl->lock);
5809 return VINF_SUCCESS;
5810}
5811
5812#ifdef IN_RING3
5813
5814
5815DECLINLINE(void) ataRelocBuffer(PPDMDEVINS pDevIns, ATADevState *s)
5816{
5817 if (s->pbIOBufferR3)
5818 s->pbIOBufferRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), s->pbIOBufferR3);
5819}
5820
5821
5822/**
5823 * @copydoc FNPDMDEVRELOCATE
5824 */
5825static DECLCALLBACK(void) ataR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
5826{
5827 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5828
5829 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5830 {
5831 pThis->aCts[i].pDevInsRC += offDelta;
5832 pThis->aCts[i].aIfs[0].pDevInsRC += offDelta;
5833 pThis->aCts[i].aIfs[0].pControllerRC += offDelta;
5834 ataRelocBuffer(pDevIns, &pThis->aCts[i].aIfs[0]);
5835 pThis->aCts[i].aIfs[1].pDevInsRC += offDelta;
5836 pThis->aCts[i].aIfs[1].pControllerRC += offDelta;
5837 ataRelocBuffer(pDevIns, &pThis->aCts[i].aIfs[1]);
5838 }
5839}
5840
5841
5842/**
5843 * Destroy a driver instance.
5844 *
5845 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
5846 * resources can be freed correctly.
5847 *
5848 * @param pDevIns The device instance data.
5849 */
5850static DECLCALLBACK(int) ataR3Destruct(PPDMDEVINS pDevIns)
5851{
5852 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5853 int rc;
5854
5855 Log(("ataR3Destruct\n"));
5856 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
5857
5858 /*
5859 * Tell the async I/O threads to terminate.
5860 */
5861 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5862 {
5863 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5864 {
5865 ASMAtomicWriteU32(&pThis->aCts[i].fShutdown, true);
5866 rc = RTSemEventSignal(pThis->aCts[i].AsyncIOSem);
5867 AssertRC(rc);
5868 rc = RTSemEventSignal(pThis->aCts[i].SuspendIOSem);
5869 AssertRC(rc);
5870 }
5871 }
5872
5873 /*
5874 * Wait for the threads to terminate before destroying their resources.
5875 */
5876 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5877 {
5878 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5879 {
5880 rc = RTThreadWait(pThis->aCts[i].AsyncIOThread, 30000 /* 30 s*/, NULL);
5881 if (RT_SUCCESS(rc))
5882 pThis->aCts[i].AsyncIOThread = NIL_RTTHREAD;
5883 else
5884 LogRel(("PIIX3 ATA Dtor: Ctl#%u is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x rc=%Rrc\n",
5885 i, pThis->aCts[i].iSelectedIf, pThis->aCts[i].iAIOIf,
5886 pThis->aCts[i].aIfs[0].uATARegCommand, pThis->aCts[i].aIfs[1].uATARegCommand, rc));
5887 }
5888 }
5889
5890 /*
5891 * Free resources.
5892 */
5893 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5894 {
5895 if (pThis->aCts[i].AsyncIORequestMutex != NIL_RTSEMMUTEX)
5896 {
5897 RTSemMutexDestroy(pThis->aCts[i].AsyncIORequestMutex);
5898 pThis->aCts[i].AsyncIORequestMutex = NIL_RTSEMMUTEX;
5899 }
5900 if (pThis->aCts[i].AsyncIOSem != NIL_RTSEMEVENT)
5901 {
5902 RTSemEventDestroy(pThis->aCts[i].AsyncIOSem);
5903 pThis->aCts[i].AsyncIOSem = NIL_RTSEMEVENT;
5904 }
5905 if (pThis->aCts[i].SuspendIOSem != NIL_RTSEMEVENT)
5906 {
5907 RTSemEventDestroy(pThis->aCts[i].SuspendIOSem);
5908 pThis->aCts[i].SuspendIOSem = NIL_RTSEMEVENT;
5909 }
5910
5911 /* try one final time */
5912 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5913 {
5914 rc = RTThreadWait(pThis->aCts[i].AsyncIOThread, 1 /*ms*/, NULL);
5915 if (RT_SUCCESS(rc))
5916 {
5917 pThis->aCts[i].AsyncIOThread = NIL_RTTHREAD;
5918 LogRel(("PIIX3 ATA Dtor: Ctl#%u actually completed.\n", i));
5919 }
5920 }
5921 }
5922
5923 return VINF_SUCCESS;
5924}
5925
5926
5927/**
5928 * Detach notification.
5929 *
5930 * The DVD drive has been unplugged.
5931 *
5932 * @param pDevIns The device instance.
5933 * @param iLUN The logical unit which is being detached.
5934 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
5935 */
5936static DECLCALLBACK(void) ataR3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
5937{
5938 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5939 PATACONTROLLER pCtl;
5940 ATADevState *pIf;
5941 unsigned iController;
5942 unsigned iInterface;
5943
5944 AssertMsg(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
5945 ("PIIX3IDE: Device does not support hotplugging\n"));
5946
5947 /*
5948 * Locate the controller and stuff.
5949 */
5950 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5951 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5952 pCtl = &pThis->aCts[iController];
5953
5954 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5955 pIf = &pCtl->aIfs[iInterface];
5956
5957 /*
5958 * Zero some important members.
5959 */
5960 pIf->pDrvBase = NULL;
5961 pIf->pDrvBlock = NULL;
5962 pIf->pDrvBlockBios = NULL;
5963 pIf->pDrvMount = NULL;
5964
5965 /*
5966 * In case there was a medium inserted.
5967 */
5968 ataMediumRemoved(pIf);
5969}
5970
5971
5972/**
5973 * Configure a LUN.
5974 *
5975 * @returns VBox status code.
5976 * @param pDevIns The device instance.
5977 * @param pIf The ATA unit state.
5978 */
5979static int ataConfigLun(PPDMDEVINS pDevIns, ATADevState *pIf)
5980{
5981 int rc = VINF_SUCCESS;
5982 PDMBLOCKTYPE enmType;
5983
5984 /*
5985 * Query Block, Bios and Mount interfaces.
5986 */
5987 pIf->pDrvBlock = PDMIBASE_QUERY_INTERFACE(pIf->pDrvBase, PDMIBLOCK);
5988 if (!pIf->pDrvBlock)
5989 {
5990 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
5991 return VERR_PDM_MISSING_INTERFACE;
5992 }
5993
5994 /** @todo implement the BIOS invisible code path. */
5995 pIf->pDrvBlockBios = PDMIBASE_QUERY_INTERFACE(pIf->pDrvBase, PDMIBLOCKBIOS);
5996 if (!pIf->pDrvBlockBios)
5997 {
5998 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pIf->iLUN));
5999 return VERR_PDM_MISSING_INTERFACE;
6000 }
6001 pIf->pDrvMount = PDMIBASE_QUERY_INTERFACE(pIf->pDrvBase, PDMIMOUNT);
6002
6003 /*
6004 * Validate type.
6005 */
6006 enmType = pIf->pDrvBlock->pfnGetType(pIf->pDrvBlock);
6007 if ( enmType != PDMBLOCKTYPE_CDROM
6008 && enmType != PDMBLOCKTYPE_DVD
6009 && enmType != PDMBLOCKTYPE_HARD_DISK)
6010 {
6011 AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
6012 return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
6013 }
6014 if ( ( enmType == PDMBLOCKTYPE_DVD
6015 || enmType == PDMBLOCKTYPE_CDROM)
6016 && !pIf->pDrvMount)
6017 {
6018 AssertMsgFailed(("Internal error: cdrom without a mountable interface, WTF???!\n"));
6019 return VERR_INTERNAL_ERROR;
6020 }
6021 pIf->fATAPI = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM;
6022 pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvBlock->pfnSendCmd != NULL) : false;
6023
6024 /*
6025 * Allocate I/O buffer.
6026 */
6027 PVM pVM = PDMDevHlpGetVM(pDevIns);
6028 if (pIf->cbIOBuffer)
6029 {
6030 /* Buffer is (probably) already allocated. Validate the fields,
6031 * because memory corruption can also overwrite pIf->cbIOBuffer. */
6032 if (pIf->fATAPI)
6033 AssertRelease(pIf->cbIOBuffer == _128K);
6034 else
6035 AssertRelease(pIf->cbIOBuffer == ATA_MAX_MULT_SECTORS * 512);
6036 Assert(pIf->pbIOBufferR3);
6037 Assert(pIf->pbIOBufferR0 == MMHyperR3ToR0(pVM, pIf->pbIOBufferR3));
6038 Assert(pIf->pbIOBufferRC == MMHyperR3ToRC(pVM, pIf->pbIOBufferR3));
6039 }
6040 else
6041 {
6042 if (pIf->fATAPI)
6043 pIf->cbIOBuffer = _128K;
6044 else
6045 pIf->cbIOBuffer = ATA_MAX_MULT_SECTORS * 512;
6046 Assert(!pIf->pbIOBufferR3);
6047 rc = MMR3HyperAllocOnceNoRel(pVM, pIf->cbIOBuffer, 0, MM_TAG_PDM_DEVICE_USER, (void **)&pIf->pbIOBufferR3);
6048 if (RT_FAILURE(rc))
6049 return VERR_NO_MEMORY;
6050 pIf->pbIOBufferR0 = MMHyperR3ToR0(pVM, pIf->pbIOBufferR3);
6051 pIf->pbIOBufferRC = MMHyperR3ToRC(pVM, pIf->pbIOBufferR3);
6052 }
6053
6054 /*
6055 * Init geometry (only for non-CD/DVD media).
6056 */
6057 if (pIf->fATAPI)
6058 {
6059 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
6060 pIf->PCHSGeometry.cCylinders = 0; /* dummy */
6061 pIf->PCHSGeometry.cHeads = 0; /* dummy */
6062 pIf->PCHSGeometry.cSectors = 0; /* dummy */
6063 LogRel(("PIIX3 ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));
6064 }
6065 else
6066 {
6067 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
6068 rc = pIf->pDrvBlockBios->pfnGetPCHSGeometry(pIf->pDrvBlockBios,
6069 &pIf->PCHSGeometry);
6070 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
6071 {
6072 pIf->PCHSGeometry.cCylinders = 0;
6073 pIf->PCHSGeometry.cHeads = 16; /*??*/
6074 pIf->PCHSGeometry.cSectors = 63; /*??*/
6075 }
6076 else if (rc == VERR_PDM_GEOMETRY_NOT_SET)
6077 {
6078 pIf->PCHSGeometry.cCylinders = 0; /* autodetect marker */
6079 rc = VINF_SUCCESS;
6080 }
6081 AssertRC(rc);
6082
6083 if ( pIf->PCHSGeometry.cCylinders == 0
6084 || pIf->PCHSGeometry.cHeads == 0
6085 || pIf->PCHSGeometry.cSectors == 0
6086 )
6087 {
6088 uint64_t cCylinders = pIf->cTotalSectors / (16 * 63);
6089 pIf->PCHSGeometry.cCylinders = RT_MAX(RT_MIN(cCylinders, 16383), 1);
6090 pIf->PCHSGeometry.cHeads = 16;
6091 pIf->PCHSGeometry.cSectors = 63;
6092 /* Set the disk geometry information. Ignore errors. */
6093 pIf->pDrvBlockBios->pfnSetPCHSGeometry(pIf->pDrvBlockBios,
6094 &pIf->PCHSGeometry);
6095 rc = VINF_SUCCESS;
6096 }
6097 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));
6098 }
6099 return rc;
6100}
6101
6102
6103/**
6104 * Attach command.
6105 *
6106 * This is called when we change block driver for the DVD drive.
6107 *
6108 * @returns VBox status code.
6109 * @param pDevIns The device instance.
6110 * @param iLUN The logical unit which is being detached.
6111 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
6112 */
6113static DECLCALLBACK(int) ataR3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
6114{
6115 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6116 PATACONTROLLER pCtl;
6117 ATADevState *pIf;
6118 int rc;
6119 unsigned iController;
6120 unsigned iInterface;
6121
6122 AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
6123 ("PIIX3IDE: Device does not support hotplugging\n"),
6124 VERR_INVALID_PARAMETER);
6125
6126 /*
6127 * Locate the controller and stuff.
6128 */
6129 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
6130 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
6131 pCtl = &pThis->aCts[iController];
6132
6133 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
6134 pIf = &pCtl->aIfs[iInterface];
6135
6136 /* the usual paranoia */
6137 AssertRelease(!pIf->pDrvBase);
6138 AssertRelease(!pIf->pDrvBlock);
6139 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
6140 Assert(pIf->iLUN == iLUN);
6141
6142 /*
6143 * Try attach the block device and get the interfaces,
6144 * required as well as optional.
6145 */
6146 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
6147 if (RT_SUCCESS(rc))
6148 {
6149 rc = ataConfigLun(pDevIns, pIf);
6150 /*
6151 * In case there is a medium inserted.
6152 */
6153 ataMediumInserted(pIf);
6154 }
6155 else
6156 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Rrc\n", pIf->iLUN, rc));
6157
6158 if (RT_FAILURE(rc))
6159 {
6160 pIf->pDrvBase = NULL;
6161 pIf->pDrvBlock = NULL;
6162 }
6163 return rc;
6164}
6165
6166
6167/**
6168 * Resume notification.
6169 *
6170 * @returns VBox status.
6171 * @param pDevIns The device instance data.
6172 */
6173static DECLCALLBACK(void) ataR3Resume(PPDMDEVINS pDevIns)
6174{
6175 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6176 int rc;
6177
6178 Log(("%s:\n", __FUNCTION__));
6179 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6180 {
6181 if (pThis->aCts[i].fRedo && pThis->aCts[i].fRedoIdle)
6182 {
6183 rc = RTSemEventSignal(pThis->aCts[i].SuspendIOSem);
6184 AssertRC(rc);
6185 }
6186 }
6187 return;
6188}
6189
6190
6191/**
6192 * Checks if all (both) the async I/O threads have quiesced.
6193 *
6194 * @returns true on success.
6195 * @returns false when one or more threads is still processing.
6196 * @param pThis Pointer to the instance data.
6197 */
6198static bool ataR3AllAsyncIOIsIdle(PPDMDEVINS pDevIns)
6199{
6200 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6201
6202 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6203 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
6204 {
6205 bool fRc = ataAsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/);
6206 if (!fRc)
6207 {
6208 /* Make it signal PDM & itself when its done */
6209 RTSemMutexRequest(pThis->aCts[i].AsyncIORequestMutex, RT_INDEFINITE_WAIT);
6210 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, true);
6211 RTSemMutexRelease(pThis->aCts[i].AsyncIORequestMutex);
6212 fRc = ataAsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/);
6213 if (!fRc)
6214 {
6215#if 0 /** @todo Need to do some time tracking here... */
6216 LogRel(("PIIX3 ATA: Ctl#%u is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",
6217 i, pThis->aCts[i].iSelectedIf, pThis->aCts[i].iAIOIf,
6218 pThis->aCts[i].aIfs[0].uATARegCommand, pThis->aCts[i].aIfs[1].uATARegCommand));
6219#endif
6220 return false;
6221 }
6222 }
6223 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, false);
6224 }
6225 return true;
6226}
6227
6228
6229/**
6230 * Callback employed by ataSuspend and ataR3PowerOff.
6231 *
6232 * @returns true if we've quiesced, false if we're still working.
6233 * @param pDevIns The device instance.
6234 */
6235static DECLCALLBACK(bool) ataR3IsAsyncSuspendOrPowerOffDone(PPDMDEVINS pDevIns)
6236{
6237 return ataR3AllAsyncIOIsIdle(pDevIns);
6238}
6239
6240
6241/**
6242 * Common worker for ataSuspend and ataR3PowerOff.
6243 */
6244static void ataR3SuspendOrPowerOff(PPDMDEVINS pDevIns)
6245{
6246 if (!ataR3AllAsyncIOIsIdle(pDevIns))
6247 PDMDevHlpSetAsyncNotification(pDevIns, ataR3IsAsyncSuspendOrPowerOffDone);
6248}
6249
6250
6251/**
6252 * Power Off notification.
6253 *
6254 * @returns VBox status.
6255 * @param pDevIns The device instance data.
6256 */
6257static DECLCALLBACK(void) ataR3PowerOff(PPDMDEVINS pDevIns)
6258{
6259 Log(("%s:\n", __FUNCTION__));
6260 ataR3SuspendOrPowerOff(pDevIns);
6261}
6262
6263
6264/**
6265 * Suspend notification.
6266 *
6267 * @returns VBox status.
6268 * @param pDevIns The device instance data.
6269 */
6270static DECLCALLBACK(void) ataR3Suspend(PPDMDEVINS pDevIns)
6271{
6272 Log(("%s:\n", __FUNCTION__));
6273 ataR3SuspendOrPowerOff(pDevIns);
6274}
6275
6276
6277/**
6278 * Callback employed by ataR3Reset.
6279 *
6280 * @returns true if we've quiesced, false if we're still working.
6281 * @param pDevIns The device instance.
6282 */
6283static DECLCALLBACK(bool) ataR3IsAsyncResetDone(PPDMDEVINS pDevIns)
6284{
6285 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6286
6287 if (!ataR3AllAsyncIOIsIdle(pDevIns))
6288 return false;
6289
6290 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6291 {
6292 PDMCritSectEnter(&pThis->aCts[i].lock, VERR_INTERNAL_ERROR);
6293 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6294 ataResetDevice(&pThis->aCts[i].aIfs[j]);
6295 PDMCritSectLeave(&pThis->aCts[i].lock);
6296 }
6297 return true;
6298}
6299
6300
6301/**
6302 * Common reset worker for ataR3Reset and ataR3Construct.
6303 *
6304 * @returns VBox status.
6305 * @param pDevIns The device instance data.
6306 * @param fConstruct Indicates who is calling.
6307 */
6308static int ataR3ResetCommon(PPDMDEVINS pDevIns, bool fConstruct)
6309{
6310 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6311
6312 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6313 {
6314 PDMCritSectEnter(&pThis->aCts[i].lock, VERR_INTERNAL_ERROR);
6315
6316 pThis->aCts[i].iSelectedIf = 0;
6317 pThis->aCts[i].iAIOIf = 0;
6318 pThis->aCts[i].BmDma.u8Cmd = 0;
6319 /* Report that both drives present on the bus are in DMA mode. This
6320 * pretends that there is a BIOS that has set it up. Normal reset
6321 * default is 0x00. */
6322 pThis->aCts[i].BmDma.u8Status = (pThis->aCts[i].aIfs[0].pDrvBase != NULL ? BM_STATUS_D0DMA : 0)
6323 | (pThis->aCts[i].aIfs[1].pDrvBase != NULL ? BM_STATUS_D1DMA : 0);
6324 pThis->aCts[i].BmDma.pvAddr = 0;
6325
6326 pThis->aCts[i].fReset = true;
6327 pThis->aCts[i].fRedo = false;
6328 pThis->aCts[i].fRedoIdle = false;
6329 ataAsyncIOClearRequests(&pThis->aCts[i]);
6330 Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i));
6331 ataAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetARequest);
6332 ataAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetCRequest);
6333
6334 PDMCritSectLeave(&pThis->aCts[i].lock);
6335 }
6336
6337 int rcRet = VINF_SUCCESS;
6338 if (!fConstruct)
6339 {
6340 /*
6341 * Setup asynchronous notification completion if the requests haven't
6342 * completed yet.
6343 */
6344 if (!ataR3IsAsyncResetDone(pDevIns))
6345 PDMDevHlpSetAsyncNotification(pDevIns, ataR3IsAsyncResetDone);
6346 }
6347 else
6348 {
6349 /*
6350 * Wait for the requests for complete.
6351 *
6352 * Would be real nice if we could do it all from EMT(0) and not
6353 * involve the worker threads, then we could dispense with all the
6354 * waiting and semaphore ping-pong here...
6355 */
6356 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6357 {
6358 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
6359 {
6360 int rc = RTSemMutexRequest(pThis->aCts[i].AsyncIORequestMutex, RT_INDEFINITE_WAIT);
6361 AssertRC(rc);
6362
6363 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, true);
6364 rc = RTThreadUserReset(pThis->aCts[i].AsyncIOThread);
6365 AssertRC(rc);
6366
6367 rc = RTSemMutexRelease(pThis->aCts[i].AsyncIORequestMutex);
6368 AssertRC(rc);
6369
6370 if (!ataAsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/))
6371 {
6372 rc = RTThreadUserWait(pThis->aCts[i].AsyncIOThread, 30*1000 /*ms*/);
6373 if (RT_FAILURE(rc))
6374 rc = RTThreadUserWait(pThis->aCts[i].AsyncIOThread, 1000 /*ms*/);
6375 if (RT_FAILURE(rc))
6376 {
6377 AssertRC(rc);
6378 rcRet = rc;
6379 }
6380 }
6381 }
6382 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, false);
6383 }
6384 if (RT_SUCCESS(rcRet))
6385 {
6386 rcRet = ataR3IsAsyncResetDone(pDevIns) ? VINF_SUCCESS : VERR_INTERNAL_ERROR;
6387 AssertRC(rcRet);
6388 }
6389 }
6390 return rcRet;
6391}
6392
6393
6394/**
6395 * Reset notification.
6396 *
6397 * @param pDevIns The device instance data.
6398 */
6399static DECLCALLBACK(void) ataR3Reset(PPDMDEVINS pDevIns)
6400{
6401 ataR3ResetCommon(pDevIns, false /*fConstruct*/);
6402}
6403
6404
6405/**
6406 * Prepare state save and load operation.
6407 *
6408 * @returns VBox status code.
6409 * @param pDevIns Device instance of the device which registered the data unit.
6410 * @param pSSM SSM operation handle.
6411 */
6412static DECLCALLBACK(int) ataSaveLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
6413{
6414 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6415
6416 /* sanity - the suspend notification will wait on the async stuff. */
6417 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6418 AssertLogRelMsgReturn(ataAsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/),
6419 ("i=%u\n", i),
6420 VERR_SSM_IDE_ASYNC_TIMEOUT);
6421 return VINF_SUCCESS;
6422}
6423
6424/**
6425 * @copydoc FNSSMDEVLIVEEXEC
6426 */
6427static DECLCALLBACK(int) ataLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
6428{
6429 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6430
6431 SSMR3PutU8(pSSM, pThis->u8Type);
6432 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6433 {
6434 SSMR3PutBool(pSSM, true); /* For controller enabled / disabled. */
6435 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6436 {
6437 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].pDrvBase != NULL);
6438 SSMR3PutStrZ(pSSM, pThis->aCts[i].aIfs[j].szSerialNumber);
6439 SSMR3PutStrZ(pSSM, pThis->aCts[i].aIfs[j].szFirmwareRevision);
6440 SSMR3PutStrZ(pSSM, pThis->aCts[i].aIfs[j].szModelNumber);
6441 }
6442 }
6443
6444 return VINF_SSM_DONT_CALL_AGAIN;
6445}
6446
6447
6448/**
6449 * @copydoc FNSSMDEVSAVEEXEC
6450 */
6451static DECLCALLBACK(int) ataSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
6452{
6453 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6454
6455 ataLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
6456
6457 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6458 {
6459 SSMR3PutU8(pSSM, pThis->aCts[i].iSelectedIf);
6460 SSMR3PutU8(pSSM, pThis->aCts[i].iAIOIf);
6461 SSMR3PutU8(pSSM, pThis->aCts[i].uAsyncIOState);
6462 SSMR3PutBool(pSSM, pThis->aCts[i].fChainedTransfer);
6463 SSMR3PutBool(pSSM, pThis->aCts[i].fReset);
6464 SSMR3PutBool(pSSM, pThis->aCts[i].fRedo);
6465 SSMR3PutBool(pSSM, pThis->aCts[i].fRedoIdle);
6466 SSMR3PutBool(pSSM, pThis->aCts[i].fRedoDMALastDesc);
6467 SSMR3PutMem(pSSM, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
6468 SSMR3PutGCPhys32(pSSM, pThis->aCts[i].pFirstDMADesc);
6469 SSMR3PutGCPhys32(pSSM, pThis->aCts[i].pLastDMADesc);
6470 SSMR3PutGCPhys32(pSSM, pThis->aCts[i].pRedoDMABuffer);
6471 SSMR3PutU32(pSSM, pThis->aCts[i].cbRedoDMABuffer);
6472
6473 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6474 {
6475 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fLBA48);
6476 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fATAPI);
6477 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fIrqPending);
6478 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].cMultSectors);
6479 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
6480 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
6481 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
6482 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
6483 SSMR3PutU64(pSSM, pThis->aCts[i].aIfs[j].cTotalSectors);
6484 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegFeature);
6485 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
6486 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegError);
6487 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegNSector);
6488 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
6489 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegSector);
6490 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegSectorHOB);
6491 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegLCyl);
6492 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegLCylHOB);
6493 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegHCyl);
6494 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegHCylHOB);
6495 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegSelect);
6496 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegStatus);
6497 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegCommand);
6498 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegDevCtl);
6499 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATATransferMode);
6500 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uTxDir);
6501 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].iBeginTransfer);
6502 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].iSourceSink);
6503 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fDMA);
6504 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fATAPITransfer);
6505 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbTotalTransfer);
6506 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbElementaryTransfer);
6507 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferCur);
6508 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferEnd);
6509 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
6510 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
6511 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iATAPILBA);
6512 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbATAPISector);
6513 SSMR3PutMem(pSSM, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
6514 SSMR3PutMem(pSSM, &pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6515 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
6516 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].MediaEventStatus);
6517 SSMR3PutMem(pSSM, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
6518 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbIOBuffer);
6519 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
6520 SSMR3PutMem(pSSM, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
6521 else
6522 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
6523 }
6524 }
6525
6526 return SSMR3PutU32(pSSM, ~0); /* sanity/terminator */
6527}
6528
6529/**
6530 * Converts the LUN number into a message string.
6531 */
6532static const char *ataStringifyLun(unsigned iLun)
6533{
6534 switch (iLun)
6535 {
6536 case 0: return "primary master";
6537 case 1: return "primary slave";
6538 case 2: return "secondary master";
6539 case 3: return "secondary slave";
6540 default: AssertFailedReturn("unknown lun");
6541 }
6542}
6543
6544/**
6545 * FNSSMDEVLOADEXEC
6546 */
6547static DECLCALLBACK(int) ataLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
6548{
6549 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6550 int rc;
6551 uint32_t u32;
6552
6553 if ( uVersion != ATA_SAVED_STATE_VERSION
6554 && uVersion != ATA_SAVED_STATE_VERSION_VBOX_30
6555 && uVersion != ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE
6556 && uVersion != ATA_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS
6557 && uVersion != ATA_SAVED_STATE_VERSION_WITH_BOOL_TYPE)
6558 {
6559 AssertMsgFailed(("uVersion=%d\n", uVersion));
6560 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
6561 }
6562
6563 /*
6564 * Verify the configuration.
6565 */
6566 if (uVersion > ATA_SAVED_STATE_VERSION_VBOX_30)
6567 {
6568 uint8_t u8Type;
6569 rc = SSMR3GetU8(pSSM, &u8Type);
6570 AssertRCReturn(rc, rc);
6571 if (u8Type != pThis->u8Type)
6572 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch: u8Type - saved=%u config=%u"), u8Type, pThis->u8Type);
6573
6574 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6575 {
6576 bool fEnabled;
6577 rc = SSMR3GetBool(pSSM, &fEnabled);
6578 AssertRCReturn(rc, rc);
6579 if (!fEnabled)
6580 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Ctr#%u onfig mismatch: fEnabled != true"), i);
6581
6582 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6583 {
6584 ATADevState const *pIf = &pThis->aCts[i].aIfs[j];
6585
6586 bool fInUse;
6587 rc = SSMR3GetBool(pSSM, &fInUse);
6588 AssertRCReturn(rc, rc);
6589 if (fInUse != (pIf->pDrvBase != NULL))
6590 return SSMR3SetCfgError(pSSM, RT_SRC_POS,
6591 N_("The %s VM is missing a %s device. Please make sure the source and target VMs have compatible storage configurations"),
6592 fInUse ? "target" : "source", ataStringifyLun(pIf->iLUN) );
6593
6594 char szSerialNumber[ATA_SERIAL_NUMBER_LENGTH+1];
6595 rc = SSMR3GetStrZ(pSSM, szSerialNumber, sizeof(szSerialNumber));
6596 AssertRCReturn(rc, rc);
6597 if (strcmp(szSerialNumber, pIf->szSerialNumber))
6598 LogRel(("PIIX3 ATA: LUN#%u config mismatch: Serial number - saved='%s' config='%s'\n",
6599 pIf->iLUN, szSerialNumber, pIf->szSerialNumber));
6600
6601 char szFirmwareRevision[ATA_FIRMWARE_REVISION_LENGTH+1];
6602 rc = SSMR3GetStrZ(pSSM, szFirmwareRevision, sizeof(szFirmwareRevision));
6603 AssertRCReturn(rc, rc);
6604 if (strcmp(szFirmwareRevision, pIf->szFirmwareRevision))
6605 LogRel(("PIIX3 ATA: LUN#%u config mismatch: Firmware revision - saved='%s' config='%s'\n",
6606 pIf->iLUN, szFirmwareRevision, pIf->szFirmwareRevision));
6607
6608 char szModelNumber[ATA_MODEL_NUMBER_LENGTH+1];
6609 rc = SSMR3GetStrZ(pSSM, szModelNumber, sizeof(szModelNumber));
6610 AssertRCReturn(rc, rc);
6611 if (strcmp(szModelNumber, pIf->szModelNumber))
6612 LogRel(("PIIX3 ATA: LUN#%u config mismatch: Model number - saved='%s' config='%s'\n",
6613 pIf->iLUN, szModelNumber, pIf->szModelNumber));
6614 }
6615 }
6616 }
6617 if (uPass != SSM_PASS_FINAL)
6618 return VINF_SUCCESS;
6619
6620 /*
6621 * Restore valid parts of the PCIATAState structure
6622 */
6623 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6624 {
6625 /* integrity check */
6626 if (!ataAsyncIOIsIdle(&pThis->aCts[i], false))
6627 {
6628 AssertMsgFailed(("Async I/O for controller %d is active\n", i));
6629 return VERR_INTERNAL_ERROR_4;
6630 }
6631
6632 SSMR3GetU8(pSSM, &pThis->aCts[i].iSelectedIf);
6633 SSMR3GetU8(pSSM, &pThis->aCts[i].iAIOIf);
6634 SSMR3GetU8(pSSM, &pThis->aCts[i].uAsyncIOState);
6635 SSMR3GetBool(pSSM, &pThis->aCts[i].fChainedTransfer);
6636 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fReset);
6637 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fRedo);
6638 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fRedoIdle);
6639 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fRedoDMALastDesc);
6640 SSMR3GetMem(pSSM, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
6641 SSMR3GetGCPhys32(pSSM, &pThis->aCts[i].pFirstDMADesc);
6642 SSMR3GetGCPhys32(pSSM, &pThis->aCts[i].pLastDMADesc);
6643 SSMR3GetGCPhys32(pSSM, &pThis->aCts[i].pRedoDMABuffer);
6644 SSMR3GetU32(pSSM, &pThis->aCts[i].cbRedoDMABuffer);
6645
6646 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6647 {
6648 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fLBA48);
6649 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fATAPI);
6650 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fIrqPending);
6651 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].cMultSectors);
6652 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
6653 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
6654 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
6655 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
6656 SSMR3GetU64(pSSM, &pThis->aCts[i].aIfs[j].cTotalSectors);
6657 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegFeature);
6658 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
6659 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegError);
6660 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegNSector);
6661 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
6662 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegSector);
6663 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegSectorHOB);
6664 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegLCyl);
6665 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegLCylHOB);
6666 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegHCyl);
6667 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegHCylHOB);
6668 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegSelect);
6669 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegStatus);
6670 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegCommand);
6671 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegDevCtl);
6672 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATATransferMode);
6673 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uTxDir);
6674 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].iBeginTransfer);
6675 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].iSourceSink);
6676 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fDMA);
6677 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fATAPITransfer);
6678 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbTotalTransfer);
6679 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbElementaryTransfer);
6680 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferCur);
6681 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferEnd);
6682 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
6683 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
6684 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iATAPILBA);
6685 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbATAPISector);
6686 SSMR3GetMem(pSSM, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
6687 if (uVersion > ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE)
6688 {
6689 SSMR3GetMem(pSSM, pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6690 }
6691 else
6692 {
6693 uint8_t uATAPISenseKey, uATAPIASC;
6694 memset(pThis->aCts[i].aIfs[j].abATAPISense, '\0', sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6695 pThis->aCts[i].aIfs[j].abATAPISense[0] = 0x70 | (1 << 7);
6696 pThis->aCts[i].aIfs[j].abATAPISense[7] = 10;
6697 SSMR3GetU8(pSSM, &uATAPISenseKey);
6698 SSMR3GetU8(pSSM, &uATAPIASC);
6699 pThis->aCts[i].aIfs[j].abATAPISense[2] = uATAPISenseKey & 0x0f;
6700 pThis->aCts[i].aIfs[j].abATAPISense[12] = uATAPIASC;
6701 }
6702 /** @todo triple-check this hack after passthrough is working */
6703 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
6704 if (uVersion > ATA_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS)
6705 SSMR3GetU32(pSSM, (uint32_t*)&pThis->aCts[i].aIfs[j].MediaEventStatus);
6706 else
6707 pThis->aCts[i].aIfs[j].MediaEventStatus = ATA_EVENT_STATUS_UNCHANGED;
6708 SSMR3GetMem(pSSM, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
6709 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbIOBuffer);
6710 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
6711 {
6712 if (pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer))
6713 SSMR3GetMem(pSSM, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
6714 else
6715 {
6716 LogRel(("ATA: No buffer for %d/%d\n", i, j));
6717 if (SSMR3HandleGetAfter(pSSM) != SSMAFTER_DEBUG_IT)
6718 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("No buffer for %d/%d"), i, j);
6719
6720 /* skip the buffer if we're loading for the debugger / animator. */
6721 uint8_t u8Ignored;
6722 size_t cbLeft = pThis->aCts[i].aIfs[j].cbIOBuffer;
6723 while (cbLeft-- > 0)
6724 SSMR3GetU8(pSSM, &u8Ignored);
6725 }
6726 }
6727 else
6728 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
6729 }
6730 }
6731 if (uVersion <= ATA_SAVED_STATE_VERSION_VBOX_30)
6732 SSMR3GetU8(pSSM, &pThis->u8Type);
6733
6734 rc = SSMR3GetU32(pSSM, &u32);
6735 if (RT_FAILURE(rc))
6736 return rc;
6737 if (u32 != ~0U)
6738 {
6739 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
6740 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
6741 return rc;
6742 }
6743
6744 return VINF_SUCCESS;
6745}
6746
6747/**
6748 * Convert config value to DEVPCBIOSBOOT.
6749 *
6750 * @returns VBox status code.
6751 * @param pDevIns The device instance data.
6752 * @param pCfg Configuration handle.
6753 * @param penmChipset Where to store the chipset type.
6754 */
6755static int ataControllerFromCfg(PPDMDEVINS pDevIns, PCFGMNODE pCfg, CHIPSET *penmChipset)
6756{
6757 char szType[20];
6758
6759 int rc = CFGMR3QueryStringDef(pCfg, "Type", &szType[0], sizeof(szType), "PIIX4");
6760 if (RT_FAILURE(rc))
6761 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
6762 N_("Configuration error: Querying \"Type\" as a string failed"));
6763 if (!strcmp(szType, "PIIX3"))
6764 *penmChipset = CHIPSET_PIIX3;
6765 else if (!strcmp(szType, "PIIX4"))
6766 *penmChipset = CHIPSET_PIIX4;
6767 else if (!strcmp(szType, "ICH6"))
6768 *penmChipset = CHIPSET_ICH6;
6769 else
6770 {
6771 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
6772 N_("Configuration error: The \"Type\" value \"%s\" is unknown"),
6773 szType);
6774 rc = VERR_INTERNAL_ERROR;
6775 }
6776 return rc;
6777}
6778
6779
6780/**
6781 * @interface_method_impl{PDMDEVREG,pfnConstruct}
6782 */
6783static DECLCALLBACK(int) ataR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
6784{
6785 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6786 PPDMIBASE pBase;
6787 int rc;
6788 bool fGCEnabled;
6789 bool fR0Enabled;
6790 uint32_t DelayIRQMillies;
6791
6792 Assert(iInstance == 0);
6793 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
6794
6795 /*
6796 * Initialize NIL handle values (for the destructor).
6797 */
6798 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6799 {
6800 pThis->aCts[i].AsyncIOSem = NIL_RTSEMEVENT;
6801 pThis->aCts[i].SuspendIOSem = NIL_RTSEMEVENT;
6802 pThis->aCts[i].AsyncIORequestMutex = NIL_RTSEMMUTEX;
6803 pThis->aCts[i].AsyncIOThread = NIL_RTTHREAD;
6804 }
6805
6806 /*
6807 * Validate and read configuration.
6808 */
6809 if (!CFGMR3AreValuesValid(pCfg,
6810 "GCEnabled\0"
6811 "R0Enabled\0"
6812 "IRQDelay\0"
6813 "Type\0")
6814 /** @todo || invalid keys */)
6815 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
6816 N_("PIIX3 configuration error: unknown option specified"));
6817
6818 rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
6819 if (RT_FAILURE(rc))
6820 return PDMDEV_SET_ERROR(pDevIns, rc,
6821 N_("PIIX3 configuration error: failed to read GCEnabled as boolean"));
6822 Log(("%s: fGCEnabled=%d\n", __FUNCTION__, fGCEnabled));
6823
6824 rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
6825 if (RT_FAILURE(rc))
6826 return PDMDEV_SET_ERROR(pDevIns, rc,
6827 N_("PIIX3 configuration error: failed to read R0Enabled as boolean"));
6828 Log(("%s: fR0Enabled=%d\n", __FUNCTION__, fR0Enabled));
6829
6830 rc = CFGMR3QueryU32Def(pCfg, "IRQDelay", &DelayIRQMillies, 0);
6831 if (RT_FAILURE(rc))
6832 return PDMDEV_SET_ERROR(pDevIns, rc,
6833 N_("PIIX3 configuration error: failed to read IRQDelay as integer"));
6834 Log(("%s: DelayIRQMillies=%d\n", __FUNCTION__, DelayIRQMillies));
6835 Assert(DelayIRQMillies < 50);
6836
6837 CHIPSET enmChipset = CHIPSET_PIIX3;
6838 rc = ataControllerFromCfg(pDevIns, pCfg, &enmChipset);
6839 if (RT_FAILURE(rc))
6840 return rc;
6841 pThis->u8Type = (uint8_t)enmChipset;
6842
6843 /*
6844 * Initialize data (most of it anyway).
6845 */
6846 /* Status LUN. */
6847 pThis->IBase.pfnQueryInterface = ataStatus_QueryInterface;
6848 pThis->ILeds.pfnQueryStatusLed = ataStatus_QueryStatusLed;
6849
6850 /* PCI configuration space. */
6851 PCIDevSetVendorId(&pThis->dev, 0x8086); /* Intel */
6852
6853 /*
6854 * When adding more IDE chipsets, don't forget to update pci_bios_init_device()
6855 * as it explicitly checks for PCI id for IDE controllers.
6856 */
6857 switch (pThis->u8Type)
6858 {
6859 case CHIPSET_ICH6:
6860 PCIDevSetDeviceId(&pThis->dev, 0x269e); /* ICH6 IDE */
6861 /** @todo: do we need it? Do we need anything else? */
6862 pThis->dev.config[0x48] = 0x00; /* UDMACTL */
6863 pThis->dev.config[0x4A] = 0x00; /* UDMATIM */
6864 pThis->dev.config[0x4B] = 0x00;
6865 {
6866 /*
6867 * See www.intel.com/Assets/PDF/manual/298600.pdf p. 30
6868 * Report
6869 * WR_Ping-Pong_EN: must be set
6870 * PCR0, PCR1: 80-pin primary cable reporting for both disks
6871 * SCR0, SCR1: 80-pin secondary cable reporting for both disks
6872 */
6873 uint16_t u16Config = (1<<10) | (1<<7) | (1<<6) | (1<<5) | (1<<4) ;
6874 pThis->dev.config[0x54] = u16Config & 0xff;
6875 pThis->dev.config[0x55] = u16Config >> 8;
6876 }
6877 break;
6878 case CHIPSET_PIIX4:
6879 PCIDevSetDeviceId(&pThis->dev, 0x7111); /* PIIX4 IDE */
6880 PCIDevSetRevisionId(&pThis->dev, 0x01); /* PIIX4E */
6881 pThis->dev.config[0x48] = 0x00; /* UDMACTL */
6882 pThis->dev.config[0x4A] = 0x00; /* UDMATIM */
6883 pThis->dev.config[0x4B] = 0x00;
6884 break;
6885 case CHIPSET_PIIX3:
6886 PCIDevSetDeviceId(&pThis->dev, 0x7010); /* PIIX3 IDE */
6887 break;
6888 default:
6889 AssertMsgFailed(("Unsupported IDE chipset type: %d\n", pThis->u8Type));
6890 }
6891
6892 PCIDevSetCommand( &pThis->dev, PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER);
6893 PCIDevSetClassProg( &pThis->dev, 0x8a); /* programming interface = PCI_IDE bus master is supported */
6894 PCIDevSetClassSub( &pThis->dev, 0x01); /* class_sub = PCI_IDE */
6895 PCIDevSetClassBase( &pThis->dev, 0x01); /* class_base = PCI_mass_storage */
6896 PCIDevSetHeaderType(&pThis->dev, 0x00);
6897
6898 pThis->pDevIns = pDevIns;
6899 pThis->fGCEnabled = fGCEnabled;
6900 pThis->fR0Enabled = fR0Enabled;
6901 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6902 {
6903 pThis->aCts[i].pDevInsR3 = pDevIns;
6904 pThis->aCts[i].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
6905 pThis->aCts[i].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
6906 pThis->aCts[i].DelayIRQMillies = (uint32_t)DelayIRQMillies;
6907 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6908 {
6909 ATADevState *pIf = &pThis->aCts[i].aIfs[j];
6910
6911 pIf->iLUN = i * RT_ELEMENTS(pThis->aCts) + j;
6912 pIf->pDevInsR3 = pDevIns;
6913 pIf->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
6914 pIf->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
6915 pIf->pControllerR3 = &pThis->aCts[i];
6916 pIf->pControllerR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
6917 pIf->pControllerRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
6918 pIf->IBase.pfnQueryInterface = ataQueryInterface;
6919 pIf->IMountNotify.pfnMountNotify = ataMountNotify;
6920 pIf->IMountNotify.pfnUnmountNotify = ataUnmountNotify;
6921 pIf->IPort.pfnQueryDeviceLocation = ataR3QueryDeviceLocation;
6922 pIf->Led.u32Magic = PDMLED_MAGIC;
6923 }
6924 }
6925
6926 Assert(RT_ELEMENTS(pThis->aCts) == 2);
6927 pThis->aCts[0].irq = 14;
6928 pThis->aCts[0].IOPortBase1 = 0x1f0;
6929 pThis->aCts[0].IOPortBase2 = 0x3f6;
6930 pThis->aCts[1].irq = 15;
6931 pThis->aCts[1].IOPortBase1 = 0x170;
6932 pThis->aCts[1].IOPortBase2 = 0x376;
6933
6934 /*
6935 * Register the PCI device.
6936 * N.B. There's a hack in the PIIX3 PCI bridge device to assign this
6937 * device the slot next to itself.
6938 */
6939 rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev);
6940 if (RT_FAILURE(rc))
6941 return PDMDEV_SET_ERROR(pDevIns, rc,
6942 N_("PIIX3 cannot register PCI device"));
6943 //AssertMsg(pThis->dev.devfn == 9 || iInstance != 0, ("pThis->dev.devfn=%d\n", pThis->dev.devfn));
6944 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataBMDMAIORangeMap);
6945 if (RT_FAILURE(rc))
6946 return PDMDEV_SET_ERROR(pDevIns, rc,
6947 N_("PIIX3 cannot register PCI I/O region for BMDMA"));
6948
6949 /*
6950 * Register the I/O ports.
6951 * The ports are all hardcoded and enforced by the PIIX3 host bridge controller.
6952 */
6953 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6954 {
6955 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTHCPTR)(uintptr_t)i,
6956 ataIOPortWrite1, ataIOPortRead1, ataIOPortWriteStr1, ataIOPortReadStr1, "ATA I/O Base 1");
6957 if (RT_FAILURE(rc))
6958 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers"));
6959
6960 if (fGCEnabled)
6961 {
6962 rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTGCPTR)i,
6963 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
6964 if (RT_FAILURE(rc))
6965 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers (GC)"));
6966 }
6967
6968 if (fR0Enabled)
6969 {
6970#if 1
6971 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
6972 "ataIOPortWrite1", "ataIOPortRead1", NULL, NULL, "ATA I/O Base 1");
6973#else
6974 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
6975 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
6976#endif
6977 if (RT_FAILURE(rc))
6978 return PDMDEV_SET_ERROR(pDevIns, rc, "PIIX3 cannot register I/O handlers (R0).");
6979 }
6980
6981 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTHCPTR)(uintptr_t)i,
6982 ataIOPortWrite2, ataIOPortRead2, NULL, NULL, "ATA I/O Base 2");
6983 if (RT_FAILURE(rc))
6984 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers"));
6985
6986 if (fGCEnabled)
6987 {
6988 rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTGCPTR)i,
6989 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
6990 if (RT_FAILURE(rc))
6991 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (GC)"));
6992 }
6993 if (fR0Enabled)
6994 {
6995 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTR0PTR)i,
6996 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
6997 if (RT_FAILURE(rc))
6998 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (R0)"));
6999 }
7000
7001 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
7002 {
7003 ATADevState *pIf = &pThis->aCts[i].aIfs[j];
7004 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATADMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7005 "Number of ATA DMA transfers.", "/Devices/IDE%d/ATA%d/Unit%d/DMA", iInstance, i, j);
7006 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7007 "Number of ATA PIO transfers.", "/Devices/IDE%d/ATA%d/Unit%d/PIO", iInstance, i, j);
7008 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIDMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7009 "Number of ATAPI DMA transfers.", "/Devices/IDE%d/ATA%d/Unit%d/AtapiDMA", iInstance, i, j);
7010 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7011 "Number of ATAPI PIO transfers.", "/Devices/IDE%d/ATA%d/Unit%d/AtapiPIO", iInstance, i, j);
7012#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
7013 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatReads, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7014 "Profiling of the read operations.", "/Devices/IDE%d/ATA%d/Unit%d/Reads", iInstance, i, j);
7015#endif
7016 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesRead, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
7017 "Amount of data read.", "/Devices/IDE%d/ATA%d/Unit%d/ReadBytes", iInstance, i, j);
7018#ifdef VBOX_INSTRUMENT_DMA_WRITES
7019 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatInstrVDWrites,STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7020 "Profiling of the VD DMA write operations.", "/Devices/IDE%d/ATA%d/Unit%d/InstrVDWrites", iInstance, i, j);
7021#endif
7022#ifdef VBOX_WITH_STATISTICS
7023 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatWrites, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7024 "Profiling of the write operations.", "/Devices/IDE%d/ATA%d/Unit%d/Writes", iInstance, i, j);
7025#endif
7026 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
7027 "Amount of data written.", "/Devices/IDE%d/ATA%d/Unit%d/WrittenBytes", iInstance, i, j);
7028#ifdef VBOX_WITH_STATISTICS
7029 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatFlushes, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7030 "Profiling of the flush operations.", "/Devices/IDE%d/ATA%d/Unit%d/Flushes", iInstance, i, j);
7031#endif
7032 }
7033#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
7034 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncOps, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7035 "The number of async operations.", "/Devices/IDE%d/ATA%d/Async/Operations", iInstance, i);
7036 /** @todo STAMUNIT_MICROSECS */
7037 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMinWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
7038 "Minimum wait in microseconds.", "/Devices/IDE%d/ATA%d/Async/MinWait", iInstance, i);
7039 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMaxWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
7040 "Maximum wait in microseconds.", "/Devices/IDE%d/ATA%d/Async/MaxWait", iInstance, i);
7041 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncTimeUS, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
7042 "Total time spent in microseconds.", "/Devices/IDE%d/ATA%d/Async/TotalTimeUS", iInstance, i);
7043 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncTime, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7044 "Profiling of async operations.", "/Devices/IDE%d/ATA%d/Async/Time", iInstance, i);
7045 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatLockWait, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7046 "Profiling of locks.", "/Devices/IDE%d/ATA%d/Async/LockWait", iInstance, i);
7047#endif /* VBOX_WITH_STATISTICS */
7048
7049 /* Initialize per-controller critical section */
7050 rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].lock, RT_SRC_POS, "ATA#%u", i);
7051 if (RT_FAILURE(rc))
7052 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot initialize critical section"));
7053 }
7054
7055 /*
7056 * Attach status driver (optional).
7057 */
7058 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pBase, "Status Port");
7059 if (RT_SUCCESS(rc))
7060 {
7061 pThis->pLedsConnector = PDMIBASE_QUERY_INTERFACE(pBase, PDMILEDCONNECTORS);
7062 pThis->pMediaNotify = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIANOTIFY);
7063 }
7064 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
7065 {
7066 AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc));
7067 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot attach to status driver"));
7068 }
7069
7070 /*
7071 * Attach the units.
7072 */
7073 uint32_t cbTotalBuffer = 0;
7074 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7075 {
7076 PATACONTROLLER pCtl = &pThis->aCts[i];
7077
7078 /*
7079 * Start the worker thread.
7080 */
7081 pCtl->uAsyncIOState = ATA_AIO_NEW;
7082 rc = RTSemEventCreate(&pCtl->AsyncIOSem);
7083 AssertLogRelRCReturn(rc, rc);
7084 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
7085 AssertLogRelRCReturn(rc, rc);
7086 rc = RTSemMutexCreate(&pCtl->AsyncIORequestMutex);
7087 AssertLogRelRCReturn(rc, rc);
7088 ataAsyncIOClearRequests(pCtl);
7089 rc = RTThreadCreateF(&pCtl->AsyncIOThread, ataAsyncIOLoop, (void *)pCtl, 128*1024 /*cbStack*/,
7090 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "ATA-%u", i);
7091 AssertLogRelRCReturn(rc, rc);
7092 Assert(pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->AsyncIOSem != NIL_RTSEMEVENT && pCtl->SuspendIOSem != NIL_RTSEMEVENT && pCtl->AsyncIORequestMutex != NIL_RTSEMMUTEX);
7093 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));
7094
7095 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
7096 {
7097 static const char *s_apszDescs[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
7098 {
7099 { "Primary Master", "Primary Slave" },
7100 { "Secondary Master", "Secondary Slave" }
7101 };
7102
7103 /*
7104 * Try attach the block device and get the interfaces,
7105 * required as well as optional.
7106 */
7107 ATADevState *pIf = &pCtl->aIfs[j];
7108
7109 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, s_apszDescs[i][j]);
7110 if (RT_SUCCESS(rc))
7111 {
7112 rc = ataConfigLun(pDevIns, pIf);
7113 if (RT_SUCCESS(rc))
7114 {
7115 /*
7116 * Init vendor product data.
7117 */
7118 static const char *s_apszCFGMKeys[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
7119 {
7120 { "PrimaryMaster", "PrimarySlave" },
7121 { "SecondaryMaster", "SecondarySlave" }
7122 };
7123
7124 /* Generate a default serial number. */
7125 char szSerial[ATA_SERIAL_NUMBER_LENGTH+1];
7126 RTUUID Uuid;
7127 if (pIf->pDrvBlock)
7128 rc = pIf->pDrvBlock->pfnGetUuid(pIf->pDrvBlock, &Uuid);
7129 else
7130 RTUuidClear(&Uuid);
7131
7132 if (RT_FAILURE(rc) || RTUuidIsNull(&Uuid))
7133 {
7134 /* Generate a predictable serial for drives which don't have a UUID. */
7135 RTStrPrintf(szSerial, sizeof(szSerial), "VB%x-%04x%04x",
7136 pIf->iLUN + pDevIns->iInstance * 32,
7137 pThis->aCts[i].IOPortBase1, pThis->aCts[i].IOPortBase2);
7138 }
7139 else
7140 RTStrPrintf(szSerial, sizeof(szSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
7141
7142 /* Get user config if present using defaults otherwise. */
7143 PCFGMNODE pCfgNode = CFGMR3GetChild(pCfg, s_apszCFGMKeys[i][j]);
7144 rc = CFGMR3QueryStringDef(pCfgNode, "SerialNumber", pIf->szSerialNumber, sizeof(pIf->szSerialNumber),
7145 szSerial);
7146 if (RT_FAILURE(rc))
7147 {
7148 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7149 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7150 N_("PIIX3 configuration error: \"SerialNumber\" is longer than 20 bytes"));
7151 return PDMDEV_SET_ERROR(pDevIns, rc,
7152 N_("PIIX3 configuration error: failed to read \"SerialNumber\" as string"));
7153 }
7154
7155 rc = CFGMR3QueryStringDef(pCfgNode, "FirmwareRevision", pIf->szFirmwareRevision, sizeof(pIf->szFirmwareRevision),
7156 "1.0");
7157 if (RT_FAILURE(rc))
7158 {
7159 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7160 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7161 N_("PIIX3 configuration error: \"FirmwareRevision\" is longer than 8 bytes"));
7162 return PDMDEV_SET_ERROR(pDevIns, rc,
7163 N_("PIIX3 configuration error: failed to read \"FirmwareRevision\" as string"));
7164 }
7165
7166 rc = CFGMR3QueryStringDef(pCfgNode, "ModelNumber", pIf->szModelNumber, sizeof(pIf->szModelNumber),
7167 pIf->fATAPI ? "VBOX CD-ROM" : "VBOX HARDDISK");
7168 if (RT_FAILURE(rc))
7169 {
7170 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7171 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7172 N_("PIIX3 configuration error: \"ModelNumber\" is longer than 40 bytes"));
7173 return PDMDEV_SET_ERROR(pDevIns, rc,
7174 N_("PIIX3 configuration error: failed to read \"ModelNumber\" as string"));
7175 }
7176
7177 rc = CFGMR3QueryBoolDef(pCfgNode, "NonRotationalMedium", &pIf->fNonRotational, false);
7178 if (RT_FAILURE(rc))
7179 return PDMDEV_SET_ERROR(pDevIns, rc,
7180 N_("PIIX3 configuration error: failed to read \"NonRotationalMedium\" as boolean"));
7181
7182 /* There are three other identification strings for CD drives used for INQUIRY */
7183 if (pIf->fATAPI)
7184 {
7185 rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIVendorId", pIf->szInquiryVendorId, sizeof(pIf->szInquiryVendorId),
7186 "VBOX");
7187 if (RT_FAILURE(rc))
7188 {
7189 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7190 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7191 N_("PIIX3 configuration error: \"ATAPIVendorId\" is longer than 16 bytes"));
7192 return PDMDEV_SET_ERROR(pDevIns, rc,
7193 N_("PIIX3 configuration error: failed to read \"ATAPIVendorId\" as string"));
7194 }
7195
7196 rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIProductId", pIf->szInquiryProductId, sizeof(pIf->szInquiryProductId),
7197 "CD-ROM");
7198 if (RT_FAILURE(rc))
7199 {
7200 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7201 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7202 N_("PIIX3 configuration error: \"ATAPIProductId\" is longer than 16 bytes"));
7203 return PDMDEV_SET_ERROR(pDevIns, rc,
7204 N_("PIIX3 configuration error: failed to read \"ATAPIProductId\" as string"));
7205 }
7206
7207 rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIRevision", pIf->szInquiryRevision, sizeof(pIf->szInquiryRevision),
7208 "1.0");
7209 if (RT_FAILURE(rc))
7210 {
7211 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7212 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7213 N_("PIIX3 configuration error: \"ATAPIRevision\" is longer than 4 bytes"));
7214 return PDMDEV_SET_ERROR(pDevIns, rc,
7215 N_("PIIX3 configuration error: failed to read \"ATAPIRevision\" as string"));
7216 }
7217 }
7218 }
7219
7220 }
7221 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
7222 {
7223 pIf->pDrvBase = NULL;
7224 pIf->pDrvBlock = NULL;
7225 pIf->cbIOBuffer = 0;
7226 pIf->pbIOBufferR3 = NULL;
7227 pIf->pbIOBufferR0 = NIL_RTR0PTR;
7228 pIf->pbIOBufferRC = NIL_RTGCPTR;
7229 LogRel(("PIIX3 ATA: LUN#%d: no unit\n", pIf->iLUN));
7230 }
7231 else
7232 {
7233 switch (rc)
7234 {
7235 case VERR_ACCESS_DENIED:
7236 /* Error already cached by DrvHostBase */
7237 return rc;
7238 default:
7239 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
7240 N_("PIIX3 cannot attach drive to the %s"),
7241 s_apszDescs[i][j]);
7242 }
7243 }
7244 cbTotalBuffer += pIf->cbIOBuffer;
7245 }
7246 }
7247
7248 rc = PDMDevHlpSSMRegisterEx(pDevIns, ATA_SAVED_STATE_VERSION, sizeof(*pThis) + cbTotalBuffer, NULL,
7249 NULL, ataLiveExec, NULL,
7250 ataSaveLoadPrep, ataSaveExec, NULL,
7251 ataSaveLoadPrep, ataLoadExec, NULL);
7252 if (RT_FAILURE(rc))
7253 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register save state handlers"));
7254
7255 /*
7256 * Initialize the device state.
7257 */
7258 return ataR3ResetCommon(pDevIns, true /*fConstruct*/);
7259}
7260
7261
7262/**
7263 * The device registration structure.
7264 */
7265const PDMDEVREG g_DevicePIIX3IDE =
7266{
7267 /* u32Version */
7268 PDM_DEVREG_VERSION,
7269 /* szName */
7270 "piix3ide",
7271 /* szRCMod */
7272 "VBoxDDGC.gc",
7273 /* szR0Mod */
7274 "VBoxDDR0.r0",
7275 /* pszDescription */
7276 "Intel PIIX3 ATA controller.\n"
7277 " LUN #0 is primary master.\n"
7278 " LUN #1 is primary slave.\n"
7279 " LUN #2 is secondary master.\n"
7280 " LUN #3 is secondary slave.\n"
7281 " LUN #999 is the LED/Status connector.",
7282 /* fFlags */
7283 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
7284 PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION,
7285 /* fClass */
7286 PDM_DEVREG_CLASS_STORAGE,
7287 /* cMaxInstances */
7288 1,
7289 /* cbInstance */
7290 sizeof(PCIATAState),
7291 /* pfnConstruct */
7292 ataR3Construct,
7293 /* pfnDestruct */
7294 ataR3Destruct,
7295 /* pfnRelocate */
7296 ataR3Relocate,
7297 /* pfnIOCtl */
7298 NULL,
7299 /* pfnPowerOn */
7300 NULL,
7301 /* pfnReset */
7302 ataR3Reset,
7303 /* pfnSuspend */
7304 ataR3Suspend,
7305 /* pfnResume */
7306 ataR3Resume,
7307 /* pfnAttach */
7308 ataR3Attach,
7309 /* pfnDetach */
7310 ataR3Detach,
7311 /* pfnQueryInterface. */
7312 NULL,
7313 /* pfnInitComplete */
7314 NULL,
7315 /* pfnPowerOff */
7316 ataR3PowerOff,
7317 /* pfnSoftReset */
7318 NULL,
7319 /* u32VersionEnd */
7320 PDM_DEVREG_VERSION
7321};
7322#endif /* IN_RING3 */
7323#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Note: See TracBrowser for help on using the repository browser.

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