VirtualBox

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

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

Main/Console+Machine: add notification for guest triggered eject, which right now results in updating the VM config
Devices/Storage/ATA+AHCI: trigger the eject notification

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

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