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