Statistics
| Branch: | Revision:

root / hw / ide.c @ e0fe67aa

History | View | Annotate | Download (68.5 kB)

1 5391d806 bellard
/*
2 5391d806 bellard
 * QEMU IDE disk and CD-ROM Emulator
3 5391d806 bellard
 * 
4 5391d806 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 5391d806 bellard
 * 
6 5391d806 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 5391d806 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 5391d806 bellard
 * in the Software without restriction, including without limitation the rights
9 5391d806 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 5391d806 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 5391d806 bellard
 * furnished to do so, subject to the following conditions:
12 5391d806 bellard
 *
13 5391d806 bellard
 * The above copyright notice and this permission notice shall be included in
14 5391d806 bellard
 * all copies or substantial portions of the Software.
15 5391d806 bellard
 *
16 5391d806 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 5391d806 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 5391d806 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 5391d806 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 5391d806 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 5391d806 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 5391d806 bellard
 * THE SOFTWARE.
23 5391d806 bellard
 */
24 5391d806 bellard
#include "vl.h"
25 5391d806 bellard
26 5391d806 bellard
/* debug IDE devices */
27 5391d806 bellard
//#define DEBUG_IDE
28 5391d806 bellard
//#define DEBUG_IDE_ATAPI
29 5391d806 bellard
30 5391d806 bellard
/* Bits of HD_STATUS */
31 5391d806 bellard
#define ERR_STAT                0x01
32 5391d806 bellard
#define INDEX_STAT                0x02
33 5391d806 bellard
#define ECC_STAT                0x04        /* Corrected error */
34 5391d806 bellard
#define DRQ_STAT                0x08
35 5391d806 bellard
#define SEEK_STAT                0x10
36 5391d806 bellard
#define SRV_STAT                0x10
37 5391d806 bellard
#define WRERR_STAT                0x20
38 5391d806 bellard
#define READY_STAT                0x40
39 5391d806 bellard
#define BUSY_STAT                0x80
40 5391d806 bellard
41 5391d806 bellard
/* Bits for HD_ERROR */
42 5391d806 bellard
#define MARK_ERR                0x01        /* Bad address mark */
43 5391d806 bellard
#define TRK0_ERR                0x02        /* couldn't find track 0 */
44 5391d806 bellard
#define ABRT_ERR                0x04        /* Command aborted */
45 5391d806 bellard
#define MCR_ERR                        0x08        /* media change request */
46 5391d806 bellard
#define ID_ERR                        0x10        /* ID field not found */
47 5391d806 bellard
#define MC_ERR                        0x20        /* media changed */
48 5391d806 bellard
#define ECC_ERR                        0x40        /* Uncorrectable ECC error */
49 5391d806 bellard
#define BBD_ERR                        0x80        /* pre-EIDE meaning:  block marked bad */
50 5391d806 bellard
#define ICRC_ERR                0x80        /* new meaning:  CRC error during transfer */
51 5391d806 bellard
52 5391d806 bellard
/* Bits of HD_NSECTOR */
53 5391d806 bellard
#define CD                        0x01
54 5391d806 bellard
#define IO                        0x02
55 5391d806 bellard
#define REL                        0x04
56 5391d806 bellard
#define TAG_MASK                0xf8
57 5391d806 bellard
58 5391d806 bellard
#define IDE_CMD_RESET           0x04
59 5391d806 bellard
#define IDE_CMD_DISABLE_IRQ     0x02
60 5391d806 bellard
61 5391d806 bellard
/* ATA/ATAPI Commands pre T13 Spec */
62 5391d806 bellard
#define WIN_NOP                                0x00
63 5391d806 bellard
/*
64 5391d806 bellard
 *        0x01->0x02 Reserved
65 5391d806 bellard
 */
66 5391d806 bellard
#define CFA_REQ_EXT_ERROR_CODE                0x03 /* CFA Request Extended Error Code */
67 5391d806 bellard
/*
68 5391d806 bellard
 *        0x04->0x07 Reserved
69 5391d806 bellard
 */
70 5391d806 bellard
#define WIN_SRST                        0x08 /* ATAPI soft reset command */
71 5391d806 bellard
#define WIN_DEVICE_RESET                0x08
72 5391d806 bellard
/*
73 5391d806 bellard
 *        0x09->0x0F Reserved
74 5391d806 bellard
 */
75 5391d806 bellard
#define WIN_RECAL                        0x10
76 5391d806 bellard
#define WIN_RESTORE                        WIN_RECAL
77 5391d806 bellard
/*
78 5391d806 bellard
 *        0x10->0x1F Reserved
79 5391d806 bellard
 */
80 5391d806 bellard
#define WIN_READ                        0x20 /* 28-Bit */
81 5391d806 bellard
#define WIN_READ_ONCE                        0x21 /* 28-Bit without retries */
82 5391d806 bellard
#define WIN_READ_LONG                        0x22 /* 28-Bit */
83 5391d806 bellard
#define WIN_READ_LONG_ONCE                0x23 /* 28-Bit without retries */
84 5391d806 bellard
#define WIN_READ_EXT                        0x24 /* 48-Bit */
85 5391d806 bellard
#define WIN_READDMA_EXT                        0x25 /* 48-Bit */
86 5391d806 bellard
#define WIN_READDMA_QUEUED_EXT                0x26 /* 48-Bit */
87 5391d806 bellard
#define WIN_READ_NATIVE_MAX_EXT                0x27 /* 48-Bit */
88 5391d806 bellard
/*
89 5391d806 bellard
 *        0x28
90 5391d806 bellard
 */
91 5391d806 bellard
#define WIN_MULTREAD_EXT                0x29 /* 48-Bit */
92 5391d806 bellard
/*
93 5391d806 bellard
 *        0x2A->0x2F Reserved
94 5391d806 bellard
 */
95 5391d806 bellard
#define WIN_WRITE                        0x30 /* 28-Bit */
96 5391d806 bellard
#define WIN_WRITE_ONCE                        0x31 /* 28-Bit without retries */
97 5391d806 bellard
#define WIN_WRITE_LONG                        0x32 /* 28-Bit */
98 5391d806 bellard
#define WIN_WRITE_LONG_ONCE                0x33 /* 28-Bit without retries */
99 5391d806 bellard
#define WIN_WRITE_EXT                        0x34 /* 48-Bit */
100 5391d806 bellard
#define WIN_WRITEDMA_EXT                0x35 /* 48-Bit */
101 5391d806 bellard
#define WIN_WRITEDMA_QUEUED_EXT                0x36 /* 48-Bit */
102 5391d806 bellard
#define WIN_SET_MAX_EXT                        0x37 /* 48-Bit */
103 5391d806 bellard
#define CFA_WRITE_SECT_WO_ERASE                0x38 /* CFA Write Sectors without erase */
104 5391d806 bellard
#define WIN_MULTWRITE_EXT                0x39 /* 48-Bit */
105 5391d806 bellard
/*
106 5391d806 bellard
 *        0x3A->0x3B Reserved
107 5391d806 bellard
 */
108 5391d806 bellard
#define WIN_WRITE_VERIFY                0x3C /* 28-Bit */
109 5391d806 bellard
/*
110 5391d806 bellard
 *        0x3D->0x3F Reserved
111 5391d806 bellard
 */
112 5391d806 bellard
#define WIN_VERIFY                        0x40 /* 28-Bit - Read Verify Sectors */
113 5391d806 bellard
#define WIN_VERIFY_ONCE                        0x41 /* 28-Bit - without retries */
114 5391d806 bellard
#define WIN_VERIFY_EXT                        0x42 /* 48-Bit */
115 5391d806 bellard
/*
116 5391d806 bellard
 *        0x43->0x4F Reserved
117 5391d806 bellard
 */
118 5391d806 bellard
#define WIN_FORMAT                        0x50
119 5391d806 bellard
/*
120 5391d806 bellard
 *        0x51->0x5F Reserved
121 5391d806 bellard
 */
122 5391d806 bellard
#define WIN_INIT                        0x60
123 5391d806 bellard
/*
124 5391d806 bellard
 *        0x61->0x5F Reserved
125 5391d806 bellard
 */
126 5391d806 bellard
#define WIN_SEEK                        0x70 /* 0x70-0x7F Reserved */
127 5391d806 bellard
#define CFA_TRANSLATE_SECTOR                0x87 /* CFA Translate Sector */
128 5391d806 bellard
#define WIN_DIAGNOSE                        0x90
129 5391d806 bellard
#define WIN_SPECIFY                        0x91 /* set drive geometry translation */
130 5391d806 bellard
#define WIN_DOWNLOAD_MICROCODE                0x92
131 5391d806 bellard
#define WIN_STANDBYNOW2                        0x94
132 5391d806 bellard
#define WIN_STANDBY2                        0x96
133 5391d806 bellard
#define WIN_SETIDLE2                        0x97
134 5391d806 bellard
#define WIN_CHECKPOWERMODE2                0x98
135 5391d806 bellard
#define WIN_SLEEPNOW2                        0x99
136 5391d806 bellard
/*
137 5391d806 bellard
 *        0x9A VENDOR
138 5391d806 bellard
 */
139 5391d806 bellard
#define WIN_PACKETCMD                        0xA0 /* Send a packet command. */
140 5391d806 bellard
#define WIN_PIDENTIFY                        0xA1 /* identify ATAPI device        */
141 5391d806 bellard
#define WIN_QUEUED_SERVICE                0xA2
142 5391d806 bellard
#define WIN_SMART                        0xB0 /* self-monitoring and reporting */
143 5391d806 bellard
#define CFA_ERASE_SECTORS               0xC0
144 5391d806 bellard
#define WIN_MULTREAD                        0xC4 /* read sectors using multiple mode*/
145 5391d806 bellard
#define WIN_MULTWRITE                        0xC5 /* write sectors using multiple mode */
146 5391d806 bellard
#define WIN_SETMULT                        0xC6 /* enable/disable multiple mode */
147 5391d806 bellard
#define WIN_READDMA_QUEUED                0xC7 /* read sectors using Queued DMA transfers */
148 5391d806 bellard
#define WIN_READDMA                        0xC8 /* read sectors using DMA transfers */
149 5391d806 bellard
#define WIN_READDMA_ONCE                0xC9 /* 28-Bit - without retries */
150 5391d806 bellard
#define WIN_WRITEDMA                        0xCA /* write sectors using DMA transfers */
151 5391d806 bellard
#define WIN_WRITEDMA_ONCE                0xCB /* 28-Bit - without retries */
152 5391d806 bellard
#define WIN_WRITEDMA_QUEUED                0xCC /* write sectors using Queued DMA transfers */
153 5391d806 bellard
#define CFA_WRITE_MULTI_WO_ERASE        0xCD /* CFA Write multiple without erase */
154 5391d806 bellard
#define WIN_GETMEDIASTATUS                0xDA        
155 5391d806 bellard
#define WIN_ACKMEDIACHANGE                0xDB /* ATA-1, ATA-2 vendor */
156 5391d806 bellard
#define WIN_POSTBOOT                        0xDC
157 5391d806 bellard
#define WIN_PREBOOT                        0xDD
158 5391d806 bellard
#define WIN_DOORLOCK                        0xDE /* lock door on removable drives */
159 5391d806 bellard
#define WIN_DOORUNLOCK                        0xDF /* unlock door on removable drives */
160 5391d806 bellard
#define WIN_STANDBYNOW1                        0xE0
161 5391d806 bellard
#define WIN_IDLEIMMEDIATE                0xE1 /* force drive to become "ready" */
162 5391d806 bellard
#define WIN_STANDBY                     0xE2 /* Set device in Standby Mode */
163 5391d806 bellard
#define WIN_SETIDLE1                        0xE3
164 5391d806 bellard
#define WIN_READ_BUFFER                        0xE4 /* force read only 1 sector */
165 5391d806 bellard
#define WIN_CHECKPOWERMODE1                0xE5
166 5391d806 bellard
#define WIN_SLEEPNOW1                        0xE6
167 5391d806 bellard
#define WIN_FLUSH_CACHE                        0xE7
168 5391d806 bellard
#define WIN_WRITE_BUFFER                0xE8 /* force write only 1 sector */
169 5391d806 bellard
#define WIN_WRITE_SAME                        0xE9 /* read ata-2 to use */
170 5391d806 bellard
        /* SET_FEATURES 0x22 or 0xDD */
171 5391d806 bellard
#define WIN_FLUSH_CACHE_EXT                0xEA /* 48-Bit */
172 5391d806 bellard
#define WIN_IDENTIFY                        0xEC /* ask drive to identify itself        */
173 5391d806 bellard
#define WIN_MEDIAEJECT                        0xED
174 5391d806 bellard
#define WIN_IDENTIFY_DMA                0xEE /* same as WIN_IDENTIFY, but DMA */
175 5391d806 bellard
#define WIN_SETFEATURES                        0xEF /* set special drive features */
176 5391d806 bellard
#define EXABYTE_ENABLE_NEST                0xF0
177 5391d806 bellard
#define WIN_SECURITY_SET_PASS                0xF1
178 5391d806 bellard
#define WIN_SECURITY_UNLOCK                0xF2
179 5391d806 bellard
#define WIN_SECURITY_ERASE_PREPARE        0xF3
180 5391d806 bellard
#define WIN_SECURITY_ERASE_UNIT                0xF4
181 5391d806 bellard
#define WIN_SECURITY_FREEZE_LOCK        0xF5
182 5391d806 bellard
#define WIN_SECURITY_DISABLE                0xF6
183 5391d806 bellard
#define WIN_READ_NATIVE_MAX                0xF8 /* return the native maximum address */
184 5391d806 bellard
#define WIN_SET_MAX                        0xF9
185 5391d806 bellard
#define DISABLE_SEAGATE                        0xFB
186 5391d806 bellard
187 5391d806 bellard
/* set to 1 set disable mult support */
188 f66723fa bellard
#define MAX_MULT_SECTORS 16
189 5391d806 bellard
190 5391d806 bellard
/* ATAPI defines */
191 5391d806 bellard
192 5391d806 bellard
#define ATAPI_PACKET_SIZE 12
193 5391d806 bellard
194 5391d806 bellard
/* The generic packet command opcodes for CD/DVD Logical Units,
195 5391d806 bellard
 * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
196 5391d806 bellard
#define GPCMD_BLANK                            0xa1
197 5391d806 bellard
#define GPCMD_CLOSE_TRACK                    0x5b
198 5391d806 bellard
#define GPCMD_FLUSH_CACHE                    0x35
199 5391d806 bellard
#define GPCMD_FORMAT_UNIT                    0x04
200 5391d806 bellard
#define GPCMD_GET_CONFIGURATION                    0x46
201 5391d806 bellard
#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
202 5391d806 bellard
#define GPCMD_GET_PERFORMANCE                    0xac
203 5391d806 bellard
#define GPCMD_INQUIRY                            0x12
204 5391d806 bellard
#define GPCMD_LOAD_UNLOAD                    0xa6
205 5391d806 bellard
#define GPCMD_MECHANISM_STATUS                    0xbd
206 5391d806 bellard
#define GPCMD_MODE_SELECT_10                    0x55
207 5391d806 bellard
#define GPCMD_MODE_SENSE_10                    0x5a
208 5391d806 bellard
#define GPCMD_PAUSE_RESUME                    0x4b
209 5391d806 bellard
#define GPCMD_PLAY_AUDIO_10                    0x45
210 5391d806 bellard
#define GPCMD_PLAY_AUDIO_MSF                    0x47
211 5391d806 bellard
#define GPCMD_PLAY_AUDIO_TI                    0x48
212 5391d806 bellard
#define GPCMD_PLAY_CD                            0xbc
213 5391d806 bellard
#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL  0x1e
214 5391d806 bellard
#define GPCMD_READ_10                            0x28
215 5391d806 bellard
#define GPCMD_READ_12                            0xa8
216 5391d806 bellard
#define GPCMD_READ_CDVD_CAPACITY            0x25
217 5391d806 bellard
#define GPCMD_READ_CD                            0xbe
218 5391d806 bellard
#define GPCMD_READ_CD_MSF                    0xb9
219 5391d806 bellard
#define GPCMD_READ_DISC_INFO                    0x51
220 5391d806 bellard
#define GPCMD_READ_DVD_STRUCTURE            0xad
221 5391d806 bellard
#define GPCMD_READ_FORMAT_CAPACITIES            0x23
222 5391d806 bellard
#define GPCMD_READ_HEADER                    0x44
223 5391d806 bellard
#define GPCMD_READ_TRACK_RZONE_INFO            0x52
224 5391d806 bellard
#define GPCMD_READ_SUBCHANNEL                    0x42
225 5391d806 bellard
#define GPCMD_READ_TOC_PMA_ATIP                    0x43
226 5391d806 bellard
#define GPCMD_REPAIR_RZONE_TRACK            0x58
227 5391d806 bellard
#define GPCMD_REPORT_KEY                    0xa4
228 5391d806 bellard
#define GPCMD_REQUEST_SENSE                    0x03
229 5391d806 bellard
#define GPCMD_RESERVE_RZONE_TRACK            0x53
230 5391d806 bellard
#define GPCMD_SCAN                            0xba
231 5391d806 bellard
#define GPCMD_SEEK                            0x2b
232 5391d806 bellard
#define GPCMD_SEND_DVD_STRUCTURE            0xad
233 5391d806 bellard
#define GPCMD_SEND_EVENT                    0xa2
234 5391d806 bellard
#define GPCMD_SEND_KEY                            0xa3
235 5391d806 bellard
#define GPCMD_SEND_OPC                            0x54
236 5391d806 bellard
#define GPCMD_SET_READ_AHEAD                    0xa7
237 5391d806 bellard
#define GPCMD_SET_STREAMING                    0xb6
238 5391d806 bellard
#define GPCMD_START_STOP_UNIT                    0x1b
239 5391d806 bellard
#define GPCMD_STOP_PLAY_SCAN                    0x4e
240 5391d806 bellard
#define GPCMD_TEST_UNIT_READY                    0x00
241 5391d806 bellard
#define GPCMD_VERIFY_10                            0x2f
242 5391d806 bellard
#define GPCMD_WRITE_10                            0x2a
243 5391d806 bellard
#define GPCMD_WRITE_AND_VERIFY_10            0x2e
244 5391d806 bellard
/* This is listed as optional in ATAPI 2.6, but is (curiously) 
245 5391d806 bellard
 * missing from Mt. Fuji, Table 57.  It _is_ mentioned in Mt. Fuji
246 5391d806 bellard
 * Table 377 as an MMC command for SCSi devices though...  Most ATAPI
247 5391d806 bellard
 * drives support it. */
248 5391d806 bellard
#define GPCMD_SET_SPEED                            0xbb
249 5391d806 bellard
/* This seems to be a SCSI specific CD-ROM opcode 
250 5391d806 bellard
 * to play data at track/index */
251 5391d806 bellard
#define GPCMD_PLAYAUDIO_TI                    0x48
252 5391d806 bellard
/*
253 5391d806 bellard
 * From MS Media Status Notification Support Specification. For
254 5391d806 bellard
 * older drives only.
255 5391d806 bellard
 */
256 5391d806 bellard
#define GPCMD_GET_MEDIA_STATUS                    0xda
257 5391d806 bellard
258 5391d806 bellard
/* Mode page codes for mode sense/set */
259 5391d806 bellard
#define GPMODE_R_W_ERROR_PAGE                0x01
260 5391d806 bellard
#define GPMODE_WRITE_PARMS_PAGE                0x05
261 5391d806 bellard
#define GPMODE_AUDIO_CTL_PAGE                0x0e
262 5391d806 bellard
#define GPMODE_POWER_PAGE                0x1a
263 5391d806 bellard
#define GPMODE_FAULT_FAIL_PAGE                0x1c
264 5391d806 bellard
#define GPMODE_TO_PROTECT_PAGE                0x1d
265 5391d806 bellard
#define GPMODE_CAPABILITIES_PAGE        0x2a
266 5391d806 bellard
#define GPMODE_ALL_PAGES                0x3f
267 5391d806 bellard
/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
268 5391d806 bellard
 * of MODE_SENSE_POWER_PAGE */
269 5391d806 bellard
#define GPMODE_CDROM_PAGE                0x0d
270 5391d806 bellard
271 5391d806 bellard
#define ATAPI_INT_REASON_CD             0x01 /* 0 = data transfer */
272 5391d806 bellard
#define ATAPI_INT_REASON_IO             0x02 /* 1 = transfer to the host */
273 5391d806 bellard
#define ATAPI_INT_REASON_REL            0x04
274 5391d806 bellard
#define ATAPI_INT_REASON_TAG            0xf8
275 5391d806 bellard
276 5391d806 bellard
/* same constants as bochs */
277 7f777bf3 bellard
#define ASC_ILLEGAL_OPCODE                   0x20
278 5391d806 bellard
#define ASC_LOGICAL_BLOCK_OOR                0x21
279 5391d806 bellard
#define ASC_INV_FIELD_IN_CMD_PACKET          0x24
280 5391d806 bellard
#define ASC_MEDIUM_NOT_PRESENT               0x3a
281 5391d806 bellard
#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
282 5391d806 bellard
283 5391d806 bellard
#define SENSE_NONE            0
284 5391d806 bellard
#define SENSE_NOT_READY       2
285 5391d806 bellard
#define SENSE_ILLEGAL_REQUEST 5
286 5391d806 bellard
#define SENSE_UNIT_ATTENTION  6
287 5391d806 bellard
288 5391d806 bellard
struct IDEState;
289 5391d806 bellard
290 5391d806 bellard
typedef void EndTransferFunc(struct IDEState *);
291 5391d806 bellard
292 caed8802 bellard
/* NOTE: IDEState represents in fact one drive */
293 5391d806 bellard
typedef struct IDEState {
294 5391d806 bellard
    /* ide config */
295 5391d806 bellard
    int is_cdrom;
296 5391d806 bellard
    int cylinders, heads, sectors;
297 5391d806 bellard
    int64_t nb_sectors;
298 5391d806 bellard
    int mult_sectors;
299 5391d806 bellard
    int irq;
300 1ade1de2 bellard
    openpic_t *openpic;
301 34e538ae bellard
    PCIDevice *pci_dev;
302 98087450 bellard
    struct BMDMAState *bmdma;
303 aedf5382 bellard
    int drive_serial;
304 5391d806 bellard
    /* ide regs */
305 5391d806 bellard
    uint8_t feature;
306 5391d806 bellard
    uint8_t error;
307 5391d806 bellard
    uint16_t nsector; /* 0 is 256 to ease computations */
308 5391d806 bellard
    uint8_t sector;
309 5391d806 bellard
    uint8_t lcyl;
310 5391d806 bellard
    uint8_t hcyl;
311 5391d806 bellard
    uint8_t select;
312 5391d806 bellard
    uint8_t status;
313 5391d806 bellard
    /* 0x3f6 command, only meaningful for drive 0 */
314 5391d806 bellard
    uint8_t cmd;
315 5391d806 bellard
    /* depends on bit 4 in select, only meaningful for drive 0 */
316 5391d806 bellard
    struct IDEState *cur_drive; 
317 5391d806 bellard
    BlockDriverState *bs;
318 5391d806 bellard
    /* ATAPI specific */
319 5391d806 bellard
    uint8_t sense_key;
320 5391d806 bellard
    uint8_t asc;
321 5391d806 bellard
    int packet_transfer_size;
322 5391d806 bellard
    int elementary_transfer_size;
323 5391d806 bellard
    int io_buffer_index;
324 5391d806 bellard
    int lba;
325 98087450 bellard
    int cd_sector_size;
326 98087450 bellard
    int atapi_dma; /* true if dma is requested for the packet cmd */
327 98087450 bellard
    /* ATA DMA state */
328 98087450 bellard
    int io_buffer_size;
329 98087450 bellard
    /* PIO transfer handling */
330 5391d806 bellard
    int req_nb_sectors; /* number of sectors per interrupt */
331 5391d806 bellard
    EndTransferFunc *end_transfer_func;
332 5391d806 bellard
    uint8_t *data_ptr;
333 5391d806 bellard
    uint8_t *data_end;
334 5391d806 bellard
    uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
335 5391d806 bellard
} IDEState;
336 5391d806 bellard
337 98087450 bellard
#define BM_STATUS_DMAING 0x01
338 98087450 bellard
#define BM_STATUS_ERROR  0x02
339 98087450 bellard
#define BM_STATUS_INT    0x04
340 98087450 bellard
341 98087450 bellard
#define BM_CMD_START     0x01
342 98087450 bellard
#define BM_CMD_READ      0x08
343 98087450 bellard
344 98087450 bellard
typedef int IDEDMAFunc(IDEState *s, 
345 98087450 bellard
                       target_phys_addr_t phys_addr, 
346 98087450 bellard
                       int transfer_size1);
347 98087450 bellard
348 98087450 bellard
typedef struct BMDMAState {
349 98087450 bellard
    uint8_t cmd;
350 98087450 bellard
    uint8_t status;
351 98087450 bellard
    uint32_t addr;
352 98087450 bellard
    /* current transfer state */
353 98087450 bellard
    IDEState *ide_if;
354 98087450 bellard
    IDEDMAFunc *dma_cb;
355 98087450 bellard
} BMDMAState;
356 98087450 bellard
357 98087450 bellard
typedef struct PCIIDEState {
358 98087450 bellard
    PCIDevice dev;
359 98087450 bellard
    IDEState ide_if[4];
360 98087450 bellard
    BMDMAState bmdma[2];
361 98087450 bellard
} PCIIDEState;
362 98087450 bellard
363 98087450 bellard
static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
364 98087450 bellard
365 5391d806 bellard
static void padstr(char *str, const char *src, int len)
366 5391d806 bellard
{
367 5391d806 bellard
    int i, v;
368 5391d806 bellard
    for(i = 0; i < len; i++) {
369 5391d806 bellard
        if (*src)
370 5391d806 bellard
            v = *src++;
371 5391d806 bellard
        else
372 5391d806 bellard
            v = ' ';
373 5391d806 bellard
        *(char *)((long)str ^ 1) = v;
374 5391d806 bellard
        str++;
375 5391d806 bellard
    }
376 5391d806 bellard
}
377 5391d806 bellard
378 bd0d90b2 bellard
static void padstr8(uint8_t *buf, int buf_size, const char *src)
379 bd0d90b2 bellard
{
380 bd0d90b2 bellard
    int i;
381 bd0d90b2 bellard
    for(i = 0; i < buf_size; i++) {
382 bd0d90b2 bellard
        if (*src)
383 bd0d90b2 bellard
            buf[i] = *src++;
384 bd0d90b2 bellard
        else
385 bd0d90b2 bellard
            buf[i] = ' ';
386 bd0d90b2 bellard
    }
387 bd0d90b2 bellard
}
388 bd0d90b2 bellard
389 67b915a5 bellard
static void put_le16(uint16_t *p, unsigned int v)
390 67b915a5 bellard
{
391 0c4ad8dc bellard
    *p = cpu_to_le16(v);
392 67b915a5 bellard
}
393 67b915a5 bellard
394 5391d806 bellard
static void ide_identify(IDEState *s)
395 5391d806 bellard
{
396 5391d806 bellard
    uint16_t *p;
397 5391d806 bellard
    unsigned int oldsize;
398 aedf5382 bellard
    char buf[20];
399 5391d806 bellard
400 5391d806 bellard
    memset(s->io_buffer, 0, 512);
401 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
402 67b915a5 bellard
    put_le16(p + 0, 0x0040);
403 67b915a5 bellard
    put_le16(p + 1, s->cylinders); 
404 67b915a5 bellard
    put_le16(p + 3, s->heads);
405 67b915a5 bellard
    put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
406 67b915a5 bellard
    put_le16(p + 5, 512); /* XXX: retired, remove ? */
407 67b915a5 bellard
    put_le16(p + 6, s->sectors); 
408 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
409 aedf5382 bellard
    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
410 67b915a5 bellard
    put_le16(p + 20, 3); /* XXX: retired, remove ? */
411 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
412 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
413 5391d806 bellard
    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
414 5391d806 bellard
    padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
415 5391d806 bellard
#if MAX_MULT_SECTORS > 1    
416 67b915a5 bellard
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
417 5391d806 bellard
#endif
418 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O */
419 e0fe67aa bellard
    put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
420 67b915a5 bellard
    put_le16(p + 51, 0x200); /* PIO transfer cycle */
421 67b915a5 bellard
    put_le16(p + 52, 0x200); /* DMA transfer cycle */
422 e0fe67aa bellard
    put_le16(p + 53, 1 | 1 << 2); /* words 54-58,88 are valid */
423 67b915a5 bellard
    put_le16(p + 54, s->cylinders);
424 67b915a5 bellard
    put_le16(p + 55, s->heads);
425 67b915a5 bellard
    put_le16(p + 56, s->sectors);
426 5391d806 bellard
    oldsize = s->cylinders * s->heads * s->sectors;
427 67b915a5 bellard
    put_le16(p + 57, oldsize);
428 67b915a5 bellard
    put_le16(p + 58, oldsize >> 16);
429 5391d806 bellard
    if (s->mult_sectors)
430 67b915a5 bellard
        put_le16(p + 59, 0x100 | s->mult_sectors);
431 67b915a5 bellard
    put_le16(p + 60, s->nb_sectors);
432 67b915a5 bellard
    put_le16(p + 61, s->nb_sectors >> 16);
433 67b915a5 bellard
    put_le16(p + 80, (1 << 1) | (1 << 2));
434 67b915a5 bellard
    put_le16(p + 82, (1 << 14));
435 67b915a5 bellard
    put_le16(p + 83, (1 << 14));
436 67b915a5 bellard
    put_le16(p + 84, (1 << 14));
437 67b915a5 bellard
    put_le16(p + 85, (1 << 14));
438 67b915a5 bellard
    put_le16(p + 86, 0);
439 67b915a5 bellard
    put_le16(p + 87, (1 << 14));
440 e0fe67aa bellard
    put_le16(p + 88, 0x1f | (1 << 13));
441 e0fe67aa bellard
    put_le16(p + 93, 1 | (1 << 14) | 0x2000 | 0x4000);
442 5391d806 bellard
}
443 5391d806 bellard
444 5391d806 bellard
static void ide_atapi_identify(IDEState *s)
445 5391d806 bellard
{
446 5391d806 bellard
    uint16_t *p;
447 aedf5382 bellard
    char buf[20];
448 5391d806 bellard
449 5391d806 bellard
    memset(s->io_buffer, 0, 512);
450 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
451 5391d806 bellard
    /* Removable CDROM, 50us response, 12 byte packets */
452 67b915a5 bellard
    put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
453 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
454 aedf5382 bellard
    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
455 67b915a5 bellard
    put_le16(p + 20, 3); /* buffer type */
456 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
457 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
458 5391d806 bellard
    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
459 5391d806 bellard
    padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
460 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
461 67b915a5 bellard
    put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
462 67b915a5 bellard
    put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
463 67b915a5 bellard
    put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
464 67b915a5 bellard
    put_le16(p + 64, 1); /* PIO modes */
465 67b915a5 bellard
    put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
466 67b915a5 bellard
    put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
467 67b915a5 bellard
    put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
468 67b915a5 bellard
    put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
469 5391d806 bellard
    
470 67b915a5 bellard
    put_le16(p + 71, 30); /* in ns */
471 67b915a5 bellard
    put_le16(p + 72, 30); /* in ns */
472 5391d806 bellard
473 67b915a5 bellard
    put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
474 5391d806 bellard
}
475 5391d806 bellard
476 5391d806 bellard
static void ide_set_signature(IDEState *s)
477 5391d806 bellard
{
478 5391d806 bellard
    s->select &= 0xf0; /* clear head */
479 5391d806 bellard
    /* put signature */
480 5391d806 bellard
    s->nsector = 1;
481 5391d806 bellard
    s->sector = 1;
482 5391d806 bellard
    if (s->is_cdrom) {
483 5391d806 bellard
        s->lcyl = 0x14;
484 5391d806 bellard
        s->hcyl = 0xeb;
485 5391d806 bellard
    } else if (s->bs) {
486 5391d806 bellard
        s->lcyl = 0;
487 5391d806 bellard
        s->hcyl = 0;
488 5391d806 bellard
    } else {
489 5391d806 bellard
        s->lcyl = 0xff;
490 5391d806 bellard
        s->hcyl = 0xff;
491 5391d806 bellard
    }
492 5391d806 bellard
}
493 5391d806 bellard
494 5391d806 bellard
static inline void ide_abort_command(IDEState *s)
495 5391d806 bellard
{
496 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
497 5391d806 bellard
    s->error = ABRT_ERR;
498 5391d806 bellard
}
499 5391d806 bellard
500 5391d806 bellard
static inline void ide_set_irq(IDEState *s)
501 5391d806 bellard
{
502 5391d806 bellard
    if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
503 1ade1de2 bellard
#ifdef TARGET_PPC
504 1ade1de2 bellard
        if (s->openpic) 
505 1ade1de2 bellard
            openpic_set_irq(s->openpic, s->irq, 1);
506 1ade1de2 bellard
        else 
507 1ade1de2 bellard
#endif
508 34e538ae bellard
        if (s->irq == 16)
509 34e538ae bellard
            pci_set_irq(s->pci_dev, 0, 1);
510 34e538ae bellard
        else
511 34e538ae bellard
            pic_set_irq(s->irq, 1);
512 5391d806 bellard
    }
513 5391d806 bellard
}
514 5391d806 bellard
515 5391d806 bellard
/* prepare data transfer and tell what to do after */
516 5391d806 bellard
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, 
517 5391d806 bellard
                               EndTransferFunc *end_transfer_func)
518 5391d806 bellard
{
519 5391d806 bellard
    s->end_transfer_func = end_transfer_func;
520 5391d806 bellard
    s->data_ptr = buf;
521 5391d806 bellard
    s->data_end = buf + size;
522 5391d806 bellard
    s->status |= DRQ_STAT;
523 5391d806 bellard
}
524 5391d806 bellard
525 5391d806 bellard
static void ide_transfer_stop(IDEState *s)
526 5391d806 bellard
{
527 5391d806 bellard
    s->end_transfer_func = ide_transfer_stop;
528 5391d806 bellard
    s->data_ptr = s->io_buffer;
529 5391d806 bellard
    s->data_end = s->io_buffer;
530 5391d806 bellard
    s->status &= ~DRQ_STAT;
531 5391d806 bellard
}
532 5391d806 bellard
533 5391d806 bellard
static int64_t ide_get_sector(IDEState *s)
534 5391d806 bellard
{
535 5391d806 bellard
    int64_t sector_num;
536 5391d806 bellard
    if (s->select & 0x40) {
537 5391d806 bellard
        /* lba */
538 5391d806 bellard
        sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) | 
539 5391d806 bellard
            (s->lcyl << 8) | s->sector;
540 5391d806 bellard
    } else {
541 5391d806 bellard
        sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
542 5391d806 bellard
            (s->select & 0x0f) * s->sectors + 
543 5391d806 bellard
            (s->sector - 1);
544 5391d806 bellard
    }
545 5391d806 bellard
    return sector_num;
546 5391d806 bellard
}
547 5391d806 bellard
548 5391d806 bellard
static void ide_set_sector(IDEState *s, int64_t sector_num)
549 5391d806 bellard
{
550 5391d806 bellard
    unsigned int cyl, r;
551 5391d806 bellard
    if (s->select & 0x40) {
552 5391d806 bellard
        s->select = (s->select & 0xf0) | (sector_num >> 24);
553 5391d806 bellard
        s->hcyl = (sector_num >> 16);
554 5391d806 bellard
        s->lcyl = (sector_num >> 8);
555 5391d806 bellard
        s->sector = (sector_num);
556 5391d806 bellard
    } else {
557 5391d806 bellard
        cyl = sector_num / (s->heads * s->sectors);
558 5391d806 bellard
        r = sector_num % (s->heads * s->sectors);
559 5391d806 bellard
        s->hcyl = cyl >> 8;
560 5391d806 bellard
        s->lcyl = cyl;
561 1b8eb456 bellard
        s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
562 5391d806 bellard
        s->sector = (r % s->sectors) + 1;
563 5391d806 bellard
    }
564 5391d806 bellard
}
565 5391d806 bellard
566 5391d806 bellard
static void ide_sector_read(IDEState *s)
567 5391d806 bellard
{
568 5391d806 bellard
    int64_t sector_num;
569 5391d806 bellard
    int ret, n;
570 5391d806 bellard
571 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
572 a136e5a8 bellard
    s->error = 0; /* not needed by IDE spec, but needed by Windows */
573 5391d806 bellard
    sector_num = ide_get_sector(s);
574 5391d806 bellard
    n = s->nsector;
575 5391d806 bellard
    if (n == 0) {
576 5391d806 bellard
        /* no more sector to read from disk */
577 5391d806 bellard
        ide_transfer_stop(s);
578 5391d806 bellard
    } else {
579 5391d806 bellard
#if defined(DEBUG_IDE)
580 5391d806 bellard
        printf("read sector=%Ld\n", sector_num);
581 5391d806 bellard
#endif
582 5391d806 bellard
        if (n > s->req_nb_sectors)
583 5391d806 bellard
            n = s->req_nb_sectors;
584 5391d806 bellard
        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
585 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
586 5391d806 bellard
        ide_set_irq(s);
587 5391d806 bellard
        ide_set_sector(s, sector_num + n);
588 5391d806 bellard
        s->nsector -= n;
589 5391d806 bellard
    }
590 5391d806 bellard
}
591 5391d806 bellard
592 98087450 bellard
static int ide_read_dma_cb(IDEState *s, 
593 98087450 bellard
                           target_phys_addr_t phys_addr, 
594 98087450 bellard
                           int transfer_size1)
595 98087450 bellard
{
596 98087450 bellard
    int len, transfer_size, n;
597 98087450 bellard
    int64_t sector_num;
598 98087450 bellard
599 98087450 bellard
    transfer_size = transfer_size1;
600 98087450 bellard
    while (transfer_size > 0) {
601 98087450 bellard
        len = s->io_buffer_size - s->io_buffer_index;
602 98087450 bellard
        if (len <= 0) {
603 98087450 bellard
            /* transfert next data */
604 98087450 bellard
            n = s->nsector;
605 98087450 bellard
            if (n == 0)
606 98087450 bellard
                break;
607 98087450 bellard
            if (n > MAX_MULT_SECTORS)
608 98087450 bellard
                n = MAX_MULT_SECTORS;
609 98087450 bellard
            sector_num = ide_get_sector(s);
610 98087450 bellard
            bdrv_read(s->bs, sector_num, s->io_buffer, n);
611 98087450 bellard
            s->io_buffer_index = 0;
612 98087450 bellard
            s->io_buffer_size = n * 512;
613 98087450 bellard
            len = s->io_buffer_size;
614 98087450 bellard
            sector_num += n;
615 98087450 bellard
            ide_set_sector(s, sector_num);
616 98087450 bellard
            s->nsector -= n;
617 98087450 bellard
        }
618 98087450 bellard
        if (len > transfer_size)
619 98087450 bellard
            len = transfer_size;
620 98087450 bellard
        cpu_physical_memory_write(phys_addr, 
621 98087450 bellard
                                  s->io_buffer + s->io_buffer_index, len);
622 98087450 bellard
        s->io_buffer_index += len;
623 98087450 bellard
        transfer_size -= len;
624 98087450 bellard
        phys_addr += len;
625 98087450 bellard
    }
626 98087450 bellard
    if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
627 98087450 bellard
        s->status = READY_STAT | SEEK_STAT;
628 98087450 bellard
        ide_set_irq(s);
629 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
630 98087450 bellard
        printf("dma status=0x%x\n", s->status);
631 98087450 bellard
#endif
632 98087450 bellard
        return 0;
633 98087450 bellard
    }
634 98087450 bellard
    return transfer_size1 - transfer_size;
635 98087450 bellard
}
636 98087450 bellard
637 98087450 bellard
static void ide_sector_read_dma(IDEState *s)
638 98087450 bellard
{
639 98087450 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
640 98087450 bellard
    s->io_buffer_index = 0;
641 98087450 bellard
    s->io_buffer_size = 0;
642 98087450 bellard
    ide_dma_start(s, ide_read_dma_cb);
643 98087450 bellard
}
644 98087450 bellard
645 5391d806 bellard
static void ide_sector_write(IDEState *s)
646 5391d806 bellard
{
647 5391d806 bellard
    int64_t sector_num;
648 5391d806 bellard
    int ret, n, n1;
649 5391d806 bellard
650 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
651 5391d806 bellard
    sector_num = ide_get_sector(s);
652 5391d806 bellard
#if defined(DEBUG_IDE)
653 5391d806 bellard
    printf("write sector=%Ld\n", sector_num);
654 5391d806 bellard
#endif
655 5391d806 bellard
    n = s->nsector;
656 5391d806 bellard
    if (n > s->req_nb_sectors)
657 5391d806 bellard
        n = s->req_nb_sectors;
658 5391d806 bellard
    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
659 5391d806 bellard
    s->nsector -= n;
660 5391d806 bellard
    if (s->nsector == 0) {
661 5391d806 bellard
        /* no more sector to write */
662 5391d806 bellard
        ide_transfer_stop(s);
663 5391d806 bellard
    } else {
664 5391d806 bellard
        n1 = s->nsector;
665 5391d806 bellard
        if (n1 > s->req_nb_sectors)
666 5391d806 bellard
            n1 = s->req_nb_sectors;
667 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
668 5391d806 bellard
    }
669 5391d806 bellard
    ide_set_sector(s, sector_num + n);
670 5391d806 bellard
    ide_set_irq(s);
671 5391d806 bellard
}
672 5391d806 bellard
673 98087450 bellard
static int ide_write_dma_cb(IDEState *s, 
674 98087450 bellard
                            target_phys_addr_t phys_addr, 
675 98087450 bellard
                            int transfer_size1)
676 98087450 bellard
{
677 98087450 bellard
    int len, transfer_size, n;
678 98087450 bellard
    int64_t sector_num;
679 98087450 bellard
680 98087450 bellard
    transfer_size = transfer_size1;
681 98087450 bellard
    for(;;) {
682 98087450 bellard
        len = s->io_buffer_size - s->io_buffer_index;
683 98087450 bellard
        if (len == 0) {
684 98087450 bellard
            n = s->io_buffer_size >> 9;
685 98087450 bellard
            sector_num = ide_get_sector(s);
686 98087450 bellard
            bdrv_write(s->bs, sector_num, s->io_buffer, 
687 98087450 bellard
                       s->io_buffer_size >> 9);
688 98087450 bellard
            sector_num += n;
689 98087450 bellard
            ide_set_sector(s, sector_num);
690 98087450 bellard
            s->nsector -= n;
691 98087450 bellard
            n = s->nsector;
692 98087450 bellard
            if (n == 0) {
693 98087450 bellard
                /* end of transfer */
694 98087450 bellard
                s->status = READY_STAT | SEEK_STAT;
695 98087450 bellard
                ide_set_irq(s);
696 98087450 bellard
                return 0;
697 98087450 bellard
            }
698 98087450 bellard
            if (n > MAX_MULT_SECTORS)
699 98087450 bellard
                n = MAX_MULT_SECTORS;
700 98087450 bellard
            s->io_buffer_index = 0;
701 98087450 bellard
            s->io_buffer_size = n * 512;
702 98087450 bellard
            len = s->io_buffer_size;
703 98087450 bellard
        }
704 98087450 bellard
        if (transfer_size <= 0)
705 98087450 bellard
            break;
706 98087450 bellard
        if (len > transfer_size)
707 98087450 bellard
            len = transfer_size;
708 98087450 bellard
        cpu_physical_memory_read(phys_addr, 
709 98087450 bellard
                                 s->io_buffer + s->io_buffer_index, len);
710 98087450 bellard
        s->io_buffer_index += len;
711 98087450 bellard
        transfer_size -= len;
712 98087450 bellard
        phys_addr += len;
713 98087450 bellard
    }
714 98087450 bellard
    return transfer_size1 - transfer_size;
715 98087450 bellard
}
716 98087450 bellard
717 98087450 bellard
static void ide_sector_write_dma(IDEState *s)
718 98087450 bellard
{
719 98087450 bellard
    int n;
720 98087450 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
721 98087450 bellard
    n = s->nsector;
722 98087450 bellard
    if (n > MAX_MULT_SECTORS)
723 98087450 bellard
        n = MAX_MULT_SECTORS;
724 98087450 bellard
    s->io_buffer_index = 0;
725 98087450 bellard
    s->io_buffer_size = n * 512;
726 98087450 bellard
    ide_dma_start(s, ide_write_dma_cb);
727 98087450 bellard
}
728 98087450 bellard
729 5391d806 bellard
static void ide_atapi_cmd_ok(IDEState *s)
730 5391d806 bellard
{
731 5391d806 bellard
    s->error = 0;
732 5391d806 bellard
    s->status = READY_STAT;
733 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
734 5391d806 bellard
    ide_set_irq(s);
735 5391d806 bellard
}
736 5391d806 bellard
737 5391d806 bellard
static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
738 5391d806 bellard
{
739 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
740 5391d806 bellard
    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
741 5391d806 bellard
#endif
742 5391d806 bellard
    s->error = sense_key << 4;
743 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
744 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
745 5391d806 bellard
    s->sense_key = sense_key;
746 5391d806 bellard
    s->asc = asc;
747 5391d806 bellard
    ide_set_irq(s);
748 5391d806 bellard
}
749 5391d806 bellard
750 5391d806 bellard
static inline void cpu_to_ube16(uint8_t *buf, int val)
751 5391d806 bellard
{
752 5391d806 bellard
    buf[0] = val >> 8;
753 5391d806 bellard
    buf[1] = val;
754 5391d806 bellard
}
755 5391d806 bellard
756 5391d806 bellard
static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
757 5391d806 bellard
{
758 5391d806 bellard
    buf[0] = val >> 24;
759 5391d806 bellard
    buf[1] = val >> 16;
760 5391d806 bellard
    buf[2] = val >> 8;
761 5391d806 bellard
    buf[3] = val;
762 5391d806 bellard
}
763 5391d806 bellard
764 5391d806 bellard
static inline int ube16_to_cpu(const uint8_t *buf)
765 5391d806 bellard
{
766 5391d806 bellard
    return (buf[0] << 8) | buf[1];
767 5391d806 bellard
}
768 5391d806 bellard
769 5391d806 bellard
static inline int ube32_to_cpu(const uint8_t *buf)
770 5391d806 bellard
{
771 5391d806 bellard
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
772 5391d806 bellard
}
773 5391d806 bellard
774 98087450 bellard
static void lba_to_msf(uint8_t *buf, int lba)
775 98087450 bellard
{
776 98087450 bellard
    lba += 150;
777 98087450 bellard
    buf[0] = (lba / 75) / 60;
778 98087450 bellard
    buf[1] = (lba / 75) % 60;
779 98087450 bellard
    buf[2] = lba % 75;
780 98087450 bellard
}
781 98087450 bellard
782 98087450 bellard
static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, 
783 98087450 bellard
                           int sector_size)
784 98087450 bellard
{
785 98087450 bellard
    switch(sector_size) {
786 98087450 bellard
    case 2048:
787 98087450 bellard
        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
788 98087450 bellard
        break;
789 98087450 bellard
    case 2352:
790 98087450 bellard
        /* sync bytes */
791 98087450 bellard
        buf[0] = 0x00;
792 98087450 bellard
        memset(buf + 1, 0xff, 11);
793 98087450 bellard
        buf += 12;
794 98087450 bellard
        /* MSF */
795 98087450 bellard
        lba_to_msf(buf, lba);
796 98087450 bellard
        buf[3] = 0x01; /* mode 1 data */
797 98087450 bellard
        buf += 4;
798 98087450 bellard
        /* data */
799 98087450 bellard
        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
800 98087450 bellard
        buf += 2048;
801 98087450 bellard
        /* ECC */
802 98087450 bellard
        memset(buf, 0, 288);
803 98087450 bellard
        break;
804 98087450 bellard
    default:
805 98087450 bellard
        break;
806 98087450 bellard
    }
807 98087450 bellard
}
808 98087450 bellard
809 5391d806 bellard
/* The whole ATAPI transfer logic is handled in this function */
810 5391d806 bellard
static void ide_atapi_cmd_reply_end(IDEState *s)
811 5391d806 bellard
{
812 5391d806 bellard
    int byte_count_limit, size;
813 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
814 5391d806 bellard
    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n", 
815 5391d806 bellard
           s->packet_transfer_size,
816 5391d806 bellard
           s->elementary_transfer_size,
817 5391d806 bellard
           s->io_buffer_index);
818 5391d806 bellard
#endif
819 5391d806 bellard
    if (s->packet_transfer_size <= 0) {
820 5391d806 bellard
        /* end of transfer */
821 5391d806 bellard
        ide_transfer_stop(s);
822 5391d806 bellard
        s->status = READY_STAT;
823 5391d806 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
824 5391d806 bellard
        ide_set_irq(s);
825 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
826 5391d806 bellard
        printf("status=0x%x\n", s->status);
827 5391d806 bellard
#endif
828 5391d806 bellard
    } else {
829 5391d806 bellard
        /* see if a new sector must be read */
830 98087450 bellard
        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
831 98087450 bellard
            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
832 5391d806 bellard
            s->lba++;
833 5391d806 bellard
            s->io_buffer_index = 0;
834 5391d806 bellard
        }
835 5391d806 bellard
        if (s->elementary_transfer_size > 0) {
836 5391d806 bellard
            /* there are some data left to transmit in this elementary
837 5391d806 bellard
               transfer */
838 98087450 bellard
            size = s->cd_sector_size - s->io_buffer_index;
839 5391d806 bellard
            if (size > s->elementary_transfer_size)
840 5391d806 bellard
                size = s->elementary_transfer_size;
841 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
842 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
843 5391d806 bellard
            s->packet_transfer_size -= size;
844 5391d806 bellard
            s->elementary_transfer_size -= size;
845 5391d806 bellard
            s->io_buffer_index += size;
846 5391d806 bellard
        } else {
847 5391d806 bellard
            /* a new transfer is needed */
848 5391d806 bellard
            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
849 5391d806 bellard
            byte_count_limit = s->lcyl | (s->hcyl << 8);
850 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
851 5391d806 bellard
            printf("byte_count_limit=%d\n", byte_count_limit);
852 5391d806 bellard
#endif
853 5391d806 bellard
            if (byte_count_limit == 0xffff)
854 5391d806 bellard
                byte_count_limit--;
855 5391d806 bellard
            size = s->packet_transfer_size;
856 5391d806 bellard
            if (size > byte_count_limit) {
857 5391d806 bellard
                /* byte count limit must be even if this case */
858 5391d806 bellard
                if (byte_count_limit & 1)
859 5391d806 bellard
                    byte_count_limit--;
860 5391d806 bellard
                size = byte_count_limit;
861 5391d806 bellard
            }
862 a136e5a8 bellard
            s->lcyl = size;
863 a136e5a8 bellard
            s->hcyl = size >> 8;
864 5391d806 bellard
            s->elementary_transfer_size = size;
865 5391d806 bellard
            /* we cannot transmit more than one sector at a time */
866 5391d806 bellard
            if (s->lba != -1) {
867 98087450 bellard
                if (size > (s->cd_sector_size - s->io_buffer_index))
868 98087450 bellard
                    size = (s->cd_sector_size - s->io_buffer_index);
869 5391d806 bellard
            }
870 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
871 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
872 5391d806 bellard
            s->packet_transfer_size -= size;
873 5391d806 bellard
            s->elementary_transfer_size -= size;
874 5391d806 bellard
            s->io_buffer_index += size;
875 5391d806 bellard
            ide_set_irq(s);
876 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
877 5391d806 bellard
            printf("status=0x%x\n", s->status);
878 5391d806 bellard
#endif
879 5391d806 bellard
        }
880 5391d806 bellard
    }
881 5391d806 bellard
}
882 5391d806 bellard
883 5391d806 bellard
/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
884 5391d806 bellard
static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
885 5391d806 bellard
{
886 5391d806 bellard
    if (size > max_size)
887 5391d806 bellard
        size = max_size;
888 5391d806 bellard
    s->lba = -1; /* no sector read */
889 5391d806 bellard
    s->packet_transfer_size = size;
890 5391d806 bellard
    s->elementary_transfer_size = 0;
891 5391d806 bellard
    s->io_buffer_index = 0;
892 5391d806 bellard
893 5391d806 bellard
    s->status = READY_STAT;
894 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
895 5391d806 bellard
}
896 5391d806 bellard
897 5391d806 bellard
/* start a CD-CDROM read command */
898 98087450 bellard
static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
899 98087450 bellard
                                   int sector_size)
900 5391d806 bellard
{
901 5391d806 bellard
    s->lba = lba;
902 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
903 5391d806 bellard
    s->elementary_transfer_size = 0;
904 98087450 bellard
    s->io_buffer_index = sector_size;
905 98087450 bellard
    s->cd_sector_size = sector_size;
906 5391d806 bellard
907 5391d806 bellard
    s->status = READY_STAT;
908 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
909 5391d806 bellard
}
910 5391d806 bellard
911 98087450 bellard
/* ATAPI DMA support */
912 98087450 bellard
static int ide_atapi_cmd_read_dma_cb(IDEState *s, 
913 98087450 bellard
                                     target_phys_addr_t phys_addr, 
914 98087450 bellard
                                     int transfer_size1)
915 98087450 bellard
{
916 98087450 bellard
    int len, transfer_size;
917 98087450 bellard
    
918 98087450 bellard
    transfer_size = transfer_size1;
919 98087450 bellard
    while (transfer_size > 0) {
920 98087450 bellard
        if (s->packet_transfer_size <= 0)
921 98087450 bellard
            break;
922 98087450 bellard
        len = s->cd_sector_size - s->io_buffer_index;
923 98087450 bellard
        if (len <= 0) {
924 98087450 bellard
            /* transfert next data */
925 98087450 bellard
            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
926 98087450 bellard
            s->lba++;
927 98087450 bellard
            s->io_buffer_index = 0;
928 98087450 bellard
            len = s->cd_sector_size;
929 98087450 bellard
        }
930 98087450 bellard
        if (len > transfer_size)
931 98087450 bellard
            len = transfer_size;
932 98087450 bellard
        cpu_physical_memory_write(phys_addr, 
933 98087450 bellard
                                  s->io_buffer + s->io_buffer_index, len);
934 98087450 bellard
        s->packet_transfer_size -= len;
935 98087450 bellard
        s->io_buffer_index += len;
936 98087450 bellard
        transfer_size -= len;
937 98087450 bellard
        phys_addr += len;
938 98087450 bellard
    }
939 98087450 bellard
    if (s->packet_transfer_size <= 0) {
940 98087450 bellard
        s->status = READY_STAT;
941 98087450 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
942 98087450 bellard
        ide_set_irq(s);
943 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
944 98087450 bellard
        printf("dma status=0x%x\n", s->status);
945 98087450 bellard
#endif
946 98087450 bellard
        return 0;
947 98087450 bellard
    }
948 98087450 bellard
    return transfer_size1 - transfer_size;
949 98087450 bellard
}
950 98087450 bellard
951 98087450 bellard
/* start a CD-CDROM read command with DMA */
952 98087450 bellard
/* XXX: test if DMA is available */
953 98087450 bellard
static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
954 98087450 bellard
                                   int sector_size)
955 98087450 bellard
{
956 98087450 bellard
    s->lba = lba;
957 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
958 98087450 bellard
    s->io_buffer_index = sector_size;
959 98087450 bellard
    s->cd_sector_size = sector_size;
960 98087450 bellard
961 98087450 bellard
    s->status = READY_STAT | DRQ_STAT;
962 98087450 bellard
    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
963 98087450 bellard
}
964 98087450 bellard
965 98087450 bellard
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, 
966 98087450 bellard
                               int sector_size)
967 98087450 bellard
{
968 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
969 98087450 bellard
    printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
970 98087450 bellard
#endif
971 98087450 bellard
    if (s->atapi_dma) {
972 98087450 bellard
        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
973 98087450 bellard
    } else {
974 98087450 bellard
        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
975 98087450 bellard
    }
976 98087450 bellard
}
977 98087450 bellard
978 5391d806 bellard
/* same toc as bochs. Return -1 if error or the toc length */
979 98087450 bellard
/* XXX: check this */
980 5391d806 bellard
static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
981 5391d806 bellard
{
982 5391d806 bellard
    uint8_t *q;
983 5391d806 bellard
    int nb_sectors, len;
984 5391d806 bellard
    
985 5391d806 bellard
    if (start_track > 1 && start_track != 0xaa)
986 5391d806 bellard
        return -1;
987 5391d806 bellard
    q = buf + 2;
988 98087450 bellard
    *q++ = 1; /* first session */
989 98087450 bellard
    *q++ = 1; /* last session */
990 5391d806 bellard
    if (start_track <= 1) {
991 5391d806 bellard
        *q++ = 0; /* reserved */
992 5391d806 bellard
        *q++ = 0x14; /* ADR, control */
993 5391d806 bellard
        *q++ = 1;    /* track number */
994 5391d806 bellard
        *q++ = 0; /* reserved */
995 5391d806 bellard
        if (msf) {
996 5391d806 bellard
            *q++ = 0; /* reserved */
997 5391d806 bellard
            *q++ = 0; /* minute */
998 5391d806 bellard
            *q++ = 2; /* second */
999 5391d806 bellard
            *q++ = 0; /* frame */
1000 5391d806 bellard
        } else {
1001 5391d806 bellard
            /* sector 0 */
1002 5391d806 bellard
            cpu_to_ube32(q, 0);
1003 5391d806 bellard
            q += 4;
1004 5391d806 bellard
        }
1005 5391d806 bellard
    }
1006 5391d806 bellard
    /* lead out track */
1007 5391d806 bellard
    *q++ = 0; /* reserved */
1008 5391d806 bellard
    *q++ = 0x16; /* ADR, control */
1009 5391d806 bellard
    *q++ = 0xaa; /* track number */
1010 5391d806 bellard
    *q++ = 0; /* reserved */
1011 5391d806 bellard
    nb_sectors = s->nb_sectors >> 2;
1012 5391d806 bellard
    if (msf) {
1013 5391d806 bellard
        *q++ = 0; /* reserved */
1014 98087450 bellard
        lba_to_msf(q, nb_sectors);
1015 98087450 bellard
        q += 3;
1016 98087450 bellard
    } else {
1017 98087450 bellard
        cpu_to_ube32(q, nb_sectors);
1018 98087450 bellard
        q += 4;
1019 98087450 bellard
    }
1020 98087450 bellard
    len = q - buf;
1021 98087450 bellard
    cpu_to_ube16(buf, len - 2);
1022 98087450 bellard
    return len;
1023 98087450 bellard
}
1024 98087450 bellard
1025 98087450 bellard
/* mostly same info as PearPc */
1026 98087450 bellard
static int cdrom_read_toc_raw(IDEState *s, uint8_t *buf, int msf, 
1027 98087450 bellard
                              int session_num)
1028 98087450 bellard
{
1029 98087450 bellard
    uint8_t *q;
1030 98087450 bellard
    int nb_sectors, len;
1031 98087450 bellard
    
1032 98087450 bellard
    q = buf + 2;
1033 98087450 bellard
    *q++ = 1; /* first session */
1034 98087450 bellard
    *q++ = 1; /* last session */
1035 98087450 bellard
1036 98087450 bellard
    *q++ = 1; /* session number */
1037 98087450 bellard
    *q++ = 0x14; /* data track */
1038 98087450 bellard
    *q++ = 0; /* track number */
1039 98087450 bellard
    *q++ = 0xa0; /* lead-in */
1040 98087450 bellard
    *q++ = 0; /* min */
1041 98087450 bellard
    *q++ = 0; /* sec */
1042 98087450 bellard
    *q++ = 0; /* frame */
1043 98087450 bellard
    *q++ = 0;
1044 98087450 bellard
    *q++ = 1; /* first track */
1045 98087450 bellard
    *q++ = 0x00; /* disk type */
1046 98087450 bellard
    *q++ = 0x00;
1047 98087450 bellard
    
1048 98087450 bellard
    *q++ = 1; /* session number */
1049 98087450 bellard
    *q++ = 0x14; /* data track */
1050 98087450 bellard
    *q++ = 0; /* track number */
1051 98087450 bellard
    *q++ = 0xa1;
1052 98087450 bellard
    *q++ = 0; /* min */
1053 98087450 bellard
    *q++ = 0; /* sec */
1054 98087450 bellard
    *q++ = 0; /* frame */
1055 98087450 bellard
    *q++ = 0;
1056 98087450 bellard
    *q++ = 1; /* last track */
1057 98087450 bellard
    *q++ = 0x00;
1058 98087450 bellard
    *q++ = 0x00;
1059 98087450 bellard
    
1060 98087450 bellard
    *q++ = 1; /* session number */
1061 98087450 bellard
    *q++ = 0x14; /* data track */
1062 98087450 bellard
    *q++ = 0; /* track number */
1063 98087450 bellard
    *q++ = 0xa2; /* lead-out */
1064 98087450 bellard
    *q++ = 0; /* min */
1065 98087450 bellard
    *q++ = 0; /* sec */
1066 98087450 bellard
    *q++ = 0; /* frame */
1067 98087450 bellard
    nb_sectors = s->nb_sectors >> 2;
1068 98087450 bellard
    if (msf) {
1069 98087450 bellard
        *q++ = 0; /* reserved */
1070 98087450 bellard
        lba_to_msf(q, nb_sectors);
1071 98087450 bellard
        q += 3;
1072 5391d806 bellard
    } else {
1073 5391d806 bellard
        cpu_to_ube32(q, nb_sectors);
1074 5391d806 bellard
        q += 4;
1075 5391d806 bellard
    }
1076 98087450 bellard
1077 98087450 bellard
    *q++ = 1; /* session number */
1078 98087450 bellard
    *q++ = 0x14; /* ADR, control */
1079 98087450 bellard
    *q++ = 0;    /* track number */
1080 98087450 bellard
    *q++ = 1;    /* point */
1081 98087450 bellard
    *q++ = 0; /* min */
1082 98087450 bellard
    *q++ = 0; /* sec */
1083 98087450 bellard
    *q++ = 0; /* frame */
1084 98087450 bellard
    *q++ = 0; 
1085 98087450 bellard
    *q++ = 0; 
1086 98087450 bellard
    *q++ = 0; 
1087 98087450 bellard
    *q++ = 0; 
1088 98087450 bellard
1089 5391d806 bellard
    len = q - buf;
1090 5391d806 bellard
    cpu_to_ube16(buf, len - 2);
1091 5391d806 bellard
    return len;
1092 5391d806 bellard
}
1093 5391d806 bellard
1094 5391d806 bellard
static void ide_atapi_cmd(IDEState *s)
1095 5391d806 bellard
{
1096 5391d806 bellard
    const uint8_t *packet;
1097 5391d806 bellard
    uint8_t *buf;
1098 5391d806 bellard
    int max_len;
1099 5391d806 bellard
1100 5391d806 bellard
    packet = s->io_buffer;
1101 5391d806 bellard
    buf = s->io_buffer;
1102 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1103 5391d806 bellard
    {
1104 5391d806 bellard
        int i;
1105 5391d806 bellard
        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
1106 5391d806 bellard
        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
1107 5391d806 bellard
            printf(" %02x", packet[i]);
1108 5391d806 bellard
        }
1109 5391d806 bellard
        printf("\n");
1110 5391d806 bellard
    }
1111 5391d806 bellard
#endif
1112 5391d806 bellard
    switch(s->io_buffer[0]) {
1113 5391d806 bellard
    case GPCMD_TEST_UNIT_READY:
1114 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1115 5391d806 bellard
            ide_atapi_cmd_ok(s);
1116 5391d806 bellard
        } else {
1117 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1118 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1119 5391d806 bellard
        }
1120 5391d806 bellard
        break;
1121 5391d806 bellard
    case GPCMD_MODE_SENSE_10:
1122 5391d806 bellard
        {
1123 5391d806 bellard
            int action, code;
1124 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1125 5391d806 bellard
            action = packet[2] >> 6;
1126 5391d806 bellard
            code = packet[2] & 0x3f;
1127 5391d806 bellard
            switch(action) {
1128 5391d806 bellard
            case 0: /* current values */
1129 5391d806 bellard
                switch(code) {
1130 5391d806 bellard
                case 0x01: /* error recovery */
1131 5391d806 bellard
                    cpu_to_ube16(&buf[0], 16 + 6);
1132 5391d806 bellard
                    buf[2] = 0x70;
1133 5391d806 bellard
                    buf[3] = 0;
1134 5391d806 bellard
                    buf[4] = 0;
1135 5391d806 bellard
                    buf[5] = 0;
1136 5391d806 bellard
                    buf[6] = 0;
1137 5391d806 bellard
                    buf[7] = 0;
1138 5391d806 bellard
1139 5391d806 bellard
                    buf[8] = 0x01;
1140 5391d806 bellard
                    buf[9] = 0x06;
1141 5391d806 bellard
                    buf[10] = 0x00;
1142 5391d806 bellard
                    buf[11] = 0x05;
1143 5391d806 bellard
                    buf[12] = 0x00;
1144 5391d806 bellard
                    buf[13] = 0x00;
1145 5391d806 bellard
                    buf[14] = 0x00;
1146 5391d806 bellard
                    buf[15] = 0x00;
1147 5391d806 bellard
                    ide_atapi_cmd_reply(s, 16, max_len);
1148 5391d806 bellard
                    break;
1149 5391d806 bellard
                case 0x2a:
1150 5391d806 bellard
                    cpu_to_ube16(&buf[0], 28 + 6);
1151 5391d806 bellard
                    buf[2] = 0x70;
1152 5391d806 bellard
                    buf[3] = 0;
1153 5391d806 bellard
                    buf[4] = 0;
1154 5391d806 bellard
                    buf[5] = 0;
1155 5391d806 bellard
                    buf[6] = 0;
1156 5391d806 bellard
                    buf[7] = 0;
1157 5391d806 bellard
1158 5391d806 bellard
                    buf[8] = 0x2a;
1159 5391d806 bellard
                    buf[9] = 0x12;
1160 5391d806 bellard
                    buf[10] = 0x00;
1161 5391d806 bellard
                    buf[11] = 0x00;
1162 5391d806 bellard
                    
1163 5391d806 bellard
                    buf[12] = 0x70;
1164 5391d806 bellard
                    buf[13] = 3 << 5;
1165 5391d806 bellard
                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
1166 caed8802 bellard
                    if (bdrv_is_locked(s->bs))
1167 5391d806 bellard
                        buf[6] |= 1 << 1;
1168 5391d806 bellard
                    buf[15] = 0x00;
1169 5391d806 bellard
                    cpu_to_ube16(&buf[16], 706);
1170 5391d806 bellard
                    buf[18] = 0;
1171 5391d806 bellard
                    buf[19] = 2;
1172 5391d806 bellard
                    cpu_to_ube16(&buf[20], 512);
1173 5391d806 bellard
                    cpu_to_ube16(&buf[22], 706);
1174 5391d806 bellard
                    buf[24] = 0;
1175 5391d806 bellard
                    buf[25] = 0;
1176 5391d806 bellard
                    buf[26] = 0;
1177 5391d806 bellard
                    buf[27] = 0;
1178 5391d806 bellard
                    ide_atapi_cmd_reply(s, 28, max_len);
1179 5391d806 bellard
                    break;
1180 5391d806 bellard
                default:
1181 5391d806 bellard
                    goto error_cmd;
1182 5391d806 bellard
                }
1183 5391d806 bellard
                break;
1184 5391d806 bellard
            case 1: /* changeable values */
1185 5391d806 bellard
                goto error_cmd;
1186 5391d806 bellard
            case 2: /* default values */
1187 5391d806 bellard
                goto error_cmd;
1188 5391d806 bellard
            default:
1189 5391d806 bellard
            case 3: /* saved values */
1190 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1191 5391d806 bellard
                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1192 5391d806 bellard
                break;
1193 5391d806 bellard
            }
1194 5391d806 bellard
        }
1195 5391d806 bellard
        break;
1196 5391d806 bellard
    case GPCMD_REQUEST_SENSE:
1197 5391d806 bellard
        max_len = packet[4];
1198 5391d806 bellard
        memset(buf, 0, 18);
1199 5391d806 bellard
        buf[0] = 0x70 | (1 << 7);
1200 5391d806 bellard
        buf[2] = s->sense_key;
1201 5391d806 bellard
        buf[7] = 10;
1202 5391d806 bellard
        buf[12] = s->asc;
1203 5391d806 bellard
        ide_atapi_cmd_reply(s, 18, max_len);
1204 5391d806 bellard
        break;
1205 5391d806 bellard
    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
1206 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1207 caed8802 bellard
            bdrv_set_locked(s->bs, packet[4] & 1);
1208 5391d806 bellard
            ide_atapi_cmd_ok(s);
1209 5391d806 bellard
        } else {
1210 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1211 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1212 5391d806 bellard
        }
1213 5391d806 bellard
        break;
1214 5391d806 bellard
    case GPCMD_READ_10:
1215 5391d806 bellard
    case GPCMD_READ_12:
1216 5391d806 bellard
        {
1217 5391d806 bellard
            int nb_sectors, lba;
1218 5391d806 bellard
1219 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1220 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1221 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1222 5391d806 bellard
                break;
1223 5391d806 bellard
            }
1224 5391d806 bellard
            if (packet[0] == GPCMD_READ_10)
1225 5391d806 bellard
                nb_sectors = ube16_to_cpu(packet + 7);
1226 5391d806 bellard
            else
1227 5391d806 bellard
                nb_sectors = ube32_to_cpu(packet + 6);
1228 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1229 5391d806 bellard
            if (nb_sectors == 0) {
1230 5391d806 bellard
                ide_atapi_cmd_ok(s);
1231 5391d806 bellard
                break;
1232 5391d806 bellard
            }
1233 5391d806 bellard
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1234 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1235 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1236 5391d806 bellard
                break;
1237 5391d806 bellard
            }
1238 98087450 bellard
            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1239 98087450 bellard
        }
1240 98087450 bellard
        break;
1241 98087450 bellard
    case GPCMD_READ_CD:
1242 98087450 bellard
        {
1243 98087450 bellard
            int nb_sectors, lba, transfer_request;
1244 98087450 bellard
1245 98087450 bellard
            if (!bdrv_is_inserted(s->bs)) {
1246 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1247 98087450 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1248 98087450 bellard
                break;
1249 98087450 bellard
            }
1250 98087450 bellard
            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1251 98087450 bellard
            lba = ube32_to_cpu(packet + 2);
1252 98087450 bellard
            if (nb_sectors == 0) {
1253 98087450 bellard
                ide_atapi_cmd_ok(s);
1254 98087450 bellard
                break;
1255 98087450 bellard
            }
1256 98087450 bellard
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1257 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1258 98087450 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1259 98087450 bellard
                break;
1260 98087450 bellard
            }
1261 98087450 bellard
            transfer_request = packet[9];
1262 98087450 bellard
            switch(transfer_request & 0xf8) {
1263 98087450 bellard
            case 0x00:
1264 98087450 bellard
                /* nothing */
1265 98087450 bellard
                ide_atapi_cmd_ok(s);
1266 98087450 bellard
                break;
1267 98087450 bellard
            case 0x10:
1268 98087450 bellard
                /* normal read */
1269 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1270 98087450 bellard
                break;
1271 98087450 bellard
            case 0xf8:
1272 98087450 bellard
                /* read all data */
1273 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
1274 98087450 bellard
                break;
1275 98087450 bellard
            default:
1276 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1277 98087450 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1278 98087450 bellard
                break;
1279 98087450 bellard
            }
1280 5391d806 bellard
        }
1281 5391d806 bellard
        break;
1282 5391d806 bellard
    case GPCMD_SEEK:
1283 5391d806 bellard
        {
1284 5391d806 bellard
            int lba;
1285 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1286 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1287 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1288 5391d806 bellard
                break;
1289 5391d806 bellard
            }
1290 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1291 5391d806 bellard
            if (((int64_t)lba << 2) > s->nb_sectors) {
1292 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1293 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1294 5391d806 bellard
                break;
1295 5391d806 bellard
            }
1296 5391d806 bellard
            ide_atapi_cmd_ok(s);
1297 5391d806 bellard
        }
1298 5391d806 bellard
        break;
1299 5391d806 bellard
    case GPCMD_START_STOP_UNIT:
1300 5391d806 bellard
        {
1301 5391d806 bellard
            int start, eject;
1302 5391d806 bellard
            start = packet[4] & 1;
1303 5391d806 bellard
            eject = (packet[4] >> 1) & 1;
1304 5391d806 bellard
            
1305 caed8802 bellard
            if (eject && !start) {
1306 caed8802 bellard
                /* eject the disk */
1307 caed8802 bellard
                bdrv_close(s->bs);
1308 caed8802 bellard
            }
1309 5391d806 bellard
            ide_atapi_cmd_ok(s);
1310 5391d806 bellard
        }
1311 5391d806 bellard
        break;
1312 5391d806 bellard
    case GPCMD_MECHANISM_STATUS:
1313 5391d806 bellard
        {
1314 5391d806 bellard
            max_len = ube16_to_cpu(packet + 8);
1315 5391d806 bellard
            cpu_to_ube16(buf, 0);
1316 5391d806 bellard
            /* no current LBA */
1317 5391d806 bellard
            buf[2] = 0;
1318 5391d806 bellard
            buf[3] = 0;
1319 5391d806 bellard
            buf[4] = 0;
1320 5391d806 bellard
            buf[5] = 1;
1321 5391d806 bellard
            cpu_to_ube16(buf + 6, 0);
1322 5391d806 bellard
            ide_atapi_cmd_reply(s, 8, max_len);
1323 5391d806 bellard
        }
1324 5391d806 bellard
        break;
1325 5391d806 bellard
    case GPCMD_READ_TOC_PMA_ATIP:
1326 5391d806 bellard
        {
1327 5391d806 bellard
            int format, msf, start_track, len;
1328 5391d806 bellard
1329 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1330 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1331 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1332 5391d806 bellard
                break;
1333 5391d806 bellard
            }
1334 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1335 5391d806 bellard
            format = packet[9] >> 6;
1336 5391d806 bellard
            msf = (packet[1] >> 1) & 1;
1337 5391d806 bellard
            start_track = packet[6];
1338 5391d806 bellard
            switch(format) {
1339 5391d806 bellard
            case 0:
1340 5391d806 bellard
                len = cdrom_read_toc(s, buf, msf, start_track);
1341 5391d806 bellard
                if (len < 0)
1342 5391d806 bellard
                    goto error_cmd;
1343 5391d806 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1344 5391d806 bellard
                break;
1345 5391d806 bellard
            case 1:
1346 5391d806 bellard
                /* multi session : only a single session defined */
1347 5391d806 bellard
                memset(buf, 0, 12);
1348 5391d806 bellard
                buf[1] = 0x0a;
1349 5391d806 bellard
                buf[2] = 0x01;
1350 5391d806 bellard
                buf[3] = 0x01;
1351 5391d806 bellard
                ide_atapi_cmd_reply(s, 12, max_len);
1352 5391d806 bellard
                break;
1353 98087450 bellard
            case 2:
1354 98087450 bellard
                len = cdrom_read_toc_raw(s, buf, msf, start_track);
1355 98087450 bellard
                if (len < 0)
1356 98087450 bellard
                    goto error_cmd;
1357 98087450 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1358 98087450 bellard
                break;
1359 5391d806 bellard
            default:
1360 7f777bf3 bellard
            error_cmd:
1361 7f777bf3 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1362 7f777bf3 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1363 7f777bf3 bellard
                break;
1364 5391d806 bellard
            }
1365 5391d806 bellard
        }
1366 5391d806 bellard
        break;
1367 5391d806 bellard
    case GPCMD_READ_CDVD_CAPACITY:
1368 caed8802 bellard
        if (!bdrv_is_inserted(s->bs)) {
1369 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1370 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1371 5391d806 bellard
            break;
1372 5391d806 bellard
        }
1373 5391d806 bellard
        /* NOTE: it is really the number of sectors minus 1 */
1374 5391d806 bellard
        cpu_to_ube32(buf, (s->nb_sectors >> 2) - 1);
1375 5391d806 bellard
        cpu_to_ube32(buf + 4, 2048);
1376 5391d806 bellard
        ide_atapi_cmd_reply(s, 8, 8);
1377 5391d806 bellard
        break;
1378 bd0d90b2 bellard
    case GPCMD_INQUIRY:
1379 bd0d90b2 bellard
        max_len = packet[4];
1380 bd0d90b2 bellard
        buf[0] = 0x05; /* CD-ROM */
1381 bd0d90b2 bellard
        buf[1] = 0x80; /* removable */
1382 bd0d90b2 bellard
        buf[2] = 0x00; /* ISO */
1383 bd0d90b2 bellard
        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1384 bd0d90b2 bellard
        buf[4] = 31; /* additionnal length */
1385 bd0d90b2 bellard
        buf[5] = 0; /* reserved */
1386 bd0d90b2 bellard
        buf[6] = 0; /* reserved */
1387 bd0d90b2 bellard
        buf[7] = 0; /* reserved */
1388 bd0d90b2 bellard
        padstr8(buf + 8, 8, "QEMU");
1389 bd0d90b2 bellard
        padstr8(buf + 16, 16, "QEMU CD-ROM");
1390 bd0d90b2 bellard
        padstr8(buf + 32, 4, QEMU_VERSION);
1391 bd0d90b2 bellard
        ide_atapi_cmd_reply(s, 36, max_len);
1392 bd0d90b2 bellard
        break;
1393 5391d806 bellard
    default:
1394 5391d806 bellard
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1395 7f777bf3 bellard
                            ASC_ILLEGAL_OPCODE);
1396 5391d806 bellard
        break;
1397 5391d806 bellard
    }
1398 5391d806 bellard
}
1399 5391d806 bellard
1400 caed8802 bellard
/* called when the inserted state of the media has changed */
1401 caed8802 bellard
static void cdrom_change_cb(void *opaque)
1402 5391d806 bellard
{
1403 caed8802 bellard
    IDEState *s = opaque;
1404 caed8802 bellard
    int64_t nb_sectors;
1405 caed8802 bellard
1406 caed8802 bellard
    /* XXX: send interrupt too */
1407 caed8802 bellard
    bdrv_get_geometry(s->bs, &nb_sectors);
1408 caed8802 bellard
    s->nb_sectors = nb_sectors;
1409 caed8802 bellard
}
1410 caed8802 bellard
1411 caed8802 bellard
static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1412 caed8802 bellard
{
1413 caed8802 bellard
    IDEState *ide_if = opaque;
1414 c45c3d00 bellard
    IDEState *s;
1415 5391d806 bellard
    int unit, n;
1416 5391d806 bellard
1417 5391d806 bellard
#ifdef DEBUG_IDE
1418 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1419 5391d806 bellard
#endif
1420 5391d806 bellard
    addr &= 7;
1421 5391d806 bellard
    switch(addr) {
1422 5391d806 bellard
    case 0:
1423 5391d806 bellard
        break;
1424 5391d806 bellard
    case 1:
1425 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
1426 c45c3d00 bellard
        ide_if[0].feature = val;
1427 c45c3d00 bellard
        ide_if[1].feature = val;
1428 5391d806 bellard
        break;
1429 5391d806 bellard
    case 2:
1430 5391d806 bellard
        if (val == 0)
1431 5391d806 bellard
            val = 256;
1432 c45c3d00 bellard
        ide_if[0].nsector = val;
1433 c45c3d00 bellard
        ide_if[1].nsector = val;
1434 5391d806 bellard
        break;
1435 5391d806 bellard
    case 3:
1436 c45c3d00 bellard
        ide_if[0].sector = val;
1437 c45c3d00 bellard
        ide_if[1].sector = val;
1438 5391d806 bellard
        break;
1439 5391d806 bellard
    case 4:
1440 c45c3d00 bellard
        ide_if[0].lcyl = val;
1441 c45c3d00 bellard
        ide_if[1].lcyl = val;
1442 5391d806 bellard
        break;
1443 5391d806 bellard
    case 5:
1444 c45c3d00 bellard
        ide_if[0].hcyl = val;
1445 c45c3d00 bellard
        ide_if[1].hcyl = val;
1446 5391d806 bellard
        break;
1447 5391d806 bellard
    case 6:
1448 7ae98627 bellard
        ide_if[0].select = (val & ~0x10) | 0xa0;
1449 7ae98627 bellard
        ide_if[1].select = (val | 0x10) | 0xa0;
1450 5391d806 bellard
        /* select drive */
1451 5391d806 bellard
        unit = (val >> 4) & 1;
1452 5391d806 bellard
        s = ide_if + unit;
1453 5391d806 bellard
        ide_if->cur_drive = s;
1454 5391d806 bellard
        break;
1455 5391d806 bellard
    default:
1456 5391d806 bellard
    case 7:
1457 5391d806 bellard
        /* command */
1458 5391d806 bellard
#if defined(DEBUG_IDE)
1459 5391d806 bellard
        printf("ide: CMD=%02x\n", val);
1460 5391d806 bellard
#endif
1461 c45c3d00 bellard
        s = ide_if->cur_drive;
1462 66201e2d bellard
        /* ignore commands to non existant slave */
1463 66201e2d bellard
        if (s != ide_if && !s->bs) 
1464 66201e2d bellard
            break;
1465 5391d806 bellard
        switch(val) {
1466 5391d806 bellard
        case WIN_IDENTIFY:
1467 5391d806 bellard
            if (s->bs && !s->is_cdrom) {
1468 5391d806 bellard
                ide_identify(s);
1469 2a282056 bellard
                s->status = READY_STAT | SEEK_STAT;
1470 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1471 5391d806 bellard
            } else {
1472 5391d806 bellard
                if (s->is_cdrom) {
1473 5391d806 bellard
                    ide_set_signature(s);
1474 5391d806 bellard
                }
1475 5391d806 bellard
                ide_abort_command(s);
1476 5391d806 bellard
            }
1477 5391d806 bellard
            ide_set_irq(s);
1478 5391d806 bellard
            break;
1479 5391d806 bellard
        case WIN_SPECIFY:
1480 5391d806 bellard
        case WIN_RECAL:
1481 a136e5a8 bellard
            s->error = 0;
1482 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
1483 5391d806 bellard
            ide_set_irq(s);
1484 5391d806 bellard
            break;
1485 5391d806 bellard
        case WIN_SETMULT:
1486 5391d806 bellard
            if (s->nsector > MAX_MULT_SECTORS || 
1487 5391d806 bellard
                s->nsector == 0 ||
1488 5391d806 bellard
                (s->nsector & (s->nsector - 1)) != 0) {
1489 5391d806 bellard
                ide_abort_command(s);
1490 5391d806 bellard
            } else {
1491 5391d806 bellard
                s->mult_sectors = s->nsector;
1492 5391d806 bellard
                s->status = READY_STAT;
1493 5391d806 bellard
            }
1494 5391d806 bellard
            ide_set_irq(s);
1495 5391d806 bellard
            break;
1496 4ce900b4 bellard
        case WIN_VERIFY:
1497 4ce900b4 bellard
        case WIN_VERIFY_ONCE:
1498 4ce900b4 bellard
            /* do sector number check ? */
1499 4ce900b4 bellard
            s->status = READY_STAT;
1500 4ce900b4 bellard
            ide_set_irq(s);
1501 4ce900b4 bellard
            break;
1502 5391d806 bellard
        case WIN_READ:
1503 5391d806 bellard
        case WIN_READ_ONCE:
1504 6b136f9e bellard
            if (!s->bs) 
1505 6b136f9e bellard
                goto abort_cmd;
1506 5391d806 bellard
            s->req_nb_sectors = 1;
1507 5391d806 bellard
            ide_sector_read(s);
1508 5391d806 bellard
            break;
1509 5391d806 bellard
        case WIN_WRITE:
1510 5391d806 bellard
        case WIN_WRITE_ONCE:
1511 a136e5a8 bellard
            s->error = 0;
1512 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1513 5391d806 bellard
            s->req_nb_sectors = 1;
1514 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1515 5391d806 bellard
            break;
1516 5391d806 bellard
        case WIN_MULTREAD:
1517 5391d806 bellard
            if (!s->mult_sectors)
1518 5391d806 bellard
                goto abort_cmd;
1519 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1520 5391d806 bellard
            ide_sector_read(s);
1521 5391d806 bellard
            break;
1522 5391d806 bellard
        case WIN_MULTWRITE:
1523 5391d806 bellard
            if (!s->mult_sectors)
1524 5391d806 bellard
                goto abort_cmd;
1525 a136e5a8 bellard
            s->error = 0;
1526 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1527 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1528 5391d806 bellard
            n = s->nsector;
1529 5391d806 bellard
            if (n > s->req_nb_sectors)
1530 5391d806 bellard
                n = s->req_nb_sectors;
1531 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1532 5391d806 bellard
            break;
1533 98087450 bellard
        case WIN_READDMA:
1534 98087450 bellard
        case WIN_READDMA_ONCE:
1535 98087450 bellard
            if (!s->bs) 
1536 98087450 bellard
                goto abort_cmd;
1537 98087450 bellard
            ide_sector_read_dma(s);
1538 98087450 bellard
            break;
1539 98087450 bellard
        case WIN_WRITEDMA:
1540 98087450 bellard
        case WIN_WRITEDMA_ONCE:
1541 98087450 bellard
            if (!s->bs) 
1542 98087450 bellard
                goto abort_cmd;
1543 98087450 bellard
            ide_sector_write_dma(s);
1544 98087450 bellard
            break;
1545 5391d806 bellard
        case WIN_READ_NATIVE_MAX:
1546 5391d806 bellard
            ide_set_sector(s, s->nb_sectors - 1);
1547 5391d806 bellard
            s->status = READY_STAT;
1548 5391d806 bellard
            ide_set_irq(s);
1549 5391d806 bellard
            break;
1550 a136e5a8 bellard
        case WIN_CHECKPOWERMODE1:
1551 a136e5a8 bellard
            s->nsector = 0xff; /* device active or idle */
1552 a136e5a8 bellard
            s->status = READY_STAT;
1553 a136e5a8 bellard
            ide_set_irq(s);
1554 a136e5a8 bellard
            break;
1555 34e538ae bellard
        case WIN_SETFEATURES:
1556 34e538ae bellard
            if (!s->bs)
1557 34e538ae bellard
                goto abort_cmd;
1558 34e538ae bellard
            /* XXX: valid for CDROM ? */
1559 34e538ae bellard
            switch(s->feature) {
1560 34e538ae bellard
            case 0x02: /* write cache enable */
1561 98087450 bellard
            case 0x03: /* set transfer mode */
1562 34e538ae bellard
            case 0x82: /* write cache disable */
1563 34e538ae bellard
            case 0xaa: /* read look-ahead enable */
1564 34e538ae bellard
            case 0x55: /* read look-ahead disable */
1565 e0fe67aa bellard
                s->status = READY_STAT | SEEK_STAT;
1566 34e538ae bellard
                ide_set_irq(s);
1567 34e538ae bellard
                break;
1568 34e538ae bellard
            default:
1569 34e538ae bellard
                goto abort_cmd;
1570 34e538ae bellard
            }
1571 34e538ae bellard
            break;
1572 a7dfe172 bellard
        case WIN_STANDBYNOW1:
1573 a7dfe172 bellard
            s->status = READY_STAT;
1574 a7dfe172 bellard
            ide_set_irq(s);
1575 a7dfe172 bellard
            break;
1576 5391d806 bellard
            /* ATAPI commands */
1577 5391d806 bellard
        case WIN_PIDENTIFY:
1578 5391d806 bellard
            if (s->is_cdrom) {
1579 5391d806 bellard
                ide_atapi_identify(s);
1580 5391d806 bellard
                s->status = READY_STAT;
1581 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1582 5391d806 bellard
            } else {
1583 5391d806 bellard
                ide_abort_command(s);
1584 5391d806 bellard
            }
1585 5391d806 bellard
            ide_set_irq(s);
1586 5391d806 bellard
            break;
1587 5391d806 bellard
        case WIN_SRST:
1588 5391d806 bellard
            if (!s->is_cdrom)
1589 5391d806 bellard
                goto abort_cmd;
1590 5391d806 bellard
            ide_set_signature(s);
1591 6b136f9e bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
1592 5391d806 bellard
            s->error = 0x01;
1593 5391d806 bellard
            break;
1594 5391d806 bellard
        case WIN_PACKETCMD:
1595 5391d806 bellard
            if (!s->is_cdrom)
1596 5391d806 bellard
                goto abort_cmd;
1597 98087450 bellard
            /* overlapping commands not supported */
1598 98087450 bellard
            if (s->feature & 0x02)
1599 5391d806 bellard
                goto abort_cmd;
1600 98087450 bellard
            s->atapi_dma = s->feature & 1;
1601 5391d806 bellard
            s->nsector = 1;
1602 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, 
1603 5391d806 bellard
                               ide_atapi_cmd);
1604 5391d806 bellard
            break;
1605 5391d806 bellard
        default:
1606 5391d806 bellard
        abort_cmd:
1607 5391d806 bellard
            ide_abort_command(s);
1608 5391d806 bellard
            ide_set_irq(s);
1609 5391d806 bellard
            break;
1610 5391d806 bellard
        }
1611 5391d806 bellard
    }
1612 5391d806 bellard
}
1613 5391d806 bellard
1614 caed8802 bellard
static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1615 5391d806 bellard
{
1616 7ae98627 bellard
    IDEState *ide_if = opaque;
1617 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1618 5391d806 bellard
    uint32_t addr;
1619 5391d806 bellard
    int ret;
1620 5391d806 bellard
1621 5391d806 bellard
    addr = addr1 & 7;
1622 5391d806 bellard
    switch(addr) {
1623 5391d806 bellard
    case 0:
1624 5391d806 bellard
        ret = 0xff;
1625 5391d806 bellard
        break;
1626 5391d806 bellard
    case 1:
1627 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1628 c45c3d00 bellard
            ret = 0;
1629 c45c3d00 bellard
        else
1630 c45c3d00 bellard
            ret = s->error;
1631 5391d806 bellard
        break;
1632 5391d806 bellard
    case 2:
1633 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1634 c45c3d00 bellard
            ret = 0;
1635 c45c3d00 bellard
        else
1636 c45c3d00 bellard
            ret = s->nsector & 0xff;
1637 5391d806 bellard
        break;
1638 5391d806 bellard
    case 3:
1639 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1640 c45c3d00 bellard
            ret = 0;
1641 c45c3d00 bellard
        else
1642 c45c3d00 bellard
            ret = s->sector;
1643 5391d806 bellard
        break;
1644 5391d806 bellard
    case 4:
1645 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1646 c45c3d00 bellard
            ret = 0;
1647 c45c3d00 bellard
        else
1648 c45c3d00 bellard
            ret = s->lcyl;
1649 5391d806 bellard
        break;
1650 5391d806 bellard
    case 5:
1651 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1652 c45c3d00 bellard
            ret = 0;
1653 c45c3d00 bellard
        else
1654 c45c3d00 bellard
            ret = s->hcyl;
1655 5391d806 bellard
        break;
1656 5391d806 bellard
    case 6:
1657 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1658 c45c3d00 bellard
            ret = 0;
1659 c45c3d00 bellard
        else
1660 7ae98627 bellard
            ret = s->select;
1661 5391d806 bellard
        break;
1662 5391d806 bellard
    default:
1663 5391d806 bellard
    case 7:
1664 66201e2d bellard
        if ((!ide_if[0].bs && !ide_if[1].bs) ||
1665 66201e2d bellard
            (s != ide_if && !s->bs))
1666 c45c3d00 bellard
            ret = 0;
1667 c45c3d00 bellard
        else
1668 c45c3d00 bellard
            ret = s->status;
1669 1ade1de2 bellard
#ifdef TARGET_PPC
1670 1ade1de2 bellard
        if (s->openpic) 
1671 1ade1de2 bellard
            openpic_set_irq(s->openpic, s->irq, 0);
1672 1ade1de2 bellard
        else 
1673 1ade1de2 bellard
#endif
1674 34e538ae bellard
        if (s->irq == 16)
1675 34e538ae bellard
            pci_set_irq(s->pci_dev, 0, 0);
1676 34e538ae bellard
        else
1677 34e538ae bellard
            pic_set_irq(s->irq, 0);
1678 5391d806 bellard
        break;
1679 5391d806 bellard
    }
1680 5391d806 bellard
#ifdef DEBUG_IDE
1681 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
1682 5391d806 bellard
#endif
1683 5391d806 bellard
    return ret;
1684 5391d806 bellard
}
1685 5391d806 bellard
1686 caed8802 bellard
static uint32_t ide_status_read(void *opaque, uint32_t addr)
1687 5391d806 bellard
{
1688 7ae98627 bellard
    IDEState *ide_if = opaque;
1689 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1690 5391d806 bellard
    int ret;
1691 7ae98627 bellard
1692 66201e2d bellard
    if ((!ide_if[0].bs && !ide_if[1].bs) ||
1693 66201e2d bellard
        (s != ide_if && !s->bs))
1694 7ae98627 bellard
        ret = 0;
1695 7ae98627 bellard
    else
1696 7ae98627 bellard
        ret = s->status;
1697 5391d806 bellard
#ifdef DEBUG_IDE
1698 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
1699 5391d806 bellard
#endif
1700 5391d806 bellard
    return ret;
1701 5391d806 bellard
}
1702 5391d806 bellard
1703 caed8802 bellard
static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
1704 5391d806 bellard
{
1705 caed8802 bellard
    IDEState *ide_if = opaque;
1706 5391d806 bellard
    IDEState *s;
1707 5391d806 bellard
    int i;
1708 5391d806 bellard
1709 5391d806 bellard
#ifdef DEBUG_IDE
1710 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
1711 5391d806 bellard
#endif
1712 5391d806 bellard
    /* common for both drives */
1713 5391d806 bellard
    if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
1714 5391d806 bellard
        (val & IDE_CMD_RESET)) {
1715 5391d806 bellard
        /* reset low to high */
1716 5391d806 bellard
        for(i = 0;i < 2; i++) {
1717 5391d806 bellard
            s = &ide_if[i];
1718 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
1719 5391d806 bellard
            s->error = 0x01;
1720 5391d806 bellard
        }
1721 5391d806 bellard
    } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
1722 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
1723 5391d806 bellard
        /* high to low */
1724 5391d806 bellard
        for(i = 0;i < 2; i++) {
1725 5391d806 bellard
            s = &ide_if[i];
1726 6b136f9e bellard
            if (s->is_cdrom)
1727 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
1728 6b136f9e bellard
            else
1729 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
1730 5391d806 bellard
            ide_set_signature(s);
1731 5391d806 bellard
        }
1732 5391d806 bellard
    }
1733 5391d806 bellard
1734 5391d806 bellard
    ide_if[0].cmd = val;
1735 5391d806 bellard
    ide_if[1].cmd = val;
1736 5391d806 bellard
}
1737 5391d806 bellard
1738 caed8802 bellard
static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
1739 5391d806 bellard
{
1740 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1741 5391d806 bellard
    uint8_t *p;
1742 5391d806 bellard
1743 5391d806 bellard
    p = s->data_ptr;
1744 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
1745 5391d806 bellard
    p += 2;
1746 5391d806 bellard
    s->data_ptr = p;
1747 5391d806 bellard
    if (p >= s->data_end)
1748 5391d806 bellard
        s->end_transfer_func(s);
1749 5391d806 bellard
}
1750 5391d806 bellard
1751 caed8802 bellard
static uint32_t ide_data_readw(void *opaque, uint32_t addr)
1752 5391d806 bellard
{
1753 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1754 5391d806 bellard
    uint8_t *p;
1755 5391d806 bellard
    int ret;
1756 5391d806 bellard
    p = s->data_ptr;
1757 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
1758 5391d806 bellard
    p += 2;
1759 5391d806 bellard
    s->data_ptr = p;
1760 5391d806 bellard
    if (p >= s->data_end)
1761 5391d806 bellard
        s->end_transfer_func(s);
1762 5391d806 bellard
    return ret;
1763 5391d806 bellard
}
1764 5391d806 bellard
1765 caed8802 bellard
static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
1766 5391d806 bellard
{
1767 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1768 5391d806 bellard
    uint8_t *p;
1769 5391d806 bellard
1770 5391d806 bellard
    p = s->data_ptr;
1771 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
1772 5391d806 bellard
    p += 4;
1773 5391d806 bellard
    s->data_ptr = p;
1774 5391d806 bellard
    if (p >= s->data_end)
1775 5391d806 bellard
        s->end_transfer_func(s);
1776 5391d806 bellard
}
1777 5391d806 bellard
1778 caed8802 bellard
static uint32_t ide_data_readl(void *opaque, uint32_t addr)
1779 5391d806 bellard
{
1780 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1781 5391d806 bellard
    uint8_t *p;
1782 5391d806 bellard
    int ret;
1783 5391d806 bellard
    
1784 5391d806 bellard
    p = s->data_ptr;
1785 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
1786 5391d806 bellard
    p += 4;
1787 5391d806 bellard
    s->data_ptr = p;
1788 5391d806 bellard
    if (p >= s->data_end)
1789 5391d806 bellard
        s->end_transfer_func(s);
1790 5391d806 bellard
    return ret;
1791 5391d806 bellard
}
1792 5391d806 bellard
1793 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
1794 a7dfe172 bellard
{
1795 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
1796 a7dfe172 bellard
    s->data_end = s->io_buffer;
1797 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
1798 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
1799 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
1800 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
1801 a7dfe172 bellard
}
1802 a7dfe172 bellard
1803 5391d806 bellard
static void ide_reset(IDEState *s)
1804 5391d806 bellard
{
1805 5391d806 bellard
    s->mult_sectors = MAX_MULT_SECTORS;
1806 5391d806 bellard
    s->cur_drive = s;
1807 5391d806 bellard
    s->select = 0xa0;
1808 5391d806 bellard
    s->status = READY_STAT;
1809 5391d806 bellard
    ide_set_signature(s);
1810 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
1811 a7dfe172 bellard
       accesses */
1812 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
1813 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
1814 5391d806 bellard
}
1815 5391d806 bellard
1816 5391d806 bellard
struct partition {
1817 5391d806 bellard
        uint8_t boot_ind;                /* 0x80 - active */
1818 5391d806 bellard
        uint8_t head;                /* starting head */
1819 5391d806 bellard
        uint8_t sector;                /* starting sector */
1820 5391d806 bellard
        uint8_t cyl;                /* starting cylinder */
1821 5391d806 bellard
        uint8_t sys_ind;                /* What partition type */
1822 5391d806 bellard
        uint8_t end_head;                /* end head */
1823 5391d806 bellard
        uint8_t end_sector;        /* end sector */
1824 5391d806 bellard
        uint8_t end_cyl;                /* end cylinder */
1825 5391d806 bellard
        uint32_t start_sect;        /* starting sector counting from 0 */
1826 5391d806 bellard
        uint32_t nr_sects;                /* nr of sectors in partition */
1827 5391d806 bellard
} __attribute__((packed));
1828 5391d806 bellard
1829 5391d806 bellard
/* try to guess the IDE geometry from the MSDOS partition table */
1830 5391d806 bellard
static void ide_guess_geometry(IDEState *s)
1831 5391d806 bellard
{
1832 5391d806 bellard
    uint8_t buf[512];
1833 5391d806 bellard
    int ret, i;
1834 5391d806 bellard
    struct partition *p;
1835 5391d806 bellard
    uint32_t nr_sects;
1836 5391d806 bellard
1837 5391d806 bellard
    if (s->cylinders != 0)
1838 5391d806 bellard
        return;
1839 5391d806 bellard
    ret = bdrv_read(s->bs, 0, buf, 1);
1840 5391d806 bellard
    if (ret < 0)
1841 5391d806 bellard
        return;
1842 5391d806 bellard
    /* test msdos magic */
1843 5391d806 bellard
    if (buf[510] != 0x55 || buf[511] != 0xaa)
1844 5391d806 bellard
        return;
1845 5391d806 bellard
    for(i = 0; i < 4; i++) {
1846 5391d806 bellard
        p = ((struct partition *)(buf + 0x1be)) + i;
1847 0c4ad8dc bellard
        nr_sects = le32_to_cpu(p->nr_sects);
1848 5391d806 bellard
        if (nr_sects && p->end_head) {
1849 5391d806 bellard
            /* We make the assumption that the partition terminates on
1850 5391d806 bellard
               a cylinder boundary */
1851 5391d806 bellard
            s->heads = p->end_head + 1;
1852 5391d806 bellard
            s->sectors = p->end_sector & 63;
1853 5391d806 bellard
            s->cylinders = s->nb_sectors / (s->heads * s->sectors);
1854 5391d806 bellard
#if 0
1855 5391d806 bellard
            printf("guessed partition: CHS=%d %d %d\n", 
1856 5391d806 bellard
                   s->cylinders, s->heads, s->sectors);
1857 5391d806 bellard
#endif
1858 5391d806 bellard
        }
1859 5391d806 bellard
    }
1860 5391d806 bellard
}
1861 5391d806 bellard
1862 69b91039 bellard
static void ide_init2(IDEState *ide_state, int irq,
1863 69b91039 bellard
                      BlockDriverState *hd0, BlockDriverState *hd1)
1864 5391d806 bellard
{
1865 69b91039 bellard
    IDEState *s;
1866 aedf5382 bellard
    static int drive_serial = 1;
1867 caed8802 bellard
    int i, cylinders, heads, secs;
1868 5391d806 bellard
    int64_t nb_sectors;
1869 5391d806 bellard
1870 caed8802 bellard
    for(i = 0; i < 2; i++) {
1871 caed8802 bellard
        s = ide_state + i;
1872 caed8802 bellard
        if (i == 0)
1873 caed8802 bellard
            s->bs = hd0;
1874 caed8802 bellard
        else
1875 caed8802 bellard
            s->bs = hd1;
1876 5391d806 bellard
        if (s->bs) {
1877 5391d806 bellard
            bdrv_get_geometry(s->bs, &nb_sectors);
1878 5391d806 bellard
            s->nb_sectors = nb_sectors;
1879 caed8802 bellard
            /* if a geometry hint is available, use it */
1880 caed8802 bellard
            bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
1881 caed8802 bellard
            if (cylinders != 0) {
1882 5391d806 bellard
                s->cylinders = cylinders;
1883 caed8802 bellard
                s->heads = heads;
1884 caed8802 bellard
                s->sectors = secs;
1885 caed8802 bellard
            } else {
1886 caed8802 bellard
                ide_guess_geometry(s);
1887 caed8802 bellard
                if (s->cylinders == 0) {
1888 caed8802 bellard
                    /* if no geometry, use a LBA compatible one */
1889 caed8802 bellard
                    cylinders = nb_sectors / (16 * 63);
1890 caed8802 bellard
                    if (cylinders > 16383)
1891 caed8802 bellard
                        cylinders = 16383;
1892 caed8802 bellard
                    else if (cylinders < 2)
1893 caed8802 bellard
                        cylinders = 2;
1894 caed8802 bellard
                    s->cylinders = cylinders;
1895 caed8802 bellard
                    s->heads = 16;
1896 caed8802 bellard
                    s->sectors = 63;
1897 caed8802 bellard
                }
1898 769bec72 bellard
                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
1899 caed8802 bellard
            }
1900 caed8802 bellard
            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
1901 caed8802 bellard
                s->is_cdrom = 1;
1902 caed8802 bellard
                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
1903 5391d806 bellard
            }
1904 5391d806 bellard
        }
1905 aedf5382 bellard
        s->drive_serial = drive_serial++;
1906 caed8802 bellard
        s->irq = irq;
1907 5391d806 bellard
        ide_reset(s);
1908 5391d806 bellard
    }
1909 69b91039 bellard
}
1910 69b91039 bellard
1911 34e538ae bellard
static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
1912 69b91039 bellard
{
1913 caed8802 bellard
    register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
1914 caed8802 bellard
    register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
1915 caed8802 bellard
    if (iobase2) {
1916 caed8802 bellard
        register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
1917 caed8802 bellard
        register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
1918 5391d806 bellard
    }
1919 caed8802 bellard
    
1920 caed8802 bellard
    /* data ports */
1921 caed8802 bellard
    register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
1922 caed8802 bellard
    register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
1923 caed8802 bellard
    register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
1924 caed8802 bellard
    register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
1925 5391d806 bellard
}
1926 69b91039 bellard
1927 69b91039 bellard
/***********************************************************/
1928 34e538ae bellard
/* ISA IDE definitions */
1929 34e538ae bellard
1930 34e538ae bellard
void isa_ide_init(int iobase, int iobase2, int irq,
1931 34e538ae bellard
                  BlockDriverState *hd0, BlockDriverState *hd1)
1932 34e538ae bellard
{
1933 34e538ae bellard
    IDEState *ide_state;
1934 34e538ae bellard
1935 34e538ae bellard
    ide_state = qemu_mallocz(sizeof(IDEState) * 2);
1936 34e538ae bellard
    if (!ide_state)
1937 34e538ae bellard
        return;
1938 34e538ae bellard
    
1939 34e538ae bellard
    ide_init2(ide_state, irq, hd0, hd1);
1940 34e538ae bellard
    ide_init_ioport(ide_state, iobase, iobase2);
1941 34e538ae bellard
}
1942 34e538ae bellard
1943 34e538ae bellard
/***********************************************************/
1944 69b91039 bellard
/* PCI IDE definitions */
1945 69b91039 bellard
1946 69b91039 bellard
static void ide_map(PCIDevice *pci_dev, int region_num, 
1947 69b91039 bellard
                    uint32_t addr, uint32_t size, int type)
1948 69b91039 bellard
{
1949 69b91039 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
1950 69b91039 bellard
    IDEState *ide_state;
1951 69b91039 bellard
1952 69b91039 bellard
    if (region_num <= 3) {
1953 69b91039 bellard
        ide_state = &d->ide_if[(region_num >> 1) * 2];
1954 69b91039 bellard
        if (region_num & 1) {
1955 69b91039 bellard
            register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
1956 69b91039 bellard
            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
1957 69b91039 bellard
        } else {
1958 69b91039 bellard
            register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
1959 69b91039 bellard
            register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
1960 69b91039 bellard
1961 69b91039 bellard
            /* data ports */
1962 69b91039 bellard
            register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
1963 69b91039 bellard
            register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
1964 69b91039 bellard
            register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
1965 69b91039 bellard
            register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
1966 69b91039 bellard
        }
1967 69b91039 bellard
    }
1968 69b91039 bellard
}
1969 69b91039 bellard
1970 98087450 bellard
/* XXX: full callback usage to prepare non blocking I/Os support -
1971 98087450 bellard
   error handling */
1972 98087450 bellard
static void ide_dma_loop(BMDMAState *bm)
1973 98087450 bellard
{
1974 98087450 bellard
    struct {
1975 98087450 bellard
        uint32_t addr;
1976 98087450 bellard
        uint32_t size;
1977 98087450 bellard
    } prd;
1978 98087450 bellard
    target_phys_addr_t cur_addr;
1979 98087450 bellard
    int len, i, len1;
1980 98087450 bellard
1981 98087450 bellard
    cur_addr = bm->addr;
1982 98087450 bellard
    /* at most one page to avoid hanging if erroneous parameters */
1983 98087450 bellard
    for(i = 0; i < 512; i++) {
1984 98087450 bellard
        cpu_physical_memory_read(cur_addr, (uint8_t *)&prd, 8);
1985 98087450 bellard
        prd.addr = le32_to_cpu(prd.addr);
1986 98087450 bellard
        prd.size = le32_to_cpu(prd.size);
1987 98087450 bellard
#ifdef DEBUG_IDE
1988 98087450 bellard
        printf("ide: dma: prd: %08x: addr=0x%08x size=0x%08x\n", 
1989 98087450 bellard
               (int)cur_addr, prd.addr, prd.size);
1990 98087450 bellard
#endif
1991 98087450 bellard
        len = prd.size & 0xfffe;
1992 98087450 bellard
        if (len == 0)
1993 98087450 bellard
            len = 0x10000;
1994 98087450 bellard
        while (len > 0) {
1995 98087450 bellard
            len1 = bm->dma_cb(bm->ide_if, prd.addr, len);
1996 98087450 bellard
            if (len1 == 0)
1997 98087450 bellard
                goto the_end;
1998 98087450 bellard
            prd.addr += len1;
1999 98087450 bellard
            len -= len1;
2000 98087450 bellard
        }
2001 98087450 bellard
        /* end of transfer */
2002 98087450 bellard
        if (prd.size & 0x80000000)
2003 98087450 bellard
            break;
2004 98087450 bellard
        cur_addr += 8;
2005 98087450 bellard
    }
2006 98087450 bellard
    /* end of transfer */
2007 98087450 bellard
 the_end:
2008 98087450 bellard
    bm->status &= ~BM_STATUS_DMAING;
2009 98087450 bellard
    bm->status |= BM_STATUS_INT;
2010 98087450 bellard
    bm->dma_cb = NULL;
2011 98087450 bellard
    bm->ide_if = NULL;
2012 98087450 bellard
}
2013 98087450 bellard
2014 98087450 bellard
static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)
2015 98087450 bellard
{
2016 98087450 bellard
    BMDMAState *bm = s->bmdma;
2017 98087450 bellard
    if(!bm)
2018 98087450 bellard
        return;
2019 98087450 bellard
    bm->ide_if = s;
2020 98087450 bellard
    bm->dma_cb = dma_cb;
2021 98087450 bellard
    if (bm->status & BM_STATUS_DMAING) {
2022 98087450 bellard
        ide_dma_loop(bm);
2023 98087450 bellard
    }
2024 98087450 bellard
}
2025 98087450 bellard
2026 98087450 bellard
static uint32_t bmdma_cmd_readb(void *opaque, uint32_t addr)
2027 98087450 bellard
{
2028 98087450 bellard
    BMDMAState *bm = opaque;
2029 98087450 bellard
    uint32_t val;
2030 98087450 bellard
    val = bm->cmd;
2031 98087450 bellard
#ifdef DEBUG_IDE
2032 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2033 98087450 bellard
#endif
2034 98087450 bellard
    return val;
2035 98087450 bellard
}
2036 98087450 bellard
2037 98087450 bellard
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2038 98087450 bellard
{
2039 98087450 bellard
    BMDMAState *bm = opaque;
2040 98087450 bellard
#ifdef DEBUG_IDE
2041 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2042 98087450 bellard
#endif
2043 98087450 bellard
    if (!(val & BM_CMD_START)) {
2044 98087450 bellard
        /* XXX: do it better */
2045 98087450 bellard
        bm->status &= ~BM_STATUS_DMAING;
2046 98087450 bellard
        bm->cmd = val & 0x09;
2047 98087450 bellard
    } else {
2048 98087450 bellard
        bm->status |= BM_STATUS_DMAING;
2049 98087450 bellard
        bm->cmd = val & 0x09;
2050 98087450 bellard
        /* start dma transfer if possible */
2051 98087450 bellard
        if (bm->dma_cb)
2052 98087450 bellard
            ide_dma_loop(bm);
2053 98087450 bellard
    }
2054 98087450 bellard
}
2055 98087450 bellard
2056 98087450 bellard
static uint32_t bmdma_status_readb(void *opaque, uint32_t addr)
2057 98087450 bellard
{
2058 98087450 bellard
    BMDMAState *bm = opaque;
2059 98087450 bellard
    uint32_t val;
2060 98087450 bellard
    val = bm->status;
2061 98087450 bellard
#ifdef DEBUG_IDE
2062 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2063 98087450 bellard
#endif
2064 98087450 bellard
    return val;
2065 98087450 bellard
}
2066 98087450 bellard
2067 98087450 bellard
static void bmdma_status_writeb(void *opaque, uint32_t addr, uint32_t val)
2068 98087450 bellard
{
2069 98087450 bellard
    BMDMAState *bm = opaque;
2070 98087450 bellard
#ifdef DEBUG_IDE
2071 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2072 98087450 bellard
#endif
2073 98087450 bellard
    bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
2074 98087450 bellard
}
2075 98087450 bellard
2076 98087450 bellard
static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
2077 98087450 bellard
{
2078 98087450 bellard
    BMDMAState *bm = opaque;
2079 98087450 bellard
    uint32_t val;
2080 98087450 bellard
    val = bm->addr;
2081 98087450 bellard
#ifdef DEBUG_IDE
2082 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2083 98087450 bellard
#endif
2084 98087450 bellard
    return val;
2085 98087450 bellard
}
2086 98087450 bellard
2087 98087450 bellard
static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
2088 98087450 bellard
{
2089 98087450 bellard
    BMDMAState *bm = opaque;
2090 98087450 bellard
#ifdef DEBUG_IDE
2091 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2092 98087450 bellard
#endif
2093 98087450 bellard
    bm->addr = val & ~3;
2094 98087450 bellard
}
2095 98087450 bellard
2096 98087450 bellard
static void bmdma_map(PCIDevice *pci_dev, int region_num, 
2097 98087450 bellard
                    uint32_t addr, uint32_t size, int type)
2098 98087450 bellard
{
2099 98087450 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2100 98087450 bellard
    int i;
2101 98087450 bellard
2102 98087450 bellard
    for(i = 0;i < 2; i++) {
2103 98087450 bellard
        BMDMAState *bm = &d->bmdma[i];
2104 98087450 bellard
        d->ide_if[2 * i].bmdma = bm;
2105 98087450 bellard
        d->ide_if[2 * i + 1].bmdma = bm;
2106 98087450 bellard
        
2107 98087450 bellard
        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
2108 98087450 bellard
        register_ioport_read(addr, 1, 1, bmdma_cmd_readb, bm);
2109 98087450 bellard
2110 98087450 bellard
        register_ioport_write(addr + 2, 1, 1, bmdma_status_writeb, bm);
2111 98087450 bellard
        register_ioport_read(addr + 2, 1, 1, bmdma_status_readb, bm);
2112 98087450 bellard
2113 98087450 bellard
        register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
2114 98087450 bellard
        register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
2115 98087450 bellard
        addr += 8;
2116 98087450 bellard
    }
2117 98087450 bellard
}
2118 98087450 bellard
2119 69b91039 bellard
/* hd_table must contain 4 block drivers */
2120 46e50e9d bellard
void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table)
2121 69b91039 bellard
{
2122 69b91039 bellard
    PCIIDEState *d;
2123 69b91039 bellard
    uint8_t *pci_conf;
2124 34e538ae bellard
    int i;
2125 34e538ae bellard
2126 46e50e9d bellard
    d = (PCIIDEState *)pci_register_device(bus, "IDE", sizeof(PCIIDEState),
2127 46e50e9d bellard
                                           -1, 
2128 73c11f63 bellard
                                           NULL, NULL);
2129 69b91039 bellard
    pci_conf = d->dev.config;
2130 69b91039 bellard
    pci_conf[0x00] = 0x86; // Intel
2131 69b91039 bellard
    pci_conf[0x01] = 0x80;
2132 69b91039 bellard
    pci_conf[0x02] = 0x00; // fake
2133 69b91039 bellard
    pci_conf[0x03] = 0x01; // fake
2134 69b91039 bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2135 69b91039 bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2136 69b91039 bellard
    pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
2137 69b91039 bellard
2138 69b91039 bellard
    pci_conf[0x2c] = 0x86; // subsys vendor
2139 69b91039 bellard
    pci_conf[0x2d] = 0x80; // subsys vendor
2140 69b91039 bellard
    pci_conf[0x2e] = 0x00; // fake
2141 69b91039 bellard
    pci_conf[0x2f] = 0x01; // fake
2142 69b91039 bellard
2143 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 0, 0x8, 
2144 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2145 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 1, 0x4, 
2146 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2147 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 2, 0x8, 
2148 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2149 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 3, 0x4, 
2150 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2151 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2152 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2153 69b91039 bellard
2154 34e538ae bellard
    pci_conf[0x3d] = 0x01; // interrupt on pin 1
2155 34e538ae bellard
2156 34e538ae bellard
    for(i = 0; i < 4; i++)
2157 34e538ae bellard
        d->ide_if[i].pci_dev = (PCIDevice *)d;
2158 34e538ae bellard
    ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]);
2159 34e538ae bellard
    ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]);
2160 34e538ae bellard
}
2161 34e538ae bellard
2162 34e538ae bellard
/* hd_table must contain 4 block drivers */
2163 34e538ae bellard
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
2164 46e50e9d bellard
void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
2165 34e538ae bellard
{
2166 34e538ae bellard
    PCIIDEState *d;
2167 34e538ae bellard
    uint8_t *pci_conf;
2168 34e538ae bellard
    
2169 34e538ae bellard
    /* register a function 1 of PIIX3 */
2170 46e50e9d bellard
    d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE", 
2171 46e50e9d bellard
                                           sizeof(PCIIDEState),
2172 46e50e9d bellard
                                           ((PCIDevice *)piix3_state)->devfn + 1, 
2173 34e538ae bellard
                                           NULL, NULL);
2174 34e538ae bellard
    pci_conf = d->dev.config;
2175 34e538ae bellard
    pci_conf[0x00] = 0x86; // Intel
2176 34e538ae bellard
    pci_conf[0x01] = 0x80;
2177 34e538ae bellard
    pci_conf[0x02] = 0x10;
2178 34e538ae bellard
    pci_conf[0x03] = 0x70;
2179 34e538ae bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2180 34e538ae bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2181 34e538ae bellard
    pci_conf[0x0e] = 0x00; // header_type
2182 34e538ae bellard
2183 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2184 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2185 34e538ae bellard
2186 69b91039 bellard
    ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]);
2187 69b91039 bellard
    ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]);
2188 34e538ae bellard
    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
2189 34e538ae bellard
    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
2190 69b91039 bellard
}
2191 1ade1de2 bellard
2192 1ade1de2 bellard
/***********************************************************/
2193 1ade1de2 bellard
/* MacIO based PowerPC IDE */
2194 1ade1de2 bellard
2195 1ade1de2 bellard
/* PowerMac IDE memory IO */
2196 1ade1de2 bellard
static void pmac_ide_writeb (void *opaque,
2197 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2198 1ade1de2 bellard
{
2199 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2200 1ade1de2 bellard
    switch (addr) {
2201 1ade1de2 bellard
    case 1 ... 7:
2202 1ade1de2 bellard
        ide_ioport_write(opaque, addr, val);
2203 1ade1de2 bellard
        break;
2204 1ade1de2 bellard
    case 8:
2205 1ade1de2 bellard
    case 22:
2206 1ade1de2 bellard
        ide_cmd_write(opaque, 0, val);
2207 1ade1de2 bellard
        break;
2208 1ade1de2 bellard
    default:
2209 1ade1de2 bellard
        break;
2210 1ade1de2 bellard
    }
2211 1ade1de2 bellard
}
2212 1ade1de2 bellard
2213 1ade1de2 bellard
static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
2214 1ade1de2 bellard
{
2215 1ade1de2 bellard
    uint8_t retval;
2216 1ade1de2 bellard
2217 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4;
2218 1ade1de2 bellard
    switch (addr) {
2219 1ade1de2 bellard
    case 1 ... 7:
2220 1ade1de2 bellard
        retval = ide_ioport_read(opaque, addr);
2221 1ade1de2 bellard
        break;
2222 1ade1de2 bellard
    case 8:
2223 1ade1de2 bellard
    case 22:
2224 1ade1de2 bellard
        retval = ide_status_read(opaque, 0);
2225 1ade1de2 bellard
        break;
2226 1ade1de2 bellard
    default:
2227 1ade1de2 bellard
        retval = 0xFF;
2228 1ade1de2 bellard
        break;
2229 1ade1de2 bellard
    }
2230 1ade1de2 bellard
    return retval;
2231 1ade1de2 bellard
}
2232 1ade1de2 bellard
2233 1ade1de2 bellard
static void pmac_ide_writew (void *opaque,
2234 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2235 1ade1de2 bellard
{
2236 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2237 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2238 1ade1de2 bellard
    val = bswap16(val);
2239 1ade1de2 bellard
#endif
2240 1ade1de2 bellard
    if (addr == 0) {
2241 1ade1de2 bellard
        ide_data_writew(opaque, 0, val);
2242 1ade1de2 bellard
    }
2243 1ade1de2 bellard
}
2244 1ade1de2 bellard
2245 1ade1de2 bellard
static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
2246 1ade1de2 bellard
{
2247 1ade1de2 bellard
    uint16_t retval;
2248 1ade1de2 bellard
2249 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2250 1ade1de2 bellard
    if (addr == 0) {
2251 1ade1de2 bellard
        retval = ide_data_readw(opaque, 0);
2252 1ade1de2 bellard
    } else {
2253 1ade1de2 bellard
        retval = 0xFFFF;
2254 1ade1de2 bellard
    }
2255 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2256 1ade1de2 bellard
    retval = bswap16(retval);
2257 1ade1de2 bellard
#endif
2258 1ade1de2 bellard
    return retval;
2259 1ade1de2 bellard
}
2260 1ade1de2 bellard
2261 1ade1de2 bellard
static void pmac_ide_writel (void *opaque,
2262 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2263 1ade1de2 bellard
{
2264 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2265 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2266 1ade1de2 bellard
    val = bswap32(val);
2267 1ade1de2 bellard
#endif
2268 1ade1de2 bellard
    if (addr == 0) {
2269 1ade1de2 bellard
        ide_data_writel(opaque, 0, val);
2270 1ade1de2 bellard
    }
2271 1ade1de2 bellard
}
2272 1ade1de2 bellard
2273 1ade1de2 bellard
static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
2274 1ade1de2 bellard
{
2275 1ade1de2 bellard
    uint32_t retval;
2276 1ade1de2 bellard
2277 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2278 1ade1de2 bellard
    if (addr == 0) {
2279 1ade1de2 bellard
        retval = ide_data_readl(opaque, 0);
2280 1ade1de2 bellard
    } else {
2281 1ade1de2 bellard
        retval = 0xFFFFFFFF;
2282 1ade1de2 bellard
    }
2283 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2284 1ade1de2 bellard
    retval = bswap32(retval);
2285 1ade1de2 bellard
#endif
2286 1ade1de2 bellard
    return retval;
2287 1ade1de2 bellard
}
2288 1ade1de2 bellard
2289 1ade1de2 bellard
static CPUWriteMemoryFunc *pmac_ide_write[] = {
2290 1ade1de2 bellard
    pmac_ide_writeb,
2291 1ade1de2 bellard
    pmac_ide_writew,
2292 1ade1de2 bellard
    pmac_ide_writel,
2293 1ade1de2 bellard
};
2294 1ade1de2 bellard
2295 1ade1de2 bellard
static CPUReadMemoryFunc *pmac_ide_read[] = {
2296 1ade1de2 bellard
    pmac_ide_readb,
2297 1ade1de2 bellard
    pmac_ide_readw,
2298 1ade1de2 bellard
    pmac_ide_readl,
2299 1ade1de2 bellard
};
2300 1ade1de2 bellard
2301 1ade1de2 bellard
/* hd_table must contain 4 block drivers */
2302 1ade1de2 bellard
/* PowerMac uses memory mapped registers, not I/O. Return the memory
2303 1ade1de2 bellard
   I/O index to access the ide. */
2304 1ade1de2 bellard
int pmac_ide_init (BlockDriverState **hd_table,
2305 1ade1de2 bellard
                   openpic_t *openpic, int irq)
2306 1ade1de2 bellard
{
2307 1ade1de2 bellard
    IDEState *ide_if;
2308 1ade1de2 bellard
    int pmac_ide_memory;
2309 1ade1de2 bellard
2310 1ade1de2 bellard
    ide_if = qemu_mallocz(sizeof(IDEState) * 2);
2311 1ade1de2 bellard
    ide_init2(&ide_if[0], irq, hd_table[0], hd_table[1]);
2312 1ade1de2 bellard
    ide_if[0].openpic = openpic;
2313 1ade1de2 bellard
    ide_if[1].openpic = openpic;
2314 1ade1de2 bellard
    
2315 1ade1de2 bellard
    pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
2316 1ade1de2 bellard
                                             pmac_ide_write, &ide_if[0]);
2317 1ade1de2 bellard
    return pmac_ide_memory;
2318 1ade1de2 bellard
}