From owner-svn-src-projects@FreeBSD.ORG Sun Oct 25 08:43:39 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 21705106566C; Sun, 25 Oct 2009 08:43:39 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 107BD8FC16; Sun, 25 Oct 2009 08:43:39 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n9P8hcqi052241; Sun, 25 Oct 2009 08:43:38 GMT (envelope-from gonzo@svn.freebsd.org) Received: (from gonzo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n9P8hcv7052240; Sun, 25 Oct 2009 08:43:38 GMT (envelope-from gonzo@svn.freebsd.org) Message-Id: <200910250843.n9P8hcv7052240@svn.freebsd.org> From: Oleksandr Tymoshenko Date: Sun, 25 Oct 2009 08:43:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r198465 - projects/mips/sys/dev/flash X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 25 Oct 2009 08:43:39 -0000 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__ */