VirtualBox

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

最後變更 在這個檔案從427是 427,由 vboxsync 提交於 18 年 前

Suspend (and later redo) I/O operations and EMT if the VDI layer reports
disk full condition. Provide a warning message in this case.

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

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