VirtualBox

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

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

VMM,Devices: Automatically use a per-device lock instead of the giant IOM lock. With exception of the PIC, APIC, IOAPIC and PCI buses which are all using the PDM crit sect, there should be no calls between devices. So, this change should be relatively safe.

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