VirtualBox

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

Last change on this file since 15845 was 15845, checked in by vboxsync, 16 years ago

warnings and minor fixes to coding style

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

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