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 --- |