VirtualBox

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

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

ATA: disabled SCSI_GET_EVENT_STATUS_NOTIFICATION passthrough command as we cannot emulate this command properly if passthrough is disabled

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