Deleted Added
full compact
mlx.c (59136) mlx.c (59249)
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 59136 2000-04-11 02:52:46Z msmith $
26 * $FreeBSD: head/sys/dev/mlx/mlx.c 59249 2000-04-15 05:54:02Z phk $
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>

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

284
285 debug_called(1);
286
287 /*
288 * Initialise per-controller queues.
289 */
290 TAILQ_INIT(&sc->mlx_work);
291 TAILQ_INIT(&sc->mlx_freecmds);
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>

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

284
285 debug_called(1);
286
287 /*
288 * Initialise per-controller queues.
289 */
290 TAILQ_INIT(&sc->mlx_work);
291 TAILQ_INIT(&sc->mlx_freecmds);
292 bufq_init(&sc->mlx_bufq);
292 bioq_init(&sc->mlx_bioq);
293
294 /*
295 * Select accessor methods based on controller interface type.
296 */
297 switch(sc->mlx_iftype) {
298 case MLX_IFTYPE_2:
299 case MLX_IFTYPE_3:
300 sc->mlx_tryqueue = mlx_v3_tryqueue;

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

582
583/********************************************************************************
584 * Bring the controller down to a dormant state and detach all child devices.
585 *
586 * This function is called before detach, system shutdown, or before performing
587 * an operation which may add or delete system disks. (Call mlx_startup to
588 * resume normal operation.)
589 *
293
294 /*
295 * Select accessor methods based on controller interface type.
296 */
297 switch(sc->mlx_iftype) {
298 case MLX_IFTYPE_2:
299 case MLX_IFTYPE_3:
300 sc->mlx_tryqueue = mlx_v3_tryqueue;

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

582
583/********************************************************************************
584 * Bring the controller down to a dormant state and detach all child devices.
585 *
586 * This function is called before detach, system shutdown, or before performing
587 * an operation which may add or delete system disks. (Call mlx_startup to
588 * resume normal operation.)
589 *
590 * Note that we can assume that the bufq on the controller is empty, as we won't
590 * Note that we can assume that the bioq on the controller is empty, as we won't
591 * allow shutdown if any device is open.
592 */
593int
594mlx_shutdown(device_t dev)
595{
596 struct mlx_softc *sc = device_get_softc(dev);
597 int i, s, error;
598

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

681 mlx_done(sc);
682};
683
684/*******************************************************************************
685 * Receive a buf structure from a child device and queue it on a particular
686 * disk resource, then poke the disk resource to start as much work as it can.
687 */
688int
591 * allow shutdown if any device is open.
592 */
593int
594mlx_shutdown(device_t dev)
595{
596 struct mlx_softc *sc = device_get_softc(dev);
597 int i, s, error;
598

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

681 mlx_done(sc);
682};
683
684/*******************************************************************************
685 * Receive a buf structure from a child device and queue it on a particular
686 * disk resource, then poke the disk resource to start as much work as it can.
687 */
688int
689mlx_submit_buf(struct mlx_softc *sc, struct buf *bp)
689mlx_submit_buf(struct mlx_softc *sc, struct bio *bp)
690{
691 int s;
692
693 debug_called(1);
694
695 s = splbio();
690{
691 int s;
692
693 debug_called(1);
694
695 s = splbio();
696 bufq_insert_tail(&sc->mlx_bufq, bp);
696 bioq_insert_tail(&sc->mlx_bioq, bp);
697 sc->mlx_waitbufs++;
698 splx(s);
699 mlx_startio(sc);
700 return(0);
701}
702
703/********************************************************************************
704 * Accept an open operation on the control device.

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

1696 return(EIO);
1697}
1698
1699/********************************************************************************
1700 * Pull as much work off the softc's work queue as possible and give it to the
1701 * controller. Leave a couple of slots free for emergencies.
1702 *
1703 * Must be called at splbio or in an equivalent fashion that prevents
697 sc->mlx_waitbufs++;
698 splx(s);
699 mlx_startio(sc);
700 return(0);
701}
702
703/********************************************************************************
704 * Accept an open operation on the control device.

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

1696 return(EIO);
1697}
1698
1699/********************************************************************************
1700 * Pull as much work off the softc's work queue as possible and give it to the
1701 * controller. Leave a couple of slots free for emergencies.
1702 *
1703 * Must be called at splbio or in an equivalent fashion that prevents
1704 * reentry or activity on the bufq.
1704 * reentry or activity on the bioq.
1705 */
1706static void
1707mlx_startio(struct mlx_softc *sc)
1708{
1709 struct mlx_command *mc;
1710 struct mlxd_softc *mlxd;
1705 */
1706static void
1707mlx_startio(struct mlx_softc *sc)
1708{
1709 struct mlx_command *mc;
1710 struct mlxd_softc *mlxd;
1711 struct buf *bp;
1711 struct bio *bp;
1712 int blkcount;
1713 int driveno;
1714 int cmd;
1715 int s;
1716
1717 /* avoid reentrancy */
1718 if (mlx_lock_tas(sc, MLX_LOCK_STARTING))
1719 return;
1720
1721 /* spin until something prevents us from doing any work */
1722 s = splbio();
1723 for (;;) {
1724
1725 /* see if there's work to be done */
1712 int blkcount;
1713 int driveno;
1714 int cmd;
1715 int s;
1716
1717 /* avoid reentrancy */
1718 if (mlx_lock_tas(sc, MLX_LOCK_STARTING))
1719 return;
1720
1721 /* spin until something prevents us from doing any work */
1722 s = splbio();
1723 for (;;) {
1724
1725 /* see if there's work to be done */
1726 if ((bp = bufq_first(&sc->mlx_bufq)) == NULL)
1726 if ((bp = bioq_first(&sc->mlx_bioq)) == NULL)
1727 break;
1728 /* get a command */
1729 if ((mc = mlx_alloccmd(sc)) == NULL)
1730 break;
1731 /* get a slot for the command */
1732 if (mlx_getslot(mc) != 0) {
1733 mlx_releasecmd(mc);
1734 break;
1735 }
1736 /* get the buf containing our work */
1727 break;
1728 /* get a command */
1729 if ((mc = mlx_alloccmd(sc)) == NULL)
1730 break;
1731 /* get a slot for the command */
1732 if (mlx_getslot(mc) != 0) {
1733 mlx_releasecmd(mc);
1734 break;
1735 }
1736 /* get the buf containing our work */
1737 bufq_remove(&sc->mlx_bufq, bp);
1737 bioq_remove(&sc->mlx_bioq, bp);
1738 sc->mlx_waitbufs--;
1739 splx(s);
1740
1741 /* connect the buf to the command */
1742 mc->mc_complete = mlx_completeio;
1743 mc->mc_private = bp;
1738 sc->mlx_waitbufs--;
1739 splx(s);
1740
1741 /* connect the buf to the command */
1742 mc->mc_complete = mlx_completeio;
1743 mc->mc_private = bp;
1744 mc->mc_data = bp->b_data;
1745 mc->mc_length = bp->b_bcount;
1746 if (bp->b_iocmd == BIO_READ) {
1744 mc->mc_data = bp->bio_data;
1745 mc->mc_length = bp->bio_bcount;
1746 if (bp->bio_cmd == BIO_READ) {
1747 mc->mc_flags |= MLX_CMD_DATAIN;
1748 cmd = MLX_CMD_READSG;
1749 } else {
1750 mc->mc_flags |= MLX_CMD_DATAOUT;
1751 cmd = MLX_CMD_WRITESG;
1752 }
1753
1754 /* map the command so the controller can work with it */
1755 mlx_mapcmd(mc);
1756
1757 /* build a suitable I/O command (assumes 512-byte rounded transfers) */
1747 mc->mc_flags |= MLX_CMD_DATAIN;
1748 cmd = MLX_CMD_READSG;
1749 } else {
1750 mc->mc_flags |= MLX_CMD_DATAOUT;
1751 cmd = MLX_CMD_WRITESG;
1752 }
1753
1754 /* map the command so the controller can work with it */
1755 mlx_mapcmd(mc);
1756
1757 /* build a suitable I/O command (assumes 512-byte rounded transfers) */
1758 mlxd = (struct mlxd_softc *)bp->b_dev->si_drv1;
1758 mlxd = (struct mlxd_softc *)bp->bio_dev->si_drv1;
1759 driveno = mlxd->mlxd_drive - sc->mlx_sysdrive;
1759 driveno = mlxd->mlxd_drive - sc->mlx_sysdrive;
1760 blkcount = (bp->b_bcount + MLX_BLKSIZE - 1) / MLX_BLKSIZE;
1760 blkcount = (bp->bio_bcount + MLX_BLKSIZE - 1) / MLX_BLKSIZE;
1761
1761
1762 if ((bp->b_pblkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
1762 if ((bp->bio_pblkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
1763 device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n",
1763 device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n",
1764 bp->b_pblkno, blkcount, sc->mlx_sysdrive[driveno].ms_size);
1764 bp->bio_pblkno, blkcount, sc->mlx_sysdrive[driveno].ms_size);
1765
1766 /*
1767 * Build the I/O command. Note that the SG list type bits are set to zero,
1768 * denoting the format of SG list that we are using.
1769 */
1770 if (sc->mlx_iftype == MLX_IFTYPE_2) {
1771 mlx_make_type1(mc, (cmd == MLX_CMD_WRITESG) ? MLX_CMD_WRITESG_OLD : MLX_CMD_READSG_OLD,
1772 blkcount & 0xff, /* xfer length low byte */
1765
1766 /*
1767 * Build the I/O command. Note that the SG list type bits are set to zero,
1768 * denoting the format of SG list that we are using.
1769 */
1770 if (sc->mlx_iftype == MLX_IFTYPE_2) {
1771 mlx_make_type1(mc, (cmd == MLX_CMD_WRITESG) ? MLX_CMD_WRITESG_OLD : MLX_CMD_READSG_OLD,
1772 blkcount & 0xff, /* xfer length low byte */
1773 bp->b_pblkno, /* physical block number */
1773 bp->bio_pblkno, /* physical block number */
1774 driveno, /* target drive number */
1775 mc->mc_sgphys, /* location of SG list */
1776 mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */
1777 } else {
1778 mlx_make_type5(mc, cmd,
1779 blkcount & 0xff, /* xfer length low byte */
1780 (driveno << 3) | ((blkcount >> 8) & 0x07), /* target and length high 3 bits */
1774 driveno, /* target drive number */
1775 mc->mc_sgphys, /* location of SG list */
1776 mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */
1777 } else {
1778 mlx_make_type5(mc, cmd,
1779 blkcount & 0xff, /* xfer length low byte */
1780 (driveno << 3) | ((blkcount >> 8) & 0x07), /* target and length high 3 bits */
1781 bp->b_pblkno, /* physical block number */
1781 bp->bio_pblkno, /* physical block number */
1782 mc->mc_sgphys, /* location of SG list */
1783 mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */
1784 }
1785
1786 /* try to give command to controller */
1787 if (mlx_start(mc) != 0) {
1788 /* fail the command */
1789 mc->mc_status = MLX_STATUS_WEDGED;

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

1797
1798/********************************************************************************
1799 * Handle completion of an I/O command.
1800 */
1801static void
1802mlx_completeio(struct mlx_command *mc)
1803{
1804 struct mlx_softc *sc = mc->mc_sc;
1782 mc->mc_sgphys, /* location of SG list */
1783 mc->mc_nsgent & 0x3f); /* size of SG list (top 3 bits clear) */
1784 }
1785
1786 /* try to give command to controller */
1787 if (mlx_start(mc) != 0) {
1788 /* fail the command */
1789 mc->mc_status = MLX_STATUS_WEDGED;

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

1797
1798/********************************************************************************
1799 * Handle completion of an I/O command.
1800 */
1801static void
1802mlx_completeio(struct mlx_command *mc)
1803{
1804 struct mlx_softc *sc = mc->mc_sc;
1805 struct buf *bp = (struct buf *)mc->mc_private;
1806 struct mlxd_softc *mlxd = (struct mlxd_softc *)bp->b_dev->si_drv1;
1805 struct bio *bp = (struct bio *)mc->mc_private;
1806 struct mlxd_softc *mlxd = (struct mlxd_softc *)bp->bio_dev->si_drv1;
1807
1808 if (mc->mc_status != MLX_STATUS_OK) { /* could be more verbose here? */
1807
1808 if (mc->mc_status != MLX_STATUS_OK) { /* could be more verbose here? */
1809 bp->b_error = EIO;
1810 bp->b_ioflags |= BIO_ERROR;
1809 bp->bio_error = EIO;
1810 bp->bio_flags |= BIO_ERROR;
1811
1812 switch(mc->mc_status) {
1813 case MLX_STATUS_RDWROFFLINE: /* system drive has gone offline */
1814 device_printf(mlxd->mlxd_dev, "drive offline\n");
1815 /* should signal this with a return code */
1816 mlxd->mlxd_drive->ms_state = MLX_SYSD_OFFLINE;
1817 break;
1818
1819 default: /* other I/O error */
1820 device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
1821#if 0
1822 device_printf(sc->mlx_dev, " b_bcount %ld blkcount %ld b_pblkno %d\n",
1811
1812 switch(mc->mc_status) {
1813 case MLX_STATUS_RDWROFFLINE: /* system drive has gone offline */
1814 device_printf(mlxd->mlxd_dev, "drive offline\n");
1815 /* should signal this with a return code */
1816 mlxd->mlxd_drive->ms_state = MLX_SYSD_OFFLINE;
1817 break;
1818
1819 default: /* other I/O error */
1820 device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
1821#if 0
1822 device_printf(sc->mlx_dev, " b_bcount %ld blkcount %ld b_pblkno %d\n",
1823 bp->b_bcount, bp->b_bcount / MLX_BLKSIZE, bp->b_pblkno);
1823 bp->bio_bcount, bp->bio_bcount / MLX_BLKSIZE, bp->bio_pblkno);
1824 device_printf(sc->mlx_dev, " %13D\n", mc->mc_mailbox, " ");
1825#endif
1826 break;
1827 }
1828 }
1829 mlx_releasecmd(mc);
1830 mlxd_intr(bp);
1831}

--- 1071 unchanged lines hidden ---
1824 device_printf(sc->mlx_dev, " %13D\n", mc->mc_mailbox, " ");
1825#endif
1826 break;
1827 }
1828 }
1829 mlx_releasecmd(mc);
1830 mlxd_intr(bp);
1831}

--- 1071 unchanged lines hidden ---