From owner-svn-src-all@freebsd.org Mon Feb 25 16:20:59 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2235B150EB22; Mon, 25 Feb 2019 16:20:59 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id BA6766D26B; Mon, 25 Feb 2019 16:20:58 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id AB9311F64D; Mon, 25 Feb 2019 16:20:58 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x1PGKwLY049711; Mon, 25 Feb 2019 16:20:58 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x1PGKwnP049710; Mon, 25 Feb 2019 16:20:58 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201902251620.x1PGKwnP049710@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Mon, 25 Feb 2019 16:20:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r344523 - head/sys/dev/flash X-SVN-Group: head X-SVN-Commit-Author: ian X-SVN-Commit-Paths: head/sys/dev/flash X-SVN-Commit-Revision: 344523 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: BA6766D26B X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.98 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.998,0]; NEURAL_HAM_SHORT(-0.98)[-0.985,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Feb 2019 16:20:59 -0000 Author: ian Date: Mon Feb 25 16:20:58 2019 New Revision: 344523 URL: https://svnweb.freebsd.org/changeset/base/344523 Log: Include the jedec "extended device information string" in the criteria used to match a chip to our table of metadata describing the chips. At least one new DataFlash chip has a 3-byte jedec ID identical to its predecessors and differs only in the extended info, and it has different metadata requiring a unique entry in the table. This paves the way for supporting such chips. The metadata table now includes two new fields, extmask and extid. The two bytes of extended info obtained from the chip are ANDed with extmask then compared to extid, so it's possible to use only a subset of the extended info in the matching. We now always read 6 bytes of jedec ID info. Most chips don't return any extended info, and the values read back for those two bytes may be indeterminate, but such chips have extmask and extid values of 0x0000 in the table, so the extid effectively doesn't participate in the matching on those chips and it doesn't matter what they return in the extended info bytes. Modified: head/sys/dev/flash/at45d.c Modified: head/sys/dev/flash/at45d.c ============================================================================== --- head/sys/dev/flash/at45d.c Mon Feb 25 15:51:31 2019 (r344522) +++ head/sys/dev/flash/at45d.c Mon Feb 25 16:20:58 2019 (r344523) @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -62,10 +63,22 @@ static struct ofw_compat_data compat_data[] = { SPIBUS_PNP_INFO(compat_data); #endif +/* This is the information returned by the MANUFACTURER_ID command. */ +struct at45d_mfg_info { + uint32_t jedec_id; /* Mfg ID, DevId1, DevId2, ExtLen */ + uint16_t ext_id; /* ExtId1, ExtId2 */ +}; + +/* + * This is an entry in our table of metadata describing the chips. We match on + * both jedec id and extended id info returned by the MANUFACTURER_ID command. + */ struct at45d_flash_ident { const char *name; uint32_t jedec; + uint16_t extid; + uint16_t extmask; uint16_t pagecount; uint16_t pageoffset; uint16_t pagesize; @@ -111,7 +124,7 @@ static void at45d_task(void *arg); /* helper routines */ static void at45d_delayed_attach(void *xsc); -static int at45d_get_mfg_info(device_t dev, uint8_t *resp); +static int at45d_get_mfg_info(device_t dev, struct at45d_mfg_info *resp); static int at45d_get_status(device_t dev, uint8_t *status); static int at45d_wait_ready(device_t dev, uint8_t *status); @@ -123,19 +136,28 @@ static int at45d_wait_ready(device_t dev, uint8_t *sta #define CONTINUOUS_ARRAY_READ 0xe8 /* + * Metadata for supported chips. + * + * The jedec id in this table includes the extended id length byte. A match is + * based on both jedec id and extended id matching. The chip's extended id (not + * present in most chips) is ANDed with ExtMask and the result is compared to + * ExtId. If a chip only returns 1 ext id byte it will be in the upper 8 bits + * of ExtId in this table. + * * A sectorsize2n != 0 is used to indicate that a device optionally supports * 2^N byte pages. If support for the latter is enabled, the sector offset * has to be reduced by one. */ static const struct at45d_flash_ident at45d_flash_devices[] = { - { "AT45DB011B", 0x1f2200, 512, 9, 264, 256 }, - { "AT45DB021B", 0x1f2300, 1024, 9, 264, 256 }, - { "AT45DB041x", 0x1f2400, 2028, 9, 264, 256 }, - { "AT45DB081B", 0x1f2500, 4096, 9, 264, 256 }, - { "AT45DB161x", 0x1f2600, 4096, 10, 528, 512 }, - { "AT45DB321x", 0x1f2700, 8192, 10, 528, 0 }, - { "AT45DB321x", 0x1f2701, 8192, 10, 528, 512 }, - { "AT45DB642x", 0x1f2800, 8192, 11, 1056, 1024 } + /* Part Name Jedec ID ExtId ExtMask PgCnt Offs PgSz PgSz2n */ + { "AT45DB011B", 0x1f220000, 0x0000, 0x0000, 512, 9, 264, 256 }, + { "AT45DB021B", 0x1f230000, 0x0000, 0x0000, 1024, 9, 264, 256 }, + { "AT45DB041x", 0x1f240000, 0x0000, 0x0000, 2028, 9, 264, 256 }, + { "AT45DB081B", 0x1f250000, 0x0000, 0x0000, 4096, 9, 264, 256 }, + { "AT45DB161x", 0x1f260000, 0x0000, 0x0000, 4096, 10, 528, 512 }, + { "AT45DB321x", 0x1f270000, 0x0000, 0x0000, 8192, 10, 528, 0 }, + { "AT45DB321x", 0x1f270100, 0x0000, 0x0000, 8192, 10, 528, 512 }, + { "AT45DB642x", 0x1f280000, 0x0000, 0x0000, 8192, 11, 1056, 1024 }, }; static int @@ -159,7 +181,7 @@ at45d_get_status(device_t dev, uint8_t *status) } static int -at45d_get_mfg_info(device_t dev, uint8_t *resp) +at45d_get_mfg_info(device_t dev, struct at45d_mfg_info *resp) { uint8_t rxBuf[8], txBuf[8]; struct spi_command cmd; @@ -172,11 +194,14 @@ at45d_get_mfg_info(device_t dev, uint8_t *resp) txBuf[0] = MANUFACTURER_ID; cmd.tx_cmd = &txBuf; cmd.rx_cmd = &rxBuf; - cmd.tx_cmd_sz = cmd.rx_cmd_sz = 5; + cmd.tx_cmd_sz = cmd.rx_cmd_sz = 7; err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); if (err) return (err); - memcpy(resp, rxBuf + 1, 4); + + resp->jedec_id = be32dec(rxBuf + 1); + resp->ext_id = be16dec(rxBuf + 5); + return (0); } @@ -268,11 +293,12 @@ static void at45d_delayed_attach(void *xsc) { struct at45d_softc *sc; + struct at45d_mfg_info mfginfo; const struct at45d_flash_ident *ident; u_int i; uint32_t jedec; uint16_t pagesize; - uint8_t buf[4], status; + uint8_t status; sc = xsc; ident = NULL; @@ -282,19 +308,18 @@ at45d_delayed_attach(void *xsc) device_printf(sc->dev, "Error waiting for device-ready.\n"); return; } - if (at45d_get_mfg_info(sc->dev, buf) != 0) { + if (at45d_get_mfg_info(sc->dev, &mfginfo) != 0) { device_printf(sc->dev, "Failed to get ID.\n"); return; } - - jedec = buf[0] << 16 | buf[1] << 8 | buf[2]; for (i = 0; i < nitems(at45d_flash_devices); i++) { - if (at45d_flash_devices[i].jedec == jedec) { - ident = &at45d_flash_devices[i]; + ident = &at45d_flash_devices[i]; + if (mfginfo.jedec_id == ident->jedec && + (mfginfo.ext_id & ident->extmask) == ident->extid) { break; } } - if (ident == NULL) { + if (i == nitems(at45d_flash_devices)) { device_printf(sc->dev, "JEDEC 0x%x not in list.\n", jedec); return; } @@ -322,8 +347,9 @@ at45d_delayed_attach(void *xsc) bioq_init(&sc->bio_queue); kproc_create(&at45d_task, sc, &sc->p, 0, 0, "task: at45d flash"); sc->taskstate = TSTATE_RUNNING; - device_printf(sc->dev, "%s, %d bytes per page, %d pages\n", - ident->name, pagesize, ident->pagecount); + device_printf(sc->dev, "%s, %d bytes per page, %d pages; %d KBytes\n", + ident->name, pagesize, ident->pagecount, + (pagesize * ident->pagecount) / 1024); } static int