Deleted Added
full compact
mlx.c (74810) mlx.c (78752)
1/*-
2 * Copyright (c) 1999 Michael Smith
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1999 Michael Smith
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/dev/mlx/mlx.c 74810 2001-03-26 12:41:29Z phk $
26 * $FreeBSD: head/sys/dev/mlx/mlx.c 78752 2001-06-25 04:32:31Z msmith $
27 */
28
29/*
30 * Driver for the Mylex DAC960 family of RAID controllers.
31 */
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/malloc.h>
36#include <sys/kernel.h>
37
27 */
28
29/*
30 * Driver for the Mylex DAC960 family of RAID controllers.
31 */
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/malloc.h>
36#include <sys/kernel.h>
37
38#include <sys/bio.h>
39#include <sys/bus.h>
40#include <sys/conf.h>
41#include <sys/devicestat.h>
42#include <sys/disk.h>
43#include <sys/stat.h>
44
45#include <machine/resource.h>
46#include <machine/bus_memio.h>
47#include <machine/bus_pio.h>
48#include <machine/bus.h>
49#include <machine/clock.h>
50#include <sys/rman.h>
51
38#include <sys/bus.h>
39#include <sys/conf.h>
40#include <sys/devicestat.h>
41#include <sys/disk.h>
42#include <sys/stat.h>
43
44#include <machine/resource.h>
45#include <machine/bus_memio.h>
46#include <machine/bus_pio.h>
47#include <machine/bus.h>
48#include <machine/clock.h>
49#include <sys/rman.h>
50
51#include <dev/mlx/mlx_compat.h>
52#include <dev/mlx/mlxio.h>
53#include <dev/mlx/mlxvar.h>
54#include <dev/mlx/mlxreg.h>
55
56#define MLX_CDEV_MAJOR 130
57
58static struct cdevsw mlx_cdevsw = {
59 /* open */ mlx_open,

--- 231 unchanged lines hidden (view full) ---

291
292 debug_called(1);
293
294 /*
295 * Initialise per-controller queues.
296 */
297 TAILQ_INIT(&sc->mlx_work);
298 TAILQ_INIT(&sc->mlx_freecmds);
52#include <dev/mlx/mlxio.h>
53#include <dev/mlx/mlxvar.h>
54#include <dev/mlx/mlxreg.h>
55
56#define MLX_CDEV_MAJOR 130
57
58static struct cdevsw mlx_cdevsw = {
59 /* open */ mlx_open,

--- 231 unchanged lines hidden (view full) ---

291
292 debug_called(1);
293
294 /*
295 * Initialise per-controller queues.
296 */
297 TAILQ_INIT(&sc->mlx_work);
298 TAILQ_INIT(&sc->mlx_freecmds);
299 bioq_init(&sc->mlx_bioq);
299 MLX_BIO_QINIT(sc->mlx_bioq);
300
301 /*
302 * Select accessor methods based on controller interface type.
303 */
304 switch(sc->mlx_iftype) {
305 case MLX_IFTYPE_2:
306 case MLX_IFTYPE_3:
307 sc->mlx_tryqueue = mlx_v3_tryqueue;

--- 383 unchanged lines hidden (view full) ---

691 mlx_done(sc);
692};
693
694/*******************************************************************************
695 * Receive a buf structure from a child device and queue it on a particular
696 * disk resource, then poke the disk resource to start as much work as it can.
697 */
698int
300
301 /*
302 * Select accessor methods based on controller interface type.
303 */
304 switch(sc->mlx_iftype) {
305 case MLX_IFTYPE_2:
306 case MLX_IFTYPE_3:
307 sc->mlx_tryqueue = mlx_v3_tryqueue;

--- 383 unchanged lines hidden (view full) ---

691 mlx_done(sc);
692};
693
694/*******************************************************************************
695 * Receive a buf structure from a child device and queue it on a particular
696 * disk resource, then poke the disk resource to start as much work as it can.
697 */
698int
699mlx_submit_buf(struct mlx_softc *sc, struct bio *bp)
699mlx_submit_buf(struct mlx_softc *sc, mlx_bio *bp)
700{
701 int s;
702
703 debug_called(1);
704
705 s = splbio();
700{
701 int s;
702
703 debug_called(1);
704
705 s = splbio();
706 bioq_insert_tail(&sc->mlx_bioq, bp);
706 MLX_BIO_QINSERT(sc->mlx_bioq, bp);
707 sc->mlx_waitbufs++;
708 splx(s);
709 mlx_startio(sc);
710 return(0);
711}
712
713/********************************************************************************
714 * Accept an open operation on the control device.

--- 1005 unchanged lines hidden (view full) ---

1720 * Must be called at splbio or in an equivalent fashion that prevents
1721 * reentry or activity on the bioq.
1722 */
1723static void
1724mlx_startio(struct mlx_softc *sc)
1725{
1726 struct mlx_command *mc;
1727 struct mlxd_softc *mlxd;
707 sc->mlx_waitbufs++;
708 splx(s);
709 mlx_startio(sc);
710 return(0);
711}
712
713/********************************************************************************
714 * Accept an open operation on the control device.

--- 1005 unchanged lines hidden (view full) ---

1720 * Must be called at splbio or in an equivalent fashion that prevents
1721 * reentry or activity on the bioq.
1722 */
1723static void
1724mlx_startio(struct mlx_softc *sc)
1725{
1726 struct mlx_command *mc;
1727 struct mlxd_softc *mlxd;
1728 struct bio *bp;
1728 mlx_bio *bp;
1729 int blkcount;
1730 int driveno;
1731 int cmd;
1732 int s;
1733
1734 /* avoid reentrancy */
1735 if (mlx_lock_tas(sc, MLX_LOCK_STARTING))
1736 return;
1737
1738 /* spin until something prevents us from doing any work */
1739 s = splbio();
1740 for (;;) {
1741
1742 /* see if there's work to be done */
1729 int blkcount;
1730 int driveno;
1731 int cmd;
1732 int s;
1733
1734 /* avoid reentrancy */
1735 if (mlx_lock_tas(sc, MLX_LOCK_STARTING))
1736 return;
1737
1738 /* spin until something prevents us from doing any work */
1739 s = splbio();
1740 for (;;) {
1741
1742 /* see if there's work to be done */
1743 if ((bp = bioq_first(&sc->mlx_bioq)) == NULL)
1743 if ((bp = MLX_BIO_QFIRST(sc->mlx_bioq)) == NULL)
1744 break;
1745 /* get a command */
1746 if ((mc = mlx_alloccmd(sc)) == NULL)
1747 break;
1748 /* get a slot for the command */
1749 if (mlx_getslot(mc) != 0) {
1750 mlx_releasecmd(mc);
1751 break;
1752 }
1753 /* get the buf containing our work */
1744 break;
1745 /* get a command */
1746 if ((mc = mlx_alloccmd(sc)) == NULL)
1747 break;
1748 /* get a slot for the command */
1749 if (mlx_getslot(mc) != 0) {
1750 mlx_releasecmd(mc);
1751 break;
1752 }
1753 /* get the buf containing our work */
1754 bioq_remove(&sc->mlx_bioq, bp);
1754 MLX_BIO_QREMOVE(sc->mlx_bioq, bp);
1755 sc->mlx_waitbufs--;
1756 splx(s);
1757
1758 /* connect the buf to the command */
1759 mc->mc_complete = mlx_completeio;
1760 mc->mc_private = bp;
1755 sc->mlx_waitbufs--;
1756 splx(s);
1757
1758 /* connect the buf to the command */
1759 mc->mc_complete = mlx_completeio;
1760 mc->mc_private = bp;
1761 mc->mc_data = bp->bio_data;
1762 mc->mc_length = bp->bio_bcount;
1763 if (bp->bio_cmd == BIO_READ) {
1761 mc->mc_data = MLX_BIO_DATA(bp);
1762 mc->mc_length = MLX_BIO_LENGTH(bp);
1763 if (MLX_BIO_IS_READ(bp)) {
1764 mc->mc_flags |= MLX_CMD_DATAIN;
1765 cmd = MLX_CMD_READSG;
1766 } else {
1767 mc->mc_flags |= MLX_CMD_DATAOUT;
1768 cmd = MLX_CMD_WRITESG;
1769 }
1770
1771 /* map the command so the controller can work with it */
1772 mlx_mapcmd(mc);
1773
1774 /* build a suitable I/O command (assumes 512-byte rounded transfers) */
1764 mc->mc_flags |= MLX_CMD_DATAIN;
1765 cmd = MLX_CMD_READSG;
1766 } else {
1767 mc->mc_flags |= MLX_CMD_DATAOUT;
1768 cmd = MLX_CMD_WRITESG;
1769 }
1770
1771 /* map the command so the controller can work with it */
1772 mlx_mapcmd(mc);
1773
1774 /* build a suitable I/O command (assumes 512-byte rounded transfers) */
1775 mlxd = (struct mlxd_softc *)bp->bio_dev->si_drv1;
1775 mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp);
1776 driveno = mlxd->mlxd_drive - sc->mlx_sysdrive;
1776 driveno = mlxd->mlxd_drive - sc->mlx_sysdrive;
1777 blkcount = (bp->bio_bcount + MLX_BLKSIZE - 1) / MLX_BLKSIZE;
1777 blkcount = (MLX_BIO_LENGTH(bp) + MLX_BLKSIZE - 1) / MLX_BLKSIZE;
1778
1778
1779 if ((bp->bio_pblkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
1779 if ((MLX_BIO_LBA(bp) + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
1780 device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n",
1780 device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n",
1781 bp->bio_pblkno, blkcount, sc->mlx_sysdrive[driveno].ms_size);
1781 MLX_BIO_LBA(bp), blkcount, sc->mlx_sysdrive[driveno].ms_size);
1782
1783 /*
1784 * Build the I/O command. Note that the SG list type bits are set to zero,
1785 * denoting the format of SG list that we are using.
1786 */
1787 if (sc->mlx_iftype == MLX_IFTYPE_2) {
1788 mlx_make_type1(mc, (cmd == MLX_CMD_WRITESG) ? MLX_CMD_WRITESG_OLD : MLX_CMD_READSG_OLD,
1789 blkcount & 0xff, /* xfer length low byte */
1782
1783 /*
1784 * Build the I/O command. Note that the SG list type bits are set to zero,
1785 * denoting the format of SG list that we are using.
1786 */
1787 if (sc->mlx_iftype == MLX_IFTYPE_2) {
1788 mlx_make_type1(mc, (cmd == MLX_CMD_WRITESG) ? MLX_CMD_WRITESG_OLD : MLX_CMD_READSG_OLD,
1789 blkcount & 0xff, /* xfer length low byte */
1790 bp->bio_pblkno, /* physical block number */
1790 MLX_BIO_LBA(bp), /* physical block number */
1791 driveno, /* target drive number */
1792 mc->mc_sgphys, /* location of SG list */
1793 mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */
1794 } else {
1795 mlx_make_type5(mc, cmd,
1796 blkcount & 0xff, /* xfer length low byte */
1797 (driveno << 3) | ((blkcount >> 8) & 0x07), /* target and length high 3 bits */
1791 driveno, /* target drive number */
1792 mc->mc_sgphys, /* location of SG list */
1793 mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */
1794 } else {
1795 mlx_make_type5(mc, cmd,
1796 blkcount & 0xff, /* xfer length low byte */
1797 (driveno << 3) | ((blkcount >> 8) & 0x07), /* target and length high 3 bits */
1798 bp->bio_pblkno, /* physical block number */
1798 MLX_BIO_LBA(bp), /* physical block number */
1799 mc->mc_sgphys, /* location of SG list */
1800 mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */
1801 }
1802
1803 /* try to give command to controller */
1804 if (mlx_start(mc) != 0) {
1805 /* fail the command */
1806 mc->mc_status = MLX_STATUS_WEDGED;

--- 7 unchanged lines hidden (view full) ---

1814
1815/********************************************************************************
1816 * Handle completion of an I/O command.
1817 */
1818static void
1819mlx_completeio(struct mlx_command *mc)
1820{
1821 struct mlx_softc *sc = mc->mc_sc;
1799 mc->mc_sgphys, /* location of SG list */
1800 mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */
1801 }
1802
1803 /* try to give command to controller */
1804 if (mlx_start(mc) != 0) {
1805 /* fail the command */
1806 mc->mc_status = MLX_STATUS_WEDGED;

--- 7 unchanged lines hidden (view full) ---

1814
1815/********************************************************************************
1816 * Handle completion of an I/O command.
1817 */
1818static void
1819mlx_completeio(struct mlx_command *mc)
1820{
1821 struct mlx_softc *sc = mc->mc_sc;
1822 struct bio *bp = (struct bio *)mc->mc_private;
1823 struct mlxd_softc *mlxd = (struct mlxd_softc *)bp->bio_dev->si_drv1;
1822 mlx_bio *bp = (mlx_bio *)mc->mc_private;
1823 struct mlxd_softc *mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp);
1824
1825 if (mc->mc_status != MLX_STATUS_OK) { /* could be more verbose here? */
1824
1825 if (mc->mc_status != MLX_STATUS_OK) { /* could be more verbose here? */
1826 bp->bio_error = EIO;
1827 bp->bio_flags |= BIO_ERROR;
1826 MLX_BIO_SET_ERROR(bp, EIO);
1828
1829 switch(mc->mc_status) {
1830 case MLX_STATUS_RDWROFFLINE: /* system drive has gone offline */
1831 device_printf(mlxd->mlxd_dev, "drive offline\n");
1832 /* should signal this with a return code */
1833 mlxd->mlxd_drive->ms_state = MLX_SYSD_OFFLINE;
1834 break;
1835
1836 default: /* other I/O error */
1837 device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
1838#if 0
1839 device_printf(sc->mlx_dev, " b_bcount %ld blkcount %ld b_pblkno %d\n",
1827
1828 switch(mc->mc_status) {
1829 case MLX_STATUS_RDWROFFLINE: /* system drive has gone offline */
1830 device_printf(mlxd->mlxd_dev, "drive offline\n");
1831 /* should signal this with a return code */
1832 mlxd->mlxd_drive->ms_state = MLX_SYSD_OFFLINE;
1833 break;
1834
1835 default: /* other I/O error */
1836 device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
1837#if 0
1838 device_printf(sc->mlx_dev, " b_bcount %ld blkcount %ld b_pblkno %d\n",
1840 bp->bio_bcount, bp->bio_bcount / MLX_BLKSIZE, bp->bio_pblkno);
1839 MLX_BIO_LENGTH(bp), MLX_BIO_LENGTH(bp) / MLX_BLKSIZE, MLX_BIO_LBA(bp));
1841 device_printf(sc->mlx_dev, " %13D\n", mc->mc_mailbox, " ");
1842#endif
1843 break;
1844 }
1845 }
1846 mlx_releasecmd(mc);
1847 mlxd_intr(bp);
1848}

--- 1081 unchanged lines hidden ---
1840 device_printf(sc->mlx_dev, " %13D\n", mc->mc_mailbox, " ");
1841#endif
1842 break;
1843 }
1844 }
1845 mlx_releasecmd(mc);
1846 mlxd_intr(bp);
1847}

--- 1081 unchanged lines hidden ---