xref: /openbmc/qemu/hw/ide/atapi.c (revision 33231e0e221543759b11a4a79b54b9a88d4b455e)
1*33231e0eSKevin Wolf /*
2*33231e0eSKevin Wolf  * QEMU ATAPI Emulation
3*33231e0eSKevin Wolf  *
4*33231e0eSKevin Wolf  * Copyright (c) 2003 Fabrice Bellard
5*33231e0eSKevin Wolf  * Copyright (c) 2006 Openedhand Ltd.
6*33231e0eSKevin Wolf  *
7*33231e0eSKevin Wolf  * Permission is hereby granted, free of charge, to any person obtaining a copy
8*33231e0eSKevin Wolf  * of this software and associated documentation files (the "Software"), to deal
9*33231e0eSKevin Wolf  * in the Software without restriction, including without limitation the rights
10*33231e0eSKevin Wolf  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11*33231e0eSKevin Wolf  * copies of the Software, and to permit persons to whom the Software is
12*33231e0eSKevin Wolf  * furnished to do so, subject to the following conditions:
13*33231e0eSKevin Wolf  *
14*33231e0eSKevin Wolf  * The above copyright notice and this permission notice shall be included in
15*33231e0eSKevin Wolf  * all copies or substantial portions of the Software.
16*33231e0eSKevin Wolf  *
17*33231e0eSKevin Wolf  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*33231e0eSKevin Wolf  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*33231e0eSKevin Wolf  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*33231e0eSKevin Wolf  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21*33231e0eSKevin Wolf  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22*33231e0eSKevin Wolf  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23*33231e0eSKevin Wolf  * THE SOFTWARE.
24*33231e0eSKevin Wolf  */
25*33231e0eSKevin Wolf 
26*33231e0eSKevin Wolf #include "hw/ide/internal.h"
27*33231e0eSKevin Wolf #include "hw/scsi.h"
28*33231e0eSKevin Wolf 
29*33231e0eSKevin Wolf static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
30*33231e0eSKevin Wolf 
31*33231e0eSKevin Wolf static void padstr8(uint8_t *buf, int buf_size, const char *src)
32*33231e0eSKevin Wolf {
33*33231e0eSKevin Wolf     int i;
34*33231e0eSKevin Wolf     for(i = 0; i < buf_size; i++) {
35*33231e0eSKevin Wolf         if (*src)
36*33231e0eSKevin Wolf             buf[i] = *src++;
37*33231e0eSKevin Wolf         else
38*33231e0eSKevin Wolf             buf[i] = ' ';
39*33231e0eSKevin Wolf     }
40*33231e0eSKevin Wolf }
41*33231e0eSKevin Wolf 
42*33231e0eSKevin Wolf static inline void cpu_to_ube16(uint8_t *buf, int val)
43*33231e0eSKevin Wolf {
44*33231e0eSKevin Wolf     buf[0] = val >> 8;
45*33231e0eSKevin Wolf     buf[1] = val & 0xff;
46*33231e0eSKevin Wolf }
47*33231e0eSKevin Wolf 
48*33231e0eSKevin Wolf static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
49*33231e0eSKevin Wolf {
50*33231e0eSKevin Wolf     buf[0] = val >> 24;
51*33231e0eSKevin Wolf     buf[1] = val >> 16;
52*33231e0eSKevin Wolf     buf[2] = val >> 8;
53*33231e0eSKevin Wolf     buf[3] = val & 0xff;
54*33231e0eSKevin Wolf }
55*33231e0eSKevin Wolf 
56*33231e0eSKevin Wolf static inline int ube16_to_cpu(const uint8_t *buf)
57*33231e0eSKevin Wolf {
58*33231e0eSKevin Wolf     return (buf[0] << 8) | buf[1];
59*33231e0eSKevin Wolf }
60*33231e0eSKevin Wolf 
61*33231e0eSKevin Wolf static inline int ube32_to_cpu(const uint8_t *buf)
62*33231e0eSKevin Wolf {
63*33231e0eSKevin Wolf     return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
64*33231e0eSKevin Wolf }
65*33231e0eSKevin Wolf 
66*33231e0eSKevin Wolf static void lba_to_msf(uint8_t *buf, int lba)
67*33231e0eSKevin Wolf {
68*33231e0eSKevin Wolf     lba += 150;
69*33231e0eSKevin Wolf     buf[0] = (lba / 75) / 60;
70*33231e0eSKevin Wolf     buf[1] = (lba / 75) % 60;
71*33231e0eSKevin Wolf     buf[2] = lba % 75;
72*33231e0eSKevin Wolf }
73*33231e0eSKevin Wolf 
74*33231e0eSKevin Wolf /* XXX: DVDs that could fit on a CD will be reported as a CD */
75*33231e0eSKevin Wolf static inline int media_present(IDEState *s)
76*33231e0eSKevin Wolf {
77*33231e0eSKevin Wolf     return (s->nb_sectors > 0);
78*33231e0eSKevin Wolf }
79*33231e0eSKevin Wolf 
80*33231e0eSKevin Wolf static inline int media_is_dvd(IDEState *s)
81*33231e0eSKevin Wolf {
82*33231e0eSKevin Wolf     return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS);
83*33231e0eSKevin Wolf }
84*33231e0eSKevin Wolf 
85*33231e0eSKevin Wolf static inline int media_is_cd(IDEState *s)
86*33231e0eSKevin Wolf {
87*33231e0eSKevin Wolf     return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS);
88*33231e0eSKevin Wolf }
89*33231e0eSKevin Wolf 
90*33231e0eSKevin Wolf static void cd_data_to_raw(uint8_t *buf, int lba)
91*33231e0eSKevin Wolf {
92*33231e0eSKevin Wolf     /* sync bytes */
93*33231e0eSKevin Wolf     buf[0] = 0x00;
94*33231e0eSKevin Wolf     memset(buf + 1, 0xff, 10);
95*33231e0eSKevin Wolf     buf[11] = 0x00;
96*33231e0eSKevin Wolf     buf += 12;
97*33231e0eSKevin Wolf     /* MSF */
98*33231e0eSKevin Wolf     lba_to_msf(buf, lba);
99*33231e0eSKevin Wolf     buf[3] = 0x01; /* mode 1 data */
100*33231e0eSKevin Wolf     buf += 4;
101*33231e0eSKevin Wolf     /* data */
102*33231e0eSKevin Wolf     buf += 2048;
103*33231e0eSKevin Wolf     /* XXX: ECC not computed */
104*33231e0eSKevin Wolf     memset(buf, 0, 288);
105*33231e0eSKevin Wolf }
106*33231e0eSKevin Wolf 
107*33231e0eSKevin Wolf static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
108*33231e0eSKevin Wolf                            int sector_size)
109*33231e0eSKevin Wolf {
110*33231e0eSKevin Wolf     int ret;
111*33231e0eSKevin Wolf 
112*33231e0eSKevin Wolf     switch(sector_size) {
113*33231e0eSKevin Wolf     case 2048:
114*33231e0eSKevin Wolf         ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
115*33231e0eSKevin Wolf         break;
116*33231e0eSKevin Wolf     case 2352:
117*33231e0eSKevin Wolf         ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
118*33231e0eSKevin Wolf         if (ret < 0)
119*33231e0eSKevin Wolf             return ret;
120*33231e0eSKevin Wolf         cd_data_to_raw(buf, lba);
121*33231e0eSKevin Wolf         break;
122*33231e0eSKevin Wolf     default:
123*33231e0eSKevin Wolf         ret = -EIO;
124*33231e0eSKevin Wolf         break;
125*33231e0eSKevin Wolf     }
126*33231e0eSKevin Wolf     return ret;
127*33231e0eSKevin Wolf }
128*33231e0eSKevin Wolf 
129*33231e0eSKevin Wolf void ide_atapi_cmd_ok(IDEState *s)
130*33231e0eSKevin Wolf {
131*33231e0eSKevin Wolf     s->error = 0;
132*33231e0eSKevin Wolf     s->status = READY_STAT | SEEK_STAT;
133*33231e0eSKevin Wolf     s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
134*33231e0eSKevin Wolf     ide_set_irq(s->bus);
135*33231e0eSKevin Wolf }
136*33231e0eSKevin Wolf 
137*33231e0eSKevin Wolf void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
138*33231e0eSKevin Wolf {
139*33231e0eSKevin Wolf #ifdef DEBUG_IDE_ATAPI
140*33231e0eSKevin Wolf     printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
141*33231e0eSKevin Wolf #endif
142*33231e0eSKevin Wolf     s->error = sense_key << 4;
143*33231e0eSKevin Wolf     s->status = READY_STAT | ERR_STAT;
144*33231e0eSKevin Wolf     s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
145*33231e0eSKevin Wolf     s->sense_key = sense_key;
146*33231e0eSKevin Wolf     s->asc = asc;
147*33231e0eSKevin Wolf     ide_set_irq(s->bus);
148*33231e0eSKevin Wolf }
149*33231e0eSKevin Wolf 
150*33231e0eSKevin Wolf void ide_atapi_io_error(IDEState *s, int ret)
151*33231e0eSKevin Wolf {
152*33231e0eSKevin Wolf     /* XXX: handle more errors */
153*33231e0eSKevin Wolf     if (ret == -ENOMEDIUM) {
154*33231e0eSKevin Wolf         ide_atapi_cmd_error(s, SENSE_NOT_READY,
155*33231e0eSKevin Wolf                             ASC_MEDIUM_NOT_PRESENT);
156*33231e0eSKevin Wolf     } else {
157*33231e0eSKevin Wolf         ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
158*33231e0eSKevin Wolf                             ASC_LOGICAL_BLOCK_OOR);
159*33231e0eSKevin Wolf     }
160*33231e0eSKevin Wolf }
161*33231e0eSKevin Wolf 
162*33231e0eSKevin Wolf /* The whole ATAPI transfer logic is handled in this function */
163*33231e0eSKevin Wolf void ide_atapi_cmd_reply_end(IDEState *s)
164*33231e0eSKevin Wolf {
165*33231e0eSKevin Wolf     int byte_count_limit, size, ret;
166*33231e0eSKevin Wolf #ifdef DEBUG_IDE_ATAPI
167*33231e0eSKevin Wolf     printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
168*33231e0eSKevin Wolf            s->packet_transfer_size,
169*33231e0eSKevin Wolf            s->elementary_transfer_size,
170*33231e0eSKevin Wolf            s->io_buffer_index);
171*33231e0eSKevin Wolf #endif
172*33231e0eSKevin Wolf     if (s->packet_transfer_size <= 0) {
173*33231e0eSKevin Wolf         /* end of transfer */
174*33231e0eSKevin Wolf         ide_transfer_stop(s);
175*33231e0eSKevin Wolf         s->status = READY_STAT | SEEK_STAT;
176*33231e0eSKevin Wolf         s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
177*33231e0eSKevin Wolf         ide_set_irq(s->bus);
178*33231e0eSKevin Wolf #ifdef DEBUG_IDE_ATAPI
179*33231e0eSKevin Wolf         printf("status=0x%x\n", s->status);
180*33231e0eSKevin Wolf #endif
181*33231e0eSKevin Wolf     } else {
182*33231e0eSKevin Wolf         /* see if a new sector must be read */
183*33231e0eSKevin Wolf         if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
184*33231e0eSKevin Wolf             ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
185*33231e0eSKevin Wolf             if (ret < 0) {
186*33231e0eSKevin Wolf                 ide_transfer_stop(s);
187*33231e0eSKevin Wolf                 ide_atapi_io_error(s, ret);
188*33231e0eSKevin Wolf                 return;
189*33231e0eSKevin Wolf             }
190*33231e0eSKevin Wolf             s->lba++;
191*33231e0eSKevin Wolf             s->io_buffer_index = 0;
192*33231e0eSKevin Wolf         }
193*33231e0eSKevin Wolf         if (s->elementary_transfer_size > 0) {
194*33231e0eSKevin Wolf             /* there are some data left to transmit in this elementary
195*33231e0eSKevin Wolf                transfer */
196*33231e0eSKevin Wolf             size = s->cd_sector_size - s->io_buffer_index;
197*33231e0eSKevin Wolf             if (size > s->elementary_transfer_size)
198*33231e0eSKevin Wolf                 size = s->elementary_transfer_size;
199*33231e0eSKevin Wolf             s->packet_transfer_size -= size;
200*33231e0eSKevin Wolf             s->elementary_transfer_size -= size;
201*33231e0eSKevin Wolf             s->io_buffer_index += size;
202*33231e0eSKevin Wolf             ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
203*33231e0eSKevin Wolf                                size, ide_atapi_cmd_reply_end);
204*33231e0eSKevin Wolf         } else {
205*33231e0eSKevin Wolf             /* a new transfer is needed */
206*33231e0eSKevin Wolf             s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
207*33231e0eSKevin Wolf             byte_count_limit = s->lcyl | (s->hcyl << 8);
208*33231e0eSKevin Wolf #ifdef DEBUG_IDE_ATAPI
209*33231e0eSKevin Wolf             printf("byte_count_limit=%d\n", byte_count_limit);
210*33231e0eSKevin Wolf #endif
211*33231e0eSKevin Wolf             if (byte_count_limit == 0xffff)
212*33231e0eSKevin Wolf                 byte_count_limit--;
213*33231e0eSKevin Wolf             size = s->packet_transfer_size;
214*33231e0eSKevin Wolf             if (size > byte_count_limit) {
215*33231e0eSKevin Wolf                 /* byte count limit must be even if this case */
216*33231e0eSKevin Wolf                 if (byte_count_limit & 1)
217*33231e0eSKevin Wolf                     byte_count_limit--;
218*33231e0eSKevin Wolf                 size = byte_count_limit;
219*33231e0eSKevin Wolf             }
220*33231e0eSKevin Wolf             s->lcyl = size;
221*33231e0eSKevin Wolf             s->hcyl = size >> 8;
222*33231e0eSKevin Wolf             s->elementary_transfer_size = size;
223*33231e0eSKevin Wolf             /* we cannot transmit more than one sector at a time */
224*33231e0eSKevin Wolf             if (s->lba != -1) {
225*33231e0eSKevin Wolf                 if (size > (s->cd_sector_size - s->io_buffer_index))
226*33231e0eSKevin Wolf                     size = (s->cd_sector_size - s->io_buffer_index);
227*33231e0eSKevin Wolf             }
228*33231e0eSKevin Wolf             s->packet_transfer_size -= size;
229*33231e0eSKevin Wolf             s->elementary_transfer_size -= size;
230*33231e0eSKevin Wolf             s->io_buffer_index += size;
231*33231e0eSKevin Wolf             ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
232*33231e0eSKevin Wolf                                size, ide_atapi_cmd_reply_end);
233*33231e0eSKevin Wolf             ide_set_irq(s->bus);
234*33231e0eSKevin Wolf #ifdef DEBUG_IDE_ATAPI
235*33231e0eSKevin Wolf             printf("status=0x%x\n", s->status);
236*33231e0eSKevin Wolf #endif
237*33231e0eSKevin Wolf         }
238*33231e0eSKevin Wolf     }
239*33231e0eSKevin Wolf }
240*33231e0eSKevin Wolf 
241*33231e0eSKevin Wolf /* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
242*33231e0eSKevin Wolf static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
243*33231e0eSKevin Wolf {
244*33231e0eSKevin Wolf     if (size > max_size)
245*33231e0eSKevin Wolf         size = max_size;
246*33231e0eSKevin Wolf     s->lba = -1; /* no sector read */
247*33231e0eSKevin Wolf     s->packet_transfer_size = size;
248*33231e0eSKevin Wolf     s->io_buffer_size = size;    /* dma: send the reply data as one chunk */
249*33231e0eSKevin Wolf     s->elementary_transfer_size = 0;
250*33231e0eSKevin Wolf     s->io_buffer_index = 0;
251*33231e0eSKevin Wolf 
252*33231e0eSKevin Wolf     if (s->atapi_dma) {
253*33231e0eSKevin Wolf         s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
254*33231e0eSKevin Wolf         s->bus->dma->ops->start_dma(s->bus->dma, s,
255*33231e0eSKevin Wolf                                    ide_atapi_cmd_read_dma_cb);
256*33231e0eSKevin Wolf     } else {
257*33231e0eSKevin Wolf         s->status = READY_STAT | SEEK_STAT;
258*33231e0eSKevin Wolf         ide_atapi_cmd_reply_end(s);
259*33231e0eSKevin Wolf     }
260*33231e0eSKevin Wolf }
261*33231e0eSKevin Wolf 
262*33231e0eSKevin Wolf /* start a CD-CDROM read command */
263*33231e0eSKevin Wolf static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
264*33231e0eSKevin Wolf                                    int sector_size)
265*33231e0eSKevin Wolf {
266*33231e0eSKevin Wolf     s->lba = lba;
267*33231e0eSKevin Wolf     s->packet_transfer_size = nb_sectors * sector_size;
268*33231e0eSKevin Wolf     s->elementary_transfer_size = 0;
269*33231e0eSKevin Wolf     s->io_buffer_index = sector_size;
270*33231e0eSKevin Wolf     s->cd_sector_size = sector_size;
271*33231e0eSKevin Wolf 
272*33231e0eSKevin Wolf     s->status = READY_STAT | SEEK_STAT;
273*33231e0eSKevin Wolf     ide_atapi_cmd_reply_end(s);
274*33231e0eSKevin Wolf }
275*33231e0eSKevin Wolf 
276*33231e0eSKevin Wolf static void ide_atapi_cmd_check_status(IDEState *s)
277*33231e0eSKevin Wolf {
278*33231e0eSKevin Wolf #ifdef DEBUG_IDE_ATAPI
279*33231e0eSKevin Wolf     printf("atapi_cmd_check_status\n");
280*33231e0eSKevin Wolf #endif
281*33231e0eSKevin Wolf     s->error = MC_ERR | (SENSE_UNIT_ATTENTION << 4);
282*33231e0eSKevin Wolf     s->status = ERR_STAT;
283*33231e0eSKevin Wolf     s->nsector = 0;
284*33231e0eSKevin Wolf     ide_set_irq(s->bus);
285*33231e0eSKevin Wolf }
286*33231e0eSKevin Wolf /* ATAPI DMA support */
287*33231e0eSKevin Wolf 
288*33231e0eSKevin Wolf /* XXX: handle read errors */
289*33231e0eSKevin Wolf static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
290*33231e0eSKevin Wolf {
291*33231e0eSKevin Wolf     IDEState *s = opaque;
292*33231e0eSKevin Wolf     int data_offset, n;
293*33231e0eSKevin Wolf 
294*33231e0eSKevin Wolf     if (ret < 0) {
295*33231e0eSKevin Wolf         ide_atapi_io_error(s, ret);
296*33231e0eSKevin Wolf         goto eot;
297*33231e0eSKevin Wolf     }
298*33231e0eSKevin Wolf 
299*33231e0eSKevin Wolf     if (s->io_buffer_size > 0) {
300*33231e0eSKevin Wolf         /*
301*33231e0eSKevin Wolf          * For a cdrom read sector command (s->lba != -1),
302*33231e0eSKevin Wolf          * adjust the lba for the next s->io_buffer_size chunk
303*33231e0eSKevin Wolf          * and dma the current chunk.
304*33231e0eSKevin Wolf          * For a command != read (s->lba == -1), just transfer
305*33231e0eSKevin Wolf          * the reply data.
306*33231e0eSKevin Wolf          */
307*33231e0eSKevin Wolf         if (s->lba != -1) {
308*33231e0eSKevin Wolf             if (s->cd_sector_size == 2352) {
309*33231e0eSKevin Wolf                 n = 1;
310*33231e0eSKevin Wolf                 cd_data_to_raw(s->io_buffer, s->lba);
311*33231e0eSKevin Wolf             } else {
312*33231e0eSKevin Wolf                 n = s->io_buffer_size >> 11;
313*33231e0eSKevin Wolf             }
314*33231e0eSKevin Wolf             s->lba += n;
315*33231e0eSKevin Wolf         }
316*33231e0eSKevin Wolf         s->packet_transfer_size -= s->io_buffer_size;
317*33231e0eSKevin Wolf         if (s->bus->dma->ops->rw_buf(s->bus->dma, 1) == 0)
318*33231e0eSKevin Wolf             goto eot;
319*33231e0eSKevin Wolf     }
320*33231e0eSKevin Wolf 
321*33231e0eSKevin Wolf     if (s->packet_transfer_size <= 0) {
322*33231e0eSKevin Wolf         s->status = READY_STAT | SEEK_STAT;
323*33231e0eSKevin Wolf         s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
324*33231e0eSKevin Wolf         ide_set_irq(s->bus);
325*33231e0eSKevin Wolf     eot:
326*33231e0eSKevin Wolf         s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
327*33231e0eSKevin Wolf         ide_set_inactive(s);
328*33231e0eSKevin Wolf         return;
329*33231e0eSKevin Wolf     }
330*33231e0eSKevin Wolf 
331*33231e0eSKevin Wolf     s->io_buffer_index = 0;
332*33231e0eSKevin Wolf     if (s->cd_sector_size == 2352) {
333*33231e0eSKevin Wolf         n = 1;
334*33231e0eSKevin Wolf         s->io_buffer_size = s->cd_sector_size;
335*33231e0eSKevin Wolf         data_offset = 16;
336*33231e0eSKevin Wolf     } else {
337*33231e0eSKevin Wolf         n = s->packet_transfer_size >> 11;
338*33231e0eSKevin Wolf         if (n > (IDE_DMA_BUF_SECTORS / 4))
339*33231e0eSKevin Wolf             n = (IDE_DMA_BUF_SECTORS / 4);
340*33231e0eSKevin Wolf         s->io_buffer_size = n * 2048;
341*33231e0eSKevin Wolf         data_offset = 0;
342*33231e0eSKevin Wolf     }
343*33231e0eSKevin Wolf #ifdef DEBUG_AIO
344*33231e0eSKevin Wolf     printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
345*33231e0eSKevin Wolf #endif
346*33231e0eSKevin Wolf     s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
347*33231e0eSKevin Wolf     s->bus->dma->iov.iov_len = n * 4 * 512;
348*33231e0eSKevin Wolf     qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
349*33231e0eSKevin Wolf     s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
350*33231e0eSKevin Wolf                                        &s->bus->dma->qiov, n * 4,
351*33231e0eSKevin Wolf                                        ide_atapi_cmd_read_dma_cb, s);
352*33231e0eSKevin Wolf     if (!s->bus->dma->aiocb) {
353*33231e0eSKevin Wolf         /* Note: media not present is the most likely case */
354*33231e0eSKevin Wolf         ide_atapi_cmd_error(s, SENSE_NOT_READY,
355*33231e0eSKevin Wolf                             ASC_MEDIUM_NOT_PRESENT);
356*33231e0eSKevin Wolf         goto eot;
357*33231e0eSKevin Wolf     }
358*33231e0eSKevin Wolf }
359*33231e0eSKevin Wolf 
360*33231e0eSKevin Wolf /* start a CD-CDROM read command with DMA */
361*33231e0eSKevin Wolf /* XXX: test if DMA is available */
362*33231e0eSKevin Wolf static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
363*33231e0eSKevin Wolf                                    int sector_size)
364*33231e0eSKevin Wolf {
365*33231e0eSKevin Wolf     s->lba = lba;
366*33231e0eSKevin Wolf     s->packet_transfer_size = nb_sectors * sector_size;
367*33231e0eSKevin Wolf     s->io_buffer_index = 0;
368*33231e0eSKevin Wolf     s->io_buffer_size = 0;
369*33231e0eSKevin Wolf     s->cd_sector_size = sector_size;
370*33231e0eSKevin Wolf 
371*33231e0eSKevin Wolf     /* XXX: check if BUSY_STAT should be set */
372*33231e0eSKevin Wolf     s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
373*33231e0eSKevin Wolf     s->bus->dma->ops->start_dma(s->bus->dma, s,
374*33231e0eSKevin Wolf                                ide_atapi_cmd_read_dma_cb);
375*33231e0eSKevin Wolf }
376*33231e0eSKevin Wolf 
377*33231e0eSKevin Wolf static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
378*33231e0eSKevin Wolf                                int sector_size)
379*33231e0eSKevin Wolf {
380*33231e0eSKevin Wolf #ifdef DEBUG_IDE_ATAPI
381*33231e0eSKevin Wolf     printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
382*33231e0eSKevin Wolf         lba, nb_sectors);
383*33231e0eSKevin Wolf #endif
384*33231e0eSKevin Wolf     if (s->atapi_dma) {
385*33231e0eSKevin Wolf         ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
386*33231e0eSKevin Wolf     } else {
387*33231e0eSKevin Wolf         ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
388*33231e0eSKevin Wolf     }
389*33231e0eSKevin Wolf }
390*33231e0eSKevin Wolf 
391*33231e0eSKevin Wolf static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
392*33231e0eSKevin Wolf                                             uint16_t profile)
393*33231e0eSKevin Wolf {
394*33231e0eSKevin Wolf     uint8_t *buf_profile = buf + 12; /* start of profiles */
395*33231e0eSKevin Wolf 
396*33231e0eSKevin Wolf     buf_profile += ((*index) * 4); /* start of indexed profile */
397*33231e0eSKevin Wolf     cpu_to_ube16 (buf_profile, profile);
398*33231e0eSKevin Wolf     buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7]));
399*33231e0eSKevin Wolf 
400*33231e0eSKevin Wolf     /* each profile adds 4 bytes to the response */
401*33231e0eSKevin Wolf     (*index)++;
402*33231e0eSKevin Wolf     buf[11] += 4; /* Additional Length */
403*33231e0eSKevin Wolf 
404*33231e0eSKevin Wolf     return 4;
405*33231e0eSKevin Wolf }
406*33231e0eSKevin Wolf 
407*33231e0eSKevin Wolf static int ide_dvd_read_structure(IDEState *s, int format,
408*33231e0eSKevin Wolf                                   const uint8_t *packet, uint8_t *buf)
409*33231e0eSKevin Wolf {
410*33231e0eSKevin Wolf     switch (format) {
411*33231e0eSKevin Wolf         case 0x0: /* Physical format information */
412*33231e0eSKevin Wolf             {
413*33231e0eSKevin Wolf                 int layer = packet[6];
414*33231e0eSKevin Wolf                 uint64_t total_sectors;
415*33231e0eSKevin Wolf 
416*33231e0eSKevin Wolf                 if (layer != 0)
417*33231e0eSKevin Wolf                     return -ASC_INV_FIELD_IN_CMD_PACKET;
418*33231e0eSKevin Wolf 
419*33231e0eSKevin Wolf                 bdrv_get_geometry(s->bs, &total_sectors);
420*33231e0eSKevin Wolf                 total_sectors >>= 2;
421*33231e0eSKevin Wolf                 if (total_sectors == 0)
422*33231e0eSKevin Wolf                     return -ASC_MEDIUM_NOT_PRESENT;
423*33231e0eSKevin Wolf 
424*33231e0eSKevin Wolf                 buf[4] = 1;   /* DVD-ROM, part version 1 */
425*33231e0eSKevin Wolf                 buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
426*33231e0eSKevin Wolf                 buf[6] = 1;   /* one layer, read-only (per MMC-2 spec) */
427*33231e0eSKevin Wolf                 buf[7] = 0;   /* default densities */
428*33231e0eSKevin Wolf 
429*33231e0eSKevin Wolf                 /* FIXME: 0x30000 per spec? */
430*33231e0eSKevin Wolf                 cpu_to_ube32(buf + 8, 0); /* start sector */
431*33231e0eSKevin Wolf                 cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */
432*33231e0eSKevin Wolf                 cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */
433*33231e0eSKevin Wolf 
434*33231e0eSKevin Wolf                 /* Size of buffer, not including 2 byte size field */
435*33231e0eSKevin Wolf                 cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
436*33231e0eSKevin Wolf 
437*33231e0eSKevin Wolf                 /* 2k data + 4 byte header */
438*33231e0eSKevin Wolf                 return (2048 + 4);
439*33231e0eSKevin Wolf             }
440*33231e0eSKevin Wolf 
441*33231e0eSKevin Wolf         case 0x01: /* DVD copyright information */
442*33231e0eSKevin Wolf             buf[4] = 0; /* no copyright data */
443*33231e0eSKevin Wolf             buf[5] = 0; /* no region restrictions */
444*33231e0eSKevin Wolf 
445*33231e0eSKevin Wolf             /* Size of buffer, not including 2 byte size field */
446*33231e0eSKevin Wolf             cpu_to_be16wu((uint16_t *)buf, 4 + 2);
447*33231e0eSKevin Wolf 
448*33231e0eSKevin Wolf             /* 4 byte header + 4 byte data */
449*33231e0eSKevin Wolf             return (4 + 4);
450*33231e0eSKevin Wolf 
451*33231e0eSKevin Wolf         case 0x03: /* BCA information - invalid field for no BCA info */
452*33231e0eSKevin Wolf             return -ASC_INV_FIELD_IN_CMD_PACKET;
453*33231e0eSKevin Wolf 
454*33231e0eSKevin Wolf         case 0x04: /* DVD disc manufacturing information */
455*33231e0eSKevin Wolf             /* Size of buffer, not including 2 byte size field */
456*33231e0eSKevin Wolf             cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
457*33231e0eSKevin Wolf 
458*33231e0eSKevin Wolf             /* 2k data + 4 byte header */
459*33231e0eSKevin Wolf             return (2048 + 4);
460*33231e0eSKevin Wolf 
461*33231e0eSKevin Wolf         case 0xff:
462*33231e0eSKevin Wolf             /*
463*33231e0eSKevin Wolf              * This lists all the command capabilities above.  Add new ones
464*33231e0eSKevin Wolf              * in order and update the length and buffer return values.
465*33231e0eSKevin Wolf              */
466*33231e0eSKevin Wolf 
467*33231e0eSKevin Wolf             buf[4] = 0x00; /* Physical format */
468*33231e0eSKevin Wolf             buf[5] = 0x40; /* Not writable, is readable */
469*33231e0eSKevin Wolf             cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4);
470*33231e0eSKevin Wolf 
471*33231e0eSKevin Wolf             buf[8] = 0x01; /* Copyright info */
472*33231e0eSKevin Wolf             buf[9] = 0x40; /* Not writable, is readable */
473*33231e0eSKevin Wolf             cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4);
474*33231e0eSKevin Wolf 
475*33231e0eSKevin Wolf             buf[12] = 0x03; /* BCA info */
476*33231e0eSKevin Wolf             buf[13] = 0x40; /* Not writable, is readable */
477*33231e0eSKevin Wolf             cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4);
478*33231e0eSKevin Wolf 
479*33231e0eSKevin Wolf             buf[16] = 0x04; /* Manufacturing info */
480*33231e0eSKevin Wolf             buf[17] = 0x40; /* Not writable, is readable */
481*33231e0eSKevin Wolf             cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4);
482*33231e0eSKevin Wolf 
483*33231e0eSKevin Wolf             /* Size of buffer, not including 2 byte size field */
484*33231e0eSKevin Wolf             cpu_to_be16wu((uint16_t *)buf, 16 + 2);
485*33231e0eSKevin Wolf 
486*33231e0eSKevin Wolf             /* data written + 4 byte header */
487*33231e0eSKevin Wolf             return (16 + 4);
488*33231e0eSKevin Wolf 
489*33231e0eSKevin Wolf         default: /* TODO: formats beyond DVD-ROM requires */
490*33231e0eSKevin Wolf             return -ASC_INV_FIELD_IN_CMD_PACKET;
491*33231e0eSKevin Wolf     }
492*33231e0eSKevin Wolf }
493*33231e0eSKevin Wolf 
494*33231e0eSKevin Wolf static unsigned int event_status_media(IDEState *s,
495*33231e0eSKevin Wolf                                        uint8_t *buf)
496*33231e0eSKevin Wolf {
497*33231e0eSKevin Wolf     enum media_event_code {
498*33231e0eSKevin Wolf         MEC_NO_CHANGE = 0,       /* Status unchanged */
499*33231e0eSKevin Wolf         MEC_EJECT_REQUESTED,     /* received a request from user to eject */
500*33231e0eSKevin Wolf         MEC_NEW_MEDIA,           /* new media inserted and ready for access */
501*33231e0eSKevin Wolf         MEC_MEDIA_REMOVAL,       /* only for media changers */
502*33231e0eSKevin Wolf         MEC_MEDIA_CHANGED,       /* only for media changers */
503*33231e0eSKevin Wolf         MEC_BG_FORMAT_COMPLETED, /* MRW or DVD+RW b/g format completed */
504*33231e0eSKevin Wolf         MEC_BG_FORMAT_RESTARTED, /* MRW or DVD+RW b/g format restarted */
505*33231e0eSKevin Wolf     };
506*33231e0eSKevin Wolf     enum media_status {
507*33231e0eSKevin Wolf         MS_TRAY_OPEN = 1,
508*33231e0eSKevin Wolf         MS_MEDIA_PRESENT = 2,
509*33231e0eSKevin Wolf     };
510*33231e0eSKevin Wolf     uint8_t event_code, media_status;
511*33231e0eSKevin Wolf 
512*33231e0eSKevin Wolf     media_status = 0;
513*33231e0eSKevin Wolf     if (s->bs->tray_open) {
514*33231e0eSKevin Wolf         media_status = MS_TRAY_OPEN;
515*33231e0eSKevin Wolf     } else if (bdrv_is_inserted(s->bs)) {
516*33231e0eSKevin Wolf         media_status = MS_MEDIA_PRESENT;
517*33231e0eSKevin Wolf     }
518*33231e0eSKevin Wolf 
519*33231e0eSKevin Wolf     /* Event notification descriptor */
520*33231e0eSKevin Wolf     event_code = MEC_NO_CHANGE;
521*33231e0eSKevin Wolf     if (media_status != MS_TRAY_OPEN && s->events.new_media) {
522*33231e0eSKevin Wolf         event_code = MEC_NEW_MEDIA;
523*33231e0eSKevin Wolf         s->events.new_media = false;
524*33231e0eSKevin Wolf     }
525*33231e0eSKevin Wolf 
526*33231e0eSKevin Wolf     buf[4] = event_code;
527*33231e0eSKevin Wolf     buf[5] = media_status;
528*33231e0eSKevin Wolf 
529*33231e0eSKevin Wolf     /* These fields are reserved, just clear them. */
530*33231e0eSKevin Wolf     buf[6] = 0;
531*33231e0eSKevin Wolf     buf[7] = 0;
532*33231e0eSKevin Wolf 
533*33231e0eSKevin Wolf     return 8; /* We wrote to 4 extra bytes from the header */
534*33231e0eSKevin Wolf }
535*33231e0eSKevin Wolf 
536*33231e0eSKevin Wolf static void handle_get_event_status_notification(IDEState *s,
537*33231e0eSKevin Wolf                                                  uint8_t *buf,
538*33231e0eSKevin Wolf                                                  const uint8_t *packet)
539*33231e0eSKevin Wolf {
540*33231e0eSKevin Wolf     struct {
541*33231e0eSKevin Wolf         uint8_t opcode;
542*33231e0eSKevin Wolf         uint8_t polled;        /* lsb bit is polled; others are reserved */
543*33231e0eSKevin Wolf         uint8_t reserved2[2];
544*33231e0eSKevin Wolf         uint8_t class;
545*33231e0eSKevin Wolf         uint8_t reserved3[2];
546*33231e0eSKevin Wolf         uint16_t len;
547*33231e0eSKevin Wolf         uint8_t control;
548*33231e0eSKevin Wolf     } __attribute__((packed)) *gesn_cdb;
549*33231e0eSKevin Wolf 
550*33231e0eSKevin Wolf     struct {
551*33231e0eSKevin Wolf         uint16_t len;
552*33231e0eSKevin Wolf         uint8_t notification_class;
553*33231e0eSKevin Wolf         uint8_t supported_events;
554*33231e0eSKevin Wolf     } __attribute((packed)) *gesn_event_header;
555*33231e0eSKevin Wolf 
556*33231e0eSKevin Wolf     enum notification_class_request_type {
557*33231e0eSKevin Wolf         NCR_RESERVED1 = 1 << 0,
558*33231e0eSKevin Wolf         NCR_OPERATIONAL_CHANGE = 1 << 1,
559*33231e0eSKevin Wolf         NCR_POWER_MANAGEMENT = 1 << 2,
560*33231e0eSKevin Wolf         NCR_EXTERNAL_REQUEST = 1 << 3,
561*33231e0eSKevin Wolf         NCR_MEDIA = 1 << 4,
562*33231e0eSKevin Wolf         NCR_MULTI_HOST = 1 << 5,
563*33231e0eSKevin Wolf         NCR_DEVICE_BUSY = 1 << 6,
564*33231e0eSKevin Wolf         NCR_RESERVED2 = 1 << 7,
565*33231e0eSKevin Wolf     };
566*33231e0eSKevin Wolf     enum event_notification_class_field {
567*33231e0eSKevin Wolf         ENC_NO_EVENTS = 0,
568*33231e0eSKevin Wolf         ENC_OPERATIONAL_CHANGE,
569*33231e0eSKevin Wolf         ENC_POWER_MANAGEMENT,
570*33231e0eSKevin Wolf         ENC_EXTERNAL_REQUEST,
571*33231e0eSKevin Wolf         ENC_MEDIA,
572*33231e0eSKevin Wolf         ENC_MULTIPLE_HOSTS,
573*33231e0eSKevin Wolf         ENC_DEVICE_BUSY,
574*33231e0eSKevin Wolf         ENC_RESERVED,
575*33231e0eSKevin Wolf     };
576*33231e0eSKevin Wolf     unsigned int max_len, used_len;
577*33231e0eSKevin Wolf 
578*33231e0eSKevin Wolf     gesn_cdb = (void *)packet;
579*33231e0eSKevin Wolf     gesn_event_header = (void *)buf;
580*33231e0eSKevin Wolf 
581*33231e0eSKevin Wolf     max_len = be16_to_cpu(gesn_cdb->len);
582*33231e0eSKevin Wolf 
583*33231e0eSKevin Wolf     /* It is fine by the MMC spec to not support async mode operations */
584*33231e0eSKevin Wolf     if (!(gesn_cdb->polled & 0x01)) { /* asynchronous mode */
585*33231e0eSKevin Wolf         /* Only polling is supported, asynchronous mode is not. */
586*33231e0eSKevin Wolf         ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
587*33231e0eSKevin Wolf                             ASC_INV_FIELD_IN_CMD_PACKET);
588*33231e0eSKevin Wolf         return;
589*33231e0eSKevin Wolf     }
590*33231e0eSKevin Wolf 
591*33231e0eSKevin Wolf     /* polling mode operation */
592*33231e0eSKevin Wolf 
593*33231e0eSKevin Wolf     /*
594*33231e0eSKevin Wolf      * These are the supported events.
595*33231e0eSKevin Wolf      *
596*33231e0eSKevin Wolf      * We currently only support requests of the 'media' type.
597*33231e0eSKevin Wolf      */
598*33231e0eSKevin Wolf     gesn_event_header->supported_events = NCR_MEDIA;
599*33231e0eSKevin Wolf 
600*33231e0eSKevin Wolf     /*
601*33231e0eSKevin Wolf      * We use |= below to set the class field; other bits in this byte
602*33231e0eSKevin Wolf      * are reserved now but this is useful to do if we have to use the
603*33231e0eSKevin Wolf      * reserved fields later.
604*33231e0eSKevin Wolf      */
605*33231e0eSKevin Wolf     gesn_event_header->notification_class = 0;
606*33231e0eSKevin Wolf 
607*33231e0eSKevin Wolf     /*
608*33231e0eSKevin Wolf      * Responses to requests are to be based on request priority.  The
609*33231e0eSKevin Wolf      * notification_class_request_type enum above specifies the
610*33231e0eSKevin Wolf      * priority: upper elements are higher prio than lower ones.
611*33231e0eSKevin Wolf      */
612*33231e0eSKevin Wolf     if (gesn_cdb->class & NCR_MEDIA) {
613*33231e0eSKevin Wolf         gesn_event_header->notification_class |= ENC_MEDIA;
614*33231e0eSKevin Wolf         used_len = event_status_media(s, buf);
615*33231e0eSKevin Wolf     } else {
616*33231e0eSKevin Wolf         gesn_event_header->notification_class = 0x80; /* No event available */
617*33231e0eSKevin Wolf         used_len = sizeof(*gesn_event_header);
618*33231e0eSKevin Wolf     }
619*33231e0eSKevin Wolf     gesn_event_header->len = cpu_to_be16(used_len
620*33231e0eSKevin Wolf                                          - sizeof(*gesn_event_header));
621*33231e0eSKevin Wolf     ide_atapi_cmd_reply(s, used_len, max_len);
622*33231e0eSKevin Wolf }
623*33231e0eSKevin Wolf 
624*33231e0eSKevin Wolf void ide_atapi_cmd(IDEState *s)
625*33231e0eSKevin Wolf {
626*33231e0eSKevin Wolf     const uint8_t *packet;
627*33231e0eSKevin Wolf     uint8_t *buf;
628*33231e0eSKevin Wolf     int max_len;
629*33231e0eSKevin Wolf 
630*33231e0eSKevin Wolf     packet = s->io_buffer;
631*33231e0eSKevin Wolf     buf = s->io_buffer;
632*33231e0eSKevin Wolf #ifdef DEBUG_IDE_ATAPI
633*33231e0eSKevin Wolf     {
634*33231e0eSKevin Wolf         int i;
635*33231e0eSKevin Wolf         printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
636*33231e0eSKevin Wolf         for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
637*33231e0eSKevin Wolf             printf(" %02x", packet[i]);
638*33231e0eSKevin Wolf         }
639*33231e0eSKevin Wolf         printf("\n");
640*33231e0eSKevin Wolf     }
641*33231e0eSKevin Wolf #endif
642*33231e0eSKevin Wolf     /*
643*33231e0eSKevin Wolf      * If there's a UNIT_ATTENTION condition pending, only
644*33231e0eSKevin Wolf      * REQUEST_SENSE, INQUIRY, GET_CONFIGURATION and
645*33231e0eSKevin Wolf      * GET_EVENT_STATUS_NOTIFICATION commands are allowed to complete.
646*33231e0eSKevin Wolf      * MMC-5, section 4.1.6.1 lists only these commands being allowed
647*33231e0eSKevin Wolf      * to complete, with other commands getting a CHECK condition
648*33231e0eSKevin Wolf      * response unless a higher priority status, defined by the drive
649*33231e0eSKevin Wolf      * here, is pending.
650*33231e0eSKevin Wolf      */
651*33231e0eSKevin Wolf     if (s->sense_key == SENSE_UNIT_ATTENTION &&
652*33231e0eSKevin Wolf         s->io_buffer[0] != GPCMD_REQUEST_SENSE &&
653*33231e0eSKevin Wolf         s->io_buffer[0] != GPCMD_INQUIRY &&
654*33231e0eSKevin Wolf         s->io_buffer[0] != GPCMD_GET_EVENT_STATUS_NOTIFICATION) {
655*33231e0eSKevin Wolf         ide_atapi_cmd_check_status(s);
656*33231e0eSKevin Wolf         return;
657*33231e0eSKevin Wolf     }
658*33231e0eSKevin Wolf     if (bdrv_is_inserted(s->bs) && s->cdrom_changed) {
659*33231e0eSKevin Wolf         ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
660*33231e0eSKevin Wolf 
661*33231e0eSKevin Wolf         s->cdrom_changed = 0;
662*33231e0eSKevin Wolf         s->sense_key = SENSE_UNIT_ATTENTION;
663*33231e0eSKevin Wolf         s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
664*33231e0eSKevin Wolf         return;
665*33231e0eSKevin Wolf     }
666*33231e0eSKevin Wolf     switch(s->io_buffer[0]) {
667*33231e0eSKevin Wolf     case GPCMD_TEST_UNIT_READY:
668*33231e0eSKevin Wolf         if (bdrv_is_inserted(s->bs)) {
669*33231e0eSKevin Wolf             ide_atapi_cmd_ok(s);
670*33231e0eSKevin Wolf         } else {
671*33231e0eSKevin Wolf             ide_atapi_cmd_error(s, SENSE_NOT_READY,
672*33231e0eSKevin Wolf                                 ASC_MEDIUM_NOT_PRESENT);
673*33231e0eSKevin Wolf         }
674*33231e0eSKevin Wolf         break;
675*33231e0eSKevin Wolf     case GPCMD_MODE_SENSE_6:
676*33231e0eSKevin Wolf     case GPCMD_MODE_SENSE_10:
677*33231e0eSKevin Wolf         {
678*33231e0eSKevin Wolf             int action, code;
679*33231e0eSKevin Wolf             if (packet[0] == GPCMD_MODE_SENSE_10)
680*33231e0eSKevin Wolf                 max_len = ube16_to_cpu(packet + 7);
681*33231e0eSKevin Wolf             else
682*33231e0eSKevin Wolf                 max_len = packet[4];
683*33231e0eSKevin Wolf             action = packet[2] >> 6;
684*33231e0eSKevin Wolf             code = packet[2] & 0x3f;
685*33231e0eSKevin Wolf             switch(action) {
686*33231e0eSKevin Wolf             case 0: /* current values */
687*33231e0eSKevin Wolf                 switch(code) {
688*33231e0eSKevin Wolf                 case GPMODE_R_W_ERROR_PAGE: /* error recovery */
689*33231e0eSKevin Wolf                     cpu_to_ube16(&buf[0], 16 + 6);
690*33231e0eSKevin Wolf                     buf[2] = 0x70;
691*33231e0eSKevin Wolf                     buf[3] = 0;
692*33231e0eSKevin Wolf                     buf[4] = 0;
693*33231e0eSKevin Wolf                     buf[5] = 0;
694*33231e0eSKevin Wolf                     buf[6] = 0;
695*33231e0eSKevin Wolf                     buf[7] = 0;
696*33231e0eSKevin Wolf 
697*33231e0eSKevin Wolf                     buf[8] = 0x01;
698*33231e0eSKevin Wolf                     buf[9] = 0x06;
699*33231e0eSKevin Wolf                     buf[10] = 0x00;
700*33231e0eSKevin Wolf                     buf[11] = 0x05;
701*33231e0eSKevin Wolf                     buf[12] = 0x00;
702*33231e0eSKevin Wolf                     buf[13] = 0x00;
703*33231e0eSKevin Wolf                     buf[14] = 0x00;
704*33231e0eSKevin Wolf                     buf[15] = 0x00;
705*33231e0eSKevin Wolf                     ide_atapi_cmd_reply(s, 16, max_len);
706*33231e0eSKevin Wolf                     break;
707*33231e0eSKevin Wolf                 case GPMODE_AUDIO_CTL_PAGE:
708*33231e0eSKevin Wolf                     cpu_to_ube16(&buf[0], 24 + 6);
709*33231e0eSKevin Wolf                     buf[2] = 0x70;
710*33231e0eSKevin Wolf                     buf[3] = 0;
711*33231e0eSKevin Wolf                     buf[4] = 0;
712*33231e0eSKevin Wolf                     buf[5] = 0;
713*33231e0eSKevin Wolf                     buf[6] = 0;
714*33231e0eSKevin Wolf                     buf[7] = 0;
715*33231e0eSKevin Wolf 
716*33231e0eSKevin Wolf                     /* Fill with CDROM audio volume */
717*33231e0eSKevin Wolf                     buf[17] = 0;
718*33231e0eSKevin Wolf                     buf[19] = 0;
719*33231e0eSKevin Wolf                     buf[21] = 0;
720*33231e0eSKevin Wolf                     buf[23] = 0;
721*33231e0eSKevin Wolf 
722*33231e0eSKevin Wolf                     ide_atapi_cmd_reply(s, 24, max_len);
723*33231e0eSKevin Wolf                     break;
724*33231e0eSKevin Wolf                 case GPMODE_CAPABILITIES_PAGE:
725*33231e0eSKevin Wolf                     cpu_to_ube16(&buf[0], 28 + 6);
726*33231e0eSKevin Wolf                     buf[2] = 0x70;
727*33231e0eSKevin Wolf                     buf[3] = 0;
728*33231e0eSKevin Wolf                     buf[4] = 0;
729*33231e0eSKevin Wolf                     buf[5] = 0;
730*33231e0eSKevin Wolf                     buf[6] = 0;
731*33231e0eSKevin Wolf                     buf[7] = 0;
732*33231e0eSKevin Wolf 
733*33231e0eSKevin Wolf                     buf[8] = 0x2a;
734*33231e0eSKevin Wolf                     buf[9] = 0x12;
735*33231e0eSKevin Wolf                     buf[10] = 0x00;
736*33231e0eSKevin Wolf                     buf[11] = 0x00;
737*33231e0eSKevin Wolf 
738*33231e0eSKevin Wolf                     /* Claim PLAY_AUDIO capability (0x01) since some Linux
739*33231e0eSKevin Wolf                        code checks for this to automount media. */
740*33231e0eSKevin Wolf                     buf[12] = 0x71;
741*33231e0eSKevin Wolf                     buf[13] = 3 << 5;
742*33231e0eSKevin Wolf                     buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
743*33231e0eSKevin Wolf                     if (bdrv_is_locked(s->bs))
744*33231e0eSKevin Wolf                         buf[6] |= 1 << 1;
745*33231e0eSKevin Wolf                     buf[15] = 0x00;
746*33231e0eSKevin Wolf                     cpu_to_ube16(&buf[16], 706);
747*33231e0eSKevin Wolf                     buf[18] = 0;
748*33231e0eSKevin Wolf                     buf[19] = 2;
749*33231e0eSKevin Wolf                     cpu_to_ube16(&buf[20], 512);
750*33231e0eSKevin Wolf                     cpu_to_ube16(&buf[22], 706);
751*33231e0eSKevin Wolf                     buf[24] = 0;
752*33231e0eSKevin Wolf                     buf[25] = 0;
753*33231e0eSKevin Wolf                     buf[26] = 0;
754*33231e0eSKevin Wolf                     buf[27] = 0;
755*33231e0eSKevin Wolf                     ide_atapi_cmd_reply(s, 28, max_len);
756*33231e0eSKevin Wolf                     break;
757*33231e0eSKevin Wolf                 default:
758*33231e0eSKevin Wolf                     goto error_cmd;
759*33231e0eSKevin Wolf                 }
760*33231e0eSKevin Wolf                 break;
761*33231e0eSKevin Wolf             case 1: /* changeable values */
762*33231e0eSKevin Wolf                 goto error_cmd;
763*33231e0eSKevin Wolf             case 2: /* default values */
764*33231e0eSKevin Wolf                 goto error_cmd;
765*33231e0eSKevin Wolf             default:
766*33231e0eSKevin Wolf             case 3: /* saved values */
767*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
768*33231e0eSKevin Wolf                                     ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
769*33231e0eSKevin Wolf                 break;
770*33231e0eSKevin Wolf             }
771*33231e0eSKevin Wolf         }
772*33231e0eSKevin Wolf         break;
773*33231e0eSKevin Wolf     case GPCMD_REQUEST_SENSE:
774*33231e0eSKevin Wolf         max_len = packet[4];
775*33231e0eSKevin Wolf         memset(buf, 0, 18);
776*33231e0eSKevin Wolf         buf[0] = 0x70 | (1 << 7);
777*33231e0eSKevin Wolf         buf[2] = s->sense_key;
778*33231e0eSKevin Wolf         buf[7] = 10;
779*33231e0eSKevin Wolf         buf[12] = s->asc;
780*33231e0eSKevin Wolf         if (s->sense_key == SENSE_UNIT_ATTENTION)
781*33231e0eSKevin Wolf             s->sense_key = SENSE_NONE;
782*33231e0eSKevin Wolf         ide_atapi_cmd_reply(s, 18, max_len);
783*33231e0eSKevin Wolf         break;
784*33231e0eSKevin Wolf     case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
785*33231e0eSKevin Wolf         bdrv_set_locked(s->bs, packet[4] & 1);
786*33231e0eSKevin Wolf         ide_atapi_cmd_ok(s);
787*33231e0eSKevin Wolf         break;
788*33231e0eSKevin Wolf     case GPCMD_READ_10:
789*33231e0eSKevin Wolf     case GPCMD_READ_12:
790*33231e0eSKevin Wolf         {
791*33231e0eSKevin Wolf             int nb_sectors, lba;
792*33231e0eSKevin Wolf 
793*33231e0eSKevin Wolf             if (packet[0] == GPCMD_READ_10)
794*33231e0eSKevin Wolf                 nb_sectors = ube16_to_cpu(packet + 7);
795*33231e0eSKevin Wolf             else
796*33231e0eSKevin Wolf                 nb_sectors = ube32_to_cpu(packet + 6);
797*33231e0eSKevin Wolf             lba = ube32_to_cpu(packet + 2);
798*33231e0eSKevin Wolf             if (nb_sectors == 0) {
799*33231e0eSKevin Wolf                 ide_atapi_cmd_ok(s);
800*33231e0eSKevin Wolf                 break;
801*33231e0eSKevin Wolf             }
802*33231e0eSKevin Wolf             ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
803*33231e0eSKevin Wolf         }
804*33231e0eSKevin Wolf         break;
805*33231e0eSKevin Wolf     case GPCMD_READ_CD:
806*33231e0eSKevin Wolf         {
807*33231e0eSKevin Wolf             int nb_sectors, lba, transfer_request;
808*33231e0eSKevin Wolf 
809*33231e0eSKevin Wolf             nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
810*33231e0eSKevin Wolf             lba = ube32_to_cpu(packet + 2);
811*33231e0eSKevin Wolf             if (nb_sectors == 0) {
812*33231e0eSKevin Wolf                 ide_atapi_cmd_ok(s);
813*33231e0eSKevin Wolf                 break;
814*33231e0eSKevin Wolf             }
815*33231e0eSKevin Wolf             transfer_request = packet[9];
816*33231e0eSKevin Wolf             switch(transfer_request & 0xf8) {
817*33231e0eSKevin Wolf             case 0x00:
818*33231e0eSKevin Wolf                 /* nothing */
819*33231e0eSKevin Wolf                 ide_atapi_cmd_ok(s);
820*33231e0eSKevin Wolf                 break;
821*33231e0eSKevin Wolf             case 0x10:
822*33231e0eSKevin Wolf                 /* normal read */
823*33231e0eSKevin Wolf                 ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
824*33231e0eSKevin Wolf                 break;
825*33231e0eSKevin Wolf             case 0xf8:
826*33231e0eSKevin Wolf                 /* read all data */
827*33231e0eSKevin Wolf                 ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
828*33231e0eSKevin Wolf                 break;
829*33231e0eSKevin Wolf             default:
830*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
831*33231e0eSKevin Wolf                                     ASC_INV_FIELD_IN_CMD_PACKET);
832*33231e0eSKevin Wolf                 break;
833*33231e0eSKevin Wolf             }
834*33231e0eSKevin Wolf         }
835*33231e0eSKevin Wolf         break;
836*33231e0eSKevin Wolf     case GPCMD_SEEK:
837*33231e0eSKevin Wolf         {
838*33231e0eSKevin Wolf             unsigned int lba;
839*33231e0eSKevin Wolf             uint64_t total_sectors;
840*33231e0eSKevin Wolf 
841*33231e0eSKevin Wolf             bdrv_get_geometry(s->bs, &total_sectors);
842*33231e0eSKevin Wolf             total_sectors >>= 2;
843*33231e0eSKevin Wolf             if (total_sectors == 0) {
844*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, SENSE_NOT_READY,
845*33231e0eSKevin Wolf                                     ASC_MEDIUM_NOT_PRESENT);
846*33231e0eSKevin Wolf                 break;
847*33231e0eSKevin Wolf             }
848*33231e0eSKevin Wolf             lba = ube32_to_cpu(packet + 2);
849*33231e0eSKevin Wolf             if (lba >= total_sectors) {
850*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
851*33231e0eSKevin Wolf                                     ASC_LOGICAL_BLOCK_OOR);
852*33231e0eSKevin Wolf                 break;
853*33231e0eSKevin Wolf             }
854*33231e0eSKevin Wolf             ide_atapi_cmd_ok(s);
855*33231e0eSKevin Wolf         }
856*33231e0eSKevin Wolf         break;
857*33231e0eSKevin Wolf     case GPCMD_START_STOP_UNIT:
858*33231e0eSKevin Wolf         {
859*33231e0eSKevin Wolf             int start, eject, sense, err = 0;
860*33231e0eSKevin Wolf             start = packet[4] & 1;
861*33231e0eSKevin Wolf             eject = (packet[4] >> 1) & 1;
862*33231e0eSKevin Wolf 
863*33231e0eSKevin Wolf             if (eject) {
864*33231e0eSKevin Wolf                 err = bdrv_eject(s->bs, !start);
865*33231e0eSKevin Wolf             }
866*33231e0eSKevin Wolf 
867*33231e0eSKevin Wolf             switch (err) {
868*33231e0eSKevin Wolf             case 0:
869*33231e0eSKevin Wolf                 ide_atapi_cmd_ok(s);
870*33231e0eSKevin Wolf                 break;
871*33231e0eSKevin Wolf             case -EBUSY:
872*33231e0eSKevin Wolf                 sense = SENSE_NOT_READY;
873*33231e0eSKevin Wolf                 if (bdrv_is_inserted(s->bs)) {
874*33231e0eSKevin Wolf                     sense = SENSE_ILLEGAL_REQUEST;
875*33231e0eSKevin Wolf                 }
876*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, sense,
877*33231e0eSKevin Wolf                                     ASC_MEDIA_REMOVAL_PREVENTED);
878*33231e0eSKevin Wolf                 break;
879*33231e0eSKevin Wolf             default:
880*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, SENSE_NOT_READY,
881*33231e0eSKevin Wolf                                     ASC_MEDIUM_NOT_PRESENT);
882*33231e0eSKevin Wolf                 break;
883*33231e0eSKevin Wolf             }
884*33231e0eSKevin Wolf         }
885*33231e0eSKevin Wolf         break;
886*33231e0eSKevin Wolf     case GPCMD_MECHANISM_STATUS:
887*33231e0eSKevin Wolf         {
888*33231e0eSKevin Wolf             max_len = ube16_to_cpu(packet + 8);
889*33231e0eSKevin Wolf             cpu_to_ube16(buf, 0);
890*33231e0eSKevin Wolf             /* no current LBA */
891*33231e0eSKevin Wolf             buf[2] = 0;
892*33231e0eSKevin Wolf             buf[3] = 0;
893*33231e0eSKevin Wolf             buf[4] = 0;
894*33231e0eSKevin Wolf             buf[5] = 1;
895*33231e0eSKevin Wolf             cpu_to_ube16(buf + 6, 0);
896*33231e0eSKevin Wolf             ide_atapi_cmd_reply(s, 8, max_len);
897*33231e0eSKevin Wolf         }
898*33231e0eSKevin Wolf         break;
899*33231e0eSKevin Wolf     case GPCMD_READ_TOC_PMA_ATIP:
900*33231e0eSKevin Wolf         {
901*33231e0eSKevin Wolf             int format, msf, start_track, len;
902*33231e0eSKevin Wolf             uint64_t total_sectors;
903*33231e0eSKevin Wolf 
904*33231e0eSKevin Wolf             bdrv_get_geometry(s->bs, &total_sectors);
905*33231e0eSKevin Wolf             total_sectors >>= 2;
906*33231e0eSKevin Wolf             if (total_sectors == 0) {
907*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, SENSE_NOT_READY,
908*33231e0eSKevin Wolf                                     ASC_MEDIUM_NOT_PRESENT);
909*33231e0eSKevin Wolf                 break;
910*33231e0eSKevin Wolf             }
911*33231e0eSKevin Wolf             max_len = ube16_to_cpu(packet + 7);
912*33231e0eSKevin Wolf             format = packet[9] >> 6;
913*33231e0eSKevin Wolf             msf = (packet[1] >> 1) & 1;
914*33231e0eSKevin Wolf             start_track = packet[6];
915*33231e0eSKevin Wolf             switch(format) {
916*33231e0eSKevin Wolf             case 0:
917*33231e0eSKevin Wolf                 len = cdrom_read_toc(total_sectors, buf, msf, start_track);
918*33231e0eSKevin Wolf                 if (len < 0)
919*33231e0eSKevin Wolf                     goto error_cmd;
920*33231e0eSKevin Wolf                 ide_atapi_cmd_reply(s, len, max_len);
921*33231e0eSKevin Wolf                 break;
922*33231e0eSKevin Wolf             case 1:
923*33231e0eSKevin Wolf                 /* multi session : only a single session defined */
924*33231e0eSKevin Wolf                 memset(buf, 0, 12);
925*33231e0eSKevin Wolf                 buf[1] = 0x0a;
926*33231e0eSKevin Wolf                 buf[2] = 0x01;
927*33231e0eSKevin Wolf                 buf[3] = 0x01;
928*33231e0eSKevin Wolf                 ide_atapi_cmd_reply(s, 12, max_len);
929*33231e0eSKevin Wolf                 break;
930*33231e0eSKevin Wolf             case 2:
931*33231e0eSKevin Wolf                 len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
932*33231e0eSKevin Wolf                 if (len < 0)
933*33231e0eSKevin Wolf                     goto error_cmd;
934*33231e0eSKevin Wolf                 ide_atapi_cmd_reply(s, len, max_len);
935*33231e0eSKevin Wolf                 break;
936*33231e0eSKevin Wolf             default:
937*33231e0eSKevin Wolf             error_cmd:
938*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
939*33231e0eSKevin Wolf                                     ASC_INV_FIELD_IN_CMD_PACKET);
940*33231e0eSKevin Wolf                 break;
941*33231e0eSKevin Wolf             }
942*33231e0eSKevin Wolf         }
943*33231e0eSKevin Wolf         break;
944*33231e0eSKevin Wolf     case GPCMD_READ_CDVD_CAPACITY:
945*33231e0eSKevin Wolf         {
946*33231e0eSKevin Wolf             uint64_t total_sectors;
947*33231e0eSKevin Wolf 
948*33231e0eSKevin Wolf             bdrv_get_geometry(s->bs, &total_sectors);
949*33231e0eSKevin Wolf             total_sectors >>= 2;
950*33231e0eSKevin Wolf             if (total_sectors == 0) {
951*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, SENSE_NOT_READY,
952*33231e0eSKevin Wolf                                     ASC_MEDIUM_NOT_PRESENT);
953*33231e0eSKevin Wolf                 break;
954*33231e0eSKevin Wolf             }
955*33231e0eSKevin Wolf             /* NOTE: it is really the number of sectors minus 1 */
956*33231e0eSKevin Wolf             cpu_to_ube32(buf, total_sectors - 1);
957*33231e0eSKevin Wolf             cpu_to_ube32(buf + 4, 2048);
958*33231e0eSKevin Wolf             ide_atapi_cmd_reply(s, 8, 8);
959*33231e0eSKevin Wolf         }
960*33231e0eSKevin Wolf         break;
961*33231e0eSKevin Wolf     case GPCMD_READ_DVD_STRUCTURE:
962*33231e0eSKevin Wolf         {
963*33231e0eSKevin Wolf             int media = packet[1];
964*33231e0eSKevin Wolf             int format = packet[7];
965*33231e0eSKevin Wolf             int ret;
966*33231e0eSKevin Wolf 
967*33231e0eSKevin Wolf             max_len = ube16_to_cpu(packet + 8);
968*33231e0eSKevin Wolf 
969*33231e0eSKevin Wolf             if (format < 0xff) {
970*33231e0eSKevin Wolf                 if (media_is_cd(s)) {
971*33231e0eSKevin Wolf                     ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
972*33231e0eSKevin Wolf                                         ASC_INCOMPATIBLE_FORMAT);
973*33231e0eSKevin Wolf                     break;
974*33231e0eSKevin Wolf                 } else if (!media_present(s)) {
975*33231e0eSKevin Wolf                     ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
976*33231e0eSKevin Wolf                                         ASC_INV_FIELD_IN_CMD_PACKET);
977*33231e0eSKevin Wolf                     break;
978*33231e0eSKevin Wolf                 }
979*33231e0eSKevin Wolf             }
980*33231e0eSKevin Wolf 
981*33231e0eSKevin Wolf             memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
982*33231e0eSKevin Wolf                    IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
983*33231e0eSKevin Wolf 
984*33231e0eSKevin Wolf             switch (format) {
985*33231e0eSKevin Wolf                 case 0x00 ... 0x7f:
986*33231e0eSKevin Wolf                 case 0xff:
987*33231e0eSKevin Wolf                     if (media == 0) {
988*33231e0eSKevin Wolf                         ret = ide_dvd_read_structure(s, format, packet, buf);
989*33231e0eSKevin Wolf 
990*33231e0eSKevin Wolf                         if (ret < 0)
991*33231e0eSKevin Wolf                             ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
992*33231e0eSKevin Wolf                         else
993*33231e0eSKevin Wolf                             ide_atapi_cmd_reply(s, ret, max_len);
994*33231e0eSKevin Wolf 
995*33231e0eSKevin Wolf                         break;
996*33231e0eSKevin Wolf                     }
997*33231e0eSKevin Wolf                     /* TODO: BD support, fall through for now */
998*33231e0eSKevin Wolf 
999*33231e0eSKevin Wolf                 /* Generic disk structures */
1000*33231e0eSKevin Wolf                 case 0x80: /* TODO: AACS volume identifier */
1001*33231e0eSKevin Wolf                 case 0x81: /* TODO: AACS media serial number */
1002*33231e0eSKevin Wolf                 case 0x82: /* TODO: AACS media identifier */
1003*33231e0eSKevin Wolf                 case 0x83: /* TODO: AACS media key block */
1004*33231e0eSKevin Wolf                 case 0x90: /* TODO: List of recognized format layers */
1005*33231e0eSKevin Wolf                 case 0xc0: /* TODO: Write protection status */
1006*33231e0eSKevin Wolf                 default:
1007*33231e0eSKevin Wolf                     ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1008*33231e0eSKevin Wolf                                         ASC_INV_FIELD_IN_CMD_PACKET);
1009*33231e0eSKevin Wolf                     break;
1010*33231e0eSKevin Wolf             }
1011*33231e0eSKevin Wolf         }
1012*33231e0eSKevin Wolf         break;
1013*33231e0eSKevin Wolf     case GPCMD_SET_SPEED:
1014*33231e0eSKevin Wolf         ide_atapi_cmd_ok(s);
1015*33231e0eSKevin Wolf         break;
1016*33231e0eSKevin Wolf     case GPCMD_INQUIRY:
1017*33231e0eSKevin Wolf         max_len = packet[4];
1018*33231e0eSKevin Wolf         buf[0] = 0x05; /* CD-ROM */
1019*33231e0eSKevin Wolf         buf[1] = 0x80; /* removable */
1020*33231e0eSKevin Wolf         buf[2] = 0x00; /* ISO */
1021*33231e0eSKevin Wolf         buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1022*33231e0eSKevin Wolf         buf[4] = 31; /* additional length */
1023*33231e0eSKevin Wolf         buf[5] = 0; /* reserved */
1024*33231e0eSKevin Wolf         buf[6] = 0; /* reserved */
1025*33231e0eSKevin Wolf         buf[7] = 0; /* reserved */
1026*33231e0eSKevin Wolf         padstr8(buf + 8, 8, "QEMU");
1027*33231e0eSKevin Wolf         padstr8(buf + 16, 16, "QEMU DVD-ROM");
1028*33231e0eSKevin Wolf         padstr8(buf + 32, 4, s->version);
1029*33231e0eSKevin Wolf         ide_atapi_cmd_reply(s, 36, max_len);
1030*33231e0eSKevin Wolf         break;
1031*33231e0eSKevin Wolf     case GPCMD_GET_CONFIGURATION:
1032*33231e0eSKevin Wolf         {
1033*33231e0eSKevin Wolf             uint32_t len;
1034*33231e0eSKevin Wolf             uint8_t index = 0;
1035*33231e0eSKevin Wolf 
1036*33231e0eSKevin Wolf             /* only feature 0 is supported */
1037*33231e0eSKevin Wolf             if (packet[2] != 0 || packet[3] != 0) {
1038*33231e0eSKevin Wolf                 ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1039*33231e0eSKevin Wolf                                     ASC_INV_FIELD_IN_CMD_PACKET);
1040*33231e0eSKevin Wolf                 break;
1041*33231e0eSKevin Wolf             }
1042*33231e0eSKevin Wolf 
1043*33231e0eSKevin Wolf             /* XXX: could result in alignment problems in some architectures */
1044*33231e0eSKevin Wolf             max_len = ube16_to_cpu(packet + 7);
1045*33231e0eSKevin Wolf 
1046*33231e0eSKevin Wolf             /*
1047*33231e0eSKevin Wolf              * XXX: avoid overflow for io_buffer if max_len is bigger than
1048*33231e0eSKevin Wolf              *      the size of that buffer (dimensioned to max number of
1049*33231e0eSKevin Wolf              *      sectors to transfer at once)
1050*33231e0eSKevin Wolf              *
1051*33231e0eSKevin Wolf              *      Only a problem if the feature/profiles grow.
1052*33231e0eSKevin Wolf              */
1053*33231e0eSKevin Wolf             if (max_len > 512) /* XXX: assume 1 sector */
1054*33231e0eSKevin Wolf                 max_len = 512;
1055*33231e0eSKevin Wolf 
1056*33231e0eSKevin Wolf             memset(buf, 0, max_len);
1057*33231e0eSKevin Wolf             /*
1058*33231e0eSKevin Wolf              * the number of sectors from the media tells us which profile
1059*33231e0eSKevin Wolf              * to use as current.  0 means there is no media
1060*33231e0eSKevin Wolf              */
1061*33231e0eSKevin Wolf             if (media_is_dvd(s))
1062*33231e0eSKevin Wolf                 cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
1063*33231e0eSKevin Wolf             else if (media_is_cd(s))
1064*33231e0eSKevin Wolf                 cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
1065*33231e0eSKevin Wolf 
1066*33231e0eSKevin Wolf             buf[10] = 0x02 | 0x01; /* persistent and current */
1067*33231e0eSKevin Wolf             len = 12; /* headers: 8 + 4 */
1068*33231e0eSKevin Wolf             len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
1069*33231e0eSKevin Wolf             len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
1070*33231e0eSKevin Wolf             cpu_to_ube32(buf, len - 4); /* data length */
1071*33231e0eSKevin Wolf 
1072*33231e0eSKevin Wolf             ide_atapi_cmd_reply(s, len, max_len);
1073*33231e0eSKevin Wolf             break;
1074*33231e0eSKevin Wolf         }
1075*33231e0eSKevin Wolf     case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
1076*33231e0eSKevin Wolf         handle_get_event_status_notification(s, buf, packet);
1077*33231e0eSKevin Wolf         break;
1078*33231e0eSKevin Wolf     default:
1079*33231e0eSKevin Wolf         ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1080*33231e0eSKevin Wolf                             ASC_ILLEGAL_OPCODE);
1081*33231e0eSKevin Wolf         break;
1082*33231e0eSKevin Wolf     }
1083*33231e0eSKevin Wolf }
1084