From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Cc: Alexander Graf <agraf@suse.de>
Subject: Re: [Qemu-devel] [PATCH] ide: fix ATAPI read drive structure command (v3)
Date: Tue, 03 Jun 2008 11:59:24 -0500 [thread overview]
Message-ID: <4845786C.5090908@codemonkey.ws> (raw)
In-Reply-To: <1212446737.13411.15.camel@lappy>
Can you send this as an attachment or inlined as plain text?
Regards,
Anthony Liguori
Alex Williamson wrote:
> This patch just updates the previous to apply cleanly since the get
> configuration change went in. Thanks,
>
> Alex
>
> On Mon, 2008-06-02 at 16:12 -0600, Alex Williamson wrote:
>
>> Hi Alex,
>>
>> I think I've incorporated all your comments. I tested with sg_raw; the
>> embedded size value is constant regardless of the allocation length in
>> the command. I added extra parameters to ide_dvd_read_structure() but I
>> still had to pass the IDEState pointer for things like the sector count,
>> and maybe others in the future as more command options are added. I
>> implemented the 0xff command based on what I saw using sg_raw on real
>> hardware. I'll note that it seems to be device dependent whether this
>> command works when the drive is empty or contains CD media.
>>
>> Hopefully we're getting close, let me know if you have further comments.
>> Thanks,
>>
>> Alex
>>
>>
>
> Fix ATAPI read drive structure command
>
> Previous version ignored the allocation length parameter and read the
> format byte from the wrong location. Re-implement to support the full
> requirements for DVD-ROM and allow for easy extension later.
>
> Signed-off-by: Alex Williamson <alex.williamson@hp.com>
> --
>
> --- a/trunk/hw/ide.c 2008-06-02 16:37:12.000000000 -0600
> +++ b/trunk/hw/ide.c 2008-06-02 16:40:11.000000000 -0600
> @@ -351,6 +351,7 @@
> #define ASC_ILLEGAL_OPCODE 0x20
> #define ASC_LOGICAL_BLOCK_OOR 0x21
> #define ASC_INV_FIELD_IN_CMD_PACKET 0x24
> +#define ASC_INCOMPATIBLE_FORMAT 0x30
> #define ASC_MEDIUM_NOT_PRESENT 0x3a
> #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
>
> @@ -434,6 +435,22 @@
> int media_changed;
> } IDEState;
>
> +/* XXX: DVDs that could fit on a CD will be reported as a CD */
> +static inline int media_present(IDEState *s)
> +{
> + return (s->nb_sectors > 0);
> +}
> +
> +static inline int media_is_dvd(IDEState *s)
> +{
> + return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS);
> +}
> +
> +static inline int media_is_cd(IDEState *s)
> +{
> + return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS);
> +}
> +
> #define BM_STATUS_DMAING 0x01
> #define BM_STATUS_ERROR 0x02
> #define BM_STATUS_INT 0x04
> @@ -1364,6 +1381,93 @@
> return 4;
> }
>
> +static int ide_dvd_read_structure(IDEState *s, int format,
> + const uint8_t *packet, uint8_t *buf)
> +{
> + switch (format) {
> + case 0x0: /* Physical format information */
> + {
> + int layer = packet[6];
> + uint64_t total_sectors;
> +
> + if (layer != 0)
> + return -ASC_INV_FIELD_IN_CMD_PACKET;
> +
> + bdrv_get_geometry(s->bs, &total_sectors);
> + total_sectors >>= 2;
> + if (total_sectors == 0)
> + return -ASC_MEDIUM_NOT_PRESENT;
> +
> + buf[4] = 1; /* DVD-ROM, part version 1 */
> + buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
> + buf[6] = 1; /* one layer, read-only (per MMC-2 spec) */
> + buf[7] = 0; /* default densities */
> +
> + /* FIXME: 0x30000 per spec? */
> + cpu_to_ube32(buf + 8, 0); /* start sector */
> + cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */
> + cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */
> +
> + /* Size of buffer, not including 2 byte size field */
> + cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
> +
> + /* 2k data + 4 byte header */
> + return (2048 + 4);
> + }
> +
> + case 0x01: /* DVD copyright information */
> + buf[4] = 0; /* no copyright data */
> + buf[5] = 0; /* no region restrictions */
> +
> + /* Size of buffer, not including 2 byte size field */
> + cpu_to_be16wu((uint16_t *)buf, 4 + 2);
> +
> + /* 4 byte header + 4 byte data */
> + return (4 + 4);
> +
> + case 0x03: /* BCA information - invalid field for no BCA info */
> + return -ASC_INV_FIELD_IN_CMD_PACKET;
> +
> + case 0x04: /* DVD disc manufacturing information */
> + /* Size of buffer, not including 2 byte size field */
> + cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
> +
> + /* 2k data + 4 byte header */
> + return (2048 + 4);
> +
> + case 0xff:
> + /*
> + * This lists all the command capabilities above. Add new ones
> + * in order and update the length and buffer return values.
> + */
> +
> + buf[4] = 0x00; /* Physical format */
> + buf[5] = 0x40; /* Not writable, is readable */
> + cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4);
> +
> + buf[8] = 0x01; /* Copyright info */
> + buf[9] = 0x40; /* Not writable, is readable */
> + cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4);
> +
> + buf[12] = 0x03; /* BCA info */
> + buf[13] = 0x40; /* Not writable, is readable */
> + cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4);
> +
> + buf[16] = 0x04; /* Manufacturing info */
> + buf[17] = 0x40; /* Not writable, is readable */
> + cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4);
> +
> + /* Size of buffer, not including 2 byte size field */
> + cpu_to_be16wu((uint16_t *)buf, 16 + 2);
> +
> + /* data written + 4 byte header */
> + return (16 + 4);
> +
> + default: /* TODO: formats beyond DVD-ROM requires */
> + return -ASC_INV_FIELD_IN_CMD_PACKET;
> + }
> +}
> +
> static void ide_atapi_cmd(IDEState *s)
> {
> const uint8_t *packet;
> @@ -1651,42 +1755,42 @@
> case GPCMD_READ_DVD_STRUCTURE:
> {
> int media = packet[1];
> - int layer = packet[6];
> - int format = packet[2];
> - uint64_t total_sectors;
> + int format = packet[7];
> + int ret;
>
> - if (media != 0 || layer != 0)
> - {
> + max_len = ube16_to_cpu(packet + 8);
> +
> + if (format < 0xff && media_is_cd(s)) {
> ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
> - ASC_INV_FIELD_IN_CMD_PACKET);
> + ASC_INCOMPATIBLE_FORMAT);
> + break;
> }
>
> + memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
> + IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
> +
> switch (format) {
> - case 0:
> - bdrv_get_geometry(s->bs, &total_sectors);
> - total_sectors >>= 2;
> - if (total_sectors == 0) {
> - ide_atapi_cmd_error(s, SENSE_NOT_READY,
> - ASC_MEDIUM_NOT_PRESENT);
> + case 0x00 ... 0x7f:
> + case 0xff:
> + if (media == 0) {
> + ret = ide_dvd_read_structure(s, format, packet, buf);
> +
> + if (ret < 0)
> + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
> + else
> + ide_atapi_cmd_reply(s, ret, max_len);
> +
> break;
> }
> + /* TODO: BD support, fall through for now */
>
> - memset(buf, 0, 2052);
> -
> - buf[4] = 1; // DVD-ROM, part version 1
> - buf[5] = 0xf; // 120mm disc, maximum rate unspecified
> - buf[6] = 0; // one layer, embossed data
> - buf[7] = 0;
> -
> - cpu_to_ube32(buf + 8, 0);
> - cpu_to_ube32(buf + 12, total_sectors - 1);
> - cpu_to_ube32(buf + 16, total_sectors - 1);
> -
> - cpu_to_be16wu((uint16_t *)buf, 2048 + 4);
> -
> - ide_atapi_cmd_reply(s, 2048 + 3, 2048 + 4);
> - break;
> -
> + /* Generic disk structures */
> + case 0x80: /* TODO: AACS volume identifier */
> + case 0x81: /* TODO: AACS media serial number */
> + case 0x82: /* TODO: AACS media identifier */
> + case 0x83: /* TODO: AACS media key block */
> + case 0x90: /* TODO: List of recognized format layers */
> + case 0xc0: /* TODO: Write protection status */
> default:
> ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
> ASC_INV_FIELD_IN_CMD_PACKET);
> @@ -1741,16 +1845,11 @@
> /*
> * the number of sectors from the media tells us which profile
> * to use as current. 0 means there is no media
> - *
> - * XXX: fails to detect correctly DVDs with less data burned
> - * than what a CD can hold
> */
> - if (s -> nb_sectors) {
> - if (s -> nb_sectors > CD_MAX_SECTORS)
> - cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
> - else
> - cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
> - }
> + if (media_is_dvd(s))
> + cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
> + else if (media_is_cd(s))
> + cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
>
> buf[10] = 0x02 | 0x01; /* persistent and current */
> len = 12; /* headers: 8 + 4 */
>
>
>
>
>
next prev parent reply other threads:[~2008-06-03 16:59 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-27 5:25 [Qemu-devel] [PATCH] ide: fix ATAPI read drive structure command Alex Williamson
2008-05-27 7:46 ` Alexander Graf
2008-05-28 19:48 ` Alex Williamson
2008-06-02 10:33 ` Alexander Graf
2008-06-02 14:58 ` Alex Williamson
2008-06-02 15:42 ` Alexander Graf
2008-06-02 22:12 ` [Qemu-devel] [PATCH] ide: fix ATAPI read drive structure command (v3) Alex Williamson
2008-06-02 22:45 ` Alex Williamson
2008-06-03 13:48 ` Alexander Graf
2008-06-03 14:21 ` Alex Williamson
2008-06-03 18:01 ` Carlo Marcelo Arenas Belon
2008-06-03 16:59 ` Anthony Liguori [this message]
2008-06-04 12:30 ` Alex Williamson
2008-06-04 14:35 ` Anthony Liguori
2008-06-04 14:49 ` Alex Williamson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4845786C.5090908@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=agraf@suse.de \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).