svn commit: r344734 - in head: share/man/man4 sys/dev/flash

Ian Lepore ian at FreeBSD.org
Sat Mar 2 23:20:48 UTC 2019


Author: ian
Date: Sat Mar  2 23:20:47 2019
New Revision: 344734
URL: https://svnweb.freebsd.org/changeset/base/344734

Log:
  Allow the sector size of the disk device to be configured using hints or
  FDT data.  The sector size must be a multiple of the device's page size.
  If not configured, use the historical default of the device page size.
  
  Setting the disk sector size to 512 or 4096 allows a variety of standard
  filesystems to be used on the device.  Of course you wouldn't want to be
  writing frequently to a SPI flash chip like it was a disk drive, but for
  data that gets written once (or rarely) and read often, using a standard
  filesystem is a nice convenient thing.

Modified:
  head/share/man/man4/at45d.4
  head/sys/dev/flash/at45d.c

Modified: head/share/man/man4/at45d.4
==============================================================================
--- head/share/man/man4/at45d.4	Sat Mar  2 22:28:43 2019	(r344733)
+++ head/share/man/man4/at45d.4	Sat Mar  2 23:20:47 2019	(r344734)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 26, 2019
+.Dd March 2, 2019
 .Dt AT45D 4
 .Os
 .Sh NAME
@@ -126,6 +126,10 @@ The following properties are optional for the
 .Nm
 device subnode:
 .Bl -tag -width indent
+.It Va freebsd,sectorsize
+The sector size of the disk created for this storage device.
+It must be a multiple of the device's page size.
+The default is the device page size.
 .It Va spi-cpha
 Empty property indicating the slave device requires shifted clock
 phase (CPHA) mode.
@@ -156,6 +160,10 @@ The chip-select number to assert when performing I/O f
 Set the high bit (1 << 31) to invert the logic level of the chip select line.
 .It Va hint.at45d.%d.mode
 The SPI mode (0-3) to use when communicating with this device.
+.It Va hint.at45d.%d.sectorsize
+The sector size of the disk created for this storage device.
+It must be a multiple of the device's page size.
+The default is the device page size.
 .El
 .Sh FILES
 .Bl -tag -width /dev/flash/at45d?

Modified: head/sys/dev/flash/at45d.c
==============================================================================
--- head/sys/dev/flash/at45d.c	Sat Mar  2 22:28:43 2019	(r344733)
+++ head/sys/dev/flash/at45d.c	Sat Mar  2 23:20:47 2019	(r344734)
@@ -288,9 +288,11 @@ at45d_detach(device_t dev)
 	AT45D_UNLOCK(sc);
 
 	if (err == 0 && sc->taskstate == TSTATE_STOPPED) {
-		disk_destroy(sc->disk);
-		bioq_flush(&sc->bio_queue, NULL, ENXIO);
-		free(sc->dummybuf, M_DEVBUF);
+		if (sc->disk) {
+			disk_destroy(sc->disk);
+			bioq_flush(&sc->bio_queue, NULL, ENXIO);
+			free(sc->dummybuf, M_DEVBUF);
+		}
 		AT45D_LOCK_DESTROY(sc);
 	}
 	return (err);
@@ -303,6 +305,7 @@ at45d_delayed_attach(void *xsc)
 	struct at45d_mfg_info mfginfo;
 	const struct at45d_flash_ident *ident;
 	u_int i;
+	int sectorsize;
 	uint32_t jedec;
 	uint16_t pagesize;
 	uint8_t status;
@@ -340,6 +343,30 @@ at45d_delayed_attach(void *xsc)
 		pagesize = ident->pagesize;
 	sc->pagesize = pagesize;
 
+	/*
+	 * By default we set up a disk with a sector size that matches the
+	 * device page size.  If there is a device hint or fdt property
+	 * requesting a different size, use that, as long as it is a multiple of
+	 * the device page size).
+	 */
+	sectorsize = pagesize;
+#ifdef FDT
+	{
+		pcell_t size;
+		if (OF_getencprop(ofw_bus_get_node(sc->dev),
+		    "freebsd,sectorsize", &size, sizeof(size)) > 0)
+			sectorsize = size;
+	}
+#endif
+	resource_int_value(device_get_name(sc->dev), device_get_unit(sc->dev),
+	    "sectorsize", &sectorsize);
+
+	if ((sectorsize % pagesize) != 0) {
+		device_printf(sc->dev, "Invalid sectorsize %d, "
+		    "must be a multiple of %d\n", sectorsize, pagesize);
+		return;
+	}
+
 	sc->dummybuf = malloc(pagesize, M_DEVBUF, M_WAITOK | M_ZERO);
 
 	sc->disk = disk_alloc();
@@ -350,7 +377,7 @@ at45d_delayed_attach(void *xsc)
 	sc->disk->d_name = "flash/at45d";
 	sc->disk->d_drv1 = sc;
 	sc->disk->d_maxsize = DFLTPHYS;
-	sc->disk->d_sectorsize = pagesize;
+	sc->disk->d_sectorsize = sectorsize;
 	sc->disk->d_mediasize = pagesize * ident->pagecount;
 	sc->disk->d_unit = device_get_unit(sc->dev);
 	disk_create(sc->disk, DISK_VERSION);
@@ -358,9 +385,10 @@ 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; %d KBytes\n",
+	device_printf(sc->dev,
+	    "%s, %d bytes per page, %d pages; %d KBytes; disk sector size %d\n",
 	    ident->name, pagesize, ident->pagecount,
-	    (pagesize * ident->pagecount) / 1024);
+	    (pagesize * ident->pagecount) / 1024, sectorsize);
 }
 
 static int


More information about the svn-src-all mailing list