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:
parent
2274a2f725
commit
e70ece1297
@ -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 for this device.
|
||||
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?
|
||||
|
@ -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", §orsize);
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user