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.
This commit is contained in:
Ian Lepore 2019-03-02 23:20:47 +00:00
parent 2274a2f725
commit e70ece1297
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=344734
2 changed files with 43 additions and 7 deletions

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd February 26, 2019 .Dd March 2, 2019
.Dt AT45D 4 .Dt AT45D 4
.Os .Os
.Sh NAME .Sh NAME
@ -126,6 +126,10 @@ The following properties are optional for the
.Nm .Nm
device subnode: device subnode:
.Bl -tag -width indent .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 .It Va spi-cpha
Empty property indicating the slave device requires shifted clock Empty property indicating the slave device requires shifted clock
phase (CPHA) mode. phase (CPHA) mode.
@ -156,6 +160,10 @@ The chip-select number to assert when performing I/O for this device.
Set the high bit (1 << 31) to invert the logic level of the chip select line. Set the high bit (1 << 31) to invert the logic level of the chip select line.
.It Va hint.at45d.%d.mode .It Va hint.at45d.%d.mode
The SPI mode (0-3) to use when communicating with this device. 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 .El
.Sh FILES .Sh FILES
.Bl -tag -width /dev/flash/at45d? .Bl -tag -width /dev/flash/at45d?

View File

@ -288,9 +288,11 @@ at45d_detach(device_t dev)
AT45D_UNLOCK(sc); AT45D_UNLOCK(sc);
if (err == 0 && sc->taskstate == TSTATE_STOPPED) { if (err == 0 && sc->taskstate == TSTATE_STOPPED) {
disk_destroy(sc->disk); if (sc->disk) {
bioq_flush(&sc->bio_queue, NULL, ENXIO); disk_destroy(sc->disk);
free(sc->dummybuf, M_DEVBUF); bioq_flush(&sc->bio_queue, NULL, ENXIO);
free(sc->dummybuf, M_DEVBUF);
}
AT45D_LOCK_DESTROY(sc); AT45D_LOCK_DESTROY(sc);
} }
return (err); return (err);
@ -303,6 +305,7 @@ at45d_delayed_attach(void *xsc)
struct at45d_mfg_info mfginfo; struct at45d_mfg_info mfginfo;
const struct at45d_flash_ident *ident; const struct at45d_flash_ident *ident;
u_int i; u_int i;
int sectorsize;
uint32_t jedec; uint32_t jedec;
uint16_t pagesize; uint16_t pagesize;
uint8_t status; uint8_t status;
@ -340,6 +343,30 @@ at45d_delayed_attach(void *xsc)
pagesize = ident->pagesize; pagesize = ident->pagesize;
sc->pagesize = 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->dummybuf = malloc(pagesize, M_DEVBUF, M_WAITOK | M_ZERO);
sc->disk = disk_alloc(); sc->disk = disk_alloc();
@ -350,7 +377,7 @@ at45d_delayed_attach(void *xsc)
sc->disk->d_name = "flash/at45d"; sc->disk->d_name = "flash/at45d";
sc->disk->d_drv1 = sc; sc->disk->d_drv1 = sc;
sc->disk->d_maxsize = DFLTPHYS; 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_mediasize = pagesize * ident->pagecount;
sc->disk->d_unit = device_get_unit(sc->dev); sc->disk->d_unit = device_get_unit(sc->dev);
disk_create(sc->disk, DISK_VERSION); disk_create(sc->disk, DISK_VERSION);
@ -358,9 +385,10 @@ at45d_delayed_attach(void *xsc)
bioq_init(&sc->bio_queue); bioq_init(&sc->bio_queue);
kproc_create(&at45d_task, sc, &sc->p, 0, 0, "task: at45d flash"); kproc_create(&at45d_task, sc, &sc->p, 0, 0, "task: at45d flash");
sc->taskstate = TSTATE_RUNNING; 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, ident->name, pagesize, ident->pagecount,
(pagesize * ident->pagecount) / 1024); (pagesize * ident->pagecount) / 1024, sectorsize);
} }
static int static int