Deleted Added
full compact
mlx.c (52439) mlx.c (52544)
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 52439 1999-10-22 20:55:15Z msmith $
26 * $FreeBSD: head/sys/dev/mlx/mlx.c 52544 1999-10-26 23:20:43Z 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>

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

273 struct mlx_enquiry2 *me2;
274 int rid, error;
275
276 debug("called");
277
278 /*
279 * Initialise per-controller queues.
280 */
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>

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

273 struct mlx_enquiry2 *me2;
274 int rid, error;
275
276 debug("called");
277
278 /*
279 * Initialise per-controller queues.
280 */
281 TAILQ_INIT(&sc->mlx_donecmd);
281 TAILQ_INIT(&sc->mlx_work);
282 TAILQ_INIT(&sc->mlx_freecmds);
283 bufq_init(&sc->mlx_bufq);
284
285 /*
286 * Select accessor methods based on controller interface type.
287 */
288 switch(sc->mlx_iftype) {
289 case MLX_IFTYPE_3:

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

374 sc->mlx_nchan = me2->me_configured_channels;
375 sc->mlx_maxiosize = me2->me_maxblk;
376 sc->mlx_maxtarg = me2->me_max_targets;
377 sc->mlx_maxtags = me2->me_max_tags;
378 sc->mlx_scsicap = me2->me_scsi_cap;
379 sc->mlx_hwid = me2->me_hardware_id;
380
381 /* print a little information about the controller and ourselves */
282 TAILQ_INIT(&sc->mlx_freecmds);
283 bufq_init(&sc->mlx_bufq);
284
285 /*
286 * Select accessor methods based on controller interface type.
287 */
288 switch(sc->mlx_iftype) {
289 case MLX_IFTYPE_3:

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

374 sc->mlx_nchan = me2->me_configured_channels;
375 sc->mlx_maxiosize = me2->me_maxblk;
376 sc->mlx_maxtarg = me2->me_max_targets;
377 sc->mlx_maxtags = me2->me_max_tags;
378 sc->mlx_scsicap = me2->me_scsi_cap;
379 sc->mlx_hwid = me2->me_hardware_id;
380
381 /* print a little information about the controller and ourselves */
382 device_printf(sc->mlx_dev, "Mylex %s, firmware %d.%d, %dMB RAM\n",
382 device_printf(sc->mlx_dev, "Mylex %s, firmware %d.%02d, %dMB RAM\n",
383 mlx_name_controller(sc->mlx_hwid), sc->mlx_fwmajor, sc->mlx_fwminor,
384 me2->me_mem_size / (1024 * 1024));
385 free(me2, M_DEVBUF);
386
387 /*
388 * Do quirk/feature related things.
389 */
390 switch(sc->mlx_iftype) {
391 case MLX_IFTYPE_3:
392 /* XXX certify 3.52? */
383 mlx_name_controller(sc->mlx_hwid), sc->mlx_fwmajor, sc->mlx_fwminor,
384 me2->me_mem_size / (1024 * 1024));
385 free(me2, M_DEVBUF);
386
387 /*
388 * Do quirk/feature related things.
389 */
390 switch(sc->mlx_iftype) {
391 case MLX_IFTYPE_3:
392 /* XXX certify 3.52? */
393 if (sc->mlx_fwminor != 51) {
394 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is NOT SUPPORTED\n");
395 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 only\n");
393 if (sc->mlx_fwminor < 51) {
394 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
395 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 or later\n");
396 }
397 break;
398 case MLX_IFTYPE_4:
399 /* XXX certify firmware versions? */
396 }
397 break;
398 case MLX_IFTYPE_4:
399 /* XXX certify firmware versions? */
400 if (sc->mlx_fwminor != 6) {
401 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is NOT SUPPORTED\n");
402 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.6 only\n");
400 if (sc->mlx_fwminor < 6) {
401 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
402 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n");
403 }
404 break;
405 default:
406 device_printf(sc->mlx_dev, "interface version corrupted to %d\n", sc->mlx_iftype);
407 return(ENXIO); /* should never happen */
408 }
409
410 /*

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

648
649/*******************************************************************************
650 * Receive a buf structure from a child device and queue it on a particular
651 * disk resource, then poke the disk resource to start as much work as it can.
652 */
653int
654mlx_submit_buf(struct mlx_softc *sc, struct buf *bp)
655{
403 }
404 break;
405 default:
406 device_printf(sc->mlx_dev, "interface version corrupted to %d\n", sc->mlx_iftype);
407 return(ENXIO); /* should never happen */
408 }
409
410 /*

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

648
649/*******************************************************************************
650 * Receive a buf structure from a child device and queue it on a particular
651 * disk resource, then poke the disk resource to start as much work as it can.
652 */
653int
654mlx_submit_buf(struct mlx_softc *sc, struct buf *bp)
655{
656 int s;
657
656 debug("called");
657
658 debug("called");
659
660 s = splbio();
658 bufq_insert_tail(&sc->mlx_bufq, bp);
659 sc->mlx_waitbufs++;
661 bufq_insert_tail(&sc->mlx_bufq, bp);
662 sc->mlx_waitbufs++;
663 splx(s);
660 mlx_startio(sc);
661 return(0);
662}
663
664/********************************************************************************
665 * Accept an open operation on the control device.
666 */
667int

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

1552
1553 count = 0;
1554 do {
1555 /* poll for completion */
1556 mlx_done(mc->mc_sc);
1557 } while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 10000));
1558 if (mc->mc_status != MLX_STATUS_BUSY) {
1559 s = splbio();
664 mlx_startio(sc);
665 return(0);
666}
667
668/********************************************************************************
669 * Accept an open operation on the control device.
670 */
671int

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

1556
1557 count = 0;
1558 do {
1559 /* poll for completion */
1560 mlx_done(mc->mc_sc);
1561 } while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 10000));
1562 if (mc->mc_status != MLX_STATUS_BUSY) {
1563 s = splbio();
1560 TAILQ_REMOVE(&sc->mlx_donecmd, mc, mc_link);
1564 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
1561 splx(s);
1562 return(0);
1563 }
1564 device_printf(sc->mlx_dev, "I/O error 0x%x\n", mc->mc_status);
1565 return(EIO);
1566}
1567
1568/********************************************************************************

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

1576mlx_startio(struct mlx_softc *sc)
1577{
1578 struct mlx_command *mc;
1579 struct mlxd_softc *mlxd;
1580 struct buf *bp;
1581 int blkcount;
1582 int driveno;
1583 int cmd;
1565 splx(s);
1566 return(0);
1567 }
1568 device_printf(sc->mlx_dev, "I/O error 0x%x\n", mc->mc_status);
1569 return(EIO);
1570}
1571
1572/********************************************************************************

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

1580mlx_startio(struct mlx_softc *sc)
1581{
1582 struct mlx_command *mc;
1583 struct mlxd_softc *mlxd;
1584 struct buf *bp;
1585 int blkcount;
1586 int driveno;
1587 int cmd;
1588 int s;
1584
1585 /* spin until something prevents us from doing any work */
1589
1590 /* spin until something prevents us from doing any work */
1591 s = splbio();
1586 for (;;) {
1587
1588 /* see if there's work to be done */
1589 if ((bp = bufq_first(&sc->mlx_bufq)) == NULL)
1590 break;
1591 /* get a command */
1592 if ((mc = mlx_alloccmd(sc)) == NULL)
1593 break;
1594 /* get a slot for the command */
1595 if (mlx_getslot(mc) != 0) {
1596 mlx_releasecmd(mc);
1597 break;
1598 }
1599 /* get the buf containing our work */
1600 bufq_remove(&sc->mlx_bufq, bp);
1601 sc->mlx_waitbufs--;
1592 for (;;) {
1593
1594 /* see if there's work to be done */
1595 if ((bp = bufq_first(&sc->mlx_bufq)) == NULL)
1596 break;
1597 /* get a command */
1598 if ((mc = mlx_alloccmd(sc)) == NULL)
1599 break;
1600 /* get a slot for the command */
1601 if (mlx_getslot(mc) != 0) {
1602 mlx_releasecmd(mc);
1603 break;
1604 }
1605 /* get the buf containing our work */
1606 bufq_remove(&sc->mlx_bufq, bp);
1607 sc->mlx_waitbufs--;
1608 splx(s);
1602
1603 /* connect the buf to the command */
1604 mc->mc_complete = mlx_completeio;
1605 mc->mc_private = bp;
1606 mc->mc_data = bp->b_data;
1607 mc->mc_length = bp->b_bcount;
1608 if (bp->b_flags & B_READ) {
1609 mc->mc_flags |= MLX_CMD_DATAIN;

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

1638
1639
1640 /* try to give command to controller */
1641 if (mlx_start(mc) != 0) {
1642 /* fail the command */
1643 mc->mc_status = MLX_STATUS_WEDGED;
1644 mlx_completeio(mc);
1645 }
1609
1610 /* connect the buf to the command */
1611 mc->mc_complete = mlx_completeio;
1612 mc->mc_private = bp;
1613 mc->mc_data = bp->b_data;
1614 mc->mc_length = bp->b_bcount;
1615 if (bp->b_flags & B_READ) {
1616 mc->mc_flags |= MLX_CMD_DATAIN;

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

1645
1646
1647 /* try to give command to controller */
1648 if (mlx_start(mc) != 0) {
1649 /* fail the command */
1650 mc->mc_status = MLX_STATUS_WEDGED;
1651 mlx_completeio(mc);
1652 }
1653 s = splbio();
1646 }
1654 }
1655 splx(s);
1647}
1648
1649/********************************************************************************
1650 * Handle completion of an I/O command.
1651 */
1652static void
1653mlx_completeio(struct mlx_command *mc)
1654{

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

1876 struct mlx_softc *sc = mc->mc_sc;
1877 int i, s, done, worked;
1878
1879 debug("called");
1880
1881 /* save the slot number as ident so we can handle this command when complete */
1882 mc->mc_mailbox[0x1] = mc->mc_slot;
1883
1656}
1657
1658/********************************************************************************
1659 * Handle completion of an I/O command.
1660 */
1661static void
1662mlx_completeio(struct mlx_command *mc)
1663{

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

1885 struct mlx_softc *sc = mc->mc_sc;
1886 int i, s, done, worked;
1887
1888 debug("called");
1889
1890 /* save the slot number as ident so we can handle this command when complete */
1891 mc->mc_mailbox[0x1] = mc->mc_slot;
1892
1884 /* set impossible status so that a woken sleeper can tell the command is in progress */
1893 /* mark the command as currently being processed */
1885 mc->mc_status = MLX_STATUS_BUSY;
1886
1887 /* assume we don't collect any completed commands */
1888 worked = 0;
1889
1890 /* spin waiting for the mailbox */
1891 for (i = 100000, done = 0; (i > 0) && !done; i--) {
1892 s = splbio();
1894 mc->mc_status = MLX_STATUS_BUSY;
1895
1896 /* assume we don't collect any completed commands */
1897 worked = 0;
1898
1899 /* spin waiting for the mailbox */
1900 for (i = 100000, done = 0; (i > 0) && !done; i--) {
1901 s = splbio();
1893 done = sc->mlx_tryqueue(sc, mc);
1902 if (sc->mlx_tryqueue(sc, mc)) {
1903 done = 1;
1904 /* move command to work queue */
1905 TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link);
1906 }
1894 splx(s);
1895 /* check for command completion while we're at it */
1896 if (mlx_done(sc))
1897 worked = 1;
1898 }
1899 /* check to see if we picked up any completed commands */
1900 if (worked)
1901 mlx_complete(sc);

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

1926{
1927 struct mlx_command *mc;
1928 int s;
1929 u_int8_t slot;
1930 u_int16_t status;
1931
1932 debug("called");
1933
1907 splx(s);
1908 /* check for command completion while we're at it */
1909 if (mlx_done(sc))
1910 worked = 1;
1911 }
1912 /* check to see if we picked up any completed commands */
1913 if (worked)
1914 mlx_complete(sc);

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

1939{
1940 struct mlx_command *mc;
1941 int s;
1942 u_int8_t slot;
1943 u_int16_t status;
1944
1945 debug("called");
1946
1934 s = splbio();
1935 mc = NULL;
1936 slot = 0;
1937
1938 /* poll for a completed command's identifier and status */
1947 mc = NULL;
1948 slot = 0;
1949
1950 /* poll for a completed command's identifier and status */
1951 s = splbio();
1939 if (sc->mlx_findcomplete(sc, &slot, &status)) {
1952 if (sc->mlx_findcomplete(sc, &slot, &status)) {
1940 mc = sc->mlx_busycmd[slot]; /* find command */
1941 if (mc != NULL) { /* paranoia */
1953 mc = sc->mlx_busycmd[slot]; /* find command */
1954 if (mc != NULL) { /* paranoia */
1942 if (mc->mc_status == MLX_STATUS_BUSY) {
1943 mc->mc_status = status; /* save status */
1944
1955 if (mc->mc_status == MLX_STATUS_BUSY) {
1956 mc->mc_status = status; /* save status */
1957
1945 /* move completed command to 'done' queue */
1946 TAILQ_INSERT_TAIL(&sc->mlx_donecmd, mc, mc_link);
1947
1948 /* free slot for reuse */
1949 sc->mlx_busycmd[slot] = NULL;
1950 sc->mlx_busycmds--;
1951 } else {
1952 device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot);
1953 mc = NULL;
1954 }
1955 } else {

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

1976 int s, count;
1977
1978 debug("called");
1979
1980 s = splbio();
1981 count = 0;
1982
1983 /* scan the list of done commands */
1958 /* free slot for reuse */
1959 sc->mlx_busycmd[slot] = NULL;
1960 sc->mlx_busycmds--;
1961 } else {
1962 device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot);
1963 mc = NULL;
1964 }
1965 } else {

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

1986 int s, count;
1987
1988 debug("called");
1989
1990 s = splbio();
1991 count = 0;
1992
1993 /* scan the list of done commands */
1984 mc = TAILQ_FIRST(&sc->mlx_donecmd);
1994 mc = TAILQ_FIRST(&sc->mlx_work);
1985 while (mc != NULL) {
1986 nc = TAILQ_NEXT(mc, mc_link);
1987
1988 /* XXX this is slightly bogus */
1989 if (count++ > (sc->mlx_maxiop * 2))
1995 while (mc != NULL) {
1996 nc = TAILQ_NEXT(mc, mc_link);
1997
1998 /* XXX this is slightly bogus */
1999 if (count++ > (sc->mlx_maxiop * 2))
1990 panic("mlx_donecmd list corrupt!");
2000 panic("mlx_work list corrupt!");
1991
2001
1992 /*
2002 /* Skip commands that are still busy */
2003 if (mc->mc_status != MLX_STATUS_BUSY) {
2004
2005
2006 /*
1993 * Does the command have a completion handler?
1994 */
2007 * Does the command have a completion handler?
2008 */
1995 if (mc->mc_complete != NULL) {
1996 /* remove from list and give to handler */
1997 TAILQ_REMOVE(&sc->mlx_donecmd, mc, mc_link);
1998 mc->mc_complete(mc);
2009 if (mc->mc_complete != NULL) {
2010 /* remove from list and give to handler */
2011 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2012 mc->mc_complete(mc);
1999
2013
2000 /*
2001 * Is there a sleeper waiting on this command?
2002 */
2003 } else if (mc->mc_private != NULL) { /* sleeping caller wants to know about it */
2014 /*
2015 * Is there a sleeper waiting on this command?
2016 */
2017 } else if (mc->mc_private != NULL) { /* sleeping caller wants to know about it */
2004
2018
2005 /* remove from list and wake up sleeper */
2006 TAILQ_REMOVE(&sc->mlx_donecmd, mc, mc_link);
2007 wakeup_one(mc->mc_private);
2019 /* remove from list and wake up sleeper */
2020 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2021 wakeup_one(mc->mc_private);
2008
2022
2009 /*
2010 * Leave the command for a caller that's polling for it.
2011 */
2012 } else {
2023 /*
2024 * Leave the command for a caller that's polling for it.
2025 */
2026 } else {
2027 }
2013 }
2014 mc = nc;
2015 }
2016 splx(s);
2017
2018 /* queue some more work if there is any */
2019 mlx_startio(sc);
2020}

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

2351 submodel = "PL";
2352 break;
2353 case 0x10:
2354 submodel = "PG";
2355 break;
2356 case 0x11:
2357 submodel = "PJ";
2358 break;
2028 }
2029 mc = nc;
2030 }
2031 splx(s);
2032
2033 /* queue some more work if there is any */
2034 mlx_startio(sc);
2035}

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

2366 submodel = "PL";
2367 break;
2368 case 0x10:
2369 submodel = "PG";
2370 break;
2371 case 0x11:
2372 submodel = "PJ";
2373 break;
2374 case 0x16:
2375 submodel = "PTL";
2376 break;
2359 default:
2360 sprintf(smbuf, " model 0x%x", hwid & 0xff);
2361 submodel = smbuf;
2362 break;
2363 }
2364 nchn = (hwid >> 8) & 0xff;
2365 sprintf(buf, "DAC960%s, %d channel%s", submodel, nchn, nchn > 1 ? "s" : "");
2366 return(buf);

--- 27 unchanged lines hidden ---
2377 default:
2378 sprintf(smbuf, " model 0x%x", hwid & 0xff);
2379 submodel = smbuf;
2380 break;
2381 }
2382 nchn = (hwid >> 8) & 0xff;
2383 sprintf(buf, "DAC960%s, %d channel%s", submodel, nchn, nchn > 1 ? "s" : "");
2384 return(buf);

--- 27 unchanged lines hidden ---