VirtualBox

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

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

VMM,Devices,Main: VMR3ReqCall w/ RT_INDEFINITE_WAIT -> VMR3ReqCallWait.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 202.3 KB
 
1/* $Id: ATAController.cpp 23012 2009-09-14 16:38:13Z 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.alldomusa.eu.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 = VMR3ReqCallWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
2259 (PFNRT)s->pDrvMount->pfnUnmount, 2, s->pDrvMount, false);
2260 AssertReleaseRC(rc);
2261 {
2262 STAM_PROFILE_START(&pCtl->StatLockWait, a);
2263 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
2264 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
2265 }
2266 }
2267 break;
2268 case 3: /* 11 - Load media */
2269 /** @todo rc = s->pDrvMount->pfnLoadMedia(s->pDrvMount) */
2270 break;
2271 }
2272 if (RT_SUCCESS(rc))
2273 atapiCmdOK(s);
2274 else
2275 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIA_LOAD_OR_EJECT_FAILED);
2276 }
2277 break;
2278 case SCSI_MECHANISM_STATUS:
2279 {
2280 cbMax = ataBE2H_U16(pbPacket + 8);
2281 ataStartTransfer(s, RT_MIN(cbMax, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MECHANISM_STATUS, true);
2282 }
2283 break;
2284 case SCSI_READ_TOC_PMA_ATIP:
2285 {
2286 uint8_t format;
2287
2288 if (s->cNotifiedMediaChange > 0)
2289 {
2290 s->cNotifiedMediaChange-- ;
2291 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2292 break;
2293 }
2294 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2295 {
2296 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2297 break;
2298 }
2299 cbMax = ataBE2H_U16(pbPacket + 7);
2300 /* SCSI MMC-3 spec says format is at offset 2 (lower 4 bits),
2301 * but Linux kernel uses offset 9 (topmost 2 bits). Hope that
2302 * the other field is clear... */
2303 format = (pbPacket[2] & 0xf) | (pbPacket[9] >> 6);
2304 switch (format)
2305 {
2306 case 0:
2307 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_NORMAL, true);
2308 break;
2309 case 1:
2310 ataStartTransfer(s, RT_MIN(cbMax, 12), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_MULTI, true);
2311 break;
2312 case 2:
2313 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_RAW, true);
2314 break;
2315 default:
2316 error_cmd:
2317 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2318 break;
2319 }
2320 }
2321 break;
2322 case SCSI_READ_CAPACITY:
2323 if (s->cNotifiedMediaChange > 0)
2324 {
2325 s->cNotifiedMediaChange-- ;
2326 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2327 break;
2328 }
2329 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2330 {
2331 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2332 break;
2333 }
2334 ataStartTransfer(s, 8, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_CAPACITY, true);
2335 break;
2336 case SCSI_READ_DISC_INFORMATION:
2337 if (s->cNotifiedMediaChange > 0)
2338 {
2339 s->cNotifiedMediaChange-- ;
2340 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2341 break;
2342 }
2343 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2344 {
2345 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2346 break;
2347 }
2348 cbMax = ataBE2H_U16(pbPacket + 7);
2349 ataStartTransfer(s, RT_MIN(cbMax, 34), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DISC_INFORMATION, true);
2350 break;
2351 case SCSI_READ_TRACK_INFORMATION:
2352 if (s->cNotifiedMediaChange > 0)
2353 {
2354 s->cNotifiedMediaChange-- ;
2355 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2356 break;
2357 }
2358 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2359 {
2360 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2361 break;
2362 }
2363 cbMax = ataBE2H_U16(pbPacket + 7);
2364 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TRACK_INFORMATION, true);
2365 break;
2366 case SCSI_GET_CONFIGURATION:
2367 /* No media change stuff here, it can confuse Linux guests. */
2368 cbMax = ataBE2H_U16(pbPacket + 7);
2369 ataStartTransfer(s, RT_MIN(cbMax, 32), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
2370 break;
2371 case SCSI_INQUIRY:
2372 cbMax = ataBE2H_U16(pbPacket + 3);
2373 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_INQUIRY, true);
2374 break;
2375 default:
2376 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2377 break;
2378 }
2379}
2380
2381
2382/*
2383 * Parse ATAPI commands, passing them directly to the CD/DVD drive.
2384 */
2385static void atapiParseCmdPassthrough(AHCIATADevState *s)
2386{
2387 const uint8_t *pbPacket;
2388 uint8_t *pbBuf;
2389 uint32_t cSectors, iATAPILBA;
2390 uint32_t cbTransfer = 0;
2391 PDMBLOCKTXDIR uTxDir = PDMBLOCKTXDIR_NONE;
2392
2393 pbPacket = s->aATAPICmd;
2394 pbBuf = s->CTXALLSUFF(pbIOBuffer);
2395 switch (pbPacket[0])
2396 {
2397 case SCSI_BLANK:
2398 goto sendcmd;
2399 case SCSI_CLOSE_TRACK_SESSION:
2400 goto sendcmd;
2401 case SCSI_ERASE_10:
2402 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2403 cbTransfer = ataBE2H_U16(pbPacket + 7);
2404 Log2(("ATAPI PT: lba %d\n", iATAPILBA));
2405 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2406 goto sendcmd;
2407 case SCSI_FORMAT_UNIT:
2408 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
2409 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2410 goto sendcmd;
2411 case SCSI_GET_CONFIGURATION:
2412 cbTransfer = ataBE2H_U16(pbPacket + 7);
2413 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2414 goto sendcmd;
2415 case SCSI_GET_EVENT_STATUS_NOTIFICATION:
2416 cbTransfer = ataBE2H_U16(pbPacket + 7);
2417 if (ASMAtomicReadU32(&s->MediaEventStatus) != ATA_EVENT_STATUS_UNCHANGED)
2418 {
2419 ataStartTransfer(s, RT_MIN(cbTransfer, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_EVENT_STATUS_NOTIFICATION, true);
2420 break;
2421 }
2422 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2423 goto sendcmd;
2424 case SCSI_GET_PERFORMANCE:
2425 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
2426 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2427 goto sendcmd;
2428 case SCSI_INQUIRY:
2429 cbTransfer = ataBE2H_U16(pbPacket + 3);
2430 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2431 goto sendcmd;
2432 case SCSI_LOAD_UNLOAD_MEDIUM:
2433 goto sendcmd;
2434 case SCSI_MECHANISM_STATUS:
2435 cbTransfer = ataBE2H_U16(pbPacket + 8);
2436 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2437 goto sendcmd;
2438 case SCSI_MODE_SELECT_10:
2439 cbTransfer = ataBE2H_U16(pbPacket + 7);
2440 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2441 goto sendcmd;
2442 case SCSI_MODE_SENSE_10:
2443 cbTransfer = ataBE2H_U16(pbPacket + 7);
2444 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2445 goto sendcmd;
2446 case SCSI_PAUSE_RESUME:
2447 goto sendcmd;
2448 case SCSI_PLAY_AUDIO_10:
2449 goto sendcmd;
2450 case SCSI_PLAY_AUDIO_12:
2451 goto sendcmd;
2452 case SCSI_PLAY_AUDIO_MSF:
2453 goto sendcmd;
2454 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
2455 /** @todo do not forget to unlock when a VM is shut down */
2456 goto sendcmd;
2457 case SCSI_READ_10:
2458 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2459 cSectors = ataBE2H_U16(pbPacket + 7);
2460 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2461 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2462 cbTransfer = cSectors * s->cbATAPISector;
2463 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2464 goto sendcmd;
2465 case SCSI_READ_12:
2466 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2467 cSectors = ataBE2H_U32(pbPacket + 6);
2468 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2469 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2470 cbTransfer = cSectors * s->cbATAPISector;
2471 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2472 goto sendcmd;
2473 case SCSI_READ_BUFFER:
2474 cbTransfer = ataBE2H_U24(pbPacket + 6);
2475 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2476 goto sendcmd;
2477 case SCSI_READ_BUFFER_CAPACITY:
2478 cbTransfer = ataBE2H_U16(pbPacket + 7);
2479 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2480 goto sendcmd;
2481 case SCSI_READ_CAPACITY:
2482 cbTransfer = 8;
2483 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2484 goto sendcmd;
2485 case SCSI_READ_CD:
2486 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2487 cbTransfer = ataBE2H_U24(pbPacket + 6) / s->cbATAPISector * s->cbATAPISector;
2488 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2489 goto sendcmd;
2490 case SCSI_READ_CD_MSF:
2491 cSectors = ataMSF2LBA(pbPacket + 6) - ataMSF2LBA(pbPacket + 3);
2492 if (cSectors > 32)
2493 cSectors = 32; /* Limit transfer size to 64~74K. Safety first. In any case this can only harm software doing CDDA extraction. */
2494 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2495 cbTransfer = cSectors * s->cbATAPISector;
2496 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2497 goto sendcmd;
2498 case SCSI_READ_DISC_INFORMATION:
2499 cbTransfer = ataBE2H_U16(pbPacket + 7);
2500 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2501 goto sendcmd;
2502 case SCSI_READ_DVD_STRUCTURE:
2503 cbTransfer = ataBE2H_U16(pbPacket + 8);
2504 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2505 goto sendcmd;
2506 case SCSI_READ_FORMAT_CAPACITIES:
2507 cbTransfer = ataBE2H_U16(pbPacket + 7);
2508 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2509 goto sendcmd;
2510 case SCSI_READ_SUBCHANNEL:
2511 cbTransfer = ataBE2H_U16(pbPacket + 7);
2512 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2513 goto sendcmd;
2514 case SCSI_READ_TOC_PMA_ATIP:
2515 cbTransfer = ataBE2H_U16(pbPacket + 7);
2516 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2517 goto sendcmd;
2518 case SCSI_READ_TRACK_INFORMATION:
2519 cbTransfer = ataBE2H_U16(pbPacket + 7);
2520 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2521 goto sendcmd;
2522 case SCSI_REPAIR_TRACK:
2523 goto sendcmd;
2524 case SCSI_REPORT_KEY:
2525 cbTransfer = ataBE2H_U16(pbPacket + 8);
2526 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2527 goto sendcmd;
2528 case SCSI_REQUEST_SENSE:
2529 cbTransfer = pbPacket[4];
2530 if ((s->abATAPISense[2] & 0x0f) != SCSI_SENSE_NONE)
2531 {
2532 ataStartTransfer(s, RT_MIN(cbTransfer, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
2533 break;
2534 }
2535 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2536 goto sendcmd;
2537 case SCSI_RESERVE_TRACK:
2538 goto sendcmd;
2539 case SCSI_SCAN:
2540 goto sendcmd;
2541 case SCSI_SEEK_10:
2542 goto sendcmd;
2543 case SCSI_SEND_CUE_SHEET:
2544 cbTransfer = ataBE2H_U24(pbPacket + 6);
2545 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2546 goto sendcmd;
2547 case SCSI_SEND_DVD_STRUCTURE:
2548 cbTransfer = ataBE2H_U16(pbPacket + 8);
2549 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2550 goto sendcmd;
2551 case SCSI_SEND_EVENT:
2552 cbTransfer = ataBE2H_U16(pbPacket + 8);
2553 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2554 goto sendcmd;
2555 case SCSI_SEND_KEY:
2556 cbTransfer = ataBE2H_U16(pbPacket + 8);
2557 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2558 goto sendcmd;
2559 case SCSI_SEND_OPC_INFORMATION:
2560 cbTransfer = ataBE2H_U16(pbPacket + 7);
2561 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2562 goto sendcmd;
2563 case SCSI_SET_CD_SPEED:
2564 goto sendcmd;
2565 case SCSI_SET_READ_AHEAD:
2566 goto sendcmd;
2567 case SCSI_SET_STREAMING:
2568 cbTransfer = ataBE2H_U16(pbPacket + 9);
2569 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2570 goto sendcmd;
2571 case SCSI_START_STOP_UNIT:
2572 goto sendcmd;
2573 case SCSI_STOP_PLAY_SCAN:
2574 goto sendcmd;
2575 case SCSI_SYNCHRONIZE_CACHE:
2576 goto sendcmd;
2577 case SCSI_TEST_UNIT_READY:
2578 goto sendcmd;
2579 case SCSI_VERIFY_10:
2580 goto sendcmd;
2581 case SCSI_WRITE_10:
2582 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2583 cSectors = ataBE2H_U16(pbPacket + 7);
2584 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2585#if 0
2586 /* The sector size is determined by the async I/O thread. */
2587 s->cbATAPISector = 0;
2588 /* Preliminary, will be corrected once the sector size is known. */
2589 cbTransfer = cSectors;
2590#else
2591 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2592 cbTransfer = cSectors * s->cbATAPISector;
2593#endif
2594 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2595 goto sendcmd;
2596 case SCSI_WRITE_12:
2597 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2598 cSectors = ataBE2H_U32(pbPacket + 6);
2599 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2600#if 0
2601 /* The sector size is determined by the async I/O thread. */
2602 s->cbATAPISector = 0;
2603 /* Preliminary, will be corrected once the sector size is known. */
2604 cbTransfer = cSectors;
2605#else
2606 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2607 cbTransfer = cSectors * s->cbATAPISector;
2608#endif
2609 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2610 goto sendcmd;
2611 case SCSI_WRITE_AND_VERIFY_10:
2612 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2613 cSectors = ataBE2H_U16(pbPacket + 7);
2614 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2615 /* The sector size is determined by the async I/O thread. */
2616 s->cbATAPISector = 0;
2617 /* Preliminary, will be corrected once the sector size is known. */
2618 cbTransfer = cSectors;
2619 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2620 goto sendcmd;
2621 case SCSI_WRITE_BUFFER:
2622 switch (pbPacket[1] & 0x1f)
2623 {
2624 case 0x04: /* download microcode */
2625 case 0x05: /* download microcode and save */
2626 case 0x06: /* download microcode with offsets */
2627 case 0x07: /* download microcode with offsets and save */
2628 case 0x0e: /* download microcode with offsets and defer activation */
2629 case 0x0f: /* activate deferred microcode */
2630 LogRel(("AHCI ATA: LUN#%d: CD-ROM passthrough command attempted to update firmware, blocked\n", s->iLUN));
2631 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2632 break;
2633 default:
2634 cbTransfer = ataBE2H_U16(pbPacket + 6);
2635 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2636 goto sendcmd;
2637 }
2638 break;
2639 case SCSI_REPORT_LUNS: /* Not part of MMC-3, but used by Windows. */
2640 cbTransfer = ataBE2H_U32(pbPacket + 6);
2641 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2642 goto sendcmd;
2643 case SCSI_REZERO_UNIT:
2644 /* Obsolete command used by cdrecord. What else would one expect?
2645 * This command is not sent to the drive, it is handled internally,
2646 * as the Linux kernel doesn't like it (message "scsi: unknown
2647 * opcode 0x01" in syslog) and replies with a sense code of 0,
2648 * which sends cdrecord to an endless loop. */
2649 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2650 break;
2651 default:
2652 LogRel(("AHCI ATA: LUN#%d: passthrough unimplemented for command %#x\n", s->iLUN, pbPacket[0]));
2653 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2654 break;
2655 sendcmd:
2656 /* Send a command to the drive, passing data in/out as required. */
2657 Log2(("ATAPI PT: max size %d\n", cbTransfer));
2658 Assert(cbTransfer <= s->cbIOBuffer);
2659 if (cbTransfer == 0)
2660 uTxDir = PDMBLOCKTXDIR_NONE;
2661 ataStartTransfer(s, cbTransfer, uTxDir, ATAFN_BT_ATAPI_PASSTHROUGH_CMD, ATAFN_SS_ATAPI_PASSTHROUGH, true);
2662 }
2663}
2664
2665
2666static void atapiParseCmd(AHCIATADevState *s)
2667{
2668 const uint8_t *pbPacket;
2669
2670 pbPacket = s->aATAPICmd;
2671#ifdef DEBUG
2672 Log(("%s: LUN#%d DMA=%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0], SCSICmdText(pbPacket[0])));
2673#else /* !DEBUG */
2674 Log(("%s: LUN#%d DMA=%d CMD=%#04x\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0]));
2675#endif /* !DEBUG */
2676 Log2(("%s: limit=%#x packet: %.*Rhxs\n", __FUNCTION__, s->uATARegLCyl | (s->uATARegHCyl << 8), ATAPI_PACKET_SIZE, pbPacket));
2677
2678 if (s->fATAPIPassthrough)
2679 atapiParseCmdPassthrough(s);
2680 else
2681 atapiParseCmdVirtualATAPI(s);
2682}
2683
2684
2685static bool ataPacketSS(AHCIATADevState *s)
2686{
2687 s->fDMA = !!(s->uATARegFeature & 1);
2688 memcpy(s->aATAPICmd, s->CTXALLSUFF(pbIOBuffer), ATAPI_PACKET_SIZE);
2689 s->uTxDir = PDMBLOCKTXDIR_NONE;
2690 s->cbTotalTransfer = 0;
2691 s->cbElementaryTransfer = 0;
2692 atapiParseCmd(s);
2693 return false;
2694}
2695
2696#if 0
2697
2698/**
2699 * SCSI_GET_EVENT_STATUS_NOTIFICATION should return "medium removed" event
2700 * from now on, regardless if there was a medium inserted or not.
2701 */
2702static void ataMediumRemoved(AHCIATADevState *s)
2703{
2704 ASMAtomicWriteU32(&s->MediaEventStatus, ATA_EVENT_STATUS_MEDIA_REMOVED);
2705}
2706
2707
2708/**
2709 * SCSI_GET_EVENT_STATUS_NOTIFICATION should return "medium inserted". If
2710 * there was already a medium inserted, don't forget to send the "medium
2711 * removed" event first.
2712 */
2713static void ataMediumInserted(AHCIATADevState *s)
2714{
2715 uint32_t OldStatus, NewStatus;
2716 do
2717 {
2718 OldStatus = ASMAtomicReadU32(&s->MediaEventStatus);
2719 switch (OldStatus)
2720 {
2721 case ATA_EVENT_STATUS_MEDIA_CHANGED:
2722 case ATA_EVENT_STATUS_MEDIA_REMOVED:
2723 /* no change, we will send "medium removed" + "medium inserted" */
2724 NewStatus = ATA_EVENT_STATUS_MEDIA_CHANGED;
2725 break;
2726 default:
2727 NewStatus = ATA_EVENT_STATUS_MEDIA_NEW;
2728 break;
2729 }
2730 } while (!ASMAtomicCmpXchgU32(&s->MediaEventStatus, NewStatus, OldStatus));
2731}
2732
2733
2734/**
2735 * Called when a media is mounted.
2736 *
2737 * @param pInterface Pointer to the interface structure containing the called function pointer.
2738 */
2739static DECLCALLBACK(void) ataMountNotify(PPDMIMOUNTNOTIFY pInterface)
2740{
2741 AHCIATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
2742 Log(("%s: changing LUN#%d\n", __FUNCTION__, pIf->iLUN));
2743
2744 /* Ignore the call if we're called while being attached. */
2745 if (!pIf->pDrvBlock)
2746 return;
2747
2748 if (pIf->fATAPI)
2749 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
2750 else
2751 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
2752
2753 /* Report media changed in TEST UNIT and other (probably incorrect) places. */
2754 if (pIf->cNotifiedMediaChange < 2)
2755 pIf->cNotifiedMediaChange = 2;
2756 ataMediumInserted(pIf);
2757}
2758
2759/**
2760 * Called when a media is unmounted
2761 * @param pInterface Pointer to the interface structure containing the called function pointer.
2762 */
2763static DECLCALLBACK(void) ataUnmountNotify(PPDMIMOUNTNOTIFY pInterface)
2764{
2765 AHCIATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
2766 Log(("%s:\n", __FUNCTION__));
2767 pIf->cTotalSectors = 0;
2768
2769 /*
2770 * Whatever I do, XP will not use the GET MEDIA STATUS nor the EVENT stuff.
2771 * However, it will respond to TEST UNIT with a 0x6 0x28 (media changed) sense code.
2772 * So, we'll give it 4 TEST UNIT command to catch up, two which the media is not
2773 * present and 2 in which it is changed.
2774 */
2775 pIf->cNotifiedMediaChange = 4;
2776 ataMediumRemoved(pIf);
2777}
2778#endif
2779
2780static void ataPacketBT(AHCIATADevState *s)
2781{
2782 s->cbElementaryTransfer = s->cbTotalTransfer;
2783 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_CD;
2784 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
2785 ataSetStatusValue(s, ATA_STAT_READY);
2786}
2787
2788
2789static void ataResetDevice(AHCIATADevState *s)
2790{
2791 s->cMultSectors = ATA_MAX_MULT_SECTORS;
2792 s->cNotifiedMediaChange = 0;
2793 ASMAtomicWriteU32(&s->MediaEventStatus, ATA_EVENT_STATUS_UNCHANGED);
2794 ataUnsetIRQ(s);
2795
2796 s->uATARegSelect = 0x20;
2797 ataSetStatusValue(s, ATA_STAT_READY);
2798 ataSetSignature(s);
2799 s->cbTotalTransfer = 0;
2800 s->cbElementaryTransfer = 0;
2801 s->iIOBufferPIODataStart = 0;
2802 s->iIOBufferPIODataEnd = 0;
2803 s->iBeginTransfer = ATAFN_BT_NULL;
2804 s->iSourceSink = ATAFN_SS_NULL;
2805 s->fATAPITransfer = false;
2806 s->uATATransferMode = ATA_MODE_UDMA | 2; /* AHCI supports only up to UDMA2 */
2807
2808 s->uATARegFeature = 0;
2809}
2810
2811
2812static bool ataExecuteDeviceDiagnosticSS(AHCIATADevState *s)
2813{
2814 ataSetSignature(s);
2815 if (s->fATAPI)
2816 ataSetStatusValue(s, 0); /* NOTE: READY is _not_ set */
2817 else
2818 ataSetStatusValue(s, ATA_STAT_READY);
2819 s->uATARegError = 0x01;
2820 return false;
2821}
2822
2823
2824static void ataParseCmd(AHCIATADevState *s, uint8_t cmd)
2825{
2826#ifdef DEBUG
2827 Log(("%s: LUN#%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, cmd, ATACmdText(cmd)));
2828#else /* !DEBUG */
2829 Log(("%s: LUN#%d CMD=%#04x\n", __FUNCTION__, s->iLUN, cmd));
2830#endif /* !DEBUG */
2831 s->fLBA48 = false;
2832 s->fDMA = false;
2833 if (cmd == ATA_IDLE_IMMEDIATE)
2834 {
2835 /* Detect Linux timeout recovery, first tries IDLE IMMEDIATE (which
2836 * would overwrite the failing command unfortunately), then RESET. */
2837 int32_t uCmdWait = -1;
2838 uint64_t uNow = RTTimeNanoTS();
2839 if (s->u64CmdTS)
2840 uCmdWait = (uNow - s->u64CmdTS) / 1000;
2841 LogRel(("AHCI ATA: LUN#%d: IDLE IMMEDIATE, CmdIf=%#04x (%d usec ago)\n",
2842 s->iLUN, s->uATARegCommand, uCmdWait));
2843 }
2844 s->uATARegCommand = cmd;
2845 switch (cmd)
2846 {
2847 case ATA_IDENTIFY_DEVICE:
2848 if (s->pDrvBlock && !s->fATAPI)
2849 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_IDENTIFY, false);
2850 else
2851 {
2852 if (s->fATAPI)
2853 ataSetSignature(s);
2854 ataCmdError(s, ABRT_ERR);
2855 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2856 }
2857 break;
2858 case ATA_INITIALIZE_DEVICE_PARAMETERS:
2859 case ATA_RECALIBRATE:
2860 ataCmdOK(s, ATA_STAT_SEEK);
2861 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2862 break;
2863 case ATA_SET_MULTIPLE_MODE:
2864 if ( s->uATARegNSector != 0
2865 && ( s->uATARegNSector > ATA_MAX_MULT_SECTORS
2866 || (s->uATARegNSector & (s->uATARegNSector - 1)) != 0))
2867 {
2868 ataCmdError(s, ABRT_ERR);
2869 }
2870 else
2871 {
2872 Log2(("%s: set multi sector count to %d\n", __FUNCTION__, s->uATARegNSector));
2873 s->cMultSectors = s->uATARegNSector;
2874 ataCmdOK(s, 0);
2875 }
2876 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2877 break;
2878 case ATA_READ_VERIFY_SECTORS_EXT:
2879 s->fLBA48 = true;
2880 case ATA_READ_VERIFY_SECTORS:
2881 case ATA_READ_VERIFY_SECTORS_WITHOUT_RETRIES:
2882 /* do sector number check ? */
2883 ataCmdOK(s, 0);
2884 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2885 break;
2886 case ATA_READ_SECTORS_EXT:
2887 s->fLBA48 = true;
2888 case ATA_READ_SECTORS:
2889 case ATA_READ_SECTORS_WITHOUT_RETRIES:
2890 if (!s->pDrvBlock)
2891 goto abort_cmd;
2892 s->cSectorsPerIRQ = 1;
2893 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
2894 break;
2895 case ATA_WRITE_SECTORS_EXT:
2896 s->fLBA48 = true;
2897 case ATA_WRITE_SECTORS:
2898 case ATA_WRITE_SECTORS_WITHOUT_RETRIES:
2899 s->cSectorsPerIRQ = 1;
2900 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
2901 break;
2902 case ATA_READ_MULTIPLE_EXT:
2903 s->fLBA48 = true;
2904 case ATA_READ_MULTIPLE:
2905 if (!s->cMultSectors)
2906 goto abort_cmd;
2907 s->cSectorsPerIRQ = s->cMultSectors;
2908 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
2909 break;
2910 case ATA_WRITE_MULTIPLE_EXT:
2911 s->fLBA48 = true;
2912 case ATA_WRITE_MULTIPLE:
2913 if (!s->cMultSectors)
2914 goto abort_cmd;
2915 s->cSectorsPerIRQ = s->cMultSectors;
2916 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
2917 break;
2918 case ATA_READ_DMA_EXT:
2919 s->fLBA48 = true;
2920 case ATA_READ_DMA:
2921 case ATA_READ_DMA_WITHOUT_RETRIES:
2922 if (!s->pDrvBlock)
2923 goto abort_cmd;
2924 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
2925 s->fDMA = true;
2926 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
2927 break;
2928 case ATA_WRITE_DMA_EXT:
2929 s->fLBA48 = true;
2930 case ATA_WRITE_DMA:
2931 case ATA_WRITE_DMA_WITHOUT_RETRIES:
2932 if (!s->pDrvBlock)
2933 goto abort_cmd;
2934 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
2935 s->fDMA = true;
2936 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
2937 break;
2938 case ATA_READ_NATIVE_MAX_ADDRESS_EXT:
2939 s->fLBA48 = true;
2940 ataSetSector(s, s->cTotalSectors - 1);
2941 ataCmdOK(s, 0);
2942 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2943 break;
2944 case ATA_READ_NATIVE_MAX_ADDRESS:
2945 ataSetSector(s, RT_MIN(s->cTotalSectors, 1 << 28) - 1);
2946 ataCmdOK(s, 0);
2947 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2948 break;
2949 case ATA_CHECK_POWER_MODE:
2950 s->uATARegNSector = 0xff; /* drive active or idle */
2951 ataCmdOK(s, 0);
2952 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2953 break;
2954 case ATA_SET_FEATURES:
2955 Log2(("%s: feature=%#x\n", __FUNCTION__, s->uATARegFeature));
2956 if (!s->pDrvBlock)
2957 goto abort_cmd;
2958 switch (s->uATARegFeature)
2959 {
2960 case 0x02: /* write cache enable */
2961 Log2(("%s: write cache enable\n", __FUNCTION__));
2962 ataCmdOK(s, ATA_STAT_SEEK);
2963 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2964 break;
2965 case 0xaa: /* read look-ahead enable */
2966 Log2(("%s: read look-ahead enable\n", __FUNCTION__));
2967 ataCmdOK(s, ATA_STAT_SEEK);
2968 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2969 break;
2970 case 0x55: /* read look-ahead disable */
2971 Log2(("%s: read look-ahead disable\n", __FUNCTION__));
2972 ataCmdOK(s, ATA_STAT_SEEK);
2973 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2974 break;
2975 case 0xcc: /* reverting to power-on defaults enable */
2976 Log2(("%s: revert to power-on defaults enable\n", __FUNCTION__));
2977 ataCmdOK(s, ATA_STAT_SEEK);
2978 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2979 break;
2980 case 0x66: /* reverting to power-on defaults disable */
2981 Log2(("%s: revert to power-on defaults disable\n", __FUNCTION__));
2982 ataCmdOK(s, ATA_STAT_SEEK);
2983 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2984 break;
2985 case 0x82: /* write cache disable */
2986 Log2(("%s: write cache disable\n", __FUNCTION__));
2987 /* As per the ATA/ATAPI-6 specs, a write cache disable
2988 * command MUST flush the write buffers to disc. */
2989 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
2990 break;
2991 case 0x03: { /* set transfer mode */
2992 Log2(("%s: transfer mode %#04x\n", __FUNCTION__, s->uATARegNSector));
2993 switch (s->uATARegNSector & 0xf8)
2994 {
2995 case 0x00: /* PIO default */
2996 case 0x08: /* PIO mode */
2997 break;
2998 case ATA_MODE_MDMA: /* MDMA mode */
2999 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_MDMA_MODE_MAX);
3000 break;
3001 case ATA_MODE_UDMA: /* UDMA mode */
3002 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_UDMA_MODE_MAX);
3003 break;
3004 default:
3005 goto abort_cmd;
3006 }
3007 ataCmdOK(s, ATA_STAT_SEEK);
3008 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3009 break;
3010 }
3011 default:
3012 goto abort_cmd;
3013 }
3014 /*
3015 * OS/2 workarond:
3016 * The OS/2 IDE driver from MCP2 appears to rely on the feature register being
3017 * reset here. According to the specification, this is a driver bug as the register
3018 * contents are undefined after the call. This means we can just as well reset it.
3019 */
3020 s->uATARegFeature = 0;
3021 break;
3022 case ATA_FLUSH_CACHE_EXT:
3023 case ATA_FLUSH_CACHE:
3024 if (!s->pDrvBlock || s->fATAPI)
3025 goto abort_cmd;
3026 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
3027 break;
3028 case ATA_STANDBY_IMMEDIATE:
3029 ataCmdOK(s, 0);
3030 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3031 break;
3032 case ATA_IDLE_IMMEDIATE:
3033 LogRel(("AHCI ATA: LUN#%d: aborting current command\n", s->iLUN));
3034 ataAbortCurrentCommand(s, false);
3035 break;
3036 /* ATAPI commands */
3037 case ATA_IDENTIFY_PACKET_DEVICE:
3038 if (s->fATAPI)
3039 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_ATAPI_IDENTIFY, false);
3040 else
3041 {
3042 ataCmdError(s, ABRT_ERR);
3043 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3044 }
3045 break;
3046 case ATA_EXECUTE_DEVICE_DIAGNOSTIC:
3047 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC, false);
3048 break;
3049 case ATA_DEVICE_RESET:
3050 if (!s->fATAPI)
3051 goto abort_cmd;
3052 LogRel(("AHCI ATA: LUN#%d: performing device RESET\n", s->iLUN));
3053 ataAbortCurrentCommand(s, true);
3054 break;
3055 case ATA_PACKET:
3056 if (!s->fATAPI)
3057 goto abort_cmd;
3058 /* overlapping commands not supported */
3059 if (s->uATARegFeature & 0x02)
3060 goto abort_cmd;
3061 ataStartTransfer(s, ATAPI_PACKET_SIZE, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_PACKET, ATAFN_SS_PACKET, false);
3062 break;
3063 default:
3064 abort_cmd:
3065 ataCmdError(s, ABRT_ERR);
3066 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3067 break;
3068 }
3069}
3070
3071
3072/**
3073 * Waits for a particular async I/O thread to complete whatever it
3074 * is doing at the moment.
3075 *
3076 * @returns true on success.
3077 * @returns false when the thread is still processing.
3078 * @param pThis Pointer to the controller data.
3079 * @param cMillies How long to wait (total).
3080 */
3081static bool ataWaitForAsyncIOIsIdle(PAHCIATACONTROLLER pCtl, unsigned cMillies)
3082{
3083 uint64_t u64Start;
3084
3085 /*
3086 * Wait for any pending async operation to finish
3087 */
3088 u64Start = RTTimeMilliTS();
3089 for (;;)
3090 {
3091 if (ataAsyncIOIsIdle(pCtl, false))
3092 return true;
3093 if (RTTimeMilliTS() - u64Start >= cMillies)
3094 break;
3095
3096 /* Sleep for a bit. */
3097 RTThreadSleep(100);
3098 }
3099
3100 return false;
3101}
3102
3103#endif /* IN_RING3 */
3104
3105static int ataIOPortWriteU8(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3106{
3107 Log2(("%s: write addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3108 addr &= 7;
3109 switch (addr)
3110 {
3111 case 0:
3112 break;
3113 case 1: /* feature register */
3114 /* NOTE: data is written to the two drives */
3115 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3116 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3117 pCtl->aIfs[0].uATARegFeatureHOB = pCtl->aIfs[0].uATARegFeature;
3118 pCtl->aIfs[1].uATARegFeatureHOB = pCtl->aIfs[1].uATARegFeature;
3119 pCtl->aIfs[0].uATARegFeature = val;
3120 pCtl->aIfs[1].uATARegFeature = val;
3121 break;
3122 case 2: /* sector count */
3123 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3124 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3125 pCtl->aIfs[0].uATARegNSectorHOB = pCtl->aIfs[0].uATARegNSector;
3126 pCtl->aIfs[1].uATARegNSectorHOB = pCtl->aIfs[1].uATARegNSector;
3127 pCtl->aIfs[0].uATARegNSector = val;
3128 pCtl->aIfs[1].uATARegNSector = val;
3129 break;
3130 case 3: /* sector number */
3131 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3132 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3133 pCtl->aIfs[0].uATARegSectorHOB = pCtl->aIfs[0].uATARegSector;
3134 pCtl->aIfs[1].uATARegSectorHOB = pCtl->aIfs[1].uATARegSector;
3135 pCtl->aIfs[0].uATARegSector = val;
3136 pCtl->aIfs[1].uATARegSector = val;
3137 break;
3138 case 4: /* cylinder low */
3139 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3140 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3141 pCtl->aIfs[0].uATARegLCylHOB = pCtl->aIfs[0].uATARegLCyl;
3142 pCtl->aIfs[1].uATARegLCylHOB = pCtl->aIfs[1].uATARegLCyl;
3143 pCtl->aIfs[0].uATARegLCyl = val;
3144 pCtl->aIfs[1].uATARegLCyl = val;
3145 break;
3146 case 5: /* cylinder high */
3147 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3148 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3149 pCtl->aIfs[0].uATARegHCylHOB = pCtl->aIfs[0].uATARegHCyl;
3150 pCtl->aIfs[1].uATARegHCylHOB = pCtl->aIfs[1].uATARegHCyl;
3151 pCtl->aIfs[0].uATARegHCyl = val;
3152 pCtl->aIfs[1].uATARegHCyl = val;
3153 break;
3154 case 6: /* drive/head */
3155 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0;
3156 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0;
3157 if (((val >> 4) & 1) != pCtl->iSelectedIf)
3158 {
3159 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3160
3161 /* select another drive */
3162 pCtl->iSelectedIf = (val >> 4) & 1;
3163 /* The IRQ line is multiplexed between the two drives, so
3164 * update the state when switching to another drive. Only need
3165 * to update interrupt line if it is enabled and there is a
3166 * state change. */
3167 if ( !(pCtl->aIfs[pCtl->iSelectedIf].uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ)
3168 && ( pCtl->aIfs[pCtl->iSelectedIf].fIrqPending
3169 != pCtl->aIfs[pCtl->iSelectedIf ^ 1].fIrqPending))
3170 {
3171 if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
3172 {
3173 Log2(("%s: LUN#%d asserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3174 /* The BMDMA unit unconditionally sets BM_STATUS_INT if
3175 * the interrupt line is asserted. It monitors the line
3176 * for a rising edge. */
3177 pCtl->BmDma.u8Status |= BM_STATUS_INT;
3178 if (pCtl->irq == 16)
3179 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
3180 else
3181 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
3182 }
3183 else
3184 {
3185 Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3186 if (pCtl->irq == 16)
3187 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
3188 else
3189 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
3190 }
3191 }
3192 }
3193 break;
3194 default:
3195 case 7: /* command */
3196 /* ignore commands to non existant slave */
3197 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
3198 break;
3199#ifndef IN_RING3
3200 /* Don't do anything complicated in GC */
3201 return VINF_IOM_HC_IOPORT_WRITE;
3202#else /* IN_RING3 */
3203 ataParseCmd(&pCtl->aIfs[pCtl->iSelectedIf], val);
3204#endif /* !IN_RING3 */
3205 }
3206 return VINF_SUCCESS;
3207}
3208
3209
3210static int ataIOPortReadU8(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32)
3211{
3212 AHCIATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3213 uint32_t val;
3214 bool fHOB;
3215
3216 fHOB = !!(s->uATARegDevCtl & (1 << 7));
3217 switch (addr & 7)
3218 {
3219 case 0: /* data register */
3220 val = 0xff;
3221 break;
3222 case 1: /* error register */
3223 /* The ATA specification is very terse when it comes to specifying
3224 * the precise effects of reading back the error/feature register.
3225 * The error register (read-only) shares the register number with
3226 * the feature register (write-only), so it seems that it's not
3227 * necessary to support the usual HOB readback here. */
3228 if (!s->pDrvBlock)
3229 val = 0;
3230 else
3231 val = s->uATARegError;
3232 break;
3233 case 2: /* sector count */
3234 if (!s->pDrvBlock)
3235 val = 0;
3236 else if (fHOB)
3237 val = s->uATARegNSectorHOB;
3238 else
3239 val = s->uATARegNSector;
3240 break;
3241 case 3: /* sector number */
3242 if (!s->pDrvBlock)
3243 val = 0;
3244 else if (fHOB)
3245 val = s->uATARegSectorHOB;
3246 else
3247 val = s->uATARegSector;
3248 break;
3249 case 4: /* cylinder low */
3250 if (!s->pDrvBlock)
3251 val = 0;
3252 else if (fHOB)
3253 val = s->uATARegLCylHOB;
3254 else
3255 val = s->uATARegLCyl;
3256 break;
3257 case 5: /* cylinder high */
3258 if (!s->pDrvBlock)
3259 val = 0;
3260 else if (fHOB)
3261 val = s->uATARegHCylHOB;
3262 else
3263 val = s->uATARegHCyl;
3264 break;
3265 case 6: /* drive/head */
3266 /* This register must always work as long as there is at least
3267 * one drive attached to the controller. It is common between
3268 * both drives anyway (completely identical content). */
3269 if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
3270 val = 0;
3271 else
3272 val = s->uATARegSelect;
3273 break;
3274 default:
3275 case 7: /* primary status */
3276 {
3277 /* Counter for number of busy status seen in GC in a row. */
3278 static unsigned cBusy = 0;
3279
3280 if (!s->pDrvBlock)
3281 val = 0;
3282 else
3283 val = s->uATARegStatus;
3284
3285 /* Give the async I/O thread an opportunity to make progress,
3286 * don't let it starve by guests polling frequently. EMT has a
3287 * lower priority than the async I/O thread, but sometimes the
3288 * host OS doesn't care. With some guests we are only allowed to
3289 * be busy for about 5 milliseconds in some situations. Note that
3290 * this is no guarantee for any other VBox thread getting
3291 * scheduled, so this just lowers the CPU load a bit when drives
3292 * are busy. It cannot help with timing problems. */
3293 if (val & ATA_STAT_BUSY)
3294 {
3295#ifdef IN_RING3
3296 cBusy = 0;
3297 PDMCritSectLeave(&pCtl->lock);
3298
3299 RTThreadYield();
3300
3301 {
3302 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3303 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3304 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3305 }
3306
3307 val = s->uATARegStatus;
3308#else /* !IN_RING3 */
3309 /* Cannot yield CPU in guest context. And switching to host
3310 * context for each and every busy status is too costly,
3311 * especially on SMP systems where we don't gain much by
3312 * yielding the CPU to someone else. */
3313 if (++cBusy >= 20)
3314 {
3315 cBusy = 0;
3316 return VINF_IOM_HC_IOPORT_READ;
3317 }
3318#endif /* !IN_RING3 */
3319 }
3320 else
3321 cBusy = 0;
3322 ataUnsetIRQ(s);
3323 break;
3324 }
3325 }
3326 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3327 *pu32 = val;
3328 return VINF_SUCCESS;
3329}
3330
3331
3332static uint32_t ataStatusRead(PAHCIATACONTROLLER pCtl, uint32_t addr)
3333{
3334 AHCIATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3335 uint32_t val;
3336
3337 if ((!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock) ||
3338 (pCtl->iSelectedIf == 1 && !s->pDrvBlock))
3339 val = 0;
3340 else
3341 val = s->uATARegStatus;
3342 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3343 return val;
3344}
3345
3346static int ataControlWrite(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3347{
3348#ifndef IN_RING3
3349 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_RESET)
3350 return VINF_IOM_HC_IOPORT_WRITE; /* The RESET stuff is too complicated for GC. */
3351#endif /* !IN_RING3 */
3352
3353 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3354 /* RESET is common for both drives attached to a controller. */
3355 if (!(pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3356 (val & ATA_DEVCTL_RESET))
3357 {
3358#ifdef IN_RING3
3359 /* Software RESET low to high */
3360 int32_t uCmdWait0 = -1, uCmdWait1 = -1;
3361 uint64_t uNow = RTTimeNanoTS();
3362 if (pCtl->aIfs[0].u64CmdTS)
3363 uCmdWait0 = (uNow - pCtl->aIfs[0].u64CmdTS) / 1000;
3364 if (pCtl->aIfs[1].u64CmdTS)
3365 uCmdWait1 = (uNow - pCtl->aIfs[1].u64CmdTS) / 1000;
3366 LogRel(("ATA: Ctl: RESET, DevSel=%d AIOIf=%d CmdIf0=%#04x (%d usec ago) CmdIf1=%#04x (%d usec ago)\n",
3367 pCtl->iSelectedIf, pCtl->iAIOIf,
3368 pCtl->aIfs[0].uATARegCommand, uCmdWait0,
3369 pCtl->aIfs[1].uATARegCommand, uCmdWait1));
3370 pCtl->fReset = true;
3371 /* Everything must be done after the reset flag is set, otherwise
3372 * there are unavoidable races with the currently executing request
3373 * (which might just finish in the mean time). */
3374 pCtl->fChainedTransfer = false;
3375 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
3376 {
3377 ataResetDevice(&pCtl->aIfs[i]);
3378 /* The following cannot be done using ataSetStatusValue() since the
3379 * reset flag is already set, which suppresses all status changes. */
3380 pCtl->aIfs[i].uATARegStatus = ATA_STAT_BUSY | ATA_STAT_SEEK;
3381 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, pCtl->aIfs[i].iLUN, pCtl->aIfs[i].uATARegStatus));
3382 pCtl->aIfs[i].uATARegError = 0x01;
3383 }
3384 ataAsyncIOClearRequests(pCtl);
3385 Log2(("%s: Ctl: message to async I/O thread, resetA\n", __FUNCTION__));
3386 if (val & ATA_DEVCTL_HOB)
3387 {
3388 val &= ~ATA_DEVCTL_HOB;
3389 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3390 }
3391 ataAsyncIOPutRequest(pCtl, &ataResetARequest);
3392#else /* !IN_RING3 */
3393 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3394#endif /* IN_RING3 */
3395 }
3396 else if ((pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3397 !(val & ATA_DEVCTL_RESET))
3398 {
3399#ifdef IN_RING3
3400 /* Software RESET high to low */
3401 Log(("%s: deasserting RESET\n", __FUNCTION__));
3402 Log2(("%s: Ctl: message to async I/O thread, resetC\n", __FUNCTION__));
3403 if (val & ATA_DEVCTL_HOB)
3404 {
3405 val &= ~ATA_DEVCTL_HOB;
3406 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3407 }
3408 ataAsyncIOPutRequest(pCtl, &ataResetCRequest);
3409#else /* !IN_RING3 */
3410 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3411#endif /* IN_RING3 */
3412 }
3413
3414 /* Change of interrupt disable flag. Update interrupt line if interrupt
3415 * is pending on the current interface. */
3416 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_DISABLE_IRQ
3417 && pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
3418 {
3419 if (!(val & ATA_DEVCTL_DISABLE_IRQ))
3420 {
3421 Log2(("%s: LUN#%d asserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3422 /* The BMDMA unit unconditionally sets BM_STATUS_INT if the
3423 * interrupt line is asserted. It monitors the line for a rising
3424 * edge. */
3425 pCtl->BmDma.u8Status |= BM_STATUS_INT;
3426 if (pCtl->irq == 16)
3427 PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 1);
3428 else
3429 PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 1);
3430 }
3431 else
3432 {
3433 Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3434 if (pCtl->irq == 16)
3435 PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 0);
3436 else
3437 PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 0);
3438 }
3439 }
3440
3441 if (val & ATA_DEVCTL_HOB)
3442 Log2(("%s: set HOB\n", __FUNCTION__));
3443
3444 pCtl->aIfs[0].uATARegDevCtl = val;
3445 pCtl->aIfs[1].uATARegDevCtl = val;
3446
3447 return VINF_SUCCESS;
3448}
3449
3450#ifdef IN_RING3
3451
3452static void ataPIOTransfer(PAHCIATACONTROLLER pCtl)
3453{
3454 AHCIATADevState *s;
3455
3456 s = &pCtl->aIfs[pCtl->iAIOIf];
3457 Log3(("%s: if=%p\n", __FUNCTION__, s));
3458
3459 if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
3460 {
3461 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"));
3462 /* Any guest OS that triggers this case has a pathetic ATA driver.
3463 * In a real system it would block the CPU via IORDY, here we do it
3464 * very similarly by not continuing with the current instruction
3465 * until the transfer to/from the storage medium is completed. */
3466 if (s->iSourceSink != ATAFN_SS_NULL)
3467 {
3468 bool fRedo;
3469 uint8_t status = s->uATARegStatus;
3470 ataSetStatusValue(s, ATA_STAT_BUSY);
3471 Log2(("%s: calling source/sink function\n", __FUNCTION__));
3472 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3473 pCtl->fRedo = fRedo;
3474 if (RT_UNLIKELY(fRedo))
3475 return;
3476 ataSetStatusValue(s, status);
3477 s->iIOBufferCur = 0;
3478 s->iIOBufferEnd = s->cbElementaryTransfer;
3479 }
3480 }
3481 if (s->cbTotalTransfer)
3482 {
3483 if (s->fATAPITransfer)
3484 ataPIOTransferLimitATAPI(s);
3485
3486 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3487 s->cbElementaryTransfer = s->cbTotalTransfer;
3488
3489 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3490 __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3491 s->cbTotalTransfer, s->cbElementaryTransfer,
3492 s->iIOBufferCur, s->iIOBufferEnd));
3493 ataPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
3494 s->cbTotalTransfer -= s->cbElementaryTransfer;
3495 s->iIOBufferCur += s->cbElementaryTransfer;
3496
3497 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3498 s->cbElementaryTransfer = s->cbTotalTransfer;
3499 }
3500 else
3501 ataPIOTransferStop(s);
3502}
3503
3504
3505DECLINLINE(void) ataPIOTransferFinish(PAHCIATACONTROLLER pCtl, AHCIATADevState *s)
3506{
3507 /* Do not interfere with RESET processing if the PIO transfer finishes
3508 * while the RESET line is asserted. */
3509 if (pCtl->fReset)
3510 {
3511 Log2(("%s: Ctl: suppressed continuing PIO transfer as RESET is active\n", __FUNCTION__));
3512 return;
3513 }
3514
3515 if ( s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE
3516 || ( s->iSourceSink != ATAFN_SS_NULL
3517 && s->iIOBufferCur >= s->iIOBufferEnd))
3518 {
3519 /* Need to continue the transfer in the async I/O thread. This is
3520 * the case for write operations or generally for not yet finished
3521 * transfers (some data might need to be read). */
3522 ataUnsetStatus(s, ATA_STAT_READY | ATA_STAT_DRQ);
3523 ataSetStatus(s, ATA_STAT_BUSY);
3524
3525 Log2(("%s: Ctl: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__));
3526 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
3527 }
3528 else
3529 {
3530 /* Either everything finished (though some data might still be pending)
3531 * or some data is pending before the next read is due. */
3532
3533 /* Continue a previously started transfer. */
3534 ataUnsetStatus(s, ATA_STAT_DRQ);
3535 ataSetStatus(s, ATA_STAT_READY);
3536
3537 if (s->cbTotalTransfer)
3538 {
3539 /* There is more to transfer, happens usually for large ATAPI
3540 * reads - the protocol limits the chunk size to 65534 bytes. */
3541 ataPIOTransfer(pCtl);
3542 ataSetIRQ(s);
3543 }
3544 else
3545 {
3546 Log2(("%s: Ctl: skipping message to async I/O thread, ending PIO transfer\n", __FUNCTION__));
3547 /* Finish PIO transfer. */
3548 ataPIOTransfer(pCtl);
3549 Assert(!pCtl->fRedo);
3550 }
3551 }
3552}
3553
3554#endif /* IN_RING3 */
3555
3556static int ataDataWrite(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf)
3557{
3558 AHCIATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3559 uint8_t *p;
3560
3561 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3562 {
3563 Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE);
3564 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3565#ifndef IN_RING3
3566 /* All but the last transfer unit is simple enough for GC, but
3567 * sending a request to the async IO thread is too complicated. */
3568 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3569 {
3570 memcpy(p, pbBuf, cbSize);
3571 s->iIOBufferPIODataStart += cbSize;
3572 }
3573 else
3574 return VINF_IOM_HC_IOPORT_WRITE;
3575#else /* IN_RING3 */
3576 memcpy(p, pbBuf, cbSize);
3577 s->iIOBufferPIODataStart += cbSize;
3578 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3579 ataPIOTransferFinish(pCtl, s);
3580#endif /* !IN_RING3 */
3581 }
3582 else
3583 Log2(("%s: DUMMY data\n", __FUNCTION__));
3584 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3585 return VINF_SUCCESS;
3586}
3587
3588static int ataDataRead(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, uint8_t *pbBuf)
3589{
3590 AHCIATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3591 uint8_t *p;
3592
3593 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3594 {
3595 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
3596 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3597#ifndef IN_RING3
3598 /* All but the last transfer unit is simple enough for GC, but
3599 * sending a request to the async IO thread is too complicated. */
3600 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3601 {
3602 memcpy(pbBuf, p, cbSize);
3603 s->iIOBufferPIODataStart += cbSize;
3604 }
3605 else
3606 return VINF_IOM_HC_IOPORT_READ;
3607#else /* IN_RING3 */
3608 memcpy(pbBuf, p, cbSize);
3609 s->iIOBufferPIODataStart += cbSize;
3610 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3611 ataPIOTransferFinish(pCtl, s);
3612#endif /* !IN_RING3 */
3613 }
3614 else
3615 {
3616 Log2(("%s: DUMMY data\n", __FUNCTION__));
3617 memset(pbBuf, '\xff', cbSize);
3618 }
3619 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3620 return VINF_SUCCESS;
3621}
3622
3623#ifdef IN_RING3
3624
3625static void ataDMATransferStop(AHCIATADevState *s)
3626{
3627 s->cbTotalTransfer = 0;
3628 s->cbElementaryTransfer = 0;
3629 s->iBeginTransfer = ATAFN_BT_NULL;
3630 s->iSourceSink = ATAFN_SS_NULL;
3631}
3632
3633
3634/**
3635 * Perform the entire DMA transfer in one go (unless a source/sink operation
3636 * has to be redone or a RESET comes in between). Unlike the PIO counterpart
3637 * this function cannot handle empty transfers.
3638 *
3639 * @param pCtl Controller for which to perform the transfer.
3640 */
3641static void ataDMATransfer(PAHCIATACONTROLLER pCtl)
3642{
3643 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3644 AHCIATADevState *s = &pCtl->aIfs[pCtl->iAIOIf];
3645 bool fRedo;
3646 RTGCPHYS32 pDesc;
3647 uint32_t cbTotalTransfer, cbElementaryTransfer;
3648 uint32_t iIOBufferCur, iIOBufferEnd;
3649 uint32_t dmalen;
3650 PDMBLOCKTXDIR uTxDir;
3651 bool fLastDesc = false;
3652
3653 Assert(sizeof(BMDMADesc) == 8);
3654
3655 fRedo = pCtl->fRedo;
3656 if (RT_LIKELY(!fRedo))
3657 Assert(s->cbTotalTransfer);
3658 uTxDir = (PDMBLOCKTXDIR)s->uTxDir;
3659 cbTotalTransfer = s->cbTotalTransfer;
3660 cbElementaryTransfer = s->cbElementaryTransfer;
3661 iIOBufferCur = s->iIOBufferCur;
3662 iIOBufferEnd = s->iIOBufferEnd;
3663
3664 /* The DMA loop is designed to hold the lock only when absolutely
3665 * necessary. This avoids long freezes should the guest access the
3666 * ATA registers etc. for some reason. */
3667 PDMCritSectLeave(&pCtl->lock);
3668
3669 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3670 __FUNCTION__, uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3671 cbTotalTransfer, cbElementaryTransfer,
3672 iIOBufferCur, iIOBufferEnd));
3673 for (pDesc = pCtl->pFirstDMADesc; pDesc <= pCtl->pLastDMADesc; pDesc += sizeof(BMDMADesc))
3674 {
3675 BMDMADesc DMADesc;
3676 RTGCPHYS32 pBuffer;
3677 uint32_t cbBuffer;
3678
3679 if (RT_UNLIKELY(fRedo))
3680 {
3681 pBuffer = pCtl->pRedoDMABuffer;
3682 cbBuffer = pCtl->cbRedoDMABuffer;
3683 fLastDesc = pCtl->fRedoDMALastDesc;
3684 }
3685 else
3686 {
3687 PDMDevHlpPhysRead(pDevIns, pDesc, &DMADesc, sizeof(BMDMADesc));
3688 pBuffer = RT_LE2H_U32(DMADesc.pBuffer);
3689 cbBuffer = RT_LE2H_U32(DMADesc.cbBuffer);
3690 fLastDesc = !!(cbBuffer & 0x80000000);
3691 cbBuffer &= 0xfffe;
3692 if (cbBuffer == 0)
3693 cbBuffer = 0x10000;
3694 if (cbBuffer > cbTotalTransfer)
3695 cbBuffer = cbTotalTransfer;
3696 }
3697
3698 while (RT_UNLIKELY(fRedo) || (cbBuffer && cbTotalTransfer))
3699 {
3700 if (RT_LIKELY(!fRedo))
3701 {
3702 dmalen = RT_MIN(cbBuffer, iIOBufferEnd - iIOBufferCur);
3703 Log2(("%s: DMA desc %#010x: addr=%#010x size=%#010x\n", __FUNCTION__,
3704 pDesc, pBuffer, cbBuffer));
3705 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
3706 PDMDevHlpPhysWrite(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3707 else
3708 PDMDevHlpPhysRead(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3709 iIOBufferCur += dmalen;
3710 cbTotalTransfer -= dmalen;
3711 cbBuffer -= dmalen;
3712 pBuffer += dmalen;
3713 }
3714 if ( iIOBufferCur == iIOBufferEnd
3715 && (uTxDir == PDMBLOCKTXDIR_TO_DEVICE || cbTotalTransfer))
3716 {
3717 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
3718 cbElementaryTransfer = cbTotalTransfer;
3719
3720 {
3721 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3722 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3723 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3724 }
3725
3726 /* The RESET handler could have cleared the DMA transfer
3727 * state (since we didn't hold the lock until just now
3728 * the guest can continue in parallel). If so, the state
3729 * is already set up so the loop is exited immediately. */
3730 if (s->iSourceSink != ATAFN_SS_NULL)
3731 {
3732 s->iIOBufferCur = iIOBufferCur;
3733 s->iIOBufferEnd = iIOBufferEnd;
3734 s->cbElementaryTransfer = cbElementaryTransfer;
3735 s->cbTotalTransfer = cbTotalTransfer;
3736 Log2(("%s: calling source/sink function\n", __FUNCTION__));
3737 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3738 if (RT_UNLIKELY(fRedo))
3739 {
3740 pCtl->pFirstDMADesc = pDesc;
3741 pCtl->pRedoDMABuffer = pBuffer;
3742 pCtl->cbRedoDMABuffer = cbBuffer;
3743 pCtl->fRedoDMALastDesc = fLastDesc;
3744 }
3745 else
3746 {
3747 cbTotalTransfer = s->cbTotalTransfer;
3748 cbElementaryTransfer = s->cbElementaryTransfer;
3749
3750 if (uTxDir == PDMBLOCKTXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
3751 cbElementaryTransfer = cbTotalTransfer;
3752 iIOBufferCur = 0;
3753 iIOBufferEnd = cbElementaryTransfer;
3754 }
3755 pCtl->fRedo = fRedo;
3756 }
3757 else
3758 {
3759 /* This forces the loop to exit immediately. */
3760 pDesc = pCtl->pLastDMADesc + 1;
3761 }
3762
3763 PDMCritSectLeave(&pCtl->lock);
3764 if (RT_UNLIKELY(fRedo))
3765 break;
3766 }
3767 }
3768
3769 if (RT_UNLIKELY(fRedo))
3770 break;
3771
3772 /* end of transfer */
3773 if (!cbTotalTransfer || fLastDesc)
3774 break;
3775
3776 {
3777 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3778 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3779 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3780 }
3781
3782 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset)
3783 {
3784 LogRel(("ATA: Ctl: ABORT DMA%s\n", pCtl->fReset ? " due to RESET" : ""));
3785 if (!pCtl->fReset)
3786 ataDMATransferStop(s);
3787 /* This forces the loop to exit immediately. */
3788 pDesc = pCtl->pLastDMADesc + 1;
3789 }
3790
3791 PDMCritSectLeave(&pCtl->lock);
3792 }
3793
3794 {
3795 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3796 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3797 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3798 }
3799
3800 if (RT_UNLIKELY(fRedo))
3801 return;
3802
3803 if (fLastDesc)
3804 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
3805 s->cbTotalTransfer = cbTotalTransfer;
3806 s->cbElementaryTransfer = cbElementaryTransfer;
3807 s->iIOBufferCur = iIOBufferCur;
3808 s->iIOBufferEnd = iIOBufferEnd;
3809}
3810
3811
3812/**
3813 * Suspend I/O operations on a controller. Also suspends EMT, because it's
3814 * waiting for I/O to make progress. The next attempt to perform an I/O
3815 * operation will be made when EMT is resumed up again (as the resume
3816 * callback below restarts I/O).
3817 *
3818 * @param pCtl Controller for which to suspend I/O.
3819 */
3820static void ataSuspendRedo(PAHCIATACONTROLLER pCtl)
3821{
3822 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3823 int rc;
3824
3825 pCtl->fRedoIdle = true;
3826 rc = VMR3ReqCallWait(PDMDevHlpGetVM(pDevIns), VMCPUID_ANY,
3827 (PFNRT)PDMDevHlpVMSuspend, 1, pDevIns);
3828 AssertReleaseRC(rc);
3829}
3830
3831/** Asynch I/O thread for an interface. Once upon a time this was readable
3832 * code with several loops and a different semaphore for each purpose. But
3833 * then came the "how can one save the state in the middle of a PIO transfer"
3834 * question. The solution was to use an ASM, which is what's there now. */
3835static DECLCALLBACK(int) ataAsyncIOLoop(RTTHREAD ThreadSelf, void *pvUser)
3836{
3837 const AHCIATARequest *pReq;
3838 uint64_t u64TS = 0; /* shut up gcc */
3839 uint64_t uWait;
3840 int rc = VINF_SUCCESS;
3841 PAHCIATACONTROLLER pCtl = (PAHCIATACONTROLLER)pvUser;
3842 AHCIATADevState *s;
3843
3844 pReq = NULL;
3845 pCtl->fChainedTransfer = false;
3846 while (!pCtl->fShutdown)
3847 {
3848 /* Keep this thread from doing anything as long as EMT is suspended. */
3849 while (pCtl->fRedoIdle)
3850 {
3851 rc = RTSemEventWait(pCtl->SuspendIOSem, RT_INDEFINITE_WAIT);
3852 if (RT_FAILURE(rc) || pCtl->fShutdown)
3853 break;
3854
3855 pCtl->fRedoIdle = false;
3856 }
3857
3858 /* Wait for work. */
3859 if (pReq == NULL)
3860 {
3861 LogBird(("ata: %x: going to sleep...\n", pCtl->IOPortBase1));
3862 rc = RTSemEventWait(pCtl->AsyncIOSem, RT_INDEFINITE_WAIT);
3863 LogBird(("ata: %x: waking up\n", pCtl->IOPortBase1));
3864 if (RT_FAILURE(rc) || pCtl->fShutdown)
3865 break;
3866
3867 pReq = ataAsyncIOGetCurrentRequest(pCtl);
3868 }
3869
3870 if (pReq == NULL)
3871 continue;
3872
3873 AHCIATAAIO ReqType = pReq->ReqType;
3874
3875 Log2(("%s: Ctl: state=%d, req=%d\n", __FUNCTION__, pCtl->uAsyncIOState, ReqType));
3876 if (pCtl->uAsyncIOState != ReqType)
3877 {
3878 /* The new state is not the state that was expected by the normal
3879 * state changes. This is either a RESET/ABORT or there's something
3880 * really strange going on. */
3881 if ( (pCtl->uAsyncIOState == AHCIATA_AIO_PIO || pCtl->uAsyncIOState == AHCIATA_AIO_DMA)
3882 && (ReqType == AHCIATA_AIO_PIO || ReqType == AHCIATA_AIO_DMA))
3883 {
3884 /* Incorrect sequence of PIO/DMA states. Dump request queue. */
3885 ataAsyncIODumpRequests(pCtl);
3886 }
3887 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));
3888 }
3889
3890 /* Do our work. */
3891 {
3892 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3893 LogBird(("ata: %x: entering critsect\n", pCtl->IOPortBase1));
3894 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3895 LogBird(("ata: %x: entered\n", pCtl->IOPortBase1));
3896 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3897 }
3898
3899 if (pCtl->uAsyncIOState == AHCIATA_AIO_NEW && !pCtl->fChainedTransfer)
3900 {
3901 u64TS = RTTimeNanoTS();
3902#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
3903 STAM_PROFILE_ADV_START(&pCtl->StatAsyncTime, a);
3904#endif /* DEBUG || VBOX_WITH_STATISTICS */
3905 }
3906
3907 switch (ReqType)
3908 {
3909 case AHCIATA_AIO_NEW:
3910
3911 pCtl->iAIOIf = pReq->u.t.iIf;
3912 s = &pCtl->aIfs[pCtl->iAIOIf];
3913 s->cbTotalTransfer = pReq->u.t.cbTotalTransfer;
3914 s->uTxDir = pReq->u.t.uTxDir;
3915 s->iBeginTransfer = pReq->u.t.iBeginTransfer;
3916 s->iSourceSink = pReq->u.t.iSourceSink;
3917 s->iIOBufferEnd = 0;
3918 s->u64CmdTS = u64TS;
3919
3920 if (s->fATAPI)
3921 {
3922 if (pCtl->fChainedTransfer)
3923 {
3924 /* Only count the actual transfers, not the PIO
3925 * transfer of the ATAPI command bytes. */
3926 if (s->fDMA)
3927 STAM_REL_COUNTER_INC(&s->StatATAPIDMA);
3928 else
3929 STAM_REL_COUNTER_INC(&s->StatATAPIPIO);
3930 }
3931 }
3932 else
3933 {
3934 if (s->fDMA)
3935 STAM_REL_COUNTER_INC(&s->StatATADMA);
3936 else
3937 STAM_REL_COUNTER_INC(&s->StatATAPIO);
3938 }
3939
3940 pCtl->fChainedTransfer = false;
3941
3942 if (s->iBeginTransfer != ATAFN_BT_NULL)
3943 {
3944 Log2(("%s: Ctl: calling begin transfer function\n", __FUNCTION__));
3945 g_apfnBeginTransFuncs[s->iBeginTransfer](s);
3946 s->iBeginTransfer = ATAFN_BT_NULL;
3947 if (s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
3948 s->iIOBufferEnd = s->cbElementaryTransfer;
3949 }
3950 else
3951 {
3952 s->cbElementaryTransfer = s->cbTotalTransfer;
3953 s->iIOBufferEnd = s->cbTotalTransfer;
3954 }
3955 s->iIOBufferCur = 0;
3956
3957 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
3958 {
3959 if (s->iSourceSink != ATAFN_SS_NULL)
3960 {
3961 bool fRedo;
3962 Log2(("%s: Ctl: calling source/sink function\n", __FUNCTION__));
3963 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3964 pCtl->fRedo = fRedo;
3965 if (RT_UNLIKELY(fRedo))
3966 {
3967 /* Operation failed at the initial transfer, restart
3968 * everything from scratch by resending the current
3969 * request. Occurs very rarely, not worth optimizing. */
3970 LogRel(("%s: Ctl: redo entire operation\n", __FUNCTION__));
3971 ataAsyncIOPutRequest(pCtl, pReq);
3972 ataSuspendRedo(pCtl);
3973 break;
3974 }
3975 }
3976 else
3977 ataCmdOK(s, 0);
3978 s->iIOBufferEnd = s->cbElementaryTransfer;
3979
3980 }
3981
3982 /* Do not go into the transfer phase if RESET is asserted.
3983 * The CritSect is released while waiting for the host OS
3984 * to finish the I/O, thus RESET is possible here. Most
3985 * important: do not change uAsyncIOState. */
3986 if (pCtl->fReset)
3987 break;
3988
3989 if (s->fDMA)
3990 {
3991 if (s->cbTotalTransfer)
3992 {
3993 ataSetStatus(s, ATA_STAT_DRQ);
3994
3995 pCtl->uAsyncIOState = AHCIATA_AIO_DMA;
3996 /* If BMDMA is already started, do the transfer now. */
3997 if (pCtl->BmDma.u8Cmd & BM_CMD_START)
3998 {
3999 Log2(("%s: Ctl: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__));
4000 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4001 }
4002 }
4003 else
4004 {
4005 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4006 /* Finish DMA transfer. */
4007 ataDMATransferStop(s);
4008 ataSetIRQ(s);
4009 pCtl->uAsyncIOState = AHCIATA_AIO_NEW;
4010 }
4011 }
4012 else
4013 {
4014 if (s->cbTotalTransfer)
4015 {
4016 ataPIOTransfer(pCtl);
4017 Assert(!pCtl->fRedo);
4018 if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4019 ataSetIRQ(s);
4020
4021 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
4022 {
4023 /* Write operations and not yet finished transfers
4024 * must be completed in the async I/O thread. */
4025 pCtl->uAsyncIOState = AHCIATA_AIO_PIO;
4026 }
4027 else
4028 {
4029 /* Finished read operation can be handled inline
4030 * in the end of PIO transfer handling code. Linux
4031 * depends on this, as it waits only briefly for
4032 * devices to become ready after incoming data
4033 * transfer. Cannot find anything in the ATA spec
4034 * that backs this assumption, but as all kernels
4035 * are affected (though most of the time it does
4036 * not cause any harm) this must work. */
4037 pCtl->uAsyncIOState = AHCIATA_AIO_NEW;
4038 }
4039 }
4040 else
4041 {
4042 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4043 /* Finish PIO transfer. */
4044 ataPIOTransfer(pCtl);
4045 Assert(!pCtl->fRedo);
4046 if (!s->fATAPITransfer)
4047 ataSetIRQ(s);
4048 pCtl->uAsyncIOState = AHCIATA_AIO_NEW;
4049 }
4050 }
4051 break;
4052
4053 case AHCIATA_AIO_DMA:
4054 {
4055 BMDMAState *bm = &pCtl->BmDma;
4056 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4057 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */
4058
4059 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
4060 AssertRelease(bm->u8Cmd & BM_CMD_WRITE);
4061 else
4062 AssertRelease(!(bm->u8Cmd & BM_CMD_WRITE));
4063
4064 if (RT_LIKELY(!pCtl->fRedo))
4065 {
4066 /* The specs say that the descriptor table must not cross a
4067 * 4K boundary. */
4068 pCtl->pFirstDMADesc = bm->pvAddr;
4069 pCtl->pLastDMADesc = RT_ALIGN_32(bm->pvAddr + 1, _4K) - sizeof(BMDMADesc);
4070 }
4071 ataDMATransfer(pCtl);
4072
4073 if (RT_UNLIKELY(pCtl->fRedo))
4074 {
4075 LogRel(("ATA: Ctl: redo DMA operation\n"));
4076 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4077 ataSuspendRedo(pCtl);
4078 break;
4079 }
4080
4081 /* The infamous delay IRQ hack. */
4082 if ( iOriginalSourceSink == ATAFN_SS_WRITE_SECTORS
4083 && s->cbTotalTransfer == 0
4084 && pCtl->DelayIRQMillies)
4085 {
4086 /* Delay IRQ for writing. Required to get the Win2K
4087 * installation work reliably (otherwise it crashes,
4088 * usually during component install). So far no better
4089 * solution has been found. */
4090 Log(("%s: delay IRQ hack\n", __FUNCTION__));
4091 PDMCritSectLeave(&pCtl->lock);
4092 RTThreadSleep(pCtl->DelayIRQMillies);
4093 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4094 }
4095
4096 ataUnsetStatus(s, ATA_STAT_DRQ);
4097 Assert(!pCtl->fChainedTransfer);
4098 Assert(s->iSourceSink == ATAFN_SS_NULL);
4099 if (s->fATAPITransfer)
4100 {
4101 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
4102 Log2(("%s: Ctl: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
4103 s->fATAPITransfer = false;
4104 }
4105 ataSetIRQ(s);
4106 pCtl->uAsyncIOState = AHCIATA_AIO_NEW;
4107 break;
4108 }
4109
4110 case AHCIATA_AIO_PIO:
4111 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4112
4113 if (s->iSourceSink != ATAFN_SS_NULL)
4114 {
4115 bool fRedo;
4116 Log2(("%s: Ctl: calling source/sink function\n", __FUNCTION__));
4117 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4118 pCtl->fRedo = fRedo;
4119 if (RT_UNLIKELY(fRedo))
4120 {
4121 LogRel(("ATA: Ctl#%d: redo PIO operation\n"));
4122 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
4123 ataSuspendRedo(pCtl);
4124 break;
4125 }
4126 s->iIOBufferCur = 0;
4127 s->iIOBufferEnd = s->cbElementaryTransfer;
4128 }
4129 else
4130 {
4131 /* Continue a previously started transfer. */
4132 ataUnsetStatus(s, ATA_STAT_BUSY);
4133 ataSetStatus(s, ATA_STAT_READY);
4134 }
4135
4136 /* It is possible that the drives on this controller get RESET
4137 * during the above call to the source/sink function. If that's
4138 * the case, don't restart the transfer and don't finish it the
4139 * usual way. RESET handling took care of all that already.
4140 * Most important: do not change uAsyncIOState. */
4141 if (pCtl->fReset)
4142 break;
4143
4144 if (s->cbTotalTransfer)
4145 {
4146 ataPIOTransfer(pCtl);
4147 ataSetIRQ(s);
4148
4149 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
4150 {
4151 /* Write operations and not yet finished transfers
4152 * must be completed in the async I/O thread. */
4153 pCtl->uAsyncIOState = AHCIATA_AIO_PIO;
4154 }
4155 else
4156 {
4157 /* Finished read operation can be handled inline
4158 * in the end of PIO transfer handling code. Linux
4159 * depends on this, as it waits only briefly for
4160 * devices to become ready after incoming data
4161 * transfer. Cannot find anything in the ATA spec
4162 * that backs this assumption, but as all kernels
4163 * are affected (though most of the time it does
4164 * not cause any harm) this must work. */
4165 pCtl->uAsyncIOState = AHCIATA_AIO_NEW;
4166 }
4167 }
4168 else
4169 {
4170 /* Finish PIO transfer. */
4171 ataPIOTransfer(pCtl);
4172 if ( !pCtl->fChainedTransfer
4173 && !s->fATAPITransfer
4174 && s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4175 {
4176 ataSetIRQ(s);
4177 }
4178 pCtl->uAsyncIOState = AHCIATA_AIO_NEW;
4179 }
4180 break;
4181
4182 case AHCIATA_AIO_RESET_ASSERTED:
4183 pCtl->uAsyncIOState = AHCIATA_AIO_RESET_CLEARED;
4184 ataPIOTransferStop(&pCtl->aIfs[0]);
4185 ataPIOTransferStop(&pCtl->aIfs[1]);
4186 /* Do not change the DMA registers, they are not affected by the
4187 * ATA controller reset logic. It should be sufficient to issue a
4188 * new command, which is now possible as the state is cleared. */
4189 break;
4190
4191 case AHCIATA_AIO_RESET_CLEARED:
4192 pCtl->uAsyncIOState = AHCIATA_AIO_NEW;
4193 pCtl->fReset = false;
4194 LogRel(("ATA: Ctl: finished processing RESET\n"));
4195 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4196 {
4197 if (pCtl->aIfs[i].fATAPI)
4198 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
4199 else
4200 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
4201 ataSetSignature(&pCtl->aIfs[i]);
4202 }
4203 break;
4204
4205 case AHCIATA_AIO_ABORT:
4206 /* Abort the current command only if it operates on the same interface. */
4207 if (pCtl->iAIOIf == pReq->u.a.iIf)
4208 {
4209 s = &pCtl->aIfs[pCtl->iAIOIf];
4210
4211 pCtl->uAsyncIOState = AHCIATA_AIO_NEW;
4212 /* Do not change the DMA registers, they are not affected by the
4213 * ATA controller reset logic. It should be sufficient to issue a
4214 * new command, which is now possible as the state is cleared. */
4215 if (pReq->u.a.fResetDrive)
4216 {
4217 ataResetDevice(s);
4218 ataExecuteDeviceDiagnosticSS(s);
4219 }
4220 else
4221 {
4222 ataPIOTransferStop(s);
4223 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
4224 ataSetStatus(s, ATA_STAT_READY);
4225 ataSetIRQ(s);
4226 }
4227 }
4228 break;
4229
4230 default:
4231 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
4232 }
4233
4234 ataAsyncIORemoveCurrentRequest(pCtl, ReqType);
4235 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4236
4237 if (pCtl->uAsyncIOState == AHCIATA_AIO_NEW && !pCtl->fChainedTransfer)
4238 {
4239#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4240 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
4241#endif /* DEBUG || VBOX_WITH_STATISTICS */
4242
4243 u64TS = RTTimeNanoTS() - u64TS;
4244 uWait = u64TS / 1000;
4245 Log(("%s: Ctl: LUN#%d finished I/O transaction in %d microseconds\n", __FUNCTION__, pCtl->aIfs[pCtl->iAIOIf].iLUN, (uint32_t)(uWait)));
4246 /* Mark command as finished. */
4247 pCtl->aIfs[pCtl->iAIOIf].u64CmdTS = 0;
4248
4249 /*
4250 * Release logging of command execution times depends on the
4251 * command type. ATAPI commands often take longer (due to CD/DVD
4252 * spin up time etc.) so the threshold is different.
4253 */
4254 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
4255 {
4256 if (uWait > 8 * 1000 * 1000)
4257 {
4258 /*
4259 * Command took longer than 8 seconds. This is close
4260 * enough or over the guest's command timeout, so place
4261 * an entry in the release log to allow tracking such
4262 * timing errors (which are often caused by the host).
4263 */
4264 LogRel(("AHCI ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
4265 }
4266 }
4267 else
4268 {
4269 if (uWait > 20 * 1000 * 1000)
4270 {
4271 /*
4272 * Command took longer than 20 seconds. This is close
4273 * enough or over the guest's command timeout, so place
4274 * an entry in the release log to allow tracking such
4275 * timing errors (which are often caused by the host).
4276 */
4277 LogRel(("AHCI ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
4278 }
4279 }
4280
4281#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4282 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
4283 pCtl->StatAsyncMinWait = uWait;
4284 if (uWait > pCtl->StatAsyncMaxWait)
4285 pCtl->StatAsyncMaxWait = uWait;
4286
4287 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
4288 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
4289#endif /* DEBUG || VBOX_WITH_STATISTICS */
4290 }
4291
4292 LogBird(("ata: %x: leaving critsect\n", pCtl->IOPortBase1));
4293 PDMCritSectLeave(&pCtl->lock);
4294 }
4295
4296 /* Cleanup the state. */
4297 if (pCtl->AsyncIOSem)
4298 {
4299 RTSemEventDestroy(pCtl->AsyncIOSem);
4300 pCtl->AsyncIOSem = NIL_RTSEMEVENT;
4301 }
4302 if (pCtl->SuspendIOSem)
4303 {
4304 RTSemEventDestroy(pCtl->SuspendIOSem);
4305 pCtl->SuspendIOSem = NIL_RTSEMEVENT;
4306 }
4307 /* Do not destroy request mutex yet, still needed for proper shutdown. */
4308 pCtl->fShutdown = false;
4309 /* This must be last, as it also signals thread exit to EMT. */
4310 pCtl->AsyncIOThread = NIL_RTTHREAD;
4311
4312 Log2(("%s: Ctl: return %Rrc\n", __FUNCTION__, rc));
4313 return rc;
4314}
4315
4316#endif /* IN_RING3 */
4317
4318static uint32_t ataBMDMACmdReadB(PAHCIATACONTROLLER pCtl, uint32_t addr)
4319{
4320 uint32_t val = pCtl->BmDma.u8Cmd;
4321 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4322 return val;
4323}
4324
4325
4326static void ataBMDMACmdWriteB(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4327{
4328 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4329 if (!(val & BM_CMD_START))
4330 {
4331 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
4332 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4333 }
4334 else
4335 {
4336#ifdef IN_RING3
4337 /* Check whether the guest OS wants to change DMA direction in
4338 * mid-flight. Not allowed, according to the AHCI specs. */
4339 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
4340 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
4341 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4342
4343 /* Do not continue DMA transfers while the RESET line is asserted. */
4344 if (pCtl->fReset)
4345 {
4346 Log2(("%s: Ctl: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__));
4347 return;
4348 }
4349
4350 /* Do not start DMA transfers if there's a PIO transfer going on. */
4351 if (!pCtl->aIfs[pCtl->iSelectedIf].fDMA)
4352 return;
4353
4354 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
4355 {
4356 Log2(("%s: Ctl: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__));
4357 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4358 }
4359#else /* !IN_RING3 */
4360 AssertMsgFailed(("DMA START handling is too complicated for GC\n"));
4361#endif /* IN_RING3 */
4362 }
4363}
4364
4365static uint32_t ataBMDMAStatusReadB(PAHCIATACONTROLLER pCtl, uint32_t addr)
4366{
4367 uint32_t val = pCtl->BmDma.u8Status;
4368 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4369 return val;
4370}
4371
4372static void ataBMDMAStatusWriteB(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4373{
4374 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4375 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
4376 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
4377 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
4378}
4379
4380static uint32_t ataBMDMAAddrReadL(PAHCIATACONTROLLER pCtl, uint32_t addr)
4381{
4382 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
4383 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4384 return val;
4385}
4386
4387static void ataBMDMAAddrWriteL(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4388{
4389 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4390 pCtl->BmDma.pvAddr = val & ~3;
4391}
4392
4393static void ataBMDMAAddrWriteLowWord(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4394{
4395 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4396 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
4397
4398}
4399
4400static void ataBMDMAAddrWriteHighWord(PAHCIATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4401{
4402 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4403 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
4404}
4405
4406#define VAL(port, size) ( ((port) & 7) | ((size) << 3) )
4407
4408/**
4409 * Port I/O Handler for bus master DMA IN operations.
4410 * @see FNIOMIOPORTIN for details.
4411 */
4412int ataControllerBMDMAIOPortRead(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4413{
4414 int rc;
4415
4416 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4417 if (rc != VINF_SUCCESS)
4418 return rc;
4419 switch (VAL(Port, cb))
4420 {
4421 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4422 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4423 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4424 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4425 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
4426 default:
4427 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb));
4428 PDMCritSectLeave(&pCtl->lock);
4429 return VERR_IOM_IOPORT_UNUSED;
4430 }
4431 PDMCritSectLeave(&pCtl->lock);
4432 return rc;
4433}
4434
4435/**
4436 * Port I/O Handler for bus master DMA OUT operations.
4437 * @see FNIOMIOPORTOUT for details.
4438 */
4439int ataControllerBMDMAIOPortWrite(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t u32, unsigned cb)
4440{
4441 int rc;
4442
4443 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4444 if (rc != VINF_SUCCESS)
4445 return rc;
4446 switch (VAL(Port, cb))
4447 {
4448 case VAL(0, 1):
4449#ifndef IN_RING3
4450 if (u32 & BM_CMD_START)
4451 {
4452 rc = VINF_IOM_HC_IOPORT_WRITE;
4453 break;
4454 }
4455#endif /* !IN_RING3 */
4456 ataBMDMACmdWriteB(pCtl, Port, u32);
4457 break;
4458 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
4459 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
4460 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
4461 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
4462 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break;
4463 }
4464 PDMCritSectLeave(&pCtl->lock);
4465 return rc;
4466}
4467
4468#undef VAL
4469
4470
4471#ifdef IN_RING3
4472#if 0
4473
4474/**
4475 * Callback function for mapping an PCI I/O region.
4476 *
4477 * @return VBox status code.
4478 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
4479 * @param iRegion The region number.
4480 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
4481 * I/O port, else it's a physical address.
4482 * This address is *NOT* relative to pci_mem_base like earlier!
4483 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
4484 */
4485static DECLCALLBACK(int) ataBMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
4486{
4487 PCIATAState *pThis = PCIDEV_2_PCIATASTATE(pPciDev);
4488 int rc = VINF_SUCCESS;
4489 Assert(enmType == PCI_ADDRESS_SPACE_IO);
4490 Assert(iRegion == 4);
4491 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
4492
4493 /* Register the port range. */
4494 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
4495 {
4496 int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4497 (RTHCPTR)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL, NULL, "ATA Bus Master DMA");
4498 AssertRC(rc2);
4499 if (rc2 < rc)
4500 rc = rc2;
4501
4502 if (pThis->fGCEnabled)
4503 {
4504 rc2 = PDMDevHlpIOPortRegisterGC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4505 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4506 AssertRC(rc2);
4507 if (rc2 < rc)
4508 rc = rc2;
4509 }
4510 if (pThis->fR0Enabled)
4511 {
4512 rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4513 (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4514 AssertRC(rc2);
4515 if (rc2 < rc)
4516 rc = rc2;
4517 }
4518 }
4519 return rc;
4520}
4521#endif
4522
4523/**
4524 * Reset the controller to an intial state.
4525 *
4526 * @returns VBox status.
4527 * @param pDevIns The device instance data.
4528 */
4529void ataControllerReset(PAHCIATACONTROLLER pCtl)
4530{
4531 pCtl->iSelectedIf = 0;
4532 pCtl->iAIOIf = 0;
4533 pCtl->BmDma.u8Cmd = 0;
4534 /* Report that both drives present on the bus are in DMA mode. This
4535 * pretends that there is a BIOS that has set it up. Normal reset
4536 * default is 0x00. */
4537 pCtl->BmDma.u8Status = (pCtl->aIfs[0].pDrvBase != NULL ? BM_STATUS_D0DMA : 0)
4538 | (pCtl->aIfs[1].pDrvBase != NULL ? BM_STATUS_D1DMA : 0);
4539 pCtl->BmDma.pvAddr = 0;
4540
4541 pCtl->fReset = true;
4542 pCtl->fRedo = false;
4543 pCtl->fRedoIdle = false;
4544 ataAsyncIOClearRequests(pCtl);
4545 Log2(("%s: Ctl: message to async I/O thread, reset controller\n", __FUNCTION__));
4546 ataAsyncIOPutRequest(pCtl, &ataResetARequest);
4547 ataAsyncIOPutRequest(pCtl, &ataResetCRequest);
4548 if (!ataWaitForAsyncIOIsIdle(pCtl, 30000))
4549 AssertReleaseMsgFailed(("Async I/O thread busy after reset\n"));
4550
4551 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4552 ataResetDevice(&pCtl->aIfs[i]);
4553}
4554
4555#if 0
4556/* -=-=-=-=-=- AHCIATADevState::IBase -=-=-=-=-=- */
4557
4558/**
4559 * Queries an interface to the driver.
4560 *
4561 * @returns Pointer to interface.
4562 * @returns NULL if the interface was not supported by the device.
4563 * @param pInterface Pointer to AHCIATADevState::IBase.
4564 * @param enmInterface The requested interface identification.
4565 */
4566static DECLCALLBACK(void *) ataQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
4567{
4568 AHCIATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
4569 switch (enmInterface)
4570 {
4571 case PDMINTERFACE_BASE:
4572 return &pIf->IBase;
4573 case PDMINTERFACE_BLOCK_PORT:
4574 return &pIf->IPort;
4575 case PDMINTERFACE_MOUNT_NOTIFY:
4576 return &pIf->IMountNotify;
4577 default:
4578 return NULL;
4579 }
4580}
4581#endif
4582#endif /* IN_RING3 */
4583
4584
4585/* -=-=-=-=-=- Wrappers -=-=-=-=-=- */
4586
4587/**
4588 * Port I/O Handler for primary port range OUT operations.
4589 * @see FNIOMIOPORTOUT for details.
4590 */
4591int ataControllerIOPortWrite1(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t u32, unsigned cb)
4592{
4593 int rc = VINF_SUCCESS;
4594
4595 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4596 if (rc != VINF_SUCCESS)
4597 return rc;
4598 if (cb == 1)
4599 rc = ataIOPortWriteU8(pCtl, Port, u32);
4600 else if (Port == pCtl->IOPortBase1)
4601 {
4602 Assert(cb == 2 || cb == 4);
4603 rc = ataDataWrite(pCtl, Port, cb, (const uint8_t *)&u32);
4604 }
4605 else
4606 AssertMsgFailed(("ataIOPortWrite1: unsupported write to port %x val=%x size=%d\n", Port, u32, cb));
4607 LogBird(("ata: leaving critsect\n"));
4608 PDMCritSectLeave(&pCtl->lock);
4609 LogBird(("ata: left critsect\n"));
4610 return rc;
4611}
4612
4613
4614/**
4615 * Port I/O Handler for primary port range IN operations.
4616 * @see FNIOMIOPORTIN for details.
4617 */
4618int ataControllerIOPortRead1(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4619{
4620 int rc = VINF_SUCCESS;
4621
4622 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4623 if (rc != VINF_SUCCESS)
4624 return rc;
4625 if (cb == 1)
4626 {
4627 rc = ataIOPortReadU8(pCtl, Port, pu32);
4628 }
4629 else if (Port == pCtl->IOPortBase1)
4630 {
4631 Assert(cb == 2 || cb == 4);
4632 rc = ataDataRead(pCtl, Port, cb, (uint8_t *)pu32);
4633 if (cb == 2)
4634 *pu32 &= 0xffff;
4635 }
4636 else
4637 {
4638 AssertMsgFailed(("ataIOPortRead1: unsupported read from port %x size=%d\n", Port, cb));
4639 rc = VERR_IOM_IOPORT_UNUSED;
4640 }
4641 PDMCritSectLeave(&pCtl->lock);
4642 return rc;
4643}
4644
4645#ifndef IN_RING0 /** @todo do this in ring-0 as well. */
4646/**
4647 * Port I/O Handler for primary port range IN string operations.
4648 * @see FNIOMIOPORTINSTRING for details.
4649 */
4650int ataControllerIOPortReadStr1(PAHCIATACONTROLLER pCtl, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb)
4651{
4652 int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4653 if (rc != VINF_SUCCESS)
4654 return rc;
4655 if (Port == pCtl->IOPortBase1)
4656 {
4657 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
4658 RTGCPTR GCDst = *pGCPtrDst;
4659 AHCIATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4660 Assert(cb == 2 || cb == 4);
4661
4662 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
4663#ifndef IN_RING3
4664 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
4665 cTransAvailable--;
4666#endif /* !IN_RING3 */
4667 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
4668 * They are not performance-critical and generally shouldn't occur at all. */
4669 if (cTransAvailable > cTransfer)
4670 cTransAvailable = cTransfer;
4671 cbTransfer = cTransAvailable * cb;
4672
4673 PPDMDEVINS pDevIns = pCtl->CTX_SUFF(pDevIns);
4674 rc = PGMPhysSimpleDirtyWriteGCPtr(PDMDevHlpGetVMCPU(pDevIns), GCDst, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
4675 Assert(rc == VINF_SUCCESS);
4676
4677 if (cbTransfer)
4678 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
4679 s->iIOBufferPIODataStart += cbTransfer;
4680 *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
4681 *pcTransfer = cTransfer - cTransAvailable;
4682#ifdef IN_RING3
4683 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4684 ataPIOTransferFinish(pCtl, s);
4685#endif /* IN_RING3 */
4686 }
4687 PDMCritSectLeave(&pCtl->lock);
4688 return rc;
4689}
4690
4691
4692/**
4693 * Port I/O Handler for primary port range OUT string operations.
4694 * @see FNIOMIOPORTOUTSTRING for details.
4695 */
4696int ataControllerIOPortWriteStr1(PAHCIATACONTROLLER pCtl, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)
4697{
4698 int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4699 if (rc != VINF_SUCCESS)
4700 return rc;
4701 if (Port == pCtl->IOPortBase1)
4702 {
4703 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
4704 RTGCPTR GCSrc = *pGCPtrSrc;
4705 AHCIATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4706 Assert(cb == 2 || cb == 4);
4707
4708 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
4709#ifndef IN_RING3
4710 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
4711 cTransAvailable--;
4712#endif /* !IN_RING3 */
4713 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
4714 * They are not performance-critical and generally shouldn't occur at all. */
4715 if (cTransAvailable > cTransfer)
4716 cTransAvailable = cTransfer;
4717 cbTransfer = cTransAvailable * cb;
4718
4719 PPDMDEVINS pDevIns = pCtl->CTX_SUFF(pDevIns);
4720 rc = PGMPhysSimpleReadGCPtr(PDMDevHlpGetVMCPU(pDevIns), s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
4721 Assert(rc == VINF_SUCCESS);
4722
4723 if (cbTransfer)
4724 Log3(("%s: addr=%#x val=%.*Rhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
4725 s->iIOBufferPIODataStart += cbTransfer;
4726 *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
4727 *pcTransfer = cTransfer - cTransAvailable;
4728#ifdef IN_RING3
4729 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4730 ataPIOTransferFinish(pCtl, s);
4731#endif /* IN_RING3 */
4732 }
4733 PDMCritSectLeave(&pCtl->lock);
4734 return rc;
4735}
4736#endif /* !IN_RING0 */
4737
4738/**
4739 * Port I/O Handler for secondary port range OUT operations.
4740 * @see FNIOMIOPORTOUT for details.
4741 */
4742int ataControllerIOPortWrite2(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t u32, unsigned cb)
4743{
4744 int rc;
4745
4746 if (cb != 1)
4747 return VINF_SUCCESS;
4748 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4749 if (rc != VINF_SUCCESS)
4750 return rc;
4751 rc = ataControlWrite(pCtl, Port, u32);
4752 PDMCritSectLeave(&pCtl->lock);
4753 return rc;
4754}
4755
4756
4757/**
4758 * Port I/O Handler for secondary port range IN operations.
4759 * @see FNIOMIOPORTIN for details.
4760 */
4761int ataControllerIOPortRead2(PAHCIATACONTROLLER pCtl, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4762{
4763 int rc;
4764
4765 if (cb != 1)
4766 return VERR_IOM_IOPORT_UNUSED;
4767
4768 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4769 if (rc != VINF_SUCCESS)
4770 return rc;
4771 *pu32 = ataStatusRead(pCtl, Port);
4772 PDMCritSectLeave(&pCtl->lock);
4773 return VINF_SUCCESS;
4774}
4775
4776#ifdef IN_RING3
4777
4778/**
4779 * Waits for all async I/O threads to complete whatever they
4780 * are doing at the moment.
4781 *
4782 * @returns true on success.
4783 * @returns false when one or more threads is still processing.
4784 * @param pThis Pointer to the instance data.
4785 * @param cMillies How long to wait (total).
4786 */
4787static bool ataWaitForAllAsyncIOIsIdle(PAHCIATACONTROLLER pCtl, unsigned cMillies)
4788{
4789 uint64_t u64Start;
4790 PPDMDEVINS pDevIns = pCtl->CTXALLSUFF(pDevIns);
4791 bool fAllIdle = false;
4792
4793 /*
4794 * Wait for any pending async operation to finish
4795 */
4796 u64Start = RTTimeMilliTS();
4797 for (;;)
4798 {
4799 /* Check all async I/O threads. */
4800 fAllIdle = true;
4801
4802 fAllIdle &= ataAsyncIOIsIdle(pCtl, false);
4803 if (!fAllIdle)
4804 break;
4805
4806 if ( fAllIdle
4807 || RTTimeMilliTS() - u64Start >= cMillies)
4808 break;
4809
4810 /* Sleep for a bit. */
4811 RTThreadSleep(100);
4812 }
4813
4814 if (!fAllIdle)
4815 LogRel(("ATA: Ctl is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",
4816 pCtl->iSelectedIf, pCtl->iAIOIf,
4817 pCtl->aIfs[0].uATARegCommand, pCtl->aIfs[1].uATARegCommand));
4818
4819 return fAllIdle;
4820}
4821
4822
4823DECLINLINE(void) ataRelocBuffer(PPDMDEVINS pDevIns, AHCIATADevState *s)
4824{
4825 if (s->pbIOBufferR3)
4826 s->pbIOBufferRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), s->pbIOBufferR3);
4827}
4828
4829
4830/**
4831 * @copydoc FNPDMDEVRELOCATE
4832 */
4833void ataControllerRelocate(PAHCIATACONTROLLER pCtl, RTGCINTPTR offDelta)
4834{
4835 PPDMDEVINS pDevIns = pCtl->CTXALLSUFF(pDevIns);
4836
4837 pCtl->pDevInsRC += offDelta;
4838 pCtl->aIfs[0].pDevInsRC += offDelta;
4839 pCtl->aIfs[0].pControllerRC += offDelta;
4840 ataRelocBuffer(pDevIns, &pCtl->aIfs[0]);
4841 pCtl->aIfs[1].pDevInsRC += offDelta;
4842 pCtl->aIfs[1].pControllerRC += offDelta;
4843 ataRelocBuffer(pDevIns, &pCtl->aIfs[1]);
4844}
4845
4846
4847/**
4848 * Destroy a controller instance.
4849 *
4850 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
4851 * resources can be freed correctly.
4852 *
4853 * @param pCtl The controller instance.
4854 */
4855int ataControllerDestroy(PAHCIATACONTROLLER pCtl)
4856{
4857 int rc;
4858
4859 Log(("%s:\n", __FUNCTION__));
4860
4861 /*
4862 * Terminate all async helper threads
4863 */
4864 if (pCtl->AsyncIOThread != NIL_RTTHREAD)
4865 {
4866 ASMAtomicXchgU32(&pCtl->fShutdown, true);
4867 rc = RTSemEventSignal(pCtl->AsyncIOSem);
4868 AssertRC(rc);
4869 }
4870
4871 if (pCtl->CTX_SUFF(pDevIns))
4872 {
4873 /*
4874 * Wait for them to complete whatever they are doing and then
4875 * for them to terminate.
4876 */
4877 if (ataWaitForAllAsyncIOIsIdle(pCtl, 20000))
4878 {
4879 uint64_t u64Start = RTTimeMilliTS();
4880 bool fAllDone;
4881 for (;;)
4882 {
4883 /* check */
4884 fAllDone = true;
4885 fAllDone &= (pCtl->AsyncIOThread == NIL_RTTHREAD);
4886
4887 if ( fAllDone
4888 || RTTimeMilliTS() - u64Start >= 500)
4889 break;
4890
4891 /* Sleep for a bit. */
4892 RTThreadSleep(100);
4893 }
4894 AssertMsg(fAllDone, ("Some of the async I/O threads are still running!\n"));
4895 }
4896 else
4897 AssertMsgFailed(("Async I/O is still busy!\n"));
4898 }
4899
4900 /*
4901 * Now the request mutexes are no longer needed. Free resources.
4902 */
4903 if (pCtl->AsyncIORequestMutex)
4904 {
4905 RTSemMutexDestroy(pCtl->AsyncIORequestMutex);
4906 pCtl->AsyncIORequestMutex = NIL_RTSEMEVENT;
4907 }
4908
4909 return VINF_SUCCESS;
4910}
4911
4912#if 0
4913/**
4914 * Detach notification.
4915 *
4916 * The DVD drive has been unplugged.
4917 *
4918 * @param pDevIns The device instance.
4919 * @param iLUN The logical unit which is being detached.
4920 */
4921static DECLCALLBACK(void) ataDetach(PPDMDEVINS pDevIns, unsigned iLUN)
4922{
4923 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4924 PAHCIATACONTROLLER pCtl;
4925 AHCIATADevState *pIf;
4926 unsigned iController;
4927 unsigned iInterface;
4928
4929 /*
4930 * Locate the controller and stuff.
4931 */
4932 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
4933 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
4934 pCtl = &pThis->aCts[iController];
4935
4936 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
4937 pIf = &pCtl->aIfs[iInterface];
4938
4939 /*
4940 * Zero some important members.
4941 */
4942 pIf->pDrvBase = NULL;
4943 pIf->pDrvBlock = NULL;
4944 pIf->pDrvBlockBios = NULL;
4945 pIf->pDrvMount = NULL;
4946
4947 /*
4948 * Just in case there was a medium inserted. Only required when attached to a physical drive
4949 * in passthrough mode as in virtual ATAPI mode we've got an unmount notification.
4950 */
4951 if (pIf->fATAPIPassthrough)
4952 ataMediumRemoved(pIf);
4953
4954}
4955#endif
4956
4957/**
4958 * Configure a LUN.
4959 *
4960 * @returns VBox status code.
4961 * @param pDevIns The device instance.
4962 * @param pIf The ATA unit state.
4963 */
4964static int ataConfigLun(PPDMDEVINS pDevIns, AHCIATADevState *pIf)
4965{
4966 int rc;
4967 PDMBLOCKTYPE enmType;
4968
4969 /*
4970 * Query Block, Bios and Mount interfaces.
4971 */
4972 pIf->pDrvBlock = (PDMIBLOCK *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK);
4973 if (!pIf->pDrvBlock)
4974 {
4975 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
4976 return VERR_PDM_MISSING_INTERFACE;
4977 }
4978
4979 /** @todo implement the BIOS invisible code path. */
4980 pIf->pDrvBlockBios = (PDMIBLOCKBIOS *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK_BIOS);
4981 if (!pIf->pDrvBlockBios)
4982 {
4983 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pIf->iLUN));
4984 return VERR_PDM_MISSING_INTERFACE;
4985 }
4986 pIf->pDrvMount = (PDMIMOUNT *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_MOUNT);
4987
4988 /*
4989 * Validate type.
4990 */
4991 enmType = pIf->pDrvBlock->pfnGetType(pIf->pDrvBlock);
4992 if ( enmType != PDMBLOCKTYPE_CDROM
4993 && enmType != PDMBLOCKTYPE_DVD
4994 && enmType != PDMBLOCKTYPE_HARD_DISK)
4995 {
4996 AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
4997 return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
4998 }
4999 if ( ( enmType == PDMBLOCKTYPE_DVD
5000 || enmType == PDMBLOCKTYPE_CDROM)
5001 && !pIf->pDrvMount)
5002 {
5003 AssertMsgFailed(("Internal error: cdrom without a mountable interface, WTF???!\n"));
5004 return VERR_INTERNAL_ERROR;
5005 }
5006 pIf->fATAPI = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM;
5007 pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvBlock->pfnSendCmd != NULL) : false;
5008
5009 /*
5010 * Allocate I/O buffer.
5011 */
5012 PVM pVM = PDMDevHlpGetVM(pDevIns);
5013 if (pIf->cbIOBuffer)
5014 {
5015 /* Buffer is (probably) already allocated. Validate the fields,
5016 * because memory corruption can also overwrite pIf->cbIOBuffer. */
5017 if (pIf->fATAPI)
5018 AssertRelease(pIf->cbIOBuffer == _128K);
5019 else
5020 AssertRelease(pIf->cbIOBuffer == ATA_MAX_MULT_SECTORS * 512);
5021 Assert(pIf->pbIOBufferR3);
5022 Assert(pIf->pbIOBufferR0 == MMHyperR3ToR0(pVM, pIf->pbIOBufferR3));
5023 Assert(pIf->pbIOBufferRC == MMHyperR3ToRC(pVM, pIf->pbIOBufferR3));
5024 }
5025 else
5026 {
5027 if (pIf->fATAPI)
5028 pIf->cbIOBuffer = _128K;
5029 else
5030 pIf->cbIOBuffer = ATA_MAX_MULT_SECTORS * 512;
5031 Assert(!pIf->pbIOBufferR3);
5032 rc = MMR3HyperAllocOnceNoRel(pVM, pIf->cbIOBuffer, 0, MM_TAG_PDM_DEVICE_USER, (void **)&pIf->pbIOBufferR3);
5033 if (RT_FAILURE(rc))
5034 return VERR_NO_MEMORY;
5035 pIf->pbIOBufferR0 = MMHyperR3ToR0(pVM, pIf->pbIOBufferR3);
5036 pIf->pbIOBufferRC = MMHyperR3ToRC(pVM, pIf->pbIOBufferR3);
5037 }
5038
5039 /*
5040 * Init geometry (only for non-CD/DVD media).
5041 */
5042 if (pIf->fATAPI)
5043 {
5044 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
5045 pIf->PCHSGeometry.cCylinders = 0; /* dummy */
5046 pIf->PCHSGeometry.cHeads = 0; /* dummy */
5047 pIf->PCHSGeometry.cSectors = 0; /* dummy */
5048 LogRel(("ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));
5049 }
5050 else
5051 {
5052 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
5053 rc = pIf->pDrvBlockBios->pfnGetPCHSGeometry(pIf->pDrvBlockBios,
5054 &pIf->PCHSGeometry);
5055 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
5056 {
5057 pIf->PCHSGeometry.cCylinders = 0;
5058 pIf->PCHSGeometry.cHeads = 16; /*??*/
5059 pIf->PCHSGeometry.cSectors = 63; /*??*/
5060 }
5061 else if (rc == VERR_PDM_GEOMETRY_NOT_SET)
5062 {
5063 pIf->PCHSGeometry.cCylinders = 0; /* autodetect marker */
5064 rc = VINF_SUCCESS;
5065 }
5066 AssertRC(rc);
5067
5068 if ( pIf->PCHSGeometry.cCylinders == 0
5069 || pIf->PCHSGeometry.cHeads == 0
5070 || pIf->PCHSGeometry.cSectors == 0
5071 )
5072 {
5073 uint64_t cCylinders = pIf->cTotalSectors / (16 * 63);
5074 pIf->PCHSGeometry.cCylinders = RT_MAX(RT_MIN(cCylinders, 16383), 1);
5075 pIf->PCHSGeometry.cHeads = 16;
5076 pIf->PCHSGeometry.cSectors = 63;
5077 /* Set the disk geometry information. */
5078 rc = pIf->pDrvBlockBios->pfnSetPCHSGeometry(pIf->pDrvBlockBios,
5079 &pIf->PCHSGeometry);
5080 }
5081 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));
5082 }
5083 return VINF_SUCCESS;
5084}
5085
5086#if 0
5087/**
5088 * Attach command.
5089 *
5090 * This is called when we change block driver for the DVD drive.
5091 *
5092 * @returns VBox status code.
5093 * @param pDevIns The device instance.
5094 * @param iLUN The logical unit which is being detached.
5095 */
5096static DECLCALLBACK(int) ataAttach(PPDMDEVINS pDevIns, unsigned iLUN)
5097{
5098 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5099 PAHCIATACONTROLLER pCtl;
5100 AHCIATADevState *pIf;
5101 int rc;
5102 unsigned iController;
5103 unsigned iInterface;
5104
5105 /*
5106 * Locate the controller and stuff.
5107 */
5108 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5109 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5110 pCtl = &pThis->aCts[iController];
5111
5112 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5113 pIf = &pCtl->aIfs[iInterface];
5114
5115 /* the usual paranoia */
5116 AssertRelease(!pIf->pDrvBase);
5117 AssertRelease(!pIf->pDrvBlock);
5118 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
5119 Assert(pIf->iLUN == iLUN);
5120
5121 /*
5122 * Try attach the block device and get the interfaces,
5123 * required as well as optional.
5124 */
5125 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
5126 if (RT_SUCCESS(rc))
5127 {
5128 rc = ataConfigLun(pDevIns, pIf);
5129 /*
5130 * In case there is a new medium inserted. In virtual ATAPI mode we get an mount
5131 * notification.
5132 */
5133 if (pIf->fATAPIPassthrough)
5134 ataMediumInserted(pIf);
5135 }
5136 else
5137 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Rrc\n", pIf->iLUN, rc));
5138
5139 if (RT_FAILURE(rc))
5140 {
5141 pIf->pDrvBase = NULL;
5142 pIf->pDrvBlock = NULL;
5143 }
5144 return rc;
5145}
5146#endif
5147
5148/**
5149 * Suspend notification.
5150 *
5151 * @returns VBox status.
5152 * @param pDevIns The device instance data.
5153 */
5154void ataControllerSuspend(PAHCIATACONTROLLER pCtl)
5155{
5156 Log(("%s:\n", __FUNCTION__));
5157 if (!ataWaitForAllAsyncIOIsIdle(pCtl, 20000))
5158 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5159 return;
5160}
5161
5162
5163/**
5164 * Resume notification.
5165 *
5166 * @returns VBox status.
5167 * @param pDevIns The device instance data.
5168 */
5169void ataControllerResume(PAHCIATACONTROLLER pCtl)
5170{
5171 int rc;
5172
5173 Log(("%s:\n", __FUNCTION__));
5174 if (pCtl->fRedo && pCtl->fRedoIdle)
5175 {
5176 rc = RTSemEventSignal(pCtl->SuspendIOSem);
5177 AssertRC(rc);
5178 }
5179
5180 return;
5181}
5182
5183
5184/**
5185 * Power Off notification.
5186 *
5187 * @returns VBox status.
5188 * @param pCtl The controller instance.
5189 */
5190void ataControllerPowerOff(PAHCIATACONTROLLER pCtl)
5191{
5192 Log(("%s:\n", __FUNCTION__));
5193 if (!ataWaitForAllAsyncIOIsIdle(pCtl, 20000))
5194 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5195 return;
5196}
5197
5198/**
5199 * Prepare state save and load operation.
5200 *
5201 * @returns VBox status code.
5202 * @param pDevIns Device instance of the device which registered the data unit.
5203 * @param pSSM SSM operation handle.
5204 */
5205static int ataSaveLoadPrep(PAHCIATACONTROLLER pCtl)
5206{
5207 /* sanity - the suspend notification will wait on the async stuff. */
5208 Assert(ataAsyncIOIsIdle(pCtl, false));
5209 if (!ataAsyncIOIsIdle(pCtl, false))
5210 return VERR_SSM_IDE_ASYNC_TIMEOUT;
5211
5212 return VINF_SUCCESS;
5213}
5214
5215/**
5216 * Prepare state save operation.
5217 *
5218 * @returns VBox status code.
5219 * @param pCtl The controller instance.
5220 * @param pSSM SSM operation handle.
5221 */
5222DECLCALLBACK(int) ataControllerSavePrep(PAHCIATACONTROLLER pCtl, PSSMHANDLE pSSM)
5223{
5224 return ataSaveLoadPrep(pCtl);
5225}
5226
5227/**
5228 * Prepare state load operation.
5229 *
5230 * @returns VBox status code.
5231 * @param pCtl The controller instance.
5232 * @param pSSM SSM operation handle.
5233 */
5234DECLCALLBACK(int) ataControllerLoadPrep(PAHCIATACONTROLLER pCtl, PSSMHANDLE pSSM)
5235{
5236 return ataSaveLoadPrep(pCtl);
5237}
5238
5239/**
5240 * Saves a state of the ATA device.
5241 *
5242 * @returns VBox status code.
5243 * @param pCtl Controller instance.
5244 * @param pSSMHandle The handle to save the state to.
5245 */
5246int ataControllerSaveExec(PAHCIATACONTROLLER pCtl, PSSMHANDLE pSSMHandle)
5247{
5248 SSMR3PutU32(pSSMHandle, ATA_CTL_SAVED_STATE_VERSION);
5249 SSMR3PutU8(pSSMHandle, pCtl->iSelectedIf);
5250 SSMR3PutU8(pSSMHandle, pCtl->iAIOIf);
5251 SSMR3PutU8(pSSMHandle, pCtl->uAsyncIOState);
5252 SSMR3PutBool(pSSMHandle, pCtl->fChainedTransfer);
5253 SSMR3PutBool(pSSMHandle, pCtl->fReset);
5254 SSMR3PutBool(pSSMHandle, pCtl->fRedo);
5255 SSMR3PutBool(pSSMHandle, pCtl->fRedoIdle);
5256 SSMR3PutBool(pSSMHandle, pCtl->fRedoDMALastDesc);
5257 SSMR3PutMem(pSSMHandle, &pCtl->BmDma, sizeof(pCtl->BmDma));
5258 SSMR3PutGCPhys32(pSSMHandle, pCtl->pFirstDMADesc);
5259 SSMR3PutGCPhys32(pSSMHandle, pCtl->pLastDMADesc);
5260 SSMR3PutGCPhys32(pSSMHandle, pCtl->pRedoDMABuffer);
5261 SSMR3PutU32(pSSMHandle, pCtl->cbRedoDMABuffer);
5262
5263 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
5264 {
5265 SSMR3PutBool(pSSMHandle, pCtl->aIfs[j].fLBA48);
5266 SSMR3PutBool(pSSMHandle, pCtl->aIfs[j].fATAPI);
5267 SSMR3PutBool(pSSMHandle, pCtl->aIfs[j].fIrqPending);
5268 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].cMultSectors);
5269 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].PCHSGeometry.cCylinders);
5270 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].PCHSGeometry.cHeads);
5271 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].PCHSGeometry.cSectors);
5272 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].cSectorsPerIRQ);
5273 SSMR3PutU64(pSSMHandle, pCtl->aIfs[j].cTotalSectors);
5274 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegFeature);
5275 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegFeatureHOB);
5276 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegError);
5277 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegNSector);
5278 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegNSectorHOB);
5279 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegSector);
5280 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegSectorHOB);
5281 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegLCyl);
5282 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegLCylHOB);
5283 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegHCyl);
5284 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegHCylHOB);
5285 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegSelect);
5286 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegStatus);
5287 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegCommand);
5288 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATARegDevCtl);
5289 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uATATransferMode);
5290 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].uTxDir);
5291 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].iBeginTransfer);
5292 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].iSourceSink);
5293 SSMR3PutBool(pSSMHandle, pCtl->aIfs[j].fDMA);
5294 SSMR3PutBool(pSSMHandle, pCtl->aIfs[j].fATAPITransfer);
5295 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].cbTotalTransfer);
5296 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].cbElementaryTransfer);
5297 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].iIOBufferCur);
5298 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].iIOBufferEnd);
5299 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].iIOBufferPIODataStart);
5300 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].iIOBufferPIODataEnd);
5301 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].iATAPILBA);
5302 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].cbATAPISector);
5303 SSMR3PutMem(pSSMHandle, &pCtl->aIfs[j].aATAPICmd, sizeof(pCtl->aIfs[j].aATAPICmd));
5304 SSMR3PutMem(pSSMHandle, &pCtl->aIfs[j].abATAPISense, sizeof(pCtl->aIfs[j].abATAPISense));
5305 SSMR3PutU8(pSSMHandle, pCtl->aIfs[j].cNotifiedMediaChange);
5306 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].MediaEventStatus);
5307 SSMR3PutMem(pSSMHandle, pCtl->aIfs[j].pLed, sizeof(PDMLED));
5308 SSMR3PutU32(pSSMHandle, pCtl->aIfs[j].cbIOBuffer);
5309 if (pCtl->aIfs[j].cbIOBuffer)
5310 SSMR3PutMem(pSSMHandle, pCtl->aIfs[j].CTX_SUFF(pbIOBuffer), pCtl->aIfs[j].cbIOBuffer);
5311 else
5312 Assert(pCtl->aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
5313 }
5314
5315 return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
5316}
5317
5318
5319/**
5320 * Loads a saved ATA device state.
5321 *
5322 * @returns VBox status code.
5323 * @param pDevIns The device instance.
5324 * @param pSSMHandle The handle to the saved state.
5325 */
5326int ataControllerLoadExec(PAHCIATACONTROLLER pCtl, PSSMHANDLE pSSMHandle)
5327{
5328 int rc;
5329 uint32_t u32Version;
5330 uint32_t u32;
5331
5332 /* Test for correct version. */
5333 rc = SSMR3GetU32(pSSMHandle, &u32Version);
5334 AssertRCReturn(rc, rc);
5335
5336 if ( u32Version != ATA_CTL_SAVED_STATE_VERSION
5337 && u32Version != ATA_CTL_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE
5338 && u32Version != ATA_CTL_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS)
5339 {
5340 AssertMsgFailed(("u32Version=%d\n", u32Version));
5341 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
5342 }
5343
5344 /* integrity check */
5345 if (!ataAsyncIOIsIdle(pCtl, false))
5346 {
5347 AssertMsgFailed(("Async I/O for controller is active\n"));
5348 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5349 }
5350
5351 SSMR3GetU8(pSSMHandle, &pCtl->iSelectedIf);
5352 SSMR3GetU8(pSSMHandle, &pCtl->iAIOIf);
5353 SSMR3GetU8(pSSMHandle, &pCtl->uAsyncIOState);
5354 SSMR3GetBool(pSSMHandle, &pCtl->fChainedTransfer);
5355 SSMR3GetBool(pSSMHandle, (bool *)&pCtl->fReset);
5356 SSMR3GetBool(pSSMHandle, (bool *)&pCtl->fRedo);
5357 SSMR3GetBool(pSSMHandle, (bool *)&pCtl->fRedoIdle);
5358 SSMR3GetBool(pSSMHandle, (bool *)&pCtl->fRedoDMALastDesc);
5359 SSMR3GetMem(pSSMHandle, &pCtl->BmDma, sizeof(pCtl->BmDma));
5360 SSMR3GetGCPhys32(pSSMHandle, &pCtl->pFirstDMADesc);
5361 SSMR3GetGCPhys32(pSSMHandle, &pCtl->pLastDMADesc);
5362 SSMR3GetGCPhys32(pSSMHandle, &pCtl->pRedoDMABuffer);
5363 SSMR3GetU32(pSSMHandle, &pCtl->cbRedoDMABuffer);
5364
5365 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
5366 {
5367 SSMR3GetBool(pSSMHandle, &pCtl->aIfs[j].fLBA48);
5368 SSMR3GetBool(pSSMHandle, &pCtl->aIfs[j].fATAPI);
5369 SSMR3GetBool(pSSMHandle, &pCtl->aIfs[j].fIrqPending);
5370 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].cMultSectors);
5371 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].PCHSGeometry.cCylinders);
5372 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].PCHSGeometry.cHeads);
5373 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].PCHSGeometry.cSectors);
5374 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].cSectorsPerIRQ);
5375 SSMR3GetU64(pSSMHandle, &pCtl->aIfs[j].cTotalSectors);
5376 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegFeature);
5377 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegFeatureHOB);
5378 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegError);
5379 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegNSector);
5380 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegNSectorHOB);
5381 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegSector);
5382 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegSectorHOB);
5383 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegLCyl);
5384 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegLCylHOB);
5385 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegHCyl);
5386 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegHCylHOB);
5387 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegSelect);
5388 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegStatus);
5389 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegCommand);
5390 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATARegDevCtl);
5391 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uATATransferMode);
5392 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].uTxDir);
5393 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].iBeginTransfer);
5394 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].iSourceSink);
5395 SSMR3GetBool(pSSMHandle, &pCtl->aIfs[j].fDMA);
5396 SSMR3GetBool(pSSMHandle, &pCtl->aIfs[j].fATAPITransfer);
5397 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].cbTotalTransfer);
5398 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].cbElementaryTransfer);
5399 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].iIOBufferCur);
5400 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].iIOBufferEnd);
5401 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].iIOBufferPIODataStart);
5402 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].iIOBufferPIODataEnd);
5403 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].iATAPILBA);
5404 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].cbATAPISector);
5405 SSMR3GetMem(pSSMHandle, &pCtl->aIfs[j].aATAPICmd, sizeof(pCtl->aIfs[j].aATAPICmd));
5406 if (u32Version > ATA_CTL_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE)
5407 {
5408 SSMR3GetMem(pSSMHandle, &pCtl->aIfs[j].abATAPISense, sizeof(pCtl->aIfs[j].abATAPISense));
5409 }
5410 else
5411 {
5412 uint8_t uATAPISenseKey, uATAPIASC;
5413 memset(pCtl->aIfs[j].abATAPISense, '\0', sizeof(pCtl->aIfs[j].abATAPISense));
5414 pCtl->aIfs[j].abATAPISense[0] = 0x70 | (1 << 7);
5415 pCtl->aIfs[j].abATAPISense[7] = 10;
5416 SSMR3GetU8(pSSMHandle, &uATAPISenseKey);
5417 SSMR3GetU8(pSSMHandle, &uATAPIASC);
5418 pCtl->aIfs[j].abATAPISense[2] = uATAPISenseKey & 0x0f;
5419 pCtl->aIfs[j].abATAPISense[12] = uATAPIASC;
5420 }
5421 /** @todo triple-check this hack after passthrough is working */
5422 SSMR3GetU8(pSSMHandle, &pCtl->aIfs[j].cNotifiedMediaChange);
5423 if (u32Version > ATA_CTL_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS)
5424 SSMR3GetU32(pSSMHandle, (uint32_t*)&pCtl->aIfs[j].MediaEventStatus);
5425 else
5426 pCtl->aIfs[j].MediaEventStatus = ATA_EVENT_STATUS_UNCHANGED;
5427
5428 PDMLED Led;
5429 SSMR3GetMem(pSSMHandle, &Led, sizeof(PDMLED));
5430 SSMR3GetU32(pSSMHandle, &pCtl->aIfs[j].cbIOBuffer);
5431 if (pCtl->aIfs[j].cbIOBuffer)
5432 {
5433 if (pCtl->aIfs[j].CTX_SUFF(pbIOBuffer))
5434 SSMR3GetMem(pSSMHandle, pCtl->aIfs[j].CTX_SUFF(pbIOBuffer), pCtl->aIfs[j].cbIOBuffer);
5435 else
5436 {
5437 LogRel(("ATA: No buffer for %d\n", j));
5438 if (SSMR3HandleGetAfter(pSSMHandle) != SSMAFTER_DEBUG_IT)
5439 return VERR_SSM_LOAD_CONFIG_MISMATCH;
5440
5441 /* skip the buffer if we're loading for the debugger / animator. */
5442 uint8_t u8Ignored;
5443 size_t cbLeft = pCtl->aIfs[j].cbIOBuffer;
5444 while (cbLeft-- > 0)
5445 SSMR3GetU8(pSSMHandle, &u8Ignored);
5446 }
5447 }
5448 else
5449 Assert(pCtl->aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
5450 }
5451
5452 rc = SSMR3GetU32(pSSMHandle, &u32);
5453 if (RT_FAILURE(rc))
5454 return rc;
5455 if (u32 != ~0U)
5456 {
5457 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
5458 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5459 return rc;
5460 }
5461
5462 return VINF_SUCCESS;
5463}
5464
5465DECLCALLBACK(int) ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl, PPDMIBASE pDrvBaseMaster, PPDMIBASE pDrvBaseSlave,
5466 uint32_t *pcbSSMState, const char *szName, PPDMLED pLed,
5467 PSTAMCOUNTER pStatBytesRead, PSTAMCOUNTER pStatBytesWritten)
5468{
5469 int rc;
5470
5471 AssertMsg(pcbSSMState, ("pcbSSMState is invalid\n"));
5472
5473 pCtl->pDevInsR3 = pDevIns;
5474 pCtl->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
5475 pCtl->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
5476
5477 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
5478 {
5479 pCtl->aIfs[j].iLUN = j;
5480 pCtl->aIfs[j].pDevInsR3 = pDevIns;
5481 pCtl->aIfs[j].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
5482 pCtl->aIfs[j].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
5483 pCtl->aIfs[j].pControllerR3 = pCtl;
5484 pCtl->aIfs[j].pControllerR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), pCtl);
5485 pCtl->aIfs[j].pControllerRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), pCtl);
5486 pCtl->aIfs[j].pLed = pLed;
5487 pCtl->aIfs[j].pStatBytesRead = pStatBytesRead;
5488 pCtl->aIfs[j].pStatBytesWritten = pStatBytesWritten;
5489 }
5490
5491 /* Initialize per-controller critical section */
5492 rc = PDMDevHlpCritSectInit(pDevIns, &pCtl->lock, szName);
5493 if (RT_FAILURE(rc))
5494 return PDMDEV_SET_ERROR(pDevIns, rc, N_("AHCI ATA: cannot initialize critical section"));
5495
5496 /*
5497 * Attach the units.
5498 */
5499 uint32_t cbTotalBuffer = 0;
5500
5501 /*
5502 * Start the worker thread.
5503 */
5504 pCtl->uAsyncIOState = AHCIATA_AIO_NEW;
5505 rc = RTSemEventCreate(&pCtl->AsyncIOSem);
5506 AssertRC(rc);
5507 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
5508 AssertRC(rc);
5509 rc = RTSemMutexCreate(&pCtl->AsyncIORequestMutex);
5510 AssertRC(rc);
5511 ataAsyncIOClearRequests(pCtl);
5512 rc = RTThreadCreate(&pCtl->AsyncIOThread, ataAsyncIOLoop, (void *)pCtl, 128*1024, RTTHREADTYPE_IO, 0, "ATA");
5513 AssertRC(rc);
5514 Assert(pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->AsyncIOSem != NIL_RTSEMEVENT && pCtl->SuspendIOSem != NIL_RTSEMEVENT && pCtl->AsyncIORequestMutex != NIL_RTSEMMUTEX);
5515 Log(("%s: controller AIO thread id %#x; sem %p susp_sem %p mutex %p\n", __FUNCTION__, pCtl->AsyncIOThread, pCtl->AsyncIOSem, pCtl->SuspendIOSem, pCtl->AsyncIORequestMutex));
5516
5517 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
5518 {
5519 /*
5520 * Try attach the block device and get the interfaces,
5521 * required as well as optional.
5522 */
5523 AHCIATADevState *pIf = &pCtl->aIfs[j];
5524
5525 pIf->pDrvBase = (j == 0) ? pDrvBaseMaster : pDrvBaseSlave;
5526
5527#if 0
5528 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, s_apszDescs[j]);
5529 if (RT_SUCCESS(rc))
5530#endif
5531 if (pIf->pDrvBase)
5532 rc = ataConfigLun(pDevIns, pIf);
5533 else
5534 {
5535 pIf->pDrvBase = NULL;
5536 pIf->pDrvBlock = NULL;
5537 pIf->cbIOBuffer = 0;
5538 pIf->pbIOBufferR3 = NULL;
5539 pIf->pbIOBufferR0 = NIL_RTR0PTR;
5540 pIf->pbIOBufferRC = NIL_RTRCPTR;
5541 LogRel(("AHCI ATA: LUN#%d: no unit\n", pIf->iLUN));
5542 }
5543 cbTotalBuffer += pIf->cbIOBuffer;
5544 }
5545
5546 *pcbSSMState = cbTotalBuffer;
5547
5548 /*
5549 * Initialize the device state.
5550 */
5551 ataControllerReset(pCtl);
5552
5553 return VINF_SUCCESS;
5554}
5555#endif /* IN_RING3 */
5556#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
5557
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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