VirtualBox

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

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

Device/Storage: fix CD/DVD media change problems in passthrough mode.

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