VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/ATAController.cpp@ 22432

Last change on this file since 22432 was 21321, checked in by vboxsync, 15 years ago

OSE: export SCSI + SATA

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