svn commit: r198465 - projects/mips/sys/dev/flash
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Sun Oct 25 08:43:39 UTC 2009
Author: gonzo
Date: Sun Oct 25 08:43:38 2009
New Revision: 198465
URL: http://svn.freebsd.org/changeset/base/198465
Log:
- Add write support for mx25l flash chip
- Some minor style(9) fixes
Modified:
projects/mips/sys/dev/flash/mx25l.c
projects/mips/sys/dev/flash/mx25lreg.h
Modified: projects/mips/sys/dev/flash/mx25l.c
==============================================================================
--- projects/mips/sys/dev/flash/mx25l.c Sun Oct 25 04:34:47 2009 (r198464)
+++ projects/mips/sys/dev/flash/mx25l.c Sun Oct 25 08:43:38 2009 (r198465)
@@ -156,6 +156,50 @@ mx25l_get_device_ident(struct mx25l_soft
return (NULL);
}
+static void
+mx25l_set_writable(device_t dev, int writable)
+{
+ uint8_t txBuf[1], rxBuf[1];
+ struct spi_command cmd;
+ int err;
+
+ memset(&cmd, 0, sizeof(cmd));
+ memset(txBuf, 0, sizeof(txBuf));
+ memset(rxBuf, 0, sizeof(rxBuf));
+
+ txBuf[0] = writable ? CMD_WRITE_ENABLE : CMD_WRITE_DISABLE;
+ cmd.tx_cmd = txBuf;
+ cmd.rx_cmd = rxBuf;
+ cmd.rx_cmd_sz = 1;
+ cmd.tx_cmd_sz = 1;
+ err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd);
+}
+
+static void
+mx25l_erase_sector(device_t dev, off_t sector)
+{
+ uint8_t txBuf[4], rxBuf[4];
+ struct spi_command cmd;
+ int err;
+
+ mx25l_wait_for_device_ready(dev);
+ mx25l_set_writable(dev, 1);
+
+ memset(&cmd, 0, sizeof(cmd));
+ memset(txBuf, 0, sizeof(txBuf));
+ memset(rxBuf, 0, sizeof(rxBuf));
+
+ txBuf[0] = CMD_SECTOR_ERASE;
+ cmd.tx_cmd = txBuf;
+ cmd.rx_cmd = rxBuf;
+ cmd.rx_cmd_sz = 4;
+ cmd.tx_cmd_sz = 4;
+ txBuf[1] = ((sector >> 16) & 0xff);
+ txBuf[2] = ((sector >> 8) & 0xff);
+ txBuf[3] = (sector & 0xff);
+ err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd);
+}
+
static int
mx25l_probe(device_t dev)
{
@@ -233,7 +277,6 @@ mx25l_ioctl(struct disk *dp, u_long cmd,
return (EINVAL);
}
-
static void
mx25l_strategy(struct bio *bp)
{
@@ -254,6 +297,8 @@ mx25l_task(void *arg)
uint8_t txBuf[8], rxBuf[8];
struct spi_command cmd;
device_t dev, pdev;
+ off_t write_offset;
+ long bytes_to_write, bytes_writen;
for (;;) {
dev = sc->sc_dev;
@@ -284,11 +329,67 @@ mx25l_task(void *arg)
cmd.tx_data_sz = bp->bio_bcount;
cmd.rx_data = bp->bio_data;
cmd.rx_data_sz = bp->bio_bcount;
+
bp->bio_error = SPIBUS_TRANSFER(pdev, dev, &cmd);
}
+ else if (bp->bio_cmd == BIO_WRITE) {
+ mx25l_erase_sector(dev, bp->bio_offset);
+
+ cmd.tx_cmd_sz = 4;
+ cmd.rx_cmd_sz = 4;
+
+ bytes_writen = 0;
+ write_offset = bp->bio_offset;
+
+ /*
+ * I assume here that we write per-sector only
+ * and sector size should be 256 bytes aligned
+ */
+ KASSERT(write_offset % FLASH_PAGE_SIZE == 0,
+ ("offset for BIO_WRITE is not %d bytes aliIgned",
+ FLASH_PAGE_SIZE));
+
+ /*
+ * Maximum write size for CMD_PAGE_PROGRAM is
+ * FLASH_PAGE_SIZE, so split data to chunks
+ * FLASH_PAGE_SIZE bytes eash and write them
+ * one by one
+ */
+ while (bytes_writen < bp->bio_bcount) {
+ txBuf[0] = CMD_PAGE_PROGRAM;
+ txBuf[1] = ((write_offset >> 16) & 0xff);
+ txBuf[2] = ((write_offset >> 8) & 0xff);
+ txBuf[3] = (write_offset & 0xff);
+
+ bytes_to_write = MIN(FLASH_PAGE_SIZE,
+ bp->bio_bcount - bytes_writen);
+ cmd.tx_cmd = txBuf;
+ cmd.rx_cmd = rxBuf;
+ cmd.tx_data = bp->bio_data + bytes_writen;
+ cmd.tx_data_sz = bytes_to_write;
+ cmd.rx_data = bp->bio_data + bytes_writen;
+ cmd.rx_data_sz = bytes_to_write;
+
+ /*
+ * Eash completed write operation resets WEL
+ * (write enable latch) to disabled state,
+ * so we re-enable it here
+ */
+ mx25l_wait_for_device_ready(dev);
+ mx25l_set_writable(dev, 1);
+
+ bp->bio_error = SPIBUS_TRANSFER(pdev, dev, &cmd);
+ if (bp->bio_error)
+ break;
+
+ bytes_writen += bytes_to_write;
+ write_offset += bytes_to_write;
+ }
+ }
else
bp->bio_error = EINVAL;
+
biodone(bp);
}
}
Modified: projects/mips/sys/dev/flash/mx25lreg.h
==============================================================================
--- projects/mips/sys/dev/flash/mx25lreg.h Sun Oct 25 04:34:47 2009 (r198464)
+++ projects/mips/sys/dev/flash/mx25lreg.h Sun Oct 25 08:43:38 2009 (r198465)
@@ -52,5 +52,7 @@
#define STATUS_WEL (1 << 1)
#define STATUS_WIP (1 << 0)
+#define FLASH_PAGE_SIZE 256
+
#endif /* __MX25LREG_H__ */
More information about the svn-src-projects
mailing list