VirtualBox

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

Last change on this file since 45973 was 45973, checked in by vboxsync, 12 years ago

Alignment.

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

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