VirtualBox

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

Last change on this file since 304 was 304, checked in by vboxsync, 18 years ago

Fixed a collection of bugs in capability reporting. Added 3 ATAPI
commands which are used frequently by Linux automount tools.

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

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