1419 return ENODEV; 1420 } 1421 1422 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL, 1423 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD, 1424 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1425 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); 1426 cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE); 1427 return ENODEV; 1428 } 1429 1430 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */ 1431 return 0; 1432} 1433 1434static int 1435scsi_low_world_start_cam(slp) 1436 struct scsi_low_softc *slp; 1437{ 1438 1439 if (!cold) 1440 scsi_low_rescan_bus_cam(slp); 1441 return 0; 1442} 1443 1444static int 1445scsi_low_dettach_cam(slp) 1446 struct scsi_low_softc *slp; 1447{ 1448 1449 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL); 1450 xpt_free_path(slp->sl_si.path); 1451 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); 1452 cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE); 1453 return 0; 1454} 1455 1456static int 1457scsi_low_ccb_setup_cam(slp, cb) 1458 struct scsi_low_softc *slp; 1459 struct slccb *cb; 1460{ 1461 union ccb *ccb = (union ccb *) cb->osdep; 1462 1463 if ((cb->ccb_flags & CCB_SCSIIO) != 0) 1464 { 1465 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes; 1466 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len; 1467 cb->ccb_scp.scp_data = ccb->csio.data_ptr; 1468 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len; 1469 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1470 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE; 1471 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */ 1472 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 1473 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000; 1474 } 1475 else 1476 { 1477 scsi_low_unit_ready_cmd(cb); 1478 } 1479 return SCSI_LOW_START_QTAG; 1480} 1481 1482static int 1483scsi_low_done_cam(slp, cb) 1484 struct scsi_low_softc *slp; 1485 struct slccb *cb; 1486{ 1487 union ccb *ccb; 1488 1489 ccb = (union ccb *) cb->osdep; 1490 if (cb->ccb_error == 0) 1491 { 1492 ccb->ccb_h.status = CAM_REQ_CMP; 1493 ccb->csio.resid = 0; 1494 } 1495 else 1496 { 1497 if (cb->ccb_rcnt >= slp->sl_max_retry) 1498 cb->ccb_error |= ABORTIO; 1499 1500 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 1501 (cb->ccb_error & ABORTIO) == 0) 1502 return EJUSTRETURN; 1503 1504 if ((cb->ccb_error & SENSEIO) != 0) 1505 { 1506 memcpy(&ccb->csio.sense_data, 1507 &cb->ccb_sense, 1508 sizeof(ccb->csio.sense_data)); 1509 } 1510 1511 ccb->ccb_h.status = scsi_low_translate_error_code(cb, 1512 &scsi_low_error_code_cam[0]); 1513 1514#ifdef SCSI_LOW_DIAGNOSTIC 1515 if ((cb->ccb_flags & CCB_SILENT) == 0 && 1516 cb->ccb_scp.scp_cmdlen > 0 && 1517 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 1518 SCSI_LOW_CMD_ABORT_WARNING) != 0) 1519 { 1520 printf("%s: WARNING: scsi_low IO abort\n", 1521 slp->sl_xname); 1522 scsi_low_print(slp, NULL); 1523 } 1524#endif /* SCSI_LOW_DIAGNOSTIC */ 1525 } 1526 1527 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0) 1528 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 1529 1530 if (cb->ccb_scp.scp_status == ST_UNKNOWN) 1531 ccb->csio.scsi_status = 0; /* XXX */ 1532 else 1533 ccb->csio.scsi_status = cb->ccb_scp.scp_status; 1534 1535 if ((cb->ccb_flags & CCB_NOSDONE) == 0) 1536 xpt_done(ccb); 1537 return 0; 1538} 1539 1540static void 1541scsi_low_timeout_cam(slp, ch, action) 1542 struct scsi_low_softc *slp; 1543 int ch; 1544 int action; 1545{ 1546 1547 switch (ch) 1548 { 1549 case SCSI_LOW_TIMEOUT_CH_IO: 1550 switch (action) 1551 { 1552 case SCSI_LOW_TIMEOUT_START: 1553 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp, 1554 hz / SCSI_LOW_TIMEOUT_HZ); 1555 break; 1556 case SCSI_LOW_TIMEOUT_STOP: 1557 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch); 1558 break; 1559 } 1560 break; 1561 1562 case SCSI_LOW_TIMEOUT_CH_ENGAGE: 1563 switch (action) 1564 { 1565 case SCSI_LOW_TIMEOUT_START: 1566 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1); 1567 break; 1568 case SCSI_LOW_TIMEOUT_STOP: 1569 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch); 1570 break; 1571 } 1572 break; 1573 case SCSI_LOW_TIMEOUT_CH_RECOVER: 1574 break; 1575 } 1576} 1577 1578#endif /* SCSI_LOW_INTERFACE_CAM */ 1579 1580/*============================================================= 1581 * END OF OS switch (All OS depend fucntions should be above) 1582 =============================================================*/ 1583 1584/************************************************************** 1585 * scsi low deactivate and activate 1586 **************************************************************/ 1587int 1588scsi_low_is_busy(slp) 1589 struct scsi_low_softc *slp; 1590{ 1591 1592 if (slp->sl_nio > 0) 1593 return EBUSY; 1594 return 0; 1595} 1596 1597int 1598scsi_low_deactivate(slp) 1599 struct scsi_low_softc *slp; 1600{ 1601 int s; 1602 1603 s = SCSI_LOW_SPLSCSI(); 1604 slp->sl_flags |= HW_INACTIVE; 1605 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1606 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP); 1607 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1608 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); 1609 splx(s); 1610 return 0; 1611} 1612 1613int 1614scsi_low_activate(slp) 1615 struct scsi_low_softc *slp; 1616{ 1617 int error, s; 1618 1619 s = SCSI_LOW_SPLSCSI(); 1620 slp->sl_flags &= ~HW_INACTIVE; 1621 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0) 1622 { 1623 slp->sl_flags |= HW_INACTIVE; 1624 splx(s); 1625 return error; 1626 } 1627 1628 slp->sl_timeout_count = 0; 1629 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1630 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 1631 splx(s); 1632 return 0; 1633} 1634 1635/************************************************************** 1636 * scsi low log 1637 **************************************************************/ 1638#ifdef SCSI_LOW_DIAGNOSTIC 1639static void scsi_low_msg_log_init(struct scsi_low_msg_log *); 1640static void scsi_low_msg_log_write(struct scsi_low_msg_log *, u_int8_t *, int); 1641static void scsi_low_msg_log_show(struct scsi_low_msg_log *, char *, int); 1642 1643static void 1644scsi_low_msg_log_init(slmlp) 1645 struct scsi_low_msg_log *slmlp; 1646{ 1647 1648 slmlp->slml_ptr = 0; 1649} 1650 1651static void 1652scsi_low_msg_log_write(slmlp, datap, len) 1653 struct scsi_low_msg_log *slmlp; 1654 u_int8_t *datap; 1655 int len; 1656{ 1657 int ptr, ind; 1658 1659 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN) 1660 return; 1661 1662 ptr = slmlp->slml_ptr ++; 1663 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++) 1664 slmlp->slml_msg[ptr].msg[ind] = datap[ind]; 1665 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++) 1666 slmlp->slml_msg[ptr].msg[ind] = 0; 1667} 1668 1669static void 1670scsi_low_msg_log_show(slmlp, s, len) 1671 struct scsi_low_msg_log *slmlp; 1672 char *s; 1673 int len; 1674{ 1675 int ptr, ind; 1676 1677 printf("%s: (%d) ", s, slmlp->slml_ptr); 1678 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++) 1679 { 1680 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]); 1681 ind ++) 1682 { 1683 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]); 1684 } 1685 printf(">"); 1686 } 1687 printf("\n"); 1688} 1689#endif /* SCSI_LOW_DIAGNOSTIC */ 1690 1691/************************************************************** 1692 * power control 1693 **************************************************************/ 1694static void 1695scsi_low_engage(arg) 1696 void *arg; 1697{ 1698 struct scsi_low_softc *slp = arg; 1699 int s = SCSI_LOW_SPLSCSI(); 1700 1701 switch (slp->sl_rstep) 1702 { 1703 case 0: 1704 slp->sl_rstep ++; 1705 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); 1706 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 1707 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START); 1708 break; 1709 1710 case 1: 1711 slp->sl_rstep ++; 1712 slp->sl_flags &= ~HW_RESUME; 1713 scsi_low_start(slp); 1714 break; 1715 1716 case 2: 1717 break; 1718 } 1719 splx(s); 1720} 1721 1722static int 1723scsi_low_init(slp, flags) 1724 struct scsi_low_softc *slp; 1725 u_int flags; 1726{ 1727 int rv = 0; 1728 1729 slp->sl_flags |= HW_INITIALIZING; 1730 1731 /* clear power control timeout */ 1732 if ((slp->sl_flags & HW_POWERCTRL) != 0) 1733 { 1734 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 1735 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); 1736 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME); 1737 slp->sl_active = 1; 1738 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 1739 } 1740 1741 /* reset current nexus */ 1742 scsi_low_reset_nexus(slp, flags); 1743 if ((slp->sl_flags & HW_INACTIVE) != 0) 1744 { 1745 rv = EBUSY; 1746 goto out; 1747 } 1748 1749 if (flags != SCSI_LOW_RESTART_SOFT) 1750 { 1751 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags)); 1752 } 1753 1754out: 1755 slp->sl_flags &= ~HW_INITIALIZING; 1756 return rv; 1757} 1758 1759/************************************************************** 1760 * allocate lun_info 1761 **************************************************************/ 1762static struct lun_info * 1763scsi_low_alloc_li(ti, lun, alloc) 1764 struct targ_info *ti; 1765 int lun; 1766 int alloc; 1767{ 1768 struct scsi_low_softc *slp = ti->ti_sc; 1769 struct lun_info *li; 1770 1771 li = LIST_FIRST(&ti->ti_litab); 1772 if (li != NULL) 1773 { 1774 if (li->li_lun == lun) 1775 return li; 1776 1777 while ((li = LIST_NEXT(li, lun_chain)) != NULL) 1778 { 1779 if (li->li_lun == lun) 1780 { 1781 LIST_REMOVE(li, lun_chain); 1782 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 1783 return li; 1784 } 1785 } 1786 } 1787 1788 if (alloc == 0) 1789 return li; 1790 1791 li = SCSI_LOW_MALLOC(ti->ti_lunsize); 1792 if (li == NULL) 1793 panic("no lun info mem"); 1794 1795 SCSI_LOW_BZERO(li, ti->ti_lunsize); 1796 li->li_lun = lun; 1797 li->li_ti = ti; 1798 1799 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC | 1800 SCSI_LOW_QTAG; 1801 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS; 1802 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID; 1803#ifdef SCSI_LOW_FLAGS_QUIRKS_OK 1804 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; 1805#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ 1806 1807 li->li_qtagbits = (u_int) -1; 1808 1809 TAILQ_INIT(&li->li_discq); 1810 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 1811 1812 /* host specific structure initialization per lun */ 1813 if (slp->sl_funcs->scsi_low_lun_init != NULL) 1814 (*slp->sl_funcs->scsi_low_lun_init) 1815 (slp, ti, li, SCSI_LOW_INFO_ALLOC); 1816 scsi_low_calcf_lun(li); 1817 return li; 1818} 1819 1820/************************************************************** 1821 * allocate targ_info 1822 **************************************************************/ 1823static struct targ_info * 1824scsi_low_alloc_ti(slp, targ) 1825 struct scsi_low_softc *slp; 1826 int targ; 1827{ 1828 struct targ_info *ti; 1829 1830 if (TAILQ_FIRST(&slp->sl_titab) == NULL) 1831 TAILQ_INIT(&slp->sl_titab); 1832 1833 ti = SCSI_LOW_MALLOC(slp->sl_targsize); 1834 if (ti == NULL) 1835 panic("%s short of memory", slp->sl_xname); 1836 1837 SCSI_LOW_BZERO(ti, slp->sl_targsize); 1838 ti->ti_id = targ; 1839 ti->ti_sc = slp; 1840 1841 slp->sl_ti[targ] = ti; 1842 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain); 1843 LIST_INIT(&ti->ti_litab); 1844 1845 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; 1846 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; 1847 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID; 1848#ifdef SCSI_LOW_FLAGS_QUIRKS_OK 1849 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; 1850#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ 1851 1852 if (slp->sl_funcs->scsi_low_targ_init != NULL) 1853 { 1854 (*slp->sl_funcs->scsi_low_targ_init) 1855 (slp, ti, SCSI_LOW_INFO_ALLOC); 1856 } 1857 scsi_low_calcf_target(ti); 1858 return ti; 1859} 1860 1861static void 1862scsi_low_free_ti(slp) 1863 struct scsi_low_softc *slp; 1864{ 1865 struct targ_info *ti, *tib; 1866 struct lun_info *li, *nli; 1867 1868 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib) 1869 { 1870 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli) 1871 { 1872 if (slp->sl_funcs->scsi_low_lun_init != NULL) 1873 { 1874 (*slp->sl_funcs->scsi_low_lun_init) 1875 (slp, ti, li, SCSI_LOW_INFO_DEALLOC); 1876 } 1877 nli = LIST_NEXT(li, lun_chain); 1878 SCSI_LOW_FREE(li); 1879 } 1880 1881 if (slp->sl_funcs->scsi_low_targ_init != NULL) 1882 { 1883 (*slp->sl_funcs->scsi_low_targ_init) 1884 (slp, ti, SCSI_LOW_INFO_DEALLOC); 1885 } 1886 tib = TAILQ_NEXT(ti, ti_chain); 1887 SCSI_LOW_FREE(ti); 1888 } 1889} 1890 1891/************************************************************** 1892 * timeout 1893 **************************************************************/ 1894void 1895scsi_low_bus_idle(slp) 1896 struct scsi_low_softc *slp; 1897{ 1898 1899 slp->sl_retry_sel = 0; 1900 if (slp->sl_Tnexus == NULL) 1901 scsi_low_start(slp); 1902} 1903 1904static void 1905scsi_low_timeout(arg) 1906 void *arg; 1907{ 1908 struct scsi_low_softc *slp = arg; 1909 int s; 1910 1911 s = SCSI_LOW_SPLSCSI(); 1912 (void) scsi_low_timeout_check(slp); 1913 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 1914 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 1915 splx(s); 1916} 1917 1918static int 1919scsi_low_timeout_check(slp) 1920 struct scsi_low_softc *slp; 1921{ 1922 struct targ_info *ti; 1923 struct lun_info *li; 1924 struct slccb *cb = NULL; /* XXX */ 1925 1926 /* selection restart */ 1927 if (slp->sl_retry_sel != 0) 1928 { 1929 slp->sl_retry_sel = 0; 1930 if (slp->sl_Tnexus != NULL) 1931 goto step1; 1932 1933 cb = TAILQ_FIRST(&slp->sl_start); 1934 if (cb == NULL) 1935 goto step1; 1936 1937 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY) 1938 { 1939 cb->ccb_flags |= CCB_NORETRY; 1940 cb->ccb_error |= SELTIMEOUTIO; 1941 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) 1942 panic("%s: ccb not finished", slp->sl_xname); 1943 } 1944 1945 if (slp->sl_Tnexus == NULL) 1946 scsi_low_start(slp); 1947 } 1948 1949 /* call hardware timeout */ 1950step1: 1951 if (slp->sl_funcs->scsi_low_timeout != NULL) 1952 { 1953 (*slp->sl_funcs->scsi_low_timeout) (slp); 1954 } 1955 1956 if (slp->sl_timeout_count ++ < 1957 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ) 1958 return 0; 1959 1960 slp->sl_timeout_count = 0; 1961 if (slp->sl_nio > 0) 1962 { 1963 if ((cb = slp->sl_Qnexus) != NULL) 1964 { 1965 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1966 if (cb->ccb_tc < 0) 1967 goto bus_reset; 1968 } 1969 else if (slp->sl_disc == 0) 1970 { 1971 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL) 1972 return 0; 1973 1974 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1975 if (cb->ccb_tc < 0) 1976 goto bus_reset; 1977 } 1978 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 1979 ti = TAILQ_NEXT(ti, ti_chain)) 1980 { 1981 if (ti->ti_disc == 0) 1982 continue; 1983 1984 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 1985 li = LIST_NEXT(li, lun_chain)) 1986 { 1987 for (cb = TAILQ_FIRST(&li->li_discq); 1988 cb != NULL; 1989 cb = TAILQ_NEXT(cb, ccb_chain)) 1990 { 1991 cb->ccb_tc -= 1992 SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 1993 if (cb->ccb_tc < 0) 1994 goto bus_reset; 1995 } 1996 } 1997 } 1998 1999 } 2000 else if ((slp->sl_flags & HW_POWERCTRL) != 0) 2001 { 2002 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0) 2003 return 0; 2004 2005 if (slp->sl_active != 0) 2006 { 2007 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 2008 slp->sl_active = 0; 2009 return 0; 2010 } 2011 2012 slp->sl_powc --; 2013 if (slp->sl_powc < 0) 2014 { 2015 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 2016 slp->sl_flags |= HW_POWDOWN; 2017 (*slp->sl_funcs->scsi_low_power) 2018 (slp, SCSI_LOW_POWDOWN); 2019 } 2020 } 2021 return 0; 2022 2023bus_reset: 2024 cb->ccb_error |= TIMEOUTIO; 2025 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb); 2026 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover."); 2027 scsi_low_init(slp, SCSI_LOW_RESTART_HARD); 2028 scsi_low_start(slp); 2029 return ERESTART; 2030} 2031 2032 2033static int 2034scsi_low_abort_ccb(slp, cb) 2035 struct scsi_low_softc *slp; 2036 struct slccb *cb; 2037{ 2038 struct targ_info *ti; 2039 struct lun_info *li; 2040 u_int msg; 2041 2042 if (cb == NULL) 2043 return EINVAL; 2044 if ((cb->ccb_omsgoutflag & 2045 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0) 2046 return EBUSY; 2047 2048 ti = cb->ti; 2049 li = cb->li; 2050 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 2051 msg = SCSI_LOW_MSG_ABORT; 2052 else 2053 msg = SCSI_LOW_MSG_ABORT_QTAG; 2054 2055 cb->ccb_error |= ABORTIO; 2056 cb->ccb_flags |= CCB_NORETRY; 2057 scsi_low_ccb_message_assert(cb, msg); 2058 2059 if (cb == slp->sl_Qnexus) 2060 { 2061 scsi_low_assert_msg(slp, ti, msg, 1); 2062 } 2063 else if ((cb->ccb_flags & CCB_DISCQ) != 0) 2064 { 2065 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL) 2066 panic("%s: revoked ccb done", slp->sl_xname); 2067 2068 cb->ccb_flags |= CCB_STARTQ; 2069 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2070 2071 if (slp->sl_Tnexus == NULL) 2072 scsi_low_start(slp); 2073 } 2074 else 2075 { 2076 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) 2077 panic("%s: revoked ccb retried", slp->sl_xname); 2078 } 2079 return 0; 2080} 2081 2082/************************************************************** 2083 * Generic SCSI INTERFACE 2084 **************************************************************/ 2085int 2086scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize) 2087 struct scsi_low_softc *slp; 2088 int openings, ntargs, nluns, targsize, lunsize; 2089{ 2090 struct targ_info *ti; 2091 struct lun_info *li; 2092 int s, i, nccb, rv; 2093 2094#ifdef SCSI_LOW_INTERFACE_XS 2095 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs; 2096#endif /* SCSI_LOW_INTERFACE_XS */ 2097#ifdef SCSI_LOW_INTERFACE_CAM 2098 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam; 2099#endif /* SCSI_LOW_INTERFACE_CAM */ 2100 2101 if (slp->sl_osdep_fp == NULL) 2102 panic("scsi_low: interface not spcified"); 2103 2104 if (ntargs > SCSI_LOW_NTARGETS) 2105 { 2106 printf("scsi_low: %d targets are too large\n", ntargs); 2107 printf("change kernel options SCSI_LOW_NTARGETS"); 2108 return EINVAL; 2109 } 2110 2111 if (openings <= 0) 2112 slp->sl_openings = (SCSI_LOW_NCCB / ntargs); 2113 else 2114 slp->sl_openings = openings; 2115 slp->sl_ntargs = ntargs; 2116 slp->sl_nluns = nluns; 2117 slp->sl_max_retry = SCSI_LOW_MAX_RETRY; 2118 2119 if (lunsize < sizeof(struct lun_info)) 2120 lunsize = sizeof(struct lun_info); 2121 2122 if (targsize < sizeof(struct targ_info)) 2123 targsize = sizeof(struct targ_info); 2124 2125 slp->sl_targsize = targsize; 2126 for (i = 0; i < ntargs; i ++) 2127 { 2128 ti = scsi_low_alloc_ti(slp, i); 2129 ti->ti_lunsize = lunsize; 2130 li = scsi_low_alloc_li(ti, 0, 1); 2131 } 2132 2133 /* initialize queue */ 2134 nccb = openings * ntargs; 2135 if (nccb >= SCSI_LOW_NCCB || nccb <= 0) 2136 nccb = SCSI_LOW_NCCB; 2137 scsi_low_init_ccbque(nccb); 2138 TAILQ_INIT(&slp->sl_start); 2139 2140 /* call os depend attach */ 2141 s = SCSI_LOW_SPLSCSI(); 2142 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp); 2143 if (rv != 0) 2144 { 2145 splx(s); 2146 printf("%s: scsi_low_attach: osdep attach failed\n", 2147 slp->sl_xname); 2148 return EINVAL; 2149 } 2150 2151 /* check hardware */ 2152 SCSI_LOW_DELAY(1000); /* wait for 1ms */ 2153 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0) 2154 { 2155 splx(s); 2156 printf("%s: scsi_low_attach: initialization failed\n", 2157 slp->sl_xname); 2158 return EINVAL; 2159 } 2160 2161 /* start watch dog */ 2162 slp->sl_timeout_count = 0; 2163 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 2164 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); 2165 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain); 2166 2167 /* fake call */ 2168 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL)); 2169 2170#ifdef SCSI_LOW_START_UP_CHECK 2171 /* probing devices */ 2172 scsi_low_start_up(slp); 2173#endif /* SCSI_LOW_START_UP_CHECK */ 2174 2175 /* call os depend attach done*/ 2176 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp); 2177 splx(s); 2178 return 0; 2179} 2180 2181int 2182scsi_low_dettach(slp) 2183 struct scsi_low_softc *slp; 2184{ 2185 int s, rv; 2186 2187 s = SCSI_LOW_SPLSCSI(); 2188 if (scsi_low_is_busy(slp) != 0) 2189 { 2190 splx(s); 2191 return EBUSY; 2192 } 2193 2194 scsi_low_deactivate(slp); 2195 2196 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp); 2197 if (rv != 0) 2198 { 2199 splx(s); 2200 return EBUSY; 2201 } 2202 2203 scsi_low_free_ti(slp); 2204 LIST_REMOVE(slp, sl_chain); 2205 splx(s); 2206 return 0; 2207} 2208 2209/************************************************************** 2210 * Generic enqueue 2211 **************************************************************/ 2212static int 2213scsi_low_enqueue(slp, ti, li, cb, flags, msg) 2214 struct scsi_low_softc *slp; 2215 struct targ_info *ti; 2216 struct lun_info *li; 2217 struct slccb *cb; 2218 u_int flags, msg; 2219{ 2220 2221 cb->ti = ti; 2222 cb->li = li; 2223 2224 scsi_low_ccb_message_assert(cb, msg); 2225 2226 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG; 2227 scsi_low_alloc_qtag(cb); 2228 2229 cb->ccb_flags = flags | CCB_STARTQ; 2230 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 2231 cb->ccb_error |= PENDINGIO; 2232 2233 if ((flags & CCB_URGENT) != 0) 2234 { 2235 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2236 } 2237 else 2238 { 2239 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain); 2240 } 2241 2242 slp->sl_nio ++; 2243 2244 if (slp->sl_Tnexus == NULL) 2245 scsi_low_start(slp); 2246 return 0; 2247} 2248 2249static int 2250scsi_low_message_enqueue(slp, ti, li, flags) 2251 struct scsi_low_softc *slp; 2252 struct targ_info *ti; 2253 struct lun_info *li; 2254 u_int flags; 2255{ 2256 struct slccb *cb; 2257 u_int tmsgflags; 2258 2259 tmsgflags = ti->ti_setup_msg; 2260 ti->ti_setup_msg = 0; 2261 2262 flags |= CCB_NORETRY; 2263 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) 2264 return ENOMEM; 2265 2266 cb->osdep = NULL; 2267 cb->bp = NULL; 2268 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags); 2269 return 0; 2270} 2271 2272/************************************************************** 2273 * Generic Start & Done 2274 **************************************************************/ 2275#define SLSC_MODE_SENSE_SHORT 0x1a 2276static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0}; 2277static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0, 2278 sizeof(struct scsi_low_mode_sense_data), 0}; 2279static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0, 2280 sizeof(struct scsi_low_inq_data), 0}; 2281static u_int8_t unit_ready_cmd[6]; 2282static int scsi_low_setup_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); 2283static int scsi_low_sense_abort_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); 2284static int scsi_low_resume(struct scsi_low_softc *); 2285 2286static void 2287scsi_low_unit_ready_cmd(cb) 2288 struct slccb *cb; 2289{ 2290 2291 cb->ccb_scp.scp_cmd = unit_ready_cmd; 2292 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd); 2293 cb->ccb_scp.scp_datalen = 0; 2294 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2295 cb->ccb_tcmax = 15; 2296} 2297 2298static int 2299scsi_low_sense_abort_start(slp, ti, li, cb) 2300 struct scsi_low_softc *slp; 2301 struct targ_info *ti; 2302 struct lun_info *li; 2303 struct slccb *cb; 2304{ 2305 2306 cb->ccb_scp.scp_cmdlen = 6; 2307 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen); 2308 cb->ccb_scsi_cmd[0] = REQUEST_SENSE; 2309 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense); 2310 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd; 2311 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense; 2312 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense); 2313 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2314 cb->ccb_tcmax = 15; 2315 scsi_low_ccb_message_clear(cb); 2316 if ((cb->ccb_flags & CCB_CLEARQ) != 0) 2317 { 2318 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 2319 } 2320 else 2321 { 2322 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense)); 2323#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 2324 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0); 2325#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 2326 } 2327 2328 return SCSI_LOW_START_NO_QTAG; 2329} 2330 2331static int 2332scsi_low_setup_start(slp, ti, li, cb) 2333 struct scsi_low_softc *slp; 2334 struct targ_info *ti; 2335 struct lun_info *li; 2336 struct slccb *cb; 2337{ 2338 2339 switch(li->li_state) 2340 { 2341 case SCSI_LOW_LUN_SLEEP: 2342 scsi_low_unit_ready_cmd(cb); 2343 break; 2344 2345 case SCSI_LOW_LUN_START: 2346 cb->ccb_scp.scp_cmd = ss_cmd; 2347 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd); 2348 cb->ccb_scp.scp_datalen = 0; 2349 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2350 cb->ccb_tcmax = 30; 2351 break; 2352 2353 case SCSI_LOW_LUN_INQ: 2354 cb->ccb_scp.scp_cmd = inq_cmd; 2355 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd); 2356 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq; 2357 cb->ccb_scp.scp_datalen = sizeof(li->li_inq); 2358 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2359 cb->ccb_tcmax = 15; 2360 break; 2361 2362 case SCSI_LOW_LUN_MODEQ: 2363 cb->ccb_scp.scp_cmd = sms_cmd; 2364 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd); 2365 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms; 2366 cb->ccb_scp.scp_datalen = sizeof(li->li_sms); 2367 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 2368 cb->ccb_tcmax = 15; 2369 return SCSI_LOW_START_QTAG; 2370 2371 default: 2372 panic("%s: no setup phase", slp->sl_xname); 2373 } 2374 2375 return SCSI_LOW_START_NO_QTAG; 2376} 2377 2378static int 2379scsi_low_resume(slp) 2380 struct scsi_low_softc *slp; 2381{ 2382 2383 if (slp->sl_flags & HW_RESUME) 2384 return EJUSTRETURN; 2385 slp->sl_flags &= ~HW_POWDOWN; 2386 if (slp->sl_funcs->scsi_low_power != NULL) 2387 { 2388 slp->sl_flags |= HW_RESUME; 2389 slp->sl_rstep = 0; 2390 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); 2391 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) 2392 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, 2393 SCSI_LOW_TIMEOUT_START); 2394 return EJUSTRETURN; 2395 } 2396 return 0; 2397} 2398 2399static void 2400scsi_low_start(slp) 2401 struct scsi_low_softc *slp; 2402{ 2403 struct targ_info *ti; 2404 struct lun_info *li; 2405 struct slccb *cb; 2406 int rv; 2407 2408 /* check hardware exists or under initializations ? */ 2409 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0) 2410 return; 2411 2412 /* check hardware power up ? */ 2413 if ((slp->sl_flags & HW_POWERCTRL) != 0) 2414 { 2415 slp->sl_active ++; 2416 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME)) 2417 { 2418 if (scsi_low_resume(slp) == EJUSTRETURN) 2419 return; 2420 } 2421 } 2422 2423 /* setup nexus */ 2424#ifdef SCSI_LOW_DIAGNOSTIC 2425 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus) 2426 { 2427 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT"); 2428 panic("%s: inconsistent", slp->sl_xname); 2429 } 2430#endif /* SCSI_LOW_DIAGNOSTIC */ 2431 2432 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL; 2433 cb = TAILQ_NEXT(cb, ccb_chain)) 2434 { 2435 li = cb->li; 2436 2437 if (li->li_disc == 0) 2438 { 2439 goto scsi_low_cmd_start; 2440 } 2441 else if (li->li_nqio > 0) 2442 { 2443 if (li->li_nqio < li->li_maxnqio || 2444 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2445 goto scsi_low_cmd_start; 2446 } 2447 } 2448 return; 2449 2450scsi_low_cmd_start: 2451 cb->ccb_flags &= ~CCB_STARTQ; 2452 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 2453 ti = cb->ti; 2454 2455 /* clear all error flag bits (for restart) */ 2456 cb->ccb_error = 0; 2457 cb->ccb_datalen = -1; 2458 cb->ccb_scp.scp_status = ST_UNKNOWN; 2459 2460 /* setup nexus pointer */ 2461 slp->sl_Qnexus = cb; 2462 slp->sl_Lnexus = li; 2463 slp->sl_Tnexus = ti; 2464 2465 /* initialize msgsys */ 2466 scsi_low_init_msgsys(slp, ti); 2467 2468 /* exec cmd */ 2469 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2470 { 2471 /* CA state or forced abort */ 2472 rv = scsi_low_sense_abort_start(slp, ti, li, cb); 2473 } 2474 else if (li->li_state >= SCSI_LOW_LUN_OK) 2475 { 2476 cb->ccb_flags &= ~CCB_INTERNAL; 2477 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb); 2478 if (cb->ccb_msgoutflag != 0) 2479 { 2480 scsi_low_ccb_message_exec(slp, cb); 2481 } 2482 } 2483 else 2484 { 2485 cb->ccb_flags |= CCB_INTERNAL; 2486 rv = scsi_low_setup_start(slp, ti, li, cb); 2487 } 2488 2489 /* allocate qtag */ 2490#define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC) 2491 2492 if (rv == SCSI_LOW_START_QTAG && 2493 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK && 2494 li->li_maxnqio > 0) 2495 { 2496 u_int qmsg; 2497 2498 scsi_low_activate_qtag(cb); 2499 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 2500 SCSI_LOW_CMD_ORDERED_QTAG) != 0) 2501 qmsg = SCSI_LOW_MSG_ORDERED_QTAG; 2502 else if ((cb->ccb_flags & CCB_URGENT) != 0) 2503 qmsg = SCSI_LOW_MSG_HEAD_QTAG; 2504 else 2505 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG; 2506 scsi_low_assert_msg(slp, ti, qmsg, 0); 2507 } 2508 2509 /* timeout */ 2510 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT) 2511 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 2512 cb->ccb_tc = cb->ccb_tcmax; 2513 2514 /* setup saved scsi data pointer */ 2515 cb->ccb_sscp = cb->ccb_scp; 2516 2517 /* setup current scsi pointer */ 2518 slp->sl_scp = cb->ccb_sscp; 2519 slp->sl_error = cb->ccb_error; 2520 2521 /* assert always an identify msg */ 2522 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0); 2523 2524 /* debug section */ 2525#ifdef SCSI_LOW_DIAGNOSTIC 2526 scsi_low_msg_log_init(&ti->ti_log_msgin); 2527 scsi_low_msg_log_init(&ti->ti_log_msgout); 2528#endif /* SCSI_LOW_DIAGNOSTIC */ 2529 2530 /* selection start */ 2531 slp->sl_selid = cb; 2532 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb)); 2533 if (rv == SCSI_LOW_START_OK) 2534 { 2535#ifdef SCSI_LOW_STATICS 2536 scsi_low_statics.nexus_win ++; 2537#endif /* SCSI_LOW_STATICS */ 2538 return; 2539 } 2540 2541 scsi_low_arbit_fail(slp, cb); 2542#ifdef SCSI_LOW_STATICS 2543 scsi_low_statics.nexus_fail ++; 2544#endif /* SCSI_LOW_STATICS */ 2545} 2546 2547void 2548scsi_low_arbit_fail(slp, cb) 2549 struct scsi_low_softc *slp; 2550 struct slccb *cb; 2551{ 2552 struct targ_info *ti = cb->ti; 2553 2554 scsi_low_deactivate_qtag(cb); 2555 scsi_low_ccb_message_retry(cb); 2556 cb->ccb_flags |= CCB_STARTQ; 2557 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 2558 2559 scsi_low_bus_release(slp, ti); 2560 2561 cb->ccb_selrcnt ++; 2562 if (slp->sl_disc == 0) 2563 { 2564#ifdef SCSI_LOW_DIAGNOSTIC 2565 printf("%s: try selection again\n", slp->sl_xname); 2566#endif /* SCSI_LOW_DIAGNOSTIC */ 2567 slp->sl_retry_sel = 1; 2568 } 2569} 2570 2571static void 2572scsi_low_bus_release(slp, ti) 2573 struct scsi_low_softc *slp; 2574 struct targ_info *ti; 2575{ 2576 2577 if (ti->ti_disc > 0) 2578 { 2579 SCSI_LOW_SETUP_PHASE(ti, PH_DISC); 2580 } 2581 else 2582 { 2583 SCSI_LOW_SETUP_PHASE(ti, PH_NULL); 2584 } 2585 2586 /* clear all nexus pointer */ 2587 slp->sl_Qnexus = NULL; 2588 slp->sl_Lnexus = NULL; 2589 slp->sl_Tnexus = NULL; 2590 2591 /* clear selection assert */ 2592 slp->sl_selid = NULL; 2593 2594 /* clear nexus data */ 2595 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK; 2596 2597 /* clear phase change counter */ 2598 slp->sl_ph_count = 0; 2599} 2600 2601static int 2602scsi_low_setup_done(slp, cb) 2603 struct scsi_low_softc *slp; 2604 struct slccb *cb; 2605{ 2606 struct targ_info *ti; 2607 struct lun_info *li; 2608 2609 ti = cb->ti; 2610 li = cb->li; 2611 2612 if (cb->ccb_rcnt >= slp->sl_max_retry) 2613 { 2614 cb->ccb_error |= ABORTIO; 2615 return SCSI_LOW_DONE_COMPLETE; 2616 } 2617 2618 /* XXX: special huck for selection timeout */ 2619 if (li->li_state == SCSI_LOW_LUN_SLEEP && 2620 (cb->ccb_error & SELTIMEOUTIO) != 0) 2621 { 2622 cb->ccb_error |= ABORTIO; 2623 return SCSI_LOW_DONE_COMPLETE; 2624 } 2625 2626 switch(li->li_state) 2627 { 2628 case SCSI_LOW_LUN_INQ: 2629 if (cb->ccb_error != 0) 2630 { 2631 li->li_diskflags &= 2632 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG); 2633 if (li->li_lun > 0) 2634 goto resume; 2635 ti->ti_diskflags &= 2636 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE); 2637 } 2638 else if ((li->li_inq.sd_version & 7) >= 2 || 2639 (li->li_inq.sd_len >= 4)) 2640 { 2641 if ((li->li_inq.sd_support & 0x2) == 0) 2642 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2643 if ((li->li_inq.sd_support & 0x8) == 0) 2644 li->li_diskflags &= ~SCSI_LOW_DISK_LINK; 2645 if (li->li_lun > 0) 2646 goto resume; 2647 if ((li->li_inq.sd_support & 0x10) == 0) 2648 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC; 2649 if ((li->li_inq.sd_support & 0x20) == 0) 2650 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16; 2651 if ((li->li_inq.sd_support & 0x40) == 0) 2652 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32; 2653 } 2654 else 2655 { 2656 li->li_diskflags &= 2657 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK); 2658 if (li->li_lun > 0) 2659 goto resume; 2660 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE; 2661 } 2662 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID; 2663resume: 2664 scsi_low_calcf_target(ti); 2665 scsi_low_calcf_lun(li); 2666 break; 2667 2668 case SCSI_LOW_LUN_MODEQ: 2669 if (cb->ccb_error != 0) 2670 { 2671 if (cb->ccb_error & SENSEIO) 2672 { 2673#ifdef SCSI_LOW_DEBUG 2674 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE) 2675 { 2676 printf("SENSE: [%x][%x][%x][%x][%x]\n", 2677 (u_int) cb->ccb_sense.error_code, 2678 (u_int) cb->ccb_sense.segment, 2679 (u_int) cb->ccb_sense.flags, 2680 (u_int) cb->ccb_sense.add_sense_code, 2681 (u_int) cb->ccb_sense.add_sense_code_qual); 2682 } 2683#endif /* SCSI_LOW_DEBUG */ 2684 } 2685 else 2686 { 2687 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2688 } 2689 } 2690 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a) 2691 { 2692 if (li->li_sms.sms_cmp.cmp_qc & 0x02) 2693 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR; 2694 else 2695 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR; 2696 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0) 2697 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; 2698 } 2699 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID; 2700 scsi_low_calcf_lun(li); 2701 break; 2702 2703 default: 2704 break; 2705 } 2706 2707 li->li_state ++; 2708 if (li->li_state == SCSI_LOW_LUN_OK) 2709 { 2710 scsi_low_calcf_target(ti); 2711 scsi_low_calcf_lun(li); 2712 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID && 2713 (slp->sl_show_result & SHOW_CALCF_RES) != 0) 2714 { 2715 scsi_low_calcf_show(li); 2716 } 2717 } 2718 2719 cb->ccb_rcnt --; 2720 return SCSI_LOW_DONE_RETRY; 2721} 2722 2723static int 2724scsi_low_done(slp, cb) 2725 struct scsi_low_softc *slp; 2726 struct slccb *cb; 2727{ 2728 int rv; 2729 2730 if (cb->ccb_error == 0) 2731 { 2732 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) 2733 { 2734#ifdef SCSI_LOW_QCLEAR_AFTER_CA 2735 /* XXX: 2736 * SCSI-2 draft suggests 2737 * page 0x0a QErr bit determins if 2738 * the target aborts or continues 2739 * the queueing io's after CA state resolved. 2740 * However many targets seem not to support 2741 * the page 0x0a. Thus we should manually clear the 2742 * queuing io's after CA state. 2743 */ 2744 if ((cb->ccb_flags & CCB_CLEARQ) == 0) 2745 { 2746 cb->ccb_rcnt --; 2747 cb->ccb_flags |= CCB_CLEARQ; 2748 goto retry; 2749 } 2750#endif /* SCSI_LOW_QCLEAR_AFTER_CA */ 2751 2752 if ((cb->ccb_flags & CCB_SENSE) != 0) 2753 cb->ccb_error |= (SENSEIO | ABORTIO); 2754 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ); 2755 } 2756 else switch (cb->ccb_sscp.scp_status) 2757 { 2758 case ST_GOOD: 2759 case ST_MET: 2760 case ST_INTERGOOD: 2761 case ST_INTERMET: 2762 if (cb->ccb_datalen == 0 || 2763 cb->ccb_scp.scp_datalen == 0) 2764 break; 2765 2766 if (cb->ccb_scp.scp_cmdlen > 0 && 2767 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & 2768 SCSI_LOW_CMD_RESIDUAL_CHK) == 0) 2769 break; 2770 2771 cb->ccb_error |= PDMAERR; 2772 break; 2773 2774 case ST_BUSY: 2775 case ST_QUEFULL: 2776 cb->ccb_error |= (BUSYERR | STATERR); 2777 break; 2778 2779 case ST_CONFLICT: 2780 cb->ccb_error |= (STATERR | ABORTIO); 2781 break; 2782 2783 case ST_CHKCOND: 2784 case ST_CMDTERM: 2785 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL)) 2786 { 2787 cb->ccb_rcnt --; 2788 cb->ccb_flags |= CCB_SENSE; 2789 goto retry; 2790 } 2791 cb->ccb_error |= (UACAERR | STATERR | ABORTIO); 2792 break; 2793 2794 case ST_UNKNOWN: 2795 default: 2796 cb->ccb_error |= FATALIO; 2797 break; 2798 } 2799 } 2800 else 2801 { 2802 if (cb->ccb_flags & CCB_SENSE) 2803 { 2804 cb->ccb_error |= (SENSEERR | ABORTIO); 2805 } 2806 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE); 2807 } 2808 2809 /* internal ccb */ 2810 if ((cb->ccb_flags & CCB_INTERNAL) != 0) 2811 { 2812 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY) 2813 goto retry; 2814 } 2815 2816 /* check a ccb msgout flag */ 2817 if (cb->ccb_omsgoutflag != 0) 2818 { 2819#define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \ 2820 SCSI_LOW_MSG_ABORT_QTAG | \ 2821 SCSI_LOW_MSG_CLEAR_QTAG | \ 2822 SCSI_LOW_MSG_TERMIO) 2823 2824 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0) 2825 { 2826 cb->ccb_error |= ABORTIO; 2827 } 2828 } 2829 2830 /* call OS depend done */ 2831 if (cb->osdep != NULL) 2832 { 2833 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb); 2834 if (rv == EJUSTRETURN) 2835 goto retry; 2836 } 2837 else if (cb->ccb_error != 0) 2838 { 2839 if (cb->ccb_rcnt >= slp->sl_max_retry) 2840 cb->ccb_error |= ABORTIO; 2841 2842 if ((cb->ccb_flags & CCB_NORETRY) == 0 && 2843 (cb->ccb_error & ABORTIO) == 0) 2844 goto retry; 2845 } 2846 2847 /* free our target */ 2848#ifdef SCSI_LOW_DEBUG 2849 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) 2850 { 2851 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n"); 2852 scsi_low_print(slp, NULL); 2853 } 2854#endif /* SCSI_LOW_DEBUG */ 2855 2856 scsi_low_deactivate_qtag(cb); 2857 scsi_low_dealloc_qtag(cb); 2858 scsi_low_free_ccb(cb); 2859 slp->sl_nio --; 2860 return SCSI_LOW_DONE_COMPLETE; 2861 2862retry: 2863#ifdef SCSI_LOW_DEBUG 2864 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) 2865 { 2866 printf("** SCSI_LOW_DONE_RETRY ===============\n"); 2867 scsi_low_print(slp, NULL); 2868 } 2869#endif /* SCSI_LOW_DEBUG */ 2870 2871 cb->ccb_rcnt ++; 2872 scsi_low_deactivate_qtag(cb); 2873 scsi_low_ccb_message_retry(cb); 2874 return SCSI_LOW_DONE_RETRY; 2875} 2876 2877/************************************************************** 2878 * Reset 2879 **************************************************************/ 2880static void 2881scsi_low_reset_nexus_target(slp, ti, fdone) 2882 struct scsi_low_softc *slp; 2883 struct targ_info *ti; 2884 int fdone; 2885{ 2886 struct lun_info *li; 2887 2888 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 2889 li = LIST_NEXT(li, lun_chain)) 2890 { 2891 scsi_low_reset_nexus_lun(slp, li, fdone); 2892 li->li_state = SCSI_LOW_LUN_SLEEP; 2893 li->li_maxnqio = 0; 2894 } 2895 2896 ti->ti_disc = 0; 2897 ti->ti_setup_msg = 0; 2898 ti->ti_setup_msg_done = 0; 2899 2900 ti->ti_osynch.offset = ti->ti_osynch.period = 0; 2901 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; 2902 2903 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; 2904 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID; 2905 2906 if (slp->sl_funcs->scsi_low_targ_init != NULL) 2907 { 2908 ((*slp->sl_funcs->scsi_low_targ_init) 2909 (slp, ti, SCSI_LOW_INFO_REVOKE)); 2910 } 2911 scsi_low_calcf_target(ti); 2912 2913 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 2914 li = LIST_NEXT(li, lun_chain)) 2915 { 2916 li->li_flags = 0; 2917 2918 li->li_diskflags = SCSI_LOW_DISK_LFLAGS; 2919 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID; 2920 2921 if (slp->sl_funcs->scsi_low_lun_init != NULL) 2922 { 2923 ((*slp->sl_funcs->scsi_low_lun_init) 2924 (slp, ti, li, SCSI_LOW_INFO_REVOKE)); 2925 } 2926 scsi_low_calcf_lun(li); 2927 } 2928} 2929 2930static void 2931scsi_low_reset_nexus(slp, fdone) 2932 struct scsi_low_softc *slp; 2933 int fdone; 2934{ 2935 struct targ_info *ti; 2936 struct slccb *cb, *topcb; 2937 2938 if ((cb = slp->sl_Qnexus) != NULL) 2939 { 2940 topcb = scsi_low_revoke_ccb(slp, cb, fdone); 2941 } 2942 else 2943 { 2944 topcb = NULL; 2945 } 2946 2947 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 2948 ti = TAILQ_NEXT(ti, ti_chain)) 2949 { 2950 scsi_low_reset_nexus_target(slp, ti, fdone); 2951 scsi_low_bus_release(slp, ti); 2952 scsi_low_init_msgsys(slp, ti); 2953 } 2954 2955 if (topcb != NULL) 2956 { 2957 topcb->ccb_flags |= CCB_STARTQ; 2958 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain); 2959 } 2960 2961 slp->sl_disc = 0; 2962 slp->sl_retry_sel = 0; 2963 slp->sl_flags &= ~HW_PDMASTART; 2964} 2965 2966/* misc */ 2967static int tw_pos; 2968static char tw_chars[] = "|/-\\"; 2969#define TWIDDLEWAIT 10000 2970 2971static void 2972scsi_low_twiddle_wait(void) 2973{ 2974 2975 cnputc('\b'); 2976 cnputc(tw_chars[tw_pos++]); 2977 tw_pos %= (sizeof(tw_chars) - 1); 2978 SCSI_LOW_DELAY(TWIDDLEWAIT); 2979} 2980 2981void 2982scsi_low_bus_reset(slp) 2983 struct scsi_low_softc *slp; 2984{ 2985 int i; 2986 2987 (*slp->sl_funcs->scsi_low_bus_reset) (slp); 2988 2989 printf("%s: try to reset scsi bus ", slp->sl_xname); 2990 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++) 2991 scsi_low_twiddle_wait(); 2992 cnputc('\b'); 2993 printf("\n"); 2994} 2995 2996int 2997scsi_low_restart(slp, flags, s) 2998 struct scsi_low_softc *slp; 2999 int flags; 3000 u_char *s; 3001{ 3002 int error; 3003 3004 if (s != NULL) 3005 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s); 3006 3007 if ((error = scsi_low_init(slp, flags)) != 0) 3008 return error; 3009 3010 scsi_low_start(slp); 3011 return 0; 3012} 3013 3014/************************************************************** 3015 * disconnect and reselect 3016 **************************************************************/ 3017#define MSGCMD_LUN(msg) (msg & 0x07) 3018 3019static struct slccb * 3020scsi_low_establish_ccb(ti, li, tag) 3021 struct targ_info *ti; 3022 struct lun_info *li; 3023 scsi_low_tag_t tag; 3024{ 3025 struct scsi_low_softc *slp = ti->ti_sc; 3026 struct slccb *cb; 3027 3028 if (li == NULL) 3029 return NULL; 3030 3031 cb = TAILQ_FIRST(&li->li_discq); 3032 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain)) 3033 if (cb->ccb_tag == tag) 3034 goto found; 3035 return cb; 3036 3037 /* 3038 * establish our ccb nexus 3039 */ 3040found: 3041#ifdef SCSI_LOW_DEBUG 3042 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) 3043 { 3044 printf("%s: nexus(0x%lx) abort check start\n", 3045 slp->sl_xname, (u_long) cb); 3046 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT); 3047 scsi_low_revoke_ccb(slp, cb, 1); 3048 return NULL; 3049 } 3050 3051 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0) 3052 { 3053 if (cb->ccb_omsgoutflag == 0) 3054 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP); 3055 } 3056#endif /* SCSI_LOW_DEBUG */ 3057 3058 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); 3059 cb->ccb_flags &= ~CCB_DISCQ; 3060 slp->sl_Qnexus = cb; 3061 3062 slp->sl_scp = cb->ccb_sscp; 3063 slp->sl_error |= cb->ccb_error; 3064 3065 slp->sl_disc --; 3066 ti->ti_disc --; 3067 li->li_disc --; 3068 3069 /* inform "ccb nexus established" to the host driver */ 3070 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3071 3072 /* check msg */ 3073 if (cb->ccb_msgoutflag != 0) 3074 { 3075 scsi_low_ccb_message_exec(slp, cb); 3076 } 3077 3078 return cb; 3079} 3080 3081struct targ_info * 3082scsi_low_reselected(slp, targ) 3083 struct scsi_low_softc *slp; 3084 u_int targ; 3085{ 3086 struct targ_info *ti; 3087 struct slccb *cb; 3088 u_char *s; 3089 3090 /* 3091 * Check select vs reselected collision. 3092 */ 3093 3094 if ((cb = slp->sl_selid) != NULL) 3095 { 3096 scsi_low_arbit_fail(slp, cb); 3097#ifdef SCSI_LOW_STATICS 3098 scsi_low_statics.nexus_conflict ++; 3099#endif /* SCSI_LOW_STATICS */ 3100 } 3101 3102 /* 3103 * Check if no current active nexus. 3104 */ 3105 if (slp->sl_Tnexus != NULL) 3106 { 3107 s = "host busy"; 3108 goto world_restart; 3109 } 3110 3111 /* 3112 * Check a valid target id asserted ? 3113 */ 3114 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid) 3115 { 3116 s = "scsi id illegal"; 3117 goto world_restart; 3118 } 3119 3120 /* 3121 * Check the target scsi status. 3122 */ 3123 ti = slp->sl_ti[targ]; 3124 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL) 3125 { 3126 s = "phase mismatch"; 3127 goto world_restart; 3128 } 3129 3130 /* 3131 * Setup init msgsys 3132 */ 3133 slp->sl_error = 0; 3134 scsi_low_init_msgsys(slp, ti); 3135 3136 /* 3137 * Establish our target nexus 3138 */ 3139 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL); 3140 slp->sl_Tnexus = ti; 3141#ifdef SCSI_LOW_STATICS 3142 scsi_low_statics.nexus_reselected ++; 3143#endif /* SCSI_LOW_STATICS */ 3144 return ti; 3145 3146world_restart: 3147 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s); 3148 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, 3149 "reselect: scsi world confused"); 3150 return NULL; 3151} 3152 3153/************************************************************** 3154 * cmd out pointer setup 3155 **************************************************************/ 3156int 3157scsi_low_cmd(slp, ti) 3158 struct scsi_low_softc *slp; 3159 struct targ_info *ti; 3160{ 3161 struct slccb *cb = slp->sl_Qnexus; 3162 3163 slp->sl_ph_count ++; 3164 if (cb == NULL) 3165 { 3166 /* 3167 * no ccb, abort! 3168 */ 3169 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd; 3170 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd); 3171 slp->sl_scp.scp_datalen = 0; 3172 slp->sl_scp.scp_direction = SCSI_LOW_READ; 3173 slp->sl_error |= FATALIO; 3174 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3175 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found"); 3176 return EINVAL; 3177 } 3178 else 3179 { 3180#ifdef SCSI_LOW_DEBUG 3181 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id)) 3182 { 3183 scsi_low_test_cmdlnk(slp, cb); 3184 } 3185#endif /* SCSI_LOW_DEBUG */ 3186 } 3187 return 0; 3188} 3189 3190/************************************************************** 3191 * data out pointer setup 3192 **************************************************************/ 3193int 3194scsi_low_data(slp, ti, bp, direction) 3195 struct scsi_low_softc *slp; 3196 struct targ_info *ti; 3197 struct buf **bp; 3198 int direction; 3199{ 3200 struct slccb *cb = slp->sl_Qnexus; 3201 3202 if (cb != NULL && direction == cb->ccb_sscp.scp_direction) 3203 { 3204 *bp = cb->bp; 3205 return 0; 3206 } 3207 3208 slp->sl_error |= (FATALIO | PDMAERR); 3209 slp->sl_scp.scp_datalen = 0; 3210 slp->sl_scp.scp_direction = direction; 3211 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3212 if (ti->ti_ophase != ti->ti_phase) 3213 { 3214 char *s; 3215 3216 if (cb == NULL) 3217 s = "DATA PHASE: ccb nexus not found"; 3218 else 3219 s = "DATA PHASE: xfer direction mismatch"; 3220 SCSI_LOW_INFO(slp, ti, s); 3221 } 3222 3223 *bp = NULL; 3224 return EINVAL; 3225} 3226 3227/************************************************************** 3228 * MSG_SYS 3229 **************************************************************/ 3230#define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;} 3231#define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3]) 3232#define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4]) 3233#define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3]) 3234#define MSGIN_DATA_LAST 0x30 3235 3236static int scsi_low_errfunc_synch(struct scsi_low_softc *, u_int); 3237static int scsi_low_errfunc_wide(struct scsi_low_softc *, u_int); 3238static int scsi_low_errfunc_identify(struct scsi_low_softc *, u_int); 3239static int scsi_low_errfunc_qtag(struct scsi_low_softc *, u_int); 3240 3241static int scsi_low_msgfunc_synch(struct scsi_low_softc *); 3242static int scsi_low_msgfunc_wide(struct scsi_low_softc *); 3243static int scsi_low_msgfunc_identify(struct scsi_low_softc *); 3244static int scsi_low_msgfunc_abort(struct scsi_low_softc *); 3245static int scsi_low_msgfunc_qabort(struct scsi_low_softc *); 3246static int scsi_low_msgfunc_qtag(struct scsi_low_softc *); 3247static int scsi_low_msgfunc_reset(struct scsi_low_softc *); 3248 3249struct scsi_low_msgout_data { 3250 u_int md_flags; 3251 u_int8_t md_msg; 3252 int (*md_msgfunc)(struct scsi_low_softc *); 3253 int (*md_errfunc)(struct scsi_low_softc *, u_int); 3254#define MSG_RELEASE_ATN 0x0001 3255 u_int md_condition; 3256}; 3257 3258struct scsi_low_msgout_data scsi_low_msgout_data[] = { 3259/* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN}, 3260/* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN}, 3261/* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN}, 3262/* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN}, 3263/* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0}, 3264/* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, 3265/* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN}, 3266/* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3267/* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3268/* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, 3269/* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN}, 3270/* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, 3271/* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN}, 3272/* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN}, 3273/* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN}, 3274/* 15 */{SCSI_LOW_MSG_ALL, 0}, 3275}; 3276 3277static int scsi_low_msginfunc_ext(struct scsi_low_softc *); 3278static int scsi_low_synch(struct scsi_low_softc *); 3279static int scsi_low_wide(struct scsi_low_softc *); 3280static int scsi_low_msginfunc_msg_reject(struct scsi_low_softc *); 3281static int scsi_low_msginfunc_rejop(struct scsi_low_softc *); 3282static int scsi_low_msginfunc_rp(struct scsi_low_softc *); 3283static int scsi_low_msginfunc_sdp(struct scsi_low_softc *); 3284static int scsi_low_msginfunc_disc(struct scsi_low_softc *); 3285static int scsi_low_msginfunc_cc(struct scsi_low_softc *); 3286static int scsi_low_msginfunc_lcc(struct scsi_low_softc *); 3287static int scsi_low_msginfunc_parity(struct scsi_low_softc *); 3288static int scsi_low_msginfunc_noop(struct scsi_low_softc *); 3289static int scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *); 3290static int scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *); 3291 3292struct scsi_low_msgin_data { 3293 u_int md_len; 3294 int (*md_msgfunc)(struct scsi_low_softc *); 3295}; 3296 3297struct scsi_low_msgin_data scsi_low_msgin_data[] = { 3298/* 0 */ {1, scsi_low_msginfunc_cc}, 3299/* 1 */ {2, scsi_low_msginfunc_ext}, 3300/* 2 */ {1, scsi_low_msginfunc_sdp}, 3301/* 3 */ {1, scsi_low_msginfunc_rp}, 3302/* 4 */ {1, scsi_low_msginfunc_disc}, 3303/* 5 */ {1, scsi_low_msginfunc_rejop}, 3304/* 6 */ {1, scsi_low_msginfunc_rejop}, 3305/* 7 */ {1, scsi_low_msginfunc_msg_reject}, 3306/* 8 */ {1, scsi_low_msginfunc_noop}, 3307/* 9 */ {1, scsi_low_msginfunc_parity}, 3308/* a */ {1, scsi_low_msginfunc_lcc}, 3309/* b */ {1, scsi_low_msginfunc_lcc}, 3310/* c */ {1, scsi_low_msginfunc_rejop}, 3311/* d */ {2, scsi_low_msginfunc_rejop}, 3312/* e */ {1, scsi_low_msginfunc_rejop}, 3313/* f */ {1, scsi_low_msginfunc_rejop}, 3314/* 0x10 */ {1, scsi_low_msginfunc_rejop}, 3315/* 0x11 */ {1, scsi_low_msginfunc_rejop}, 3316/* 0x12 */ {1, scsi_low_msginfunc_rejop}, 3317/* 0x13 */ {1, scsi_low_msginfunc_rejop}, 3318/* 0x14 */ {1, scsi_low_msginfunc_rejop}, 3319/* 0x15 */ {1, scsi_low_msginfunc_rejop}, 3320/* 0x16 */ {1, scsi_low_msginfunc_rejop}, 3321/* 0x17 */ {1, scsi_low_msginfunc_rejop}, 3322/* 0x18 */ {1, scsi_low_msginfunc_rejop}, 3323/* 0x19 */ {1, scsi_low_msginfunc_rejop}, 3324/* 0x1a */ {1, scsi_low_msginfunc_rejop}, 3325/* 0x1b */ {1, scsi_low_msginfunc_rejop}, 3326/* 0x1c */ {1, scsi_low_msginfunc_rejop}, 3327/* 0x1d */ {1, scsi_low_msginfunc_rejop}, 3328/* 0x1e */ {1, scsi_low_msginfunc_rejop}, 3329/* 0x1f */ {1, scsi_low_msginfunc_rejop}, 3330/* 0x20 */ {2, scsi_low_msginfunc_simple_qtag}, 3331/* 0x21 */ {2, scsi_low_msginfunc_rejop}, 3332/* 0x22 */ {2, scsi_low_msginfunc_rejop}, 3333/* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue}, 3334/* 0x24 */ {2, scsi_low_msginfunc_rejop}, 3335/* 0x25 */ {2, scsi_low_msginfunc_rejop}, 3336/* 0x26 */ {2, scsi_low_msginfunc_rejop}, 3337/* 0x27 */ {2, scsi_low_msginfunc_rejop}, 3338/* 0x28 */ {2, scsi_low_msginfunc_rejop}, 3339/* 0x29 */ {2, scsi_low_msginfunc_rejop}, 3340/* 0x2a */ {2, scsi_low_msginfunc_rejop}, 3341/* 0x2b */ {2, scsi_low_msginfunc_rejop}, 3342/* 0x2c */ {2, scsi_low_msginfunc_rejop}, 3343/* 0x2d */ {2, scsi_low_msginfunc_rejop}, 3344/* 0x2e */ {2, scsi_low_msginfunc_rejop}, 3345/* 0x2f */ {2, scsi_low_msginfunc_rejop}, 3346/* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */ 3347}; 3348 3349/************************************************************** 3350 * msgout 3351 **************************************************************/ 3352static int 3353scsi_low_msgfunc_synch(slp) 3354 struct scsi_low_softc *slp; 3355{ 3356 struct targ_info *ti = slp->sl_Tnexus; 3357 int ptr = ti->ti_msgoutlen; 3358 3359 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN; 3360 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE; 3361 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period; 3362 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset; 3363 return MSG_EXTEND_SYNCHLEN + 2; 3364} 3365 3366static int 3367scsi_low_msgfunc_wide(slp) 3368 struct scsi_low_softc *slp; 3369{ 3370 struct targ_info *ti = slp->sl_Tnexus; 3371 int ptr = ti->ti_msgoutlen; 3372 3373 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN; 3374 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE; 3375 ti->ti_msgoutstr[ptr + 3] = ti->ti_width; 3376 return MSG_EXTEND_WIDELEN + 2; 3377} 3378 3379static int 3380scsi_low_msgfunc_identify(slp) 3381 struct scsi_low_softc *slp; 3382{ 3383 struct targ_info *ti = slp->sl_Tnexus; 3384 struct lun_info *li = slp->sl_Lnexus; 3385 struct slccb *cb = slp->sl_Qnexus; 3386 int ptr = ti->ti_msgoutlen; 3387 u_int8_t msg; 3388 3389 msg = MSG_IDENTIFY; 3390 if (cb == NULL) 3391 { 3392 slp->sl_error |= FATALIO; 3393 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3394 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown"); 3395 } 3396 else 3397 { 3398 if (scsi_low_is_disconnect_ok(cb) != 0) 3399 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun); 3400 else 3401 msg |= li->li_lun; 3402 3403 if (ti->ti_phase == PH_MSGOUT) 3404 { 3405 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); 3406 if (cb->ccb_tag == SCSI_LOW_UNKTAG) 3407 { 3408 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3409 } 3410 } 3411 } 3412 ti->ti_msgoutstr[ptr + 0] = msg; 3413 return 1; 3414} 3415 3416static int 3417scsi_low_msgfunc_abort(slp) 3418 struct scsi_low_softc *slp; 3419{ 3420 3421 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT); 3422 return 1; 3423} 3424 3425static int 3426scsi_low_msgfunc_qabort(slp) 3427 struct scsi_low_softc *slp; 3428{ 3429 3430 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM); 3431 return 1; 3432} 3433 3434static int 3435scsi_low_msgfunc_reset(slp) 3436 struct scsi_low_softc *slp; 3437{ 3438 3439 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET); 3440 return 1; 3441} 3442 3443static int 3444scsi_low_msgfunc_qtag(slp) 3445 struct scsi_low_softc *slp; 3446{ 3447 struct targ_info *ti = slp->sl_Tnexus; 3448 struct slccb *cb = slp->sl_Qnexus; 3449 int ptr = ti->ti_msgoutlen; 3450 3451 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG) 3452 { 3453 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP; 3454 return 1; 3455 } 3456 else 3457 { 3458 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag; 3459 if (ti->ti_phase == PH_MSGOUT) 3460 { 3461 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); 3462 } 3463 } 3464 return 2; 3465} 3466 3467/* 3468 * The following functions are called when targets give unexpected 3469 * responces in msgin (after msgout). 3470 */ 3471static int 3472scsi_low_errfunc_identify(slp, msgflags) 3473 struct scsi_low_softc *slp; 3474 u_int msgflags; 3475{ 3476 3477 if (slp->sl_Lnexus != NULL) 3478 { 3479 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC; 3480 scsi_low_calcf_lun(slp->sl_Lnexus); 3481 } 3482 return 0; 3483} 3484 3485static int 3486scsi_low_errfunc_synch(slp, msgflags) 3487 struct scsi_low_softc *slp; 3488 u_int msgflags; 3489{ 3490 struct targ_info *ti = slp->sl_Tnexus; 3491 3492 MSGIN_PERIOD(ti) = 0; 3493 MSGIN_OFFSET(ti) = 0; 3494 scsi_low_synch(slp); 3495 return 0; 3496} 3497 3498static int 3499scsi_low_errfunc_wide(slp, msgflags) 3500 struct scsi_low_softc *slp; 3501 u_int msgflags; 3502{ 3503 struct targ_info *ti = slp->sl_Tnexus; 3504 3505 MSGIN_WIDTHP(ti) = 0; 3506 scsi_low_wide(slp); 3507 return 0; 3508} 3509 3510static int 3511scsi_low_errfunc_qtag(slp, msgflags) 3512 struct scsi_low_softc *slp; 3513 u_int msgflags; 3514{ 3515 3516 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0) 3517 { 3518 if (slp->sl_Qnexus != NULL) 3519 { 3520 scsi_low_deactivate_qtag(slp->sl_Qnexus); 3521 } 3522 if (slp->sl_Lnexus != NULL) 3523 { 3524 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG; 3525 scsi_low_calcf_lun(slp->sl_Lnexus); 3526 } 3527 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname); 3528 } 3529 return 0; 3530} 3531 3532 3533int 3534scsi_low_msgout(slp, ti, fl) 3535 struct scsi_low_softc *slp; 3536 struct targ_info *ti; 3537 u_int fl; 3538{ 3539 struct scsi_low_msgout_data *mdp; 3540 int len = 0; 3541 3542#ifdef SCSI_LOW_DIAGNOSTIC 3543 if (ti != slp->sl_Tnexus) 3544 { 3545 scsi_low_print(slp, NULL); 3546 panic("scsi_low_msgout: Target nexus inconsistent"); 3547 } 3548#endif /* SCSI_LOW_DIAGNOSTIC */ 3549 3550 slp->sl_ph_count ++; 3551 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) 3552 { 3553 printf("%s: too many phase changes\n", slp->sl_xname); 3554 slp->sl_error |= FATALIO; 3555 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3556 } 3557 3558 /* STEP I. 3559 * Scsi phase changes. 3560 * Previously msgs asserted are accepted by our target or 3561 * processed by scsi_low_msgin. 3562 * Thus clear all saved informations. 3563 */ 3564 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0) 3565 { 3566 ti->ti_omsgflags = 0; 3567 ti->ti_emsgflags = 0; 3568 } 3569 else if (slp->sl_atten == 0) 3570 { 3571 /* STEP II. 3572 * We did not assert attention, however still our target required 3573 * msgs. Resend previous msgs. 3574 */ 3575 ti->ti_msgflags |= ti->ti_omsgflags; 3576 ti->ti_omsgflags = 0; 3577#ifdef SCSI_LOW_DIAGNOSTIC 3578 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname); 3579#endif /* SCSI_LOW_DIAGNOSTIC */ 3580 } 3581 3582 /* STEP III. 3583 * We have no msgs. send MSG_NOOP (OK?) 3584 */ 3585 if (scsi_low_is_msgout_continue(ti, 0) == 0) 3586 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0); 3587 3588 /* STEP IV. 3589 * Process all msgs 3590 */ 3591 ti->ti_msgoutlen = 0; 3592 slp->sl_clear_atten = 0; 3593 mdp = &scsi_low_msgout_data[0]; 3594 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 3595 { 3596 if ((ti->ti_msgflags & mdp->md_flags) != 0) 3597 { 3598 ti->ti_omsgflags |= mdp->md_flags; 3599 ti->ti_msgflags &= ~mdp->md_flags; 3600 ti->ti_emsgflags = mdp->md_flags; 3601 3602 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg; 3603 if (mdp->md_msgfunc != NULL) 3604 len = (*mdp->md_msgfunc) (slp); 3605 else 3606 len = 1; 3607 3608#ifdef SCSI_LOW_DIAGNOSTIC 3609 scsi_low_msg_log_write(&ti->ti_log_msgout, 3610 &ti->ti_msgoutstr[ti->ti_msgoutlen], len); 3611#endif /* SCSI_LOW_DIAGNOSTIC */ 3612 3613 ti->ti_msgoutlen += len; 3614 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0) 3615 { 3616 slp->sl_clear_atten = 1; 3617 break; 3618 } 3619 3620 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 || 3621 ti->ti_msgflags == 0) 3622 break; 3623 3624 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5) 3625 break; 3626 } 3627 } 3628 3629 if (scsi_low_is_msgout_continue(ti, 0) == 0) 3630 slp->sl_clear_atten = 1; 3631 3632 return ti->ti_msgoutlen; 3633} 3634 3635/************************************************************** 3636 * msgin 3637 **************************************************************/ 3638static int 3639scsi_low_msginfunc_noop(slp) 3640 struct scsi_low_softc *slp; 3641{ 3642 3643 return 0; 3644} 3645 3646static int 3647scsi_low_msginfunc_rejop(slp) 3648 struct scsi_low_softc *slp; 3649{ 3650 struct targ_info *ti = slp->sl_Tnexus; 3651 u_int8_t msg = ti->ti_msgin[0]; 3652 3653 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg); 3654 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3655 return 0; 3656} 3657 3658static int 3659scsi_low_msginfunc_cc(slp) 3660 struct scsi_low_softc *slp; 3661{ 3662 struct lun_info *li; 3663 3664 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC); 3665 3666 /* validate status */ 3667 if (slp->sl_Qnexus == NULL) 3668 return ENOENT; 3669 3670 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status; 3671 li = slp->sl_Lnexus; 3672 switch (slp->sl_scp.scp_status) 3673 { 3674 case ST_GOOD: 3675 li->li_maxnqio = li->li_maxnexus; 3676 break; 3677 3678 case ST_CHKCOND: 3679 li->li_maxnqio = 0; 3680 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR) 3681 scsi_low_reset_nexus_lun(slp, li, 0); 3682 break; 3683 3684 case ST_BUSY: 3685 li->li_maxnqio = 0; 3686 break; 3687 3688 case ST_QUEFULL: 3689 if (li->li_maxnexus >= li->li_nqio) 3690 li->li_maxnexus = li->li_nqio - 1; 3691 li->li_maxnqio = li->li_maxnexus; 3692 break; 3693 3694 case ST_INTERGOOD: 3695 case ST_INTERMET: 3696 slp->sl_error |= MSGERR; 3697 break; 3698 3699 default: 3700 break; 3701 } 3702 return 0; 3703} 3704 3705static int 3706scsi_low_msginfunc_lcc(slp) 3707 struct scsi_low_softc *slp; 3708{ 3709 struct targ_info *ti; 3710 struct lun_info *li; 3711 struct slccb *ncb, *cb; 3712 3713 ti = slp->sl_Tnexus; 3714 li = slp->sl_Lnexus; 3715 if ((cb = slp->sl_Qnexus) == NULL) 3716 goto bad; 3717 3718 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status; 3719 switch (slp->sl_scp.scp_status) 3720 { 3721 case ST_INTERGOOD: 3722 case ST_INTERMET: 3723 li->li_maxnqio = li->li_maxnexus; 3724 break; 3725 3726 default: 3727 slp->sl_error |= MSGERR; 3728 break; 3729 } 3730 3731 if ((li->li_flags & SCSI_LOW_LINK) == 0) 3732 goto bad; 3733 3734 cb->ccb_error |= slp->sl_error; 3735 if (cb->ccb_error != 0) 3736 goto bad; 3737 3738 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL; 3739 ncb = TAILQ_NEXT(ncb, ccb_chain)) 3740 { 3741 if (ncb->li == li) 3742 goto cmd_link_start; 3743 } 3744 3745 3746bad: 3747 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM); 3748 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 3749 return EIO; 3750 3751cmd_link_start: 3752 ncb->ccb_flags &= ~CCB_STARTQ; 3753 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain); 3754 3755 scsi_low_dealloc_qtag(ncb); 3756 ncb->ccb_tag = cb->ccb_tag; 3757 ncb->ccb_otag = cb->ccb_otag; 3758 cb->ccb_tag = SCSI_LOW_UNKTAG; 3759 cb->ccb_otag = SCSI_LOW_UNKTAG; 3760 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) 3761 panic("%s: linked ccb retried", slp->sl_xname); 3762 3763 slp->sl_Qnexus = ncb; 3764 slp->sl_ph_count = 0; 3765 3766 ncb->ccb_error = 0; 3767 ncb->ccb_datalen = -1; 3768 ncb->ccb_scp.scp_status = ST_UNKNOWN; 3769 ncb->ccb_flags &= ~CCB_INTERNAL; 3770 3771 scsi_low_init_msgsys(slp, ti); 3772 3773 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb); 3774 3775 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT) 3776 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 3777 ncb->ccb_tc = ncb->ccb_tcmax; 3778 3779 /* setup saved scsi data pointer */ 3780 ncb->ccb_sscp = ncb->ccb_scp; 3781 slp->sl_scp = ncb->ccb_sscp; 3782 slp->sl_error = ncb->ccb_error; 3783 3784#ifdef SCSI_LOW_DIAGNOSTIC 3785 scsi_low_msg_log_init(&ti->ti_log_msgin); 3786 scsi_low_msg_log_init(&ti->ti_log_msgout); 3787#endif /* SCSI_LOW_DIAGNOSTIC */ 3788 return EJUSTRETURN; 3789} 3790 3791static int 3792scsi_low_msginfunc_disc(slp) 3793 struct scsi_low_softc *slp; 3794{ 3795 3796 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC); 3797 return 0; 3798} 3799 3800static int 3801scsi_low_msginfunc_sdp(slp) 3802 struct scsi_low_softc *slp; 3803{ 3804 struct slccb *cb = slp->sl_Qnexus; 3805 3806 if (cb != NULL) 3807 { 3808 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen; 3809 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data; 3810 } 3811 else 3812 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); 3813 return 0; 3814} 3815 3816static int 3817scsi_low_msginfunc_rp(slp) 3818 struct scsi_low_softc *slp; 3819{ 3820 3821 if (slp->sl_Qnexus != NULL) 3822 slp->sl_scp = slp->sl_Qnexus->ccb_sscp; 3823 else 3824 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); 3825 return 0; 3826} 3827 3828static int 3829scsi_low_synch(slp) 3830 struct scsi_low_softc *slp; 3831{ 3832 struct targ_info *ti = slp->sl_Tnexus; 3833 u_int period = 0, offset = 0, speed; 3834 u_char *s; 3835 int error; 3836 3837 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period && 3838 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) || 3839 MSGIN_OFFSET(ti) == 0) 3840 { 3841 if ((offset = MSGIN_OFFSET(ti)) != 0) 3842 period = MSGIN_PERIOD(ti); 3843 s = offset ? "synchronous" : "async"; 3844 } 3845 else 3846 { 3847 /* XXX: 3848 * Target seems to be brain damaged. 3849 * Force async transfer. 3850 */ 3851 ti->ti_maxsynch.period = 0; 3852 ti->ti_maxsynch.offset = 0; 3853 printf("%s: target brain damaged. async transfer\n", 3854 slp->sl_xname); 3855 return EINVAL; 3856 } 3857 3858 ti->ti_maxsynch.period = period; 3859 ti->ti_maxsynch.offset = offset; 3860 3861 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH); 3862 if (error != 0) 3863 { 3864 /* XXX: 3865 * Current period and offset are not acceptable 3866 * for our adapter. 3867 * The adapter changes max synch and max offset. 3868 */ 3869 printf("%s: synch neg failed. retry synch msg neg ...\n", 3870 slp->sl_xname); 3871 return error; 3872 } 3873 3874 ti->ti_osynch = ti->ti_maxsynch; 3875 if (offset > 0) 3876 { 3877 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH; 3878 } 3879 3880 /* inform data */ 3881 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0) 3882 { 3883#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 3884 struct slccb *cb = slp->sl_Qnexus; 3885 3886 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) 3887 return 0; 3888#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 3889 3890 printf("%s(%d:*): <%s> offset %d period %dns ", 3891 slp->sl_xname, ti->ti_id, s, offset, period * 4); 3892 3893 if (period != 0) 3894 { 3895 speed = 1000 * 10 / (period * 4); 3896 printf("%d.%d M/s", speed / 10, speed % 10); 3897 } 3898 printf("\n"); 3899 } 3900 return 0; 3901} 3902 3903static int 3904scsi_low_wide(slp) 3905 struct scsi_low_softc *slp; 3906{ 3907 struct targ_info *ti = slp->sl_Tnexus; 3908 int error; 3909 3910 ti->ti_width = MSGIN_WIDTHP(ti); 3911 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE); 3912 if (error != 0) 3913 { 3914 /* XXX: 3915 * Current width is not acceptable for our adapter. 3916 * The adapter changes max width. 3917 */ 3918 printf("%s: wide neg failed. retry wide msg neg ...\n", 3919 slp->sl_xname); 3920 return error; 3921 } 3922 3923 ti->ti_owidth = ti->ti_width; 3924 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8) 3925 { 3926 ti->ti_setup_msg_done |= 3927 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE); 3928 } 3929 3930 /* inform data */ 3931 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0) 3932 { 3933#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE 3934 struct slccb *cb = slp->sl_Qnexus; 3935 3936 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) 3937 return 0; 3938#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ 3939 3940 printf("%s(%d:*): transfer width %d bits\n", 3941 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width)); 3942 } 3943 return 0; 3944} 3945 3946static int 3947scsi_low_msginfunc_simple_qtag(slp) 3948 struct scsi_low_softc *slp; 3949{ 3950 struct targ_info *ti = slp->sl_Tnexus; 3951 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1]; 3952 3953 if (slp->sl_Qnexus != NULL) 3954 { 3955 if (slp->sl_Qnexus->ccb_tag != etag) 3956 { 3957 slp->sl_error |= FATALIO; 3958 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 3959 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch"); 3960 } 3961 } 3962 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL) 3963 { 3964#ifdef SCSI_LOW_DEBUG 3965 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id)) 3966 return 0; 3967#endif /* SCSI_LOW_DEBUG */ 3968 3969 slp->sl_error |= FATALIO; 3970 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0); 3971 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found"); 3972 } 3973 return 0; 3974} 3975 3976static int 3977scsi_low_msginfunc_i_wide_residue(slp) 3978 struct scsi_low_softc *slp; 3979{ 3980 struct targ_info *ti = slp->sl_Tnexus; 3981 struct slccb *cb = slp->sl_Qnexus; 3982 int res = (int) ti->ti_msgin[1]; 3983 3984 if (cb == NULL || res <= 0 || 3985 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) || 3986 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3)) 3987 return EINVAL; 3988 3989 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen) 3990 return EINVAL; 3991 3992 slp->sl_scp.scp_datalen += res; 3993 slp->sl_scp.scp_data -= res; 3994 scsi_low_data_finish(slp); 3995 return 0; 3996} 3997 3998static int 3999scsi_low_msginfunc_ext(slp) 4000 struct scsi_low_softc *slp; 4001{ 4002 struct slccb *cb = slp->sl_Qnexus; 4003 struct lun_info *li = slp->sl_Lnexus; 4004 struct targ_info *ti = slp->sl_Tnexus; 4005 int count, retry; 4006 u_int32_t *ptr; 4007 4008 if (ti->ti_msginptr == 2) 4009 { 4010 ti->ti_msginlen = ti->ti_msgin[1] + 2; 4011 return 0; 4012 } 4013 4014 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2])) 4015 { 4016 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE): 4017 if (cb == NULL) 4018 break; 4019 4020 ptr = (u_int32_t *)(&ti->ti_msgin[3]); 4021 count = (int) htonl((long) (*ptr)); 4022 if(slp->sl_scp.scp_datalen - count < 0 || 4023 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen) 4024 break; 4025 4026 slp->sl_scp.scp_datalen -= count; 4027 slp->sl_scp.scp_data += count; 4028 return 0; 4029 4030 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE): 4031 if (li == NULL) 4032 break; 4033 4034 retry = scsi_low_synch(slp); 4035 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0) 4036 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0); 4037 4038#ifdef SCSI_LOW_DEBUG 4039 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) 4040 { 4041 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH); 4042 } 4043#endif /* SCSI_LOW_DEBUG */ 4044 return 0; 4045 4046 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE): 4047 if (li == NULL) 4048 break; 4049 4050 retry = scsi_low_wide(slp); 4051 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0) 4052 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0); 4053 4054 return 0; 4055 4056 default: 4057 break; 4058 } 4059 4060 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 4061 return EINVAL; 4062} 4063 4064static int 4065scsi_low_msginfunc_parity(slp) 4066 struct scsi_low_softc *slp; 4067{ 4068 struct targ_info *ti = slp->sl_Tnexus; 4069 4070 /* only I -> T, invalid! */ 4071 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 4072 return 0; 4073} 4074 4075static int 4076scsi_low_msginfunc_msg_reject(slp) 4077 struct scsi_low_softc *slp; 4078{ 4079 struct targ_info *ti = slp->sl_Tnexus; 4080 struct scsi_low_msgout_data *mdp; 4081 u_int msgflags; 4082 4083 if (ti->ti_emsgflags != 0) 4084 { 4085 printf("%s: msg flags [0x%x] rejected\n", 4086 slp->sl_xname, ti->ti_emsgflags); 4087 msgflags = SCSI_LOW_MSG_REJECT; 4088 mdp = &scsi_low_msgout_data[0]; 4089 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 4090 { 4091 if ((ti->ti_emsgflags & mdp->md_flags) != 0) 4092 { 4093 ti->ti_emsgflags &= ~mdp->md_flags; 4094 if (mdp->md_errfunc != NULL) 4095 (*mdp->md_errfunc) (slp, msgflags); 4096 break; 4097 } 4098 } 4099 return 0; 4100 } 4101 else 4102 { 4103 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found"); 4104 slp->sl_error |= MSGERR; 4105 } 4106 return EINVAL; 4107} 4108 4109int 4110scsi_low_msgin(slp, ti, c) 4111 struct scsi_low_softc *slp; 4112 struct targ_info *ti; 4113 u_int c; 4114{ 4115 struct scsi_low_msgin_data *sdp; 4116 struct lun_info *li; 4117 u_int8_t msg; 4118 4119#ifdef SCSI_LOW_DIAGNOSTIC 4120 if (ti != slp->sl_Tnexus) 4121 { 4122 scsi_low_print(slp, NULL); 4123 panic("scsi_low_msgin: Target nexus inconsistent"); 4124 } 4125#endif /* SCSI_LOW_DIAGNOSTIC */ 4126 4127 /* 4128 * Phase changes, clear the pointer. 4129 */ 4130 if (ti->ti_ophase != ti->ti_phase) 4131 { 4132 MSGINPTR_CLR(ti); 4133 ti->ti_msgin_parity_error = 0; 4134 4135 slp->sl_ph_count ++; 4136 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) 4137 { 4138 printf("%s: too many phase changes\n", slp->sl_xname); 4139 slp->sl_error |= FATALIO; 4140 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 4141 } 4142 } 4143 4144 /* 4145 * Store a current messages byte into buffer and 4146 * wait for the completion of the current msg. 4147 */ 4148 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c; 4149 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN) 4150 { 4151 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1; 4152 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 4153 } 4154 4155 /* 4156 * Check parity errors. 4157 */ 4158 if ((c & SCSI_LOW_DATA_PE) != 0) 4159 { 4160 ti->ti_msgin_parity_error ++; 4161 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0); 4162 goto out; 4163 } 4164 4165 if (ti->ti_msgin_parity_error != 0) 4166 goto out; 4167 4168 /* 4169 * Calculate messages length. 4170 */ 4171 msg = ti->ti_msgin[0]; 4172 if (msg < MSGIN_DATA_LAST) 4173 sdp = &scsi_low_msgin_data[msg]; 4174 else 4175 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST]; 4176 4177 if (ti->ti_msginlen == 0) 4178 { 4179 ti->ti_msginlen = sdp->md_len; 4180 } 4181 4182 /* 4183 * Check comletion. 4184 */ 4185 if (ti->ti_msginptr < ti->ti_msginlen) 4186 return EJUSTRETURN; 4187 4188 /* 4189 * Do process. 4190 */ 4191 if ((msg & MSG_IDENTIFY) == 0) 4192 { 4193 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN) 4194 return EJUSTRETURN; 4195 } 4196 else 4197 { 4198 li = slp->sl_Lnexus; 4199 if (li == NULL) 4200 { 4201 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0); 4202 if (li == NULL) 4203 goto badlun; 4204 slp->sl_Lnexus = li; 4205 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); 4206 } 4207 else 4208 { 4209 if (MSGCMD_LUN(msg) != li->li_lun) 4210 goto badlun; 4211 } 4212 4213 if (slp->sl_Qnexus == NULL && li->li_nqio == 0) 4214 { 4215 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG)) 4216 { 4217#ifdef SCSI_LOW_DEBUG 4218 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) 4219 { 4220 goto out; 4221 } 4222#endif /* SCSI_LOW_DEBUG */ 4223 goto badlun; 4224 } 4225 } 4226 } 4227 goto out; 4228 4229 /* 4230 * Msg process completed, reset msgin pointer and assert ATN if desired. 4231 */ 4232badlun: 4233 slp->sl_error |= FATALIO; 4234 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 4235 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong"); 4236 4237out: 4238 if (ti->ti_msginptr < ti->ti_msginlen) 4239 return EJUSTRETURN; 4240 4241#ifdef SCSI_LOW_DIAGNOSTIC 4242 scsi_low_msg_log_write(&ti->ti_log_msgin, 4243 &ti->ti_msgin[0], ti->ti_msginlen); 4244#endif /* SCSI_LOW_DIAGNOSTIC */ 4245 4246 MSGINPTR_CLR(ti); 4247 return 0; 4248} 4249 4250/********************************************************** 4251 * disconnect 4252 **********************************************************/ 4253int 4254scsi_low_disconnected(slp, ti) 4255 struct scsi_low_softc *slp; 4256 struct targ_info *ti; 4257{ 4258 struct slccb *cb = slp->sl_Qnexus; 4259 4260 /* check phase completion */ 4261 switch (slp->sl_msgphase) 4262 { 4263 case MSGPH_RESET: 4264 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4265 scsi_low_msginfunc_cc(slp); 4266 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0); 4267 goto io_resume; 4268 4269 case MSGPH_ABORT: 4270 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4271 scsi_low_msginfunc_cc(slp); 4272 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0); 4273 goto io_resume; 4274 4275 case MSGPH_TERM: 4276 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); 4277 scsi_low_msginfunc_cc(slp); 4278 goto io_resume; 4279 4280 case MSGPH_DISC: 4281 if (cb != NULL) 4282 { 4283 struct lun_info *li; 4284 4285 li = cb->li; 4286 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain); 4287 cb->ccb_flags |= CCB_DISCQ; 4288 cb->ccb_error |= slp->sl_error; 4289 li->li_disc ++; 4290 ti->ti_disc ++; 4291 slp->sl_disc ++; 4292 } 4293 4294#ifdef SCSI_LOW_STATICS 4295 scsi_low_statics.nexus_disconnected ++; 4296#endif /* SCSI_LOW_STATICS */ 4297 4298#ifdef SCSI_LOW_DEBUG 4299 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0) 4300 { 4301 printf("## SCSI_LOW_DISCONNECTED ===============\n"); 4302 scsi_low_print(slp, NULL); 4303 } 4304#endif /* SCSI_LOW_DEBUG */ 4305 break; 4306 4307 case MSGPH_NULL: 4308 slp->sl_error |= FATALIO; 4309 if (ti->ti_phase == PH_SELSTART) 4310 slp->sl_error |= SELTIMEOUTIO; 4311 else 4312 slp->sl_error |= UBFERR; 4313 /* fall through */ 4314 4315 case MSGPH_LCTERM: 4316 case MSGPH_CMDC: 4317io_resume: 4318 if (cb == NULL) 4319 break; 4320 4321#ifdef SCSI_LOW_DEBUG 4322 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) 4323 { 4324 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP && 4325 (cb->ccb_msgoutflag != 0 || 4326 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP))) 4327 { 4328 scsi_low_info(slp, ti, "ATTEN CHECK FAILED"); 4329 } 4330 } 4331#endif /* SCSI_LOW_DEBUG */ 4332 4333 cb->ccb_error |= slp->sl_error; 4334 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) 4335 { 4336 cb->ccb_flags |= CCB_STARTQ; 4337 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 4338 } 4339 break; 4340 } 4341 4342 scsi_low_bus_release(slp, ti); 4343 scsi_low_start(slp); 4344 return 1; 4345} 4346 4347/********************************************************** 4348 * TAG operations 4349 **********************************************************/ 4350static int 4351scsi_low_alloc_qtag(cb) 4352 struct slccb *cb; 4353{ 4354 struct lun_info *li = cb->li; 4355 scsi_low_tag_t etag; 4356 4357 if (cb->ccb_otag != SCSI_LOW_UNKTAG) 4358 return 0; 4359 4360#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE 4361 etag = ffs(li->li_qtagbits); 4362 if (etag == 0) 4363 return ENOSPC; 4364 4365 li->li_qtagbits &= ~(1 << (etag - 1)); 4366 cb->ccb_otag = etag; 4367 return 0; 4368 4369#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4370 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++) 4371 if (li->li_qtagarray[li->li_qd] == 0) 4372 goto found; 4373 4374 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++) 4375 if (li->li_qtagarray[li->li_qd] == 0) 4376 goto found; 4377 4378 return ENOSPC; 4379 4380found: 4381 li->li_qtagarray[li->li_qd] ++; 4382 cb->ccb_otag = (li->li_qd ++); 4383 return 0; 4384#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4385} 4386 4387static int 4388scsi_low_dealloc_qtag(cb) 4389 struct slccb *cb; 4390{ 4391 struct lun_info *li = cb->li; 4392 scsi_low_tag_t etag; 4393 4394 if (cb->ccb_otag == SCSI_LOW_UNKTAG) 4395 return 0; 4396 4397#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE 4398 etag = cb->ccb_otag - 1; 4399#ifdef SCSI_LOW_DIAGNOSTIC 4400 if (etag >= sizeof(li->li_qtagbits) * NBBY) 4401 panic("scsi_low_dealloc_tag: illegal tag"); 4402#endif /* SCSI_LOW_DIAGNOSTIC */ 4403 li->li_qtagbits |= (1 << etag); 4404 4405#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4406 etag = cb->ccb_otag; 4407#ifdef SCSI_LOW_DIAGNOSTIC 4408 if (etag >= SCSI_LOW_MAXNEXUS) 4409 panic("scsi_low_dealloc_tag: illegal tag"); 4410#endif /* SCSI_LOW_DIAGNOSTIC */ 4411 li->li_qtagarray[etag] --; 4412#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ 4413 4414 cb->ccb_otag = SCSI_LOW_UNKTAG; 4415 return 0; 4416} 4417 4418static struct slccb * 4419scsi_low_revoke_ccb(slp, cb, fdone) 4420 struct scsi_low_softc *slp; 4421 struct slccb *cb; 4422 int fdone; 4423{ 4424 struct targ_info *ti = cb->ti; 4425 struct lun_info *li = cb->li; 4426 4427#ifdef SCSI_LOW_DIAGNOSTIC 4428 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) == 4429 (CCB_STARTQ | CCB_DISCQ)) 4430 { 4431 panic("%s: ccb in both queue", slp->sl_xname); 4432 } 4433#endif /* SCSI_LOW_DIAGNOSTIC */ 4434 4435 if ((cb->ccb_flags & CCB_STARTQ) != 0) 4436 { 4437 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 4438 } 4439 4440 if ((cb->ccb_flags & CCB_DISCQ) != 0) 4441 { 4442 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); 4443 li->li_disc --; 4444 ti->ti_disc --; 4445 slp->sl_disc --; 4446 } 4447 4448 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ | 4449 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL); 4450 4451 if (fdone != 0 && 4452 (cb->ccb_rcnt ++ >= slp->sl_max_retry || 4453 (cb->ccb_flags & CCB_NORETRY) != 0)) 4454 { 4455 cb->ccb_error |= FATALIO; 4456 cb->ccb_flags &= ~CCB_AUTOSENSE; 4457 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE) 4458 panic("%s: done ccb retried", slp->sl_xname); 4459 return NULL; 4460 } 4461 else 4462 { 4463 cb->ccb_error |= PENDINGIO; 4464 scsi_low_deactivate_qtag(cb); 4465 scsi_low_ccb_message_retry(cb); 4466 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 4467 return cb; 4468 } 4469} 4470 4471static void 4472scsi_low_reset_nexus_lun(slp, li, fdone) 4473 struct scsi_low_softc *slp; 4474 struct lun_info *li; 4475 int fdone; 4476{ 4477 struct slccb *cb, *ncb, *ecb; 4478 4479 if (li == NULL) 4480 return; 4481 4482 ecb = NULL; 4483 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb) 4484 { 4485 ncb = TAILQ_NEXT(cb, ccb_chain); 4486 cb = scsi_low_revoke_ccb(slp, cb, fdone); 4487 if (cb != NULL) 4488 { 4489 /* 4490 * presumely keep ordering of io 4491 */ 4492 cb->ccb_flags |= CCB_STARTQ; 4493 if (ecb == NULL) 4494 { 4495 TAILQ_INSERT_HEAD(&slp->sl_start,\ 4496 cb, ccb_chain); 4497 } 4498 else 4499 { 4500 TAILQ_INSERT_AFTER(&slp->sl_start,\ 4501 ecb, cb, ccb_chain); 4502 } 4503 ecb = cb; 4504 } 4505 } 4506} 4507 4508/************************************************************** 4509 * Qurik setup 4510 **************************************************************/ 4511static void 4512scsi_low_calcf_lun(li) 4513 struct lun_info *li; 4514{ 4515 struct targ_info *ti = li->li_ti; 4516 struct scsi_low_softc *slp = ti->ti_sc; 4517 u_int cfgflags, diskflags; 4518 4519 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID) 4520 cfgflags = li->li_cfgflags; 4521 else 4522 cfgflags = 0; 4523 4524 diskflags = li->li_diskflags & li->li_quirks; 4525 4526 /* disconnect */ 4527 li->li_flags &= ~SCSI_LOW_DISC; 4528 if ((slp->sl_cfgflags & CFG_NODISC) == 0 && 4529 (diskflags & SCSI_LOW_DISK_DISC) != 0 && 4530 (cfgflags & SCSI_LOW_DISC) != 0) 4531 li->li_flags |= SCSI_LOW_DISC; 4532 4533 /* parity */ 4534 li->li_flags |= SCSI_LOW_NOPARITY; 4535 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 && 4536 (diskflags & SCSI_LOW_DISK_PARITY) != 0 && 4537 (cfgflags & SCSI_LOW_NOPARITY) == 0) 4538 li->li_flags &= ~SCSI_LOW_NOPARITY; 4539 4540 /* qtag */ 4541 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 && 4542 (cfgflags & SCSI_LOW_QTAG) != 0 && 4543 (diskflags & SCSI_LOW_DISK_QTAG) != 0) 4544 { 4545 li->li_flags |= SCSI_LOW_QTAG; 4546 li->li_maxnexus = SCSI_LOW_MAXNEXUS; 4547 li->li_maxnqio = li->li_maxnexus; 4548 } 4549 else 4550 { 4551 li->li_flags &= ~SCSI_LOW_QTAG; 4552 li->li_maxnexus = 0; 4553 li->li_maxnqio = li->li_maxnexus; 4554 } 4555 4556 /* cmd link */ 4557 li->li_flags &= ~SCSI_LOW_LINK; 4558 if ((cfgflags & SCSI_LOW_LINK) != 0 && 4559 (diskflags & SCSI_LOW_DISK_LINK) != 0) 4560 li->li_flags |= SCSI_LOW_LINK; 4561 4562 /* compatible flags */ 4563 li->li_flags &= ~SCSI_LOW_SYNC; 4564 if (ti->ti_maxsynch.offset > 0) 4565 li->li_flags |= SCSI_LOW_SYNC; 4566 4567#ifdef SCSI_LOW_DEBUG 4568 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) 4569 { 4570 scsi_low_calcf_show(li); 4571 } 4572#endif /* SCSI_LOW_DEBUG */ 4573} 4574 4575static void 4576scsi_low_calcf_target(ti) 4577 struct targ_info *ti; 4578{ 4579 struct scsi_low_softc *slp = ti->ti_sc; 4580 u_int offset, period, diskflags; 4581 4582 diskflags = ti->ti_diskflags & ti->ti_quirks; 4583 4584 /* synch */ 4585 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 && 4586 (diskflags & SCSI_LOW_DISK_SYNC) != 0) 4587 { 4588 offset = ti->ti_maxsynch.offset; 4589 period = ti->ti_maxsynch.period; 4590 if (offset == 0 || period == 0) 4591 offset = period = 0; 4592 } 4593 else 4594 { 4595 offset = period = 0; 4596 } 4597 4598 ti->ti_maxsynch.offset = offset; 4599 ti->ti_maxsynch.period = period; 4600 4601 /* wide */ 4602 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 && 4603 ti->ti_width > SCSI_LOW_BUS_WIDTH_16) 4604 ti->ti_width = SCSI_LOW_BUS_WIDTH_16; 4605 4606 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 && 4607 ti->ti_width > SCSI_LOW_BUS_WIDTH_8) 4608 ti->ti_width = SCSI_LOW_BUS_WIDTH_8; 4609 4610 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID) 4611 { 4612 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset || 4613 ti->ti_maxsynch.period != ti->ti_osynch.period) 4614 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH; 4615 if (ti->ti_width != ti->ti_owidth) 4616 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH); 4617 4618 ti->ti_osynch = ti->ti_maxsynch; 4619 ti->ti_owidth = ti->ti_width; 4620 } 4621 4622#ifdef SCSI_LOW_DEBUG 4623 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) 4624 { 4625 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n", 4626 slp->sl_xname, ti->ti_id, 4627 ti->ti_maxsynch.period * 4, 4628 ti->ti_maxsynch.offset, 4629 ti->ti_width); 4630 } 4631#endif /* SCSI_LOW_DEBUG */ 4632} 4633 4634static void 4635scsi_low_calcf_show(li) 4636 struct lun_info *li; 4637{ 4638 struct targ_info *ti = li->li_ti; 4639 struct scsi_low_softc *slp = ti->ti_sc; 4640 4641 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n", 4642 slp->sl_xname, ti->ti_id, li->li_lun, 4643 ti->ti_maxsynch.period * 4, 4644 ti->ti_maxsynch.offset, 4645 ti->ti_width, 4646 li->li_flags, SCSI_LOW_BITS); 4647} 4648 4649#ifdef SCSI_LOW_START_UP_CHECK 4650/************************************************************** 4651 * scsi world start up 4652 **************************************************************/ 4653static int scsi_low_poll(struct scsi_low_softc *, struct slccb *); 4654 4655static int 4656scsi_low_start_up(slp) 4657 struct scsi_low_softc *slp; 4658{ 4659 struct targ_info *ti; 4660 struct lun_info *li; 4661 struct slccb *cb; 4662 int target, lun; 4663 4664 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname); 4665 4666 for (target = 0; target < slp->sl_ntargs; target ++) 4667 { 4668 if (target == slp->sl_hostid) 4669 { 4670 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4671 { 4672 printf("%s: scsi_low: target %d (host card)\n", 4673 slp->sl_xname, target); 4674 } 4675 continue; 4676 } 4677 4678 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4679 { 4680 printf("%s: scsi_low: target %d lun ", 4681 slp->sl_xname, target); 4682 } 4683 4684 ti = slp->sl_ti[target]; 4685 for (lun = 0; lun < slp->sl_nluns; lun ++) 4686 { 4687 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) 4688 break; 4689 4690 cb->osdep = NULL; 4691 cb->bp = NULL; 4692 4693 li = scsi_low_alloc_li(ti, lun, 1); 4694 4695 scsi_low_enqueue(slp, ti, li, cb, 4696 CCB_AUTOSENSE | CCB_POLLED, 0); 4697 4698 scsi_low_poll(slp, cb); 4699 4700 if (li->li_state != SCSI_LOW_LUN_OK) 4701 break; 4702 4703 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4704 { 4705 printf("%d ", lun); 4706 } 4707 } 4708 4709 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) 4710 { 4711 printf("\n"); 4712 } 4713 } 4714 return 0; 4715} 4716 4717static int 4718scsi_low_poll(slp, cb) 4719 struct scsi_low_softc *slp; 4720 struct slccb *cb; 4721{ 4722 int tcount; 4723 4724 tcount = 0; 4725 while (slp->sl_nio > 0) 4726 { 4727 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ); 4728 4729 (*slp->sl_funcs->scsi_low_poll) (slp); 4730 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ) 4731 continue; 4732 4733 tcount = 0; 4734 scsi_low_timeout_check(slp); 4735 } 4736 4737 return 0; 4738} 4739#endif /* SCSI_LOW_START_UP_CHECK */ 4740 4741/********************************************************** 4742 * DEBUG SECTION 4743 **********************************************************/ 4744#ifdef SCSI_LOW_DEBUG 4745static void 4746scsi_low_test_abort(slp, ti, li) 4747 struct scsi_low_softc *slp; 4748 struct targ_info *ti; 4749 struct lun_info *li; 4750{ 4751 struct slccb *acb; 4752 4753 if (li->li_disc > 1) 4754 { 4755 acb = TAILQ_FIRST(&li->li_discq); 4756 if (scsi_low_abort_ccb(slp, acb) == 0) 4757 { 4758 printf("%s: aborting ccb(0x%lx) start\n", 4759 slp->sl_xname, (u_long) acb); 4760 } 4761 } 4762} 4763 4764static void 4765scsi_low_test_atten(slp, ti, msg) 4766 struct scsi_low_softc *slp; 4767 struct targ_info *ti; 4768 u_int msg; 4769{ 4770 4771 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK) 4772 scsi_low_assert_msg(slp, ti, msg, 0); 4773 else 4774 printf("%s: atten check OK\n", slp->sl_xname); 4775} 4776 4777static void 4778scsi_low_test_cmdlnk(slp, cb) 4779 struct scsi_low_softc *slp; 4780 struct slccb *cb; 4781{ 4782#define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ) 4783 4784 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0) 4785 return; 4786 4787 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd, 4788 slp->sl_scp.scp_cmdlen); 4789 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1; 4790 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd; 4791} 4792#endif /* SCSI_LOW_DEBUG */ 4793 4794/* static */ void 4795scsi_low_info(slp, ti, s) 4796 struct scsi_low_softc *slp; 4797 struct targ_info *ti; 4798 u_char *s; 4799{ 4800 4801 if (slp == NULL) 4802 slp = LIST_FIRST(&sl_tab); 4803 if (s == NULL) 4804 s = "no message"; 4805 4806 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s); 4807 if (ti == NULL) 4808 { 4809 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL; 4810 ti = TAILQ_NEXT(ti, ti_chain)) 4811 { 4812 scsi_low_print(slp, ti); 4813 } 4814 } 4815 else 4816 { 4817 scsi_low_print(slp, ti); 4818 } 4819} 4820 4821static u_char *phase[] = 4822{ 4823 "FREE", "ARBSTART", "SELSTART", "SELECTED", 4824 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL" 4825}; 4826 4827void 4828scsi_low_print(slp, ti) 4829 struct scsi_low_softc *slp; 4830 struct targ_info *ti; 4831{ 4832 struct lun_info *li; 4833 struct slccb *cb; 4834 struct sc_p *sp; 4835 4836 if (ti == NULL || ti == slp->sl_Tnexus) 4837 { 4838 ti = slp->sl_Tnexus; 4839 li = slp->sl_Lnexus; 4840 cb = slp->sl_Qnexus; 4841 } 4842 else 4843 { 4844 li = LIST_FIRST(&ti->ti_litab); 4845 cb = TAILQ_FIRST(&li->li_discq); 4846 } 4847 sp = &slp->sl_scp; 4848 4849 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n", 4850 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb, 4851 slp->sl_nio); 4852 4853 /* target stat */ 4854 if (ti != NULL) 4855 { 4856 u_int flags = 0, maxnqio = 0, nqio = 0; 4857 int lun = -1; 4858 4859 if (li != NULL) 4860 { 4861 lun = li->li_lun; 4862 flags = li->li_flags; 4863 maxnqio = li->li_maxnqio; 4864 nqio = li->li_nqio; 4865 } 4866 4867 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n", 4868 slp->sl_xname, 4869 ti->ti_id, lun, phase[(int) ti->ti_ophase], 4870 phase[(int) ti->ti_phase], ti->ti_disc, 4871 nqio, maxnqio); 4872 4873 if (cb != NULL) 4874 { 4875printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n", 4876 (u_int) cb->ccb_scp.scp_cmd[0], 4877 cb->ccb_scp.scp_cmdlen, 4878 cb->ccb_datalen, 4879 cb->ccb_scp.scp_datalen, 4880 (u_int) cb->ccb_sscp.scp_status, 4881 cb->ccb_error, SCSI_LOW_ERRORBITS); 4882 } 4883 4884printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n", 4885 (u_int) (ti->ti_msginptr), 4886 (u_int) (ti->ti_msgin[0]), 4887 (u_int) (ti->ti_msgin[1]), 4888 (u_int) (ti->ti_msgin[2]), 4889 (u_int) (ti->ti_msgin[3]), 4890 (u_int) (ti->ti_msgin[4]), 4891 slp->sl_atten); 4892 4893printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n", 4894 (u_int) ti->ti_msgflags, 4895 (u_int) (ti->ti_msgoutstr[0]), 4896 (u_int) (ti->ti_msgoutstr[1]), 4897 (u_int) (ti->ti_msgoutstr[2]), 4898 (u_int) (ti->ti_msgoutstr[3]), 4899 (u_int) (ti->ti_msgoutstr[4]), 4900 ti->ti_msgoutlen, 4901 flags, SCSI_LOW_BITS); 4902 4903#ifdef SCSI_LOW_DIAGNOSTIC 4904 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2); 4905 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2); 4906#endif /* SCSI_LOW_DIAGNOSTIC */ 4907 4908 } 4909 4910 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n", 4911 (u_long) sp->scp_data, 4912 sp->scp_datalen, 4913 (u_int) sp->scp_status, 4914 slp->sl_error, SCSI_LOW_ERRORBITS); 4915}
|