VirtualBox

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

Last change on this file since 1 was 1, checked in by vboxsync, 55 years ago

import

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

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