From nobody Tue Oct 28 12:37:21 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515015364251263.33277202988586; Wed, 3 Jan 2018 13:36:04 -0800 (PST) Received: from localhost ([::1]:37699 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eWqhf-0002aB-9R for importer@patchew.org; Wed, 03 Jan 2018 16:36:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52973) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eWqYR-0003RU-P8 for qemu-devel@nongnu.org; Wed, 03 Jan 2018 16:26:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eWqYN-0000WE-HE for qemu-devel@nongnu.org; Wed, 03 Jan 2018 16:26:31 -0500 Received: from mail-qt0-x242.google.com ([2607:f8b0:400d:c0d::242]:41403) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eWqYN-0000Vt-BD for qemu-devel@nongnu.org; Wed, 03 Jan 2018 16:26:27 -0500 Received: by mail-qt0-x242.google.com with SMTP id i40so3793807qti.8 for ; Wed, 03 Jan 2018 13:26:27 -0800 (PST) Received: from x1.lan ([138.117.48.219]) by smtp.gmail.com with ESMTPSA id a19sm1104402qtj.74.2018.01.03.13.26.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 03 Jan 2018 13:26:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OoitqVI/q9QxUnPMXpubwNHQFDaln3aodDXjXb4G6iw=; b=SlYoV+sA+HkmReMbGgVJAVMMVM0TWzxxn4wAXJR2ck635zRqtR0OdvxpR19iNfvI+W NFCESCT5U/NniCUBGXbGHmXPyqW7juQcQJDgNDIRXKSnMviHA0ZbL40RPNC+KujXqIdy xPv9CL8vJCKBLXh+o1EQNiljiyjnXv1Z/D1lFVOAlI/MQXGbjKnx1KHNoi0SPo5tER8S TTwfyAnSJaxN6My8cBW0A6ky3ihcCiLjidpDQRtXNHoloNRCD5xskMca5oRcJT0DdKGs SiAk7v3r5447S4DKUy3gMnPoDu0s1xSirrhX8K1z3NB5udDrvWZPb2rmFDN9vcDw88gH GT8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=OoitqVI/q9QxUnPMXpubwNHQFDaln3aodDXjXb4G6iw=; b=fwYgeLnMMJgBh65wOE3KBN5vqci6tvGykYYOC65+eJmYHSxc71/4h6fr8xTikvt4E/ 4Ql3PzhOYY5SWsXojOtYsWAJc9aabIbkAJQYh9TTMFQmfkf8SrmN0vya7hj5aoXGuHvb O4j6rLUxBpT1U5ulmHxoaqUIvujdHht5wrq50oPAri8QXGXem+6QQvoEjJOEHV7XdY6k 6artdp6pt2XY6Eh+OV5lj50iMAADMjxytFxOFBWozleARHCdK3ydjNG0RD8GBIMuG6ja fNOMUaL6JscjwGL+6Wqf5Ji4lGbOgJDM1bRn/YGA5henmj9c5MrtCopB8BZTdycuhgT1 3gBg== X-Gm-Message-State: AKGB3mLn19XzXxB53/IG959HI3rulqVlO/Q7eWGYTjeq7kyoqXalGMgn u8rxsjlkgwTF3NaOiZwJ3DY= X-Google-Smtp-Source: ACJfBoslMPdusDHNhOqUXtFncPtTIr06Eq0H1U43ivgmpy7oRhdPvK0F0oKpO8/xlEZYsqLqaDnbOg== X-Received: by 10.200.8.56 with SMTP id u53mr3671691qth.85.1515014786699; Wed, 03 Jan 2018 13:26:26 -0800 (PST) From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: Alistair Francis , Peter Maydell , Igor Mitsyanko , Andrew Baumann , Olbrich , Andrzej Zaborowski Date: Wed, 3 Jan 2018 18:24:34 -0300 Message-Id: <20180103212436.15762-24-f4bug@amsat.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180103212436.15762-1-f4bug@amsat.org> References: <20180103212436.15762-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400d:c0d::242 Subject: [Qemu-devel] [RFC PATCH v2 23/25] sdcard: store the bus protocol in an enum X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Edgar E . Iglesias" , Prasad J Pandit , Peter Crosthwaite , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org, Paul Brook , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 One and only one protocol can be used at a time. We use a bitmask 'bus_protocol' simplify to check with one variable which protocols are supported (this will help when we start using the MMC mode). Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/sd/sd.h | 5 ++ include/hw/sd/sdcard_legacy.h | 2 +- hw/sd/sd.c | 141 ++++++++++++++++++++++++++++----------= ---- 3 files changed, 100 insertions(+), 48 deletions(-) diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index a342e7bc3e..6874696ff7 100644 --- a/include/hw/sd/sd.h +++ b/include/hw/sd/sd.h @@ -55,6 +55,11 @@ #define AKE_SEQ_ERROR (1 << 3) #define OCR_CCS_BITN 30 =20 +typedef enum { + PROTO_SD =3D 0, + PROTO_SPI =3D 1 << 1, +} sd_bus_protocol_t; + typedef enum { sd_none =3D -1, sd_bc =3D 0, /* broadcast -- no response */ diff --git a/include/hw/sd/sdcard_legacy.h b/include/hw/sd/sdcard_legacy.h index 882e13a8f1..08674797b5 100644 --- a/include/hw/sd/sdcard_legacy.h +++ b/include/hw/sd/sdcard_legacy.h @@ -32,7 +32,7 @@ #include "hw/sd/sd.h" =20 /* Legacy functions to be used only by non-qdevified callers */ -SDState *sd_init(BlockBackend *blk, bool is_spi); +SDState *sd_init(BlockBackend *blk, bool is_spi); /* deprecated */ int sd_do_command(SDState *card, SDRequest *request, uint8_t *response); void sd_write_data(SDState *card, uint8_t value); uint8_t sd_read_data(SDState *card); diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 16199cd886..d626445282 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -127,7 +127,7 @@ struct SDState { uint8_t function_group[6]; =20 int spec_version; - bool spi; + uint32_t bus_protocol; sd_card_capacity_t capacity; =20 uint32_t mode; /* current card mode, one of SDCardModes */ @@ -150,6 +150,18 @@ struct SDState { const char *proto_name; }; =20 +static const char *sd_protocol_name(sd_bus_protocol_t protocol) +{ + switch (protocol) { + case PROTO_SD: + return "SD"; + case PROTO_SPI: + return "SPI"; + default: + g_assert_not_reached(); + } +} + static const char *sd_state_name(enum SDCardStates state) { static const char *state_name[] =3D { @@ -365,7 +377,16 @@ static bool cmd_version_supported(SDState *sd, uint8_t= cmd, bool is_acmd) const sd_cmd_supported_t *cmdset =3D is_acmd ? acmd_supported : cmd_su= pported; uint16_t cmd_version; =20 - cmd_version =3D sd->spi ? cmdset[cmd].spi.version : cmdset[cmd].sd.ver= sion; + switch (sd->bus_protocol) { + case PROTO_SD: + cmd_version =3D cmdset[cmd].sd.version; + break; + case PROTO_SPI: + cmd_version =3D cmdset[cmd].spi.version; + break; + default: + g_assert_not_reached(); + } if (cmd_version) { return true; } @@ -381,9 +402,17 @@ static bool cmd_class_supported(SDState *sd, uint8_t c= md, uint8_t class, const sd_cmd_supported_t *cmdset =3D is_acmd ? acmd_supported : cmd_su= pported; uint32_t cmd_ccc_mask; =20 - cmd_ccc_mask =3D sd->spi ? cmdset[cmd].spi.ccc_mask : cmdset[cmd].sd.c= cc_mask; - - /* class 1, 3 and 9 are not supported in SPI mode */ + switch (sd->bus_protocol) { + case PROTO_SD: + cmd_ccc_mask =3D cmdset[cmd].sd.ccc_mask; + break; + case PROTO_SPI: + /* class 1, 3 and 9 are not supported in SPI mode */ + cmd_ccc_mask =3D cmdset[cmd].spi.ccc_mask; + break; + default: + g_assert_not_reached(); + } if (cmd_ccc_mask & BIT(class)) { return true; } @@ -603,7 +632,7 @@ static size_t sd_response_r1_make(SDState *sd, uint8_t = *response) /* Clear the "clear on read" status bits */ sd->card_status &=3D ~CARD_STATUS_C; =20 - if (sd->spi) { + if (sd->bus_protocol =3D=3D PROTO_SPI) { response[0] =3D 0xff; /* XXX */ return 1; } else { @@ -619,7 +648,7 @@ static size_t sd_response_r1b_make(SDState *sd, uint8_t= *response) { /* This response token is identical to the R1 format with the * optional addition of the busy signal. */ - if (sd->spi) { + if (sd->bus_protocol =3D=3D PROTO_SPI) { /* The busy signal token can be any number of bytes. A zero value * indicates card is busy. A non-zero value indicates the card is * ready for the next command. */ @@ -634,7 +663,7 @@ static size_t sd_response_r1b_make(SDState *sd, uint8_t= *response) =20 static size_t sd_response_r2s_make(SDState *sd, uint8_t *response) { - if (sd->spi) { + if (sd->bus_protocol =3D=3D PROTO_SPI) { /* TODO */ return 2; } else { @@ -647,7 +676,7 @@ static size_t sd_response_r3_make(SDState *sd, uint8_t = *response) { int ofs =3D 0; =20 - if (sd->spi) { + if (sd->bus_protocol =3D=3D PROTO_SPI) { ofs +=3D sd_response_r1_make(sd, response); } response[ofs++] =3D (sd->ocr >> 24) & 0xff; @@ -663,6 +692,7 @@ static void sd_response_r6_make(SDState *sd, uint8_t *r= esponse) uint16_t arg; uint16_t status; =20 + assert(sd->bus_protocol !=3D PROTO_SPI); arg =3D sd->rca; status =3D ((sd->card_status >> 8) & 0xc000) | ((sd->card_status >> 6) & 0x2000) | @@ -677,6 +707,7 @@ static void sd_response_r6_make(SDState *sd, uint8_t *r= esponse) =20 static void sd_response_r7_make(SDState *sd, uint8_t *response) { + assert(sd->bus_protocol !=3D PROTO_SPI); response[0] =3D (sd->vhs >> 24) & 0xff; response[1] =3D (sd->vhs >> 16) & 0xff; response[2] =3D (sd->vhs >> 8) & 0xff; @@ -844,7 +875,7 @@ static const VMStateDescription sd_vmstate =3D { }; =20 /* Legacy initialization function for use by non-qdevified callers */ -SDState *sd_init(BlockBackend *blk, bool is_spi) +static SDState *sdcard_init(BlockBackend *blk, sd_bus_protocol_t bus_proto= col) { Object *obj; DeviceState *dev; @@ -857,7 +888,13 @@ SDState *sd_init(BlockBackend *blk, bool is_spi) error_report("sd_init failed: %s", error_get_pretty(err)); return NULL; } - qdev_prop_set_bit(dev, "spi", is_spi); + switch (bus_protocol) { + case PROTO_SPI: + qdev_prop_set_bit(dev, "spi", true); + break; + default: + break; + } object_property_set_bool(obj, true, "realized", &err); if (err) { error_report("sd_init failed: %s", error_get_pretty(err)); @@ -867,6 +904,11 @@ SDState *sd_init(BlockBackend *blk, bool is_spi) return SD_CARD(dev); } =20 +SDState *sd_init(BlockBackend *blk, bool is_spi) +{ + return sdcard_init(blk, is_spi ? PROTO_SPI : PROTO_SD); +} + void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert) { sd->readonly_cb =3D readonly; @@ -1062,13 +1104,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,= SDRequest req) sd->state =3D sd_idle_state; sd_reset(DEVICE(sd)); } - return sd->spi ? sd_r1 : sd_r0; + return sd->bus_protocol =3D=3D PROTO_SPI ? sd_r1 : sd_r0; =20 case 1: /* CMD1: SEND_OP_CMD */ - if (!sd->spi) - goto bad_cmd; - sd->state =3D sd_transfer_state; - return sd_r1; + if (sd->bus_protocol =3D=3D PROTO_SPI) { + sd->state =3D sd_transfer_state; + return sd_r1; + } + goto bad_cmd; =20 case 2: /* CMD2: ALL_SEND_CID */ if (sd->state =3D=3D sd_ready_state) { @@ -1157,7 +1200,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, S= DRequest req) =20 /* No response if not exactly one VHS bit is set. */ if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1= ))) { - return sd->spi ? sd_r7 : sd_r0; + return sd->bus_protocol =3D=3D PROTO_SPI ? sd_r7 : sd_r0; = /* XXX */ } =20 /* Accept. */ @@ -1178,13 +1221,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,= SDRequest req) return sd_r2_s; =20 case sd_transfer_state: - if (!sd->spi) - break; - sd->state =3D sd_sendingdata_state; - memcpy(sd->data, sd->csd, 16); - sd->data_start =3D addr; - sd->data_offset =3D 0; - return sd_r1; + if (sd->bus_protocol =3D=3D PROTO_SPI) { + sd->state =3D sd_sendingdata_state; + memcpy(sd->data, sd->csd, 16); + sd->data_start =3D addr; + sd->data_offset =3D 0; + return sd_r1; + } =20 default: break; @@ -1200,13 +1243,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,= SDRequest req) return sd_r2_i; =20 case sd_transfer_state: - if (!sd->spi) - break; - sd->state =3D sd_sendingdata_state; - memcpy(sd->data, sd->cid, 16); - sd->data_start =3D addr; - sd->data_offset =3D 0; - return sd_r1; + if (sd->bus_protocol =3D=3D PROTO_SPI) { + sd->state =3D sd_sendingdata_state; + memcpy(sd->data, sd->cid, 16); + sd->data_start =3D addr; + sd->data_offset =3D 0; + return sd_r1; + } =20 default: break; @@ -1306,8 +1349,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, S= DRequest req) =20 /* Block write commands (Class 4) */ case 24: /* CMD24: WRITE_SINGLE_BLOCK */ - if (sd->spi) + if (sd->bus_protocol =3D=3D PROTO_SPI) { goto unimplemented_cmd; + } if (sd->state =3D=3D sd_transfer_state) { sd->state =3D sd_receivingdata_state; sd->data_start =3D addr; @@ -1325,8 +1369,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, S= DRequest req) break; =20 case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */ - if (sd->spi) + if (sd->bus_protocol =3D=3D PROTO_SPI) { goto unimplemented_cmd; + } if (sd->state =3D=3D sd_transfer_state) { sd->state =3D sd_receivingdata_state; sd->data_start =3D addr; @@ -1353,8 +1398,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, S= DRequest req) break; =20 case 27: /* CMD27: PROGRAM_CSD */ - if (sd->spi) + if (sd->bus_protocol =3D=3D PROTO_SPI) { goto unimplemented_cmd; + } if (sd->state =3D=3D sd_transfer_state) { sd->state =3D sd_receivingdata_state; sd->data_start =3D 0; @@ -1400,7 +1446,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, S= DRequest req) *(uint32_t *) sd->data =3D sd_wpbits(sd, req.arg); sd->data_start =3D addr; sd->data_offset =3D 0; - return sd->spi ? sd_r1 : sd_r1b; + return sd->bus_protocol =3D=3D PROTO_SPI ? sd_r1 : sd_r1b; } break; =20 @@ -1436,8 +1482,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, S= DRequest req) =20 /* Lock card commands (Class 7) */ case 42: /* CMD42: LOCK_UNLOCK */ - if (sd->spi) + if (sd->bus_protocol =3D=3D PROTO_SPI) { goto unimplemented_cmd; + } if (sd->state =3D=3D sd_transfer_state) { sd->state =3D sd_receivingdata_state; sd->data_start =3D 0; @@ -1457,7 +1504,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, S= DRequest req) =20 /* Application specific commands (Class 8) */ case 55: /* CMD55: APP_CMD */ - if (!sd->spi) { + if (sd->bus_protocol !=3D PROTO_SPI) { if (sd->rca !=3D rca) { return sd_r0; } @@ -1478,13 +1525,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,= SDRequest req) break; =20 case 58: /* CMD58: READ_OCR (SPI) */ - if (!sd->spi) { + if (sd->bus_protocol !=3D PROTO_SPI) { goto bad_cmd; } return sd_r3; =20 case 59: /* CMD59: CRC_ON_OFF (SPI) */ - if (!sd->spi) { + if (sd->bus_protocol !=3D PROTO_SPI) { goto bad_cmd; } goto unimplemented_cmd; @@ -1524,12 +1571,12 @@ static sd_rsp_type_t sd_app_command(SDState *sd, SD= Request req) sd->state =3D sd_sendingdata_state; sd->data_start =3D 0; sd->data_offset =3D 0; - return sd->spi ? sd_r2_s : sd_r1; + return sd->bus_protocol =3D=3D PROTO_SPI ? sd_r2_s : sd_r1; } break; =20 case 18: - if (sd->spi) { + if (sd->bus_protocol =3D=3D PROTO_SPI) { goto unimplemented_cmd; } break; @@ -1553,19 +1600,19 @@ static sd_rsp_type_t sd_app_command(SDState *sd, SD= Request req) =20 case 25: case 26: - if (sd->spi) { + if (sd->bus_protocol =3D=3D PROTO_SPI) { goto unimplemented_cmd; } break; =20 case 38: - if (sd->spi) { + if (sd->bus_protocol =3D=3D PROTO_SPI) { goto unimplemented_cmd; } break; =20 case 41: /* ACMD41: SD_APP_OP_COND */ - if (sd->spi) { + if (sd->bus_protocol =3D=3D PROTO_SPI) { /* SEND_OP_CMD */ sd->state =3D sd_transfer_state; return sd_r1; @@ -1611,7 +1658,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd, SDRe= quest req) break; =20 case 43 ... 49: - if (sd->spi) { + if (sd->bus_protocol =3D=3D PROTO_SPI) { goto unimplemented_cmd; } break; @@ -2100,7 +2147,7 @@ static void sd_realize(DeviceState *dev, Error **errp) SDState *sd =3D SD_CARD(dev); int ret; =20 - sd->proto_name =3D sd->spi ? "SPI" : "SD"; + sd->proto_name =3D sd_protocol_name(sd->bus_protocol); sd->spec_version =3D SD_PHY_SPEC_VER_2_00; =20 if (sd->blk && blk_is_read_only(sd->blk)) { @@ -2146,7 +2193,7 @@ static Property sd_properties[] =3D { * whether card should be in SSI or MMC/SD mode. It is also up to the * board to ensure that ssi transfers only occur when the chip select * is asserted. */ - DEFINE_PROP_BOOL("spi", SDState, spi, false), + DEFINE_PROP_BIT("spi", SDState, bus_protocol, 1, false), DEFINE_PROP_END_OF_LIST() }; =20 --=20 2.15.1