Merge ^/head r303250 through r308226.
This commit is contained in:
commit
a2b802ce70
@ -543,8 +543,8 @@ HMAKE+= PATH=${TMPPATH} METALOG=${METALOG} -DNO_ROOT
|
|||||||
|
|
||||||
CROSSENV+= CC="${XCC} ${XCFLAGS}" CXX="${XCXX} ${XCXXFLAGS} ${XCFLAGS}" \
|
CROSSENV+= CC="${XCC} ${XCFLAGS}" CXX="${XCXX} ${XCXXFLAGS} ${XCFLAGS}" \
|
||||||
CPP="${XCPP} ${XCFLAGS}" \
|
CPP="${XCPP} ${XCFLAGS}" \
|
||||||
AS="${XAS}" AR="${XAR}" LD="${XLD}" NM=${XNM} \
|
AS="${XAS}" AR="${XAR}" LD="${XLD}" LLVM_LINK="${XLLVM_LINK}" \
|
||||||
OBJCOPY="${XOBJCOPY}" \
|
NM=${XNM} OBJCOPY="${XOBJCOPY}" \
|
||||||
RANLIB=${XRANLIB} STRINGS=${XSTRINGS} \
|
RANLIB=${XRANLIB} STRINGS=${XSTRINGS} \
|
||||||
SIZE="${XSIZE}"
|
SIZE="${XSIZE}"
|
||||||
|
|
||||||
|
@ -52,9 +52,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "hv_kvp.h"
|
#include "hv_kvp.h"
|
||||||
|
#include "hv_utilreg.h"
|
||||||
typedef uint8_t __u8;
|
typedef uint8_t __u8;
|
||||||
typedef uint16_t __u16;
|
typedef uint16_t __u16;
|
||||||
typedef uint32_t __u32;
|
typedef uint32_t __u32;
|
||||||
@ -684,18 +685,16 @@ kvp_get_ipconfig_info(char *if_name, struct hv_kvp_ipaddr_value *buffer)
|
|||||||
*/
|
*/
|
||||||
kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
|
kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
|
||||||
(MAX_GATEWAY_SIZE * 2), INET_ADDRSTRLEN, 0);
|
(MAX_GATEWAY_SIZE * 2), INET_ADDRSTRLEN, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve the IPV6 address of default gateway.
|
* Retrieve the IPV6 address of default gateway.
|
||||||
*/
|
*/
|
||||||
snprintf(cmd, sizeof(cmd), "netstat -rn inet6 | grep %s | awk '/default/ {print $2 }", if_name);
|
snprintf(cmd, sizeof(cmd), "netstat -rn inet6 | grep %s | awk '/default/ {print $2 }'", if_name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execute the command to gather gateway IPV6 info.
|
* Execute the command to gather gateway IPV6 info.
|
||||||
*/
|
*/
|
||||||
kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
|
kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
|
||||||
(MAX_GATEWAY_SIZE * 2), INET6_ADDRSTRLEN, 1);
|
(MAX_GATEWAY_SIZE * 2), INET6_ADDRSTRLEN, 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we just invoke an external script to get the DNS info.
|
* we just invoke an external script to get the DNS info.
|
||||||
*
|
*
|
||||||
@ -782,11 +781,11 @@ kvp_process_ip_address(void *addrp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((length - *offset) < addr_length + 1) {
|
if ((length - *offset) < addr_length + 1) {
|
||||||
return (HV_KVP_E_FAIL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
strlcpy(buffer, "inet_ntop failed\n", length);
|
strlcpy(buffer, "inet_ntop failed\n", length);
|
||||||
return (HV_KVP_E_FAIL);
|
return (errno);
|
||||||
}
|
}
|
||||||
if (*offset == 0) {
|
if (*offset == 0) {
|
||||||
strlcpy(buffer, tmp, length);
|
strlcpy(buffer, tmp, length);
|
||||||
@ -832,7 +831,7 @@ kvp_get_ip_info(int family, char *if_name, int op,
|
|||||||
|
|
||||||
if (getifaddrs(&ifap)) {
|
if (getifaddrs(&ifap)) {
|
||||||
strlcpy(buffer, "getifaddrs failed\n", buffer_length);
|
strlcpy(buffer, "getifaddrs failed\n", buffer_length);
|
||||||
return (HV_KVP_E_FAIL);
|
return (errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
curp = ifap;
|
curp = ifap;
|
||||||
@ -924,7 +923,6 @@ kvp_get_ip_info(int family, char *if_name, int op,
|
|||||||
/*
|
/*
|
||||||
* Collect other ip configuration info.
|
* Collect other ip configuration info.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
kvp_get_ipconfig_info(if_name, ip_buffer);
|
kvp_get_ipconfig_info(if_name, ip_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,7 +952,7 @@ kvp_write_file(FILE *f, const char *s1, const char *s2, const char *s3)
|
|||||||
ret = fprintf(f, "%s%s%s%s\n", s1, s2, "=", s3);
|
ret = fprintf(f, "%s%s%s%s\n", s1, s2, "=", s3);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return (HV_KVP_E_FAIL);
|
return (EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -979,7 +977,7 @@ kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
|
|||||||
|
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
KVP_LOG(LOG_ERR, "FreeBSD Failed to open config file\n");
|
KVP_LOG(LOG_ERR, "FreeBSD Failed to open config file\n");
|
||||||
return (HV_KVP_E_FAIL);
|
return (errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -988,7 +986,7 @@ kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
|
|||||||
|
|
||||||
mac_addr = kvp_if_name_to_mac(if_name);
|
mac_addr = kvp_if_name_to_mac(if_name);
|
||||||
if (mac_addr == NULL) {
|
if (mac_addr == NULL) {
|
||||||
error = HV_KVP_E_FAIL;
|
error = EINVAL;
|
||||||
goto kvp_set_ip_info_error;
|
goto kvp_set_ip_info_error;
|
||||||
}
|
}
|
||||||
/* MAC Address */
|
/* MAC Address */
|
||||||
@ -1091,28 +1089,30 @@ kvp_op_getipinfo(struct hv_kvp_msg *op_msg, void *data __unused)
|
|||||||
{
|
{
|
||||||
struct hv_kvp_ipaddr_value *ip_val;
|
struct hv_kvp_ipaddr_value *ip_val;
|
||||||
char *if_name;
|
char *if_name;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
assert(op_msg != NULL);
|
assert(op_msg != NULL);
|
||||||
KVP_LOG(LOG_DEBUG, "In kvp_op_getipinfo.\n");
|
KVP_LOG(LOG_DEBUG, "In kvp_op_getipinfo.\n");
|
||||||
|
|
||||||
ip_val = &op_msg->body.kvp_ip_val;
|
ip_val = &op_msg->body.kvp_ip_val;
|
||||||
op_msg->hdr.error = HV_KVP_S_OK;
|
op_msg->hdr.error = HV_S_OK;
|
||||||
|
|
||||||
if_name = kvp_mac_to_if_name((char *)ip_val->adapter_id);
|
if_name = kvp_mac_to_if_name((char *)ip_val->adapter_id);
|
||||||
|
|
||||||
if (if_name == NULL) {
|
if (if_name == NULL) {
|
||||||
/* No interface found with the mac address. */
|
/* No interface found with the mac address. */
|
||||||
op_msg->hdr.error = HV_KVP_E_FAIL;
|
op_msg->hdr.error = HV_E_FAIL;
|
||||||
goto kvp_op_getipinfo_done;
|
goto kvp_op_getipinfo_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
op_msg->hdr.error = kvp_get_ip_info(0, if_name,
|
error = kvp_get_ip_info(0, if_name,
|
||||||
HV_KVP_OP_GET_IP_INFO, ip_val, (MAX_IP_ADDR_SIZE * 2));
|
HV_KVP_OP_GET_IP_INFO, ip_val, (MAX_IP_ADDR_SIZE * 2));
|
||||||
|
if (error)
|
||||||
|
op_msg->hdr.error = HV_E_FAIL;
|
||||||
free(if_name);
|
free(if_name);
|
||||||
|
|
||||||
kvp_op_getipinfo_done:
|
kvp_op_getipinfo_done:
|
||||||
return(op_msg->hdr.error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1121,25 +1121,27 @@ kvp_op_setipinfo(struct hv_kvp_msg *op_msg, void *data __unused)
|
|||||||
{
|
{
|
||||||
struct hv_kvp_ipaddr_value *ip_val;
|
struct hv_kvp_ipaddr_value *ip_val;
|
||||||
char *if_name;
|
char *if_name;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
assert(op_msg != NULL);
|
assert(op_msg != NULL);
|
||||||
KVP_LOG(LOG_DEBUG, "In kvp_op_setipinfo.\n");
|
KVP_LOG(LOG_DEBUG, "In kvp_op_setipinfo.\n");
|
||||||
|
|
||||||
ip_val = &op_msg->body.kvp_ip_val;
|
ip_val = &op_msg->body.kvp_ip_val;
|
||||||
op_msg->hdr.error = HV_KVP_S_OK;
|
op_msg->hdr.error = HV_S_OK;
|
||||||
|
|
||||||
if_name = (char *)ip_val->adapter_id;
|
if_name = (char *)ip_val->adapter_id;
|
||||||
|
|
||||||
if (if_name == NULL) {
|
if (if_name == NULL) {
|
||||||
/* No adapter provided. */
|
/* No adapter provided. */
|
||||||
op_msg->hdr.error = HV_KVP_GUID_NOTFOUND;
|
op_msg->hdr.error = HV_GUID_NOTFOUND;
|
||||||
goto kvp_op_setipinfo_done;
|
goto kvp_op_setipinfo_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
op_msg->hdr.error = kvp_set_ip_info(if_name, ip_val);
|
error = kvp_set_ip_info(if_name, ip_val);
|
||||||
|
if (error)
|
||||||
|
op_msg->hdr.error = HV_E_FAIL;
|
||||||
kvp_op_setipinfo_done:
|
kvp_op_setipinfo_done:
|
||||||
return(op_msg->hdr.error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1154,7 +1156,7 @@ kvp_op_setgetdel(struct hv_kvp_msg *op_msg, void *data)
|
|||||||
assert(op_hdlr != NULL);
|
assert(op_hdlr != NULL);
|
||||||
|
|
||||||
op_pool = op_msg->hdr.kvp_hdr.pool;
|
op_pool = op_msg->hdr.kvp_hdr.pool;
|
||||||
op_msg->hdr.error = HV_KVP_S_OK;
|
op_msg->hdr.error = HV_S_OK;
|
||||||
|
|
||||||
switch(op_hdlr->kvp_op_key) {
|
switch(op_hdlr->kvp_op_key) {
|
||||||
case HV_KVP_OP_SET:
|
case HV_KVP_OP_SET:
|
||||||
@ -1198,8 +1200,7 @@ kvp_op_setgetdel(struct hv_kvp_msg *op_msg, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
op_msg->hdr.error = HV_KVP_S_CONT;
|
op_msg->hdr.error = HV_S_CONT;
|
||||||
|
|
||||||
return(error);
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1216,7 +1217,7 @@ kvp_op_enumerate(struct hv_kvp_msg *op_msg, void *data __unused)
|
|||||||
|
|
||||||
op = op_msg->hdr.kvp_hdr.operation;
|
op = op_msg->hdr.kvp_hdr.operation;
|
||||||
op_pool = op_msg->hdr.kvp_hdr.pool;
|
op_pool = op_msg->hdr.kvp_hdr.pool;
|
||||||
op_msg->hdr.error = HV_KVP_S_OK;
|
op_msg->hdr.error = HV_S_OK;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the pool is not HV_KVP_POOL_AUTO, read from the appropriate
|
* If the pool is not HV_KVP_POOL_AUTO, read from the appropriate
|
||||||
@ -1229,7 +1230,7 @@ kvp_op_enumerate(struct hv_kvp_msg *op_msg, void *data __unused)
|
|||||||
HV_KVP_EXCHANGE_MAX_KEY_SIZE,
|
HV_KVP_EXCHANGE_MAX_KEY_SIZE,
|
||||||
op_msg->body.kvp_enum_data.data.msg_value.value,
|
op_msg->body.kvp_enum_data.data.msg_value.value,
|
||||||
HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) {
|
HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) {
|
||||||
op_msg->hdr.error = HV_KVP_S_CONT;
|
op_msg->hdr.error = HV_S_CONT;
|
||||||
error = -1;
|
error = -1;
|
||||||
}
|
}
|
||||||
goto kvp_op_enumerate_done;
|
goto kvp_op_enumerate_done;
|
||||||
@ -1298,12 +1299,14 @@ kvp_op_enumerate(struct hv_kvp_msg *op_msg, void *data __unused)
|
|||||||
KVP_LOG(LOG_ERR, "Auto pool Index %d not found.\n",
|
KVP_LOG(LOG_ERR, "Auto pool Index %d not found.\n",
|
||||||
op_msg->body.kvp_enum_data.index);
|
op_msg->body.kvp_enum_data.index);
|
||||||
#endif
|
#endif
|
||||||
op_msg->hdr.error = HV_KVP_S_CONT;
|
op_msg->hdr.error = HV_S_CONT;
|
||||||
error = -1;
|
error = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
kvp_op_enumerate_done:
|
kvp_op_enumerate_done:
|
||||||
|
if (error != 0)
|
||||||
|
op_msg->hdr.error = HV_S_CONT;
|
||||||
return(error);
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1496,10 +1499,13 @@ main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
error = kvp_op_hdlrs[op].kvp_op_exec(hv_msg,
|
error = kvp_op_hdlrs[op].kvp_op_exec(hv_msg,
|
||||||
(void *)&kvp_op_hdlrs[op]);
|
(void *)&kvp_op_hdlrs[op]);
|
||||||
if (error != 0 && hv_msg->hdr.error != HV_KVP_S_CONT)
|
if (error != 0) {
|
||||||
KVP_LOG(LOG_WARNING,
|
assert(hv_msg->hdr.error != HV_S_OK);
|
||||||
"Operation failed OP = %d, error = 0x%x\n",
|
if (hv_msg->hdr.error != HV_S_CONT)
|
||||||
op, error);
|
KVP_LOG(LOG_WARNING,
|
||||||
|
"Operation failed OP = %d, error = 0x%x\n",
|
||||||
|
op, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -468,6 +468,7 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
|
|||||||
if (kex == NULL)
|
if (kex == NULL)
|
||||||
return SSH_ERR_INVALID_ARGUMENT;
|
return SSH_ERR_INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
|
||||||
ptr = sshpkt_ptr(ssh, &dlen);
|
ptr = sshpkt_ptr(ssh, &dlen);
|
||||||
if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
|
if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -459,7 +459,7 @@ distrib-dirs: ${MTREES:N/*} distrib-cleanup .PHONY
|
|||||||
.endif
|
.endif
|
||||||
|
|
||||||
etc-examples-install: ${META_DEPS}
|
etc-examples-install: ${META_DEPS}
|
||||||
cd ${.CURDIR}; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 444 \
|
cd ${.CURDIR}; ${INSTALL} ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 \
|
||||||
${BIN1} ${BIN2} nsmb.conf opieaccess \
|
${BIN1} ${BIN2} nsmb.conf opieaccess \
|
||||||
${DESTDIR}${SHAREDIR}/examples/etc
|
${DESTDIR}${SHAREDIR}/examples/etc
|
||||||
|
|
||||||
|
@ -78,6 +78,8 @@
|
|||||||
..
|
..
|
||||||
ssl
|
ssl
|
||||||
..
|
..
|
||||||
|
syslog.d
|
||||||
|
..
|
||||||
zfs
|
zfs
|
||||||
..
|
..
|
||||||
..
|
..
|
||||||
|
@ -34,3 +34,5 @@ cron.* /var/log/cron
|
|||||||
!ppp
|
!ppp
|
||||||
*.* /var/log/ppp.log
|
*.* /var/log/ppp.log
|
||||||
!*
|
!*
|
||||||
|
include /etc/syslog.d
|
||||||
|
include /usr/local/etc/syslog.d
|
||||||
|
@ -397,11 +397,11 @@ _libinstall: _lib-eh-install
|
|||||||
|
|
||||||
_lib-eh-install:
|
_lib-eh-install:
|
||||||
.if ${MK_INSTALLLIB} != "no"
|
.if ${MK_INSTALLLIB} != "no"
|
||||||
${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
|
${INSTALL} ${TAG_ARGS} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
|
||||||
${_INSTALLFLAGS} libgcc_eh.a ${DESTDIR}${LIBDIR}
|
${_INSTALLFLAGS} libgcc_eh.a ${DESTDIR}${LIBDIR}
|
||||||
.endif
|
.endif
|
||||||
.if ${MK_PROFILE} != "no"
|
.if ${MK_PROFILE} != "no"
|
||||||
${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
|
${INSTALL} ${TAG_ARGS} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
|
||||||
${_INSTALLFLAGS} libgcc_eh_p.a ${DESTDIR}${LIBDIR}
|
${_INSTALLFLAGS} libgcc_eh_p.a ${DESTDIR}${LIBDIR}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "un-namespace.h"
|
#include "un-namespace.h"
|
||||||
|
|
||||||
|
#include "endian.h"
|
||||||
#include "collate.h"
|
#include "collate.h"
|
||||||
#include "setlocale.h"
|
#include "setlocale.h"
|
||||||
#include "ldpart.h"
|
#include "ldpart.h"
|
||||||
@ -160,7 +161,7 @@ __collate_load_tables_l(const char *encoding, struct xlocale_collate *table)
|
|||||||
|
|
||||||
if ((info->directive_count < 1) ||
|
if ((info->directive_count < 1) ||
|
||||||
(info->directive_count >= COLL_WEIGHTS_MAX) ||
|
(info->directive_count >= COLL_WEIGHTS_MAX) ||
|
||||||
((chains = info->chain_count) < 0)) {
|
((chains = BSWAP(info->chain_count)) < 0)) {
|
||||||
(void) munmap(map, sbuf.st_size);
|
(void) munmap(map, sbuf.st_size);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return (_LDP_ERROR);
|
return (_LDP_ERROR);
|
||||||
@ -168,9 +169,9 @@ __collate_load_tables_l(const char *encoding, struct xlocale_collate *table)
|
|||||||
|
|
||||||
i = (sizeof (collate_char_t) * (UCHAR_MAX + 1)) +
|
i = (sizeof (collate_char_t) * (UCHAR_MAX + 1)) +
|
||||||
(sizeof (collate_chain_t) * chains) +
|
(sizeof (collate_chain_t) * chains) +
|
||||||
(sizeof (collate_large_t) * info->large_count);
|
(sizeof (collate_large_t) * BSWAP(info->large_count));
|
||||||
for (z = 0; z < info->directive_count; z++) {
|
for (z = 0; z < info->directive_count; z++) {
|
||||||
i += sizeof (collate_subst_t) * info->subst_count[z];
|
i += sizeof (collate_subst_t) * BSWAP(info->subst_count[z]);
|
||||||
}
|
}
|
||||||
if (i != (sbuf.st_size - (TMP - map))) {
|
if (i != (sbuf.st_size - (TMP - map))) {
|
||||||
(void) munmap(map, sbuf.st_size);
|
(void) munmap(map, sbuf.st_size);
|
||||||
@ -183,9 +184,9 @@ __collate_load_tables_l(const char *encoding, struct xlocale_collate *table)
|
|||||||
TMP += sizeof (collate_char_t) * (UCHAR_MAX + 1);
|
TMP += sizeof (collate_char_t) * (UCHAR_MAX + 1);
|
||||||
|
|
||||||
for (z = 0; z < info->directive_count; z++) {
|
for (z = 0; z < info->directive_count; z++) {
|
||||||
if (info->subst_count[z] > 0) {
|
if (BSWAP(info->subst_count[z]) > 0) {
|
||||||
table->subst_table[z] = (void *)TMP;
|
table->subst_table[z] = (void *)TMP;
|
||||||
TMP += info->subst_count[z] * sizeof (collate_subst_t);
|
TMP += BSWAP(info->subst_count[z]) * sizeof (collate_subst_t);
|
||||||
} else {
|
} else {
|
||||||
table->subst_table[z] = NULL;
|
table->subst_table[z] = NULL;
|
||||||
}
|
}
|
||||||
@ -196,7 +197,7 @@ __collate_load_tables_l(const char *encoding, struct xlocale_collate *table)
|
|||||||
TMP += chains * sizeof (collate_chain_t);
|
TMP += chains * sizeof (collate_chain_t);
|
||||||
} else
|
} else
|
||||||
table->chain_pri_table = NULL;
|
table->chain_pri_table = NULL;
|
||||||
if (info->large_count > 0)
|
if (BSWAP(info->large_count) > 0)
|
||||||
table->large_pri_table = (void *)TMP;
|
table->large_pri_table = (void *)TMP;
|
||||||
else
|
else
|
||||||
table->large_pri_table = NULL;
|
table->large_pri_table = NULL;
|
||||||
@ -209,7 +210,7 @@ static const int32_t *
|
|||||||
substsearch(struct xlocale_collate *table, const wchar_t key, int pass)
|
substsearch(struct xlocale_collate *table, const wchar_t key, int pass)
|
||||||
{
|
{
|
||||||
const collate_subst_t *p;
|
const collate_subst_t *p;
|
||||||
int n = table->info->subst_count[pass];
|
int n = BSWAP(table->info->subst_count[pass]);
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -221,7 +222,8 @@ substsearch(struct xlocale_collate *table, const wchar_t key, int pass)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
p = table->subst_table[pass] + (key & ~COLLATE_SUBST_PRIORITY);
|
p = table->subst_table[pass] + (key & ~COLLATE_SUBST_PRIORITY);
|
||||||
assert(p->key == key);
|
assert(BSWAP(p->key) == key);
|
||||||
|
|
||||||
return (p->pri);
|
return (p->pri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +231,7 @@ static collate_chain_t *
|
|||||||
chainsearch(struct xlocale_collate *table, const wchar_t *key, int *len)
|
chainsearch(struct xlocale_collate *table, const wchar_t *key, int *len)
|
||||||
{
|
{
|
||||||
int low = 0;
|
int low = 0;
|
||||||
int high = table->info->chain_count - 1;;
|
int high = BSWAP(table->info->chain_count) - 1;
|
||||||
int next, compar, l;
|
int next, compar, l;
|
||||||
collate_chain_t *p;
|
collate_chain_t *p;
|
||||||
collate_chain_t *tab = table->chain_pri_table;
|
collate_chain_t *tab = table->chain_pri_table;
|
||||||
@ -240,7 +242,7 @@ chainsearch(struct xlocale_collate *table, const wchar_t *key, int *len)
|
|||||||
while (low <= high) {
|
while (low <= high) {
|
||||||
next = (low + high) / 2;
|
next = (low + high) / 2;
|
||||||
p = tab + next;
|
p = tab + next;
|
||||||
compar = *key - *p->str;
|
compar = *key - le16toh(*p->str);
|
||||||
if (compar == 0) {
|
if (compar == 0) {
|
||||||
l = wcsnlen(p->str, COLLATE_STR_LEN);
|
l = wcsnlen(p->str, COLLATE_STR_LEN);
|
||||||
compar = wcsncmp(key, p->str, l);
|
compar = wcsncmp(key, p->str, l);
|
||||||
@ -261,7 +263,7 @@ static collate_large_t *
|
|||||||
largesearch(struct xlocale_collate *table, const wchar_t key)
|
largesearch(struct xlocale_collate *table, const wchar_t key)
|
||||||
{
|
{
|
||||||
int low = 0;
|
int low = 0;
|
||||||
int high = table->info->large_count - 1;
|
int high = BSWAP(table->info->large_count) - 1;
|
||||||
int next, compar;
|
int next, compar;
|
||||||
collate_large_t *p;
|
collate_large_t *p;
|
||||||
collate_large_t *tab = table->large_pri_table;
|
collate_large_t *tab = table->large_pri_table;
|
||||||
@ -272,7 +274,7 @@ largesearch(struct xlocale_collate *table, const wchar_t key)
|
|||||||
while (low <= high) {
|
while (low <= high) {
|
||||||
next = (low + high) / 2;
|
next = (low + high) / 2;
|
||||||
p = tab + next;
|
p = tab + next;
|
||||||
compar = key - p->val;
|
compar = key - BSWAP(p->val);
|
||||||
if (compar == 0)
|
if (compar == 0)
|
||||||
return (p);
|
return (p);
|
||||||
if (compar > 0)
|
if (compar > 0)
|
||||||
@ -337,15 +339,15 @@ _collate_lookup(struct xlocale_collate *table, const wchar_t *t, int *len,
|
|||||||
* Character is a small (8-bit) character.
|
* Character is a small (8-bit) character.
|
||||||
* We just look these up directly for speed.
|
* We just look these up directly for speed.
|
||||||
*/
|
*/
|
||||||
*pri = table->char_pri_table[*t].pri[which];
|
*pri = BSWAP(table->char_pri_table[*t].pri[which]);
|
||||||
|
|
||||||
} else if ((table->info->large_count > 0) &&
|
} else if ((BSWAP(table->info->large_count) > 0) &&
|
||||||
((match = largesearch(table, *t)) != NULL)) {
|
((match = largesearch(table, *t)) != NULL)) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Character was found in the extended table.
|
* Character was found in the extended table.
|
||||||
*/
|
*/
|
||||||
*pri = match->pri.pri[which];
|
*pri = BSWAP(match->pri.pri[which]);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -355,7 +357,7 @@ _collate_lookup(struct xlocale_collate *table, const wchar_t *t, int *len,
|
|||||||
/* Mask off sign bit to prevent ordering confusion. */
|
/* Mask off sign bit to prevent ordering confusion. */
|
||||||
*pri = (*t & COLLATE_MAX_PRIORITY);
|
*pri = (*t & COLLATE_MAX_PRIORITY);
|
||||||
} else {
|
} else {
|
||||||
*pri = table->info->undef_pri[which];
|
*pri = BSWAP(table->info->undef_pri[which]);
|
||||||
}
|
}
|
||||||
/* No substitutions for undefined characters! */
|
/* No substitutions for undefined characters! */
|
||||||
return;
|
return;
|
||||||
@ -374,9 +376,9 @@ _collate_lookup(struct xlocale_collate *table, const wchar_t *t, int *len,
|
|||||||
* code ensures this for us.
|
* code ensures this for us.
|
||||||
*/
|
*/
|
||||||
if ((sptr = substsearch(table, *pri, which)) != NULL) {
|
if ((sptr = substsearch(table, *pri, which)) != NULL) {
|
||||||
if ((*pri = *sptr) > 0) {
|
if ((*pri = BSWAP(*sptr)) > 0) {
|
||||||
sptr++;
|
sptr++;
|
||||||
*state = *sptr ? sptr : NULL;
|
*state = BSWAP(*sptr) ? sptr : NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +520,7 @@ static int
|
|||||||
xfrm(struct xlocale_collate *table, unsigned char *p, int pri, int pass)
|
xfrm(struct xlocale_collate *table, unsigned char *p, int pri, int pass)
|
||||||
{
|
{
|
||||||
/* we use unsigned to ensure zero fill on right shift */
|
/* we use unsigned to ensure zero fill on right shift */
|
||||||
uint32_t val = (uint32_t)table->info->pri_count[pass];
|
uint32_t val = BSWAP((uint32_t)table->info->pri_count[pass]);
|
||||||
int nc = 0;
|
int nc = 0;
|
||||||
|
|
||||||
while (val) {
|
while (val) {
|
||||||
@ -678,7 +680,7 @@ __collate_equiv_value(locale_t locale, const wchar_t *str, size_t len)
|
|||||||
e = -1;
|
e = -1;
|
||||||
if (*str <= UCHAR_MAX)
|
if (*str <= UCHAR_MAX)
|
||||||
e = table->char_pri_table[*str].pri[0];
|
e = table->char_pri_table[*str].pri[0];
|
||||||
else if (table->info->large_count > 0) {
|
else if (BSWAP(table->info->large_count) > 0) {
|
||||||
collate_large_t *match_large;
|
collate_large_t *match_large;
|
||||||
match_large = largesearch(table, *str);
|
match_large = largesearch(table, *str);
|
||||||
if (match_large)
|
if (match_large)
|
||||||
@ -688,7 +690,7 @@ __collate_equiv_value(locale_t locale, const wchar_t *str, size_t len)
|
|||||||
return (1);
|
return (1);
|
||||||
return (e > 0 ? e : 0);
|
return (e > 0 ? e : 0);
|
||||||
}
|
}
|
||||||
if (table->info->chain_count > 0) {
|
if (BSWAP(table->info->chain_count) > 0) {
|
||||||
wchar_t name[COLLATE_STR_LEN];
|
wchar_t name[COLLATE_STR_LEN];
|
||||||
collate_chain_t *match_chain;
|
collate_chain_t *match_chain;
|
||||||
int clen;
|
int clen;
|
||||||
|
52
lib/libc/locale/endian.h
Normal file
52
lib/libc/locale/endian.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Portions of this software were developed by SRI International and the
|
||||||
|
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
|
||||||
|
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||||
|
*
|
||||||
|
* Portions of this software were developed by the University of Cambridge
|
||||||
|
* Computer Laboratory as part of the CTSRD Project, with support from the
|
||||||
|
* UK Higher Education Innovation Fund (HEIF).
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $FreeBSD$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/endian.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We assume locale files were generated on EL machine
|
||||||
|
* (e.g. during cross build on amd64 host), but used on EB
|
||||||
|
* machine (e.g. MIPS64EB), so convert it to host endianness.
|
||||||
|
*
|
||||||
|
* TODO: detect host endianness on the build machine and use
|
||||||
|
* correct macros here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if BYTE_ORDER == BIG_ENDIAN && defined(__mips__)
|
||||||
|
#define BSWAP(x) le32toh(x)
|
||||||
|
#else
|
||||||
|
#define BSWAP(x) x
|
||||||
|
#endif
|
@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "un-namespace.h"
|
#include "un-namespace.h"
|
||||||
|
|
||||||
|
#include "endian.h"
|
||||||
#include "runefile.h"
|
#include "runefile.h"
|
||||||
|
|
||||||
_RuneLocale *
|
_RuneLocale *
|
||||||
@ -107,29 +108,29 @@ _Read_RuneMagi(const char *fname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
runetype_ext_ranges = (_FileRuneEntry *)variable;
|
runetype_ext_ranges = (_FileRuneEntry *)variable;
|
||||||
variable = runetype_ext_ranges + frl->runetype_ext_nranges;
|
variable = runetype_ext_ranges + BSWAP(frl->runetype_ext_nranges);
|
||||||
if (variable > lastp) {
|
if (variable > lastp) {
|
||||||
goto invalid;
|
goto invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
maplower_ext_ranges = (_FileRuneEntry *)variable;
|
maplower_ext_ranges = (_FileRuneEntry *)variable;
|
||||||
variable = maplower_ext_ranges + frl->maplower_ext_nranges;
|
variable = maplower_ext_ranges + BSWAP(frl->maplower_ext_nranges);
|
||||||
if (variable > lastp) {
|
if (variable > lastp) {
|
||||||
goto invalid;
|
goto invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapupper_ext_ranges = (_FileRuneEntry *)variable;
|
mapupper_ext_ranges = (_FileRuneEntry *)variable;
|
||||||
variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
|
variable = mapupper_ext_ranges + BSWAP(frl->mapupper_ext_nranges);
|
||||||
if (variable > lastp) {
|
if (variable > lastp) {
|
||||||
goto invalid;
|
goto invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
frr = runetype_ext_ranges;
|
frr = runetype_ext_ranges;
|
||||||
for (x = 0; x < frl->runetype_ext_nranges; ++x) {
|
for (x = 0; x < BSWAP(frl->runetype_ext_nranges); ++x) {
|
||||||
uint32_t *types;
|
uint32_t *types;
|
||||||
|
|
||||||
if (frr[x].map == 0) {
|
if (BSWAP(frr[x].map) == 0) {
|
||||||
int len = frr[x].max - frr[x].min + 1;
|
int len = BSWAP(frr[x].max) - BSWAP(frr[x].min) + 1;
|
||||||
types = variable;
|
types = variable;
|
||||||
variable = types + len;
|
variable = types + len;
|
||||||
runetype_ext_len += len;
|
runetype_ext_len += len;
|
||||||
@ -139,7 +140,7 @@ _Read_RuneMagi(const char *fname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((char *)variable + frl->variable_len > (char *)lastp) {
|
if ((char *)variable + BSWAP(frl->variable_len) > (char *)lastp) {
|
||||||
goto invalid;
|
goto invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,10 +148,10 @@ _Read_RuneMagi(const char *fname)
|
|||||||
* Convert from disk format to host format.
|
* Convert from disk format to host format.
|
||||||
*/
|
*/
|
||||||
data = malloc(sizeof(_RuneLocale) +
|
data = malloc(sizeof(_RuneLocale) +
|
||||||
(frl->runetype_ext_nranges + frl->maplower_ext_nranges +
|
(BSWAP(frl->runetype_ext_nranges) + BSWAP(frl->maplower_ext_nranges) +
|
||||||
frl->mapupper_ext_nranges) * sizeof(_RuneEntry) +
|
BSWAP(frl->mapupper_ext_nranges)) * sizeof(_RuneEntry) +
|
||||||
runetype_ext_len * sizeof(*rr->__types) +
|
runetype_ext_len * sizeof(*rr->__types) +
|
||||||
frl->variable_len);
|
BSWAP(frl->variable_len));
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
saverr = errno;
|
saverr = errno;
|
||||||
munmap(fdata, sb.st_size);
|
munmap(fdata, sb.st_size);
|
||||||
@ -164,15 +165,15 @@ _Read_RuneMagi(const char *fname)
|
|||||||
memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic));
|
memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic));
|
||||||
memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding));
|
memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding));
|
||||||
|
|
||||||
rl->__variable_len = frl->variable_len;
|
rl->__variable_len = BSWAP(frl->variable_len);
|
||||||
rl->__runetype_ext.__nranges = frl->runetype_ext_nranges;
|
rl->__runetype_ext.__nranges = BSWAP(frl->runetype_ext_nranges);
|
||||||
rl->__maplower_ext.__nranges = frl->maplower_ext_nranges;
|
rl->__maplower_ext.__nranges = BSWAP(frl->maplower_ext_nranges);
|
||||||
rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges;
|
rl->__mapupper_ext.__nranges = BSWAP(frl->mapupper_ext_nranges);
|
||||||
|
|
||||||
for (x = 0; x < _CACHED_RUNES; ++x) {
|
for (x = 0; x < _CACHED_RUNES; ++x) {
|
||||||
rl->__runetype[x] = frl->runetype[x];
|
rl->__runetype[x] = BSWAP(frl->runetype[x]);
|
||||||
rl->__maplower[x] = frl->maplower[x];
|
rl->__maplower[x] = BSWAP(frl->maplower[x]);
|
||||||
rl->__mapupper[x] = frl->mapupper[x];
|
rl->__mapupper[x] = BSWAP(frl->mapupper[x]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
|
rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
|
||||||
@ -187,15 +188,15 @@ _Read_RuneMagi(const char *fname)
|
|||||||
rl->__variable = rl->__mapupper_ext.__ranges +
|
rl->__variable = rl->__mapupper_ext.__ranges +
|
||||||
rl->__mapupper_ext.__nranges;
|
rl->__mapupper_ext.__nranges;
|
||||||
|
|
||||||
variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
|
variable = mapupper_ext_ranges + BSWAP(frl->mapupper_ext_nranges);
|
||||||
frr = runetype_ext_ranges;
|
frr = runetype_ext_ranges;
|
||||||
rr = rl->__runetype_ext.__ranges;
|
rr = rl->__runetype_ext.__ranges;
|
||||||
for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
|
for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
|
||||||
uint32_t *types;
|
uint32_t *types;
|
||||||
|
|
||||||
rr[x].__min = frr[x].min;
|
rr[x].__min = BSWAP(frr[x].min);
|
||||||
rr[x].__max = frr[x].max;
|
rr[x].__max = BSWAP(frr[x].max);
|
||||||
rr[x].__map = frr[x].map;
|
rr[x].__map = BSWAP(frr[x].map);
|
||||||
if (rr[x].__map == 0) {
|
if (rr[x].__map == 0) {
|
||||||
int len = rr[x].__max - rr[x].__min + 1;
|
int len = rr[x].__max - rr[x].__min + 1;
|
||||||
types = variable;
|
types = variable;
|
||||||
@ -211,17 +212,17 @@ _Read_RuneMagi(const char *fname)
|
|||||||
frr = maplower_ext_ranges;
|
frr = maplower_ext_ranges;
|
||||||
rr = rl->__maplower_ext.__ranges;
|
rr = rl->__maplower_ext.__ranges;
|
||||||
for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
|
for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
|
||||||
rr[x].__min = frr[x].min;
|
rr[x].__min = BSWAP(frr[x].min);
|
||||||
rr[x].__max = frr[x].max;
|
rr[x].__max = BSWAP(frr[x].max);
|
||||||
rr[x].__map = frr[x].map;
|
rr[x].__map = BSWAP(frr[x].map);
|
||||||
}
|
}
|
||||||
|
|
||||||
frr = mapupper_ext_ranges;
|
frr = mapupper_ext_ranges;
|
||||||
rr = rl->__mapupper_ext.__ranges;
|
rr = rl->__mapupper_ext.__ranges;
|
||||||
for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
|
for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
|
||||||
rr[x].__min = frr[x].min;
|
rr[x].__min = BSWAP(frr[x].min);
|
||||||
rr[x].__max = frr[x].max;
|
rr[x].__max = BSWAP(frr[x].max);
|
||||||
rr[x].__map = frr[x].map;
|
rr[x].__map = BSWAP(frr[x].map);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(rl->__variable, variable, rl->__variable_len);
|
memcpy(rl->__variable, variable, rl->__variable_len);
|
||||||
|
@ -75,140 +75,140 @@ static const struct {
|
|||||||
double hi;
|
double hi;
|
||||||
double lo;
|
double lo;
|
||||||
} tbl[INTERVALS] = {
|
} tbl[INTERVALS] = {
|
||||||
0x1p+0, 0x0p+0,
|
{ 0x1p+0, 0x0p+0 },
|
||||||
/*
|
/*
|
||||||
* XXX hi is rounded down, and the formatting is not quite normal.
|
* XXX hi is rounded down, and the formatting is not quite normal.
|
||||||
* But I rather like both. The 0x1.*p format is good for 4N+1
|
* But I rather like both. The 0x1.*p format is good for 4N+1
|
||||||
* mantissa bits. Rounding down makes the lo terms positive,
|
* mantissa bits. Rounding down makes the lo terms positive,
|
||||||
* so that the columnar formatting can be simpler.
|
* so that the columnar formatting can be simpler.
|
||||||
*/
|
*/
|
||||||
0x1.0163da9fb3335p+0, 0x1.b61299ab8cdb7p-54,
|
{ 0x1.0163da9fb3335p+0, 0x1.b61299ab8cdb7p-54 },
|
||||||
0x1.02c9a3e778060p+0, 0x1.dcdef95949ef4p-53,
|
{ 0x1.02c9a3e778060p+0, 0x1.dcdef95949ef4p-53 },
|
||||||
0x1.04315e86e7f84p+0, 0x1.7ae71f3441b49p-53,
|
{ 0x1.04315e86e7f84p+0, 0x1.7ae71f3441b49p-53 },
|
||||||
0x1.059b0d3158574p+0, 0x1.d73e2a475b465p-55,
|
{ 0x1.059b0d3158574p+0, 0x1.d73e2a475b465p-55 },
|
||||||
0x1.0706b29ddf6ddp+0, 0x1.8db880753b0f6p-53,
|
{ 0x1.0706b29ddf6ddp+0, 0x1.8db880753b0f6p-53 },
|
||||||
0x1.0874518759bc8p+0, 0x1.186be4bb284ffp-57,
|
{ 0x1.0874518759bc8p+0, 0x1.186be4bb284ffp-57 },
|
||||||
0x1.09e3ecac6f383p+0, 0x1.1487818316136p-54,
|
{ 0x1.09e3ecac6f383p+0, 0x1.1487818316136p-54 },
|
||||||
0x1.0b5586cf9890fp+0, 0x1.8a62e4adc610bp-54,
|
{ 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc610bp-54 },
|
||||||
0x1.0cc922b7247f7p+0, 0x1.01edc16e24f71p-54,
|
{ 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f71p-54 },
|
||||||
0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c57b53p-59,
|
{ 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c57b53p-59 },
|
||||||
0x1.0fb66affed31ap+0, 0x1.e464123bb1428p-53,
|
{ 0x1.0fb66affed31ap+0, 0x1.e464123bb1428p-53 },
|
||||||
0x1.11301d0125b50p+0, 0x1.49d77e35db263p-53,
|
{ 0x1.11301d0125b50p+0, 0x1.49d77e35db263p-53 },
|
||||||
0x1.12abdc06c31cbp+0, 0x1.f72575a649ad2p-53,
|
{ 0x1.12abdc06c31cbp+0, 0x1.f72575a649ad2p-53 },
|
||||||
0x1.1429aaea92ddfp+0, 0x1.66820328764b1p-53,
|
{ 0x1.1429aaea92ddfp+0, 0x1.66820328764b1p-53 },
|
||||||
0x1.15a98c8a58e51p+0, 0x1.2406ab9eeab0ap-55,
|
{ 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeab0ap-55 },
|
||||||
0x1.172b83c7d517ap+0, 0x1.b9bef918a1d63p-53,
|
{ 0x1.172b83c7d517ap+0, 0x1.b9bef918a1d63p-53 },
|
||||||
0x1.18af9388c8de9p+0, 0x1.777ee1734784ap-53,
|
{ 0x1.18af9388c8de9p+0, 0x1.777ee1734784ap-53 },
|
||||||
0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4968e4p-55,
|
{ 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4968e4p-55 },
|
||||||
0x1.1bbe084045cd3p+0, 0x1.3563ce56884fcp-53,
|
{ 0x1.1bbe084045cd3p+0, 0x1.3563ce56884fcp-53 },
|
||||||
0x1.1d4873168b9aap+0, 0x1.e016e00a2643cp-54,
|
{ 0x1.1d4873168b9aap+0, 0x1.e016e00a2643cp-54 },
|
||||||
0x1.1ed5022fcd91cp+0, 0x1.71033fec2243ap-53,
|
{ 0x1.1ed5022fcd91cp+0, 0x1.71033fec2243ap-53 },
|
||||||
0x1.2063b88628cd6p+0, 0x1.dc775814a8495p-55,
|
{ 0x1.2063b88628cd6p+0, 0x1.dc775814a8495p-55 },
|
||||||
0x1.21f49917ddc96p+0, 0x1.2a97e9494a5eep-55,
|
{ 0x1.21f49917ddc96p+0, 0x1.2a97e9494a5eep-55 },
|
||||||
0x1.2387a6e756238p+0, 0x1.9b07eb6c70573p-54,
|
{ 0x1.2387a6e756238p+0, 0x1.9b07eb6c70573p-54 },
|
||||||
0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f4a4p-55,
|
{ 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f4a4p-55 },
|
||||||
0x1.26b4565e27cddp+0, 0x1.2bd339940e9d9p-55,
|
{ 0x1.26b4565e27cddp+0, 0x1.2bd339940e9d9p-55 },
|
||||||
0x1.284dfe1f56380p+0, 0x1.2d9e2b9e07941p-53,
|
{ 0x1.284dfe1f56380p+0, 0x1.2d9e2b9e07941p-53 },
|
||||||
0x1.29e9df51fdee1p+0, 0x1.612e8afad1255p-55,
|
{ 0x1.29e9df51fdee1p+0, 0x1.612e8afad1255p-55 },
|
||||||
0x1.2b87fd0dad98fp+0, 0x1.fbbd48ca71f95p-53,
|
{ 0x1.2b87fd0dad98fp+0, 0x1.fbbd48ca71f95p-53 },
|
||||||
0x1.2d285a6e4030bp+0, 0x1.0024754db41d5p-54,
|
{ 0x1.2d285a6e4030bp+0, 0x1.0024754db41d5p-54 },
|
||||||
0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d52383p-56,
|
{ 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d52383p-56 },
|
||||||
0x1.306fe0a31b715p+0, 0x1.6f46ad23182e4p-55,
|
{ 0x1.306fe0a31b715p+0, 0x1.6f46ad23182e4p-55 },
|
||||||
0x1.32170fc4cd831p+0, 0x1.a9ce78e18047cp-55,
|
{ 0x1.32170fc4cd831p+0, 0x1.a9ce78e18047cp-55 },
|
||||||
0x1.33c08b26416ffp+0, 0x1.32721843659a6p-54,
|
{ 0x1.33c08b26416ffp+0, 0x1.32721843659a6p-54 },
|
||||||
0x1.356c55f929ff0p+0, 0x1.928c468ec6e76p-53,
|
{ 0x1.356c55f929ff0p+0, 0x1.928c468ec6e76p-53 },
|
||||||
0x1.371a7373aa9cap+0, 0x1.4e28aa05e8a8fp-53,
|
{ 0x1.371a7373aa9cap+0, 0x1.4e28aa05e8a8fp-53 },
|
||||||
0x1.38cae6d05d865p+0, 0x1.0b53961b37da2p-53,
|
{ 0x1.38cae6d05d865p+0, 0x1.0b53961b37da2p-53 },
|
||||||
0x1.3a7db34e59ff6p+0, 0x1.d43792533c144p-53,
|
{ 0x1.3a7db34e59ff6p+0, 0x1.d43792533c144p-53 },
|
||||||
0x1.3c32dc313a8e4p+0, 0x1.08003e4516b1ep-53,
|
{ 0x1.3c32dc313a8e4p+0, 0x1.08003e4516b1ep-53 },
|
||||||
0x1.3dea64c123422p+0, 0x1.ada0911f09ebcp-55,
|
{ 0x1.3dea64c123422p+0, 0x1.ada0911f09ebcp-55 },
|
||||||
0x1.3fa4504ac801bp+0, 0x1.417ee03548306p-53,
|
{ 0x1.3fa4504ac801bp+0, 0x1.417ee03548306p-53 },
|
||||||
0x1.4160a21f72e29p+0, 0x1.f0864b71e7b6cp-53,
|
{ 0x1.4160a21f72e29p+0, 0x1.f0864b71e7b6cp-53 },
|
||||||
0x1.431f5d950a896p+0, 0x1.b8e088728219ap-53,
|
{ 0x1.431f5d950a896p+0, 0x1.b8e088728219ap-53 },
|
||||||
0x1.44e086061892dp+0, 0x1.89b7a04ef80d0p-59,
|
{ 0x1.44e086061892dp+0, 0x1.89b7a04ef80d0p-59 },
|
||||||
0x1.46a41ed1d0057p+0, 0x1.c944bd1648a76p-54,
|
{ 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a76p-54 },
|
||||||
0x1.486a2b5c13cd0p+0, 0x1.3c1a3b69062f0p-56,
|
{ 0x1.486a2b5c13cd0p+0, 0x1.3c1a3b69062f0p-56 },
|
||||||
0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be56p-54,
|
{ 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be56p-54 },
|
||||||
0x1.4bfdad5362a27p+0, 0x1.d4397afec42e2p-56,
|
{ 0x1.4bfdad5362a27p+0, 0x1.d4397afec42e2p-56 },
|
||||||
0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a7833p-54,
|
{ 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a7833p-54 },
|
||||||
0x1.4f9b2769d2ca6p+0, 0x1.5a67b16d3540ep-53,
|
{ 0x1.4f9b2769d2ca6p+0, 0x1.5a67b16d3540ep-53 },
|
||||||
0x1.516daa2cf6641p+0, 0x1.8225ea5909b04p-53,
|
{ 0x1.516daa2cf6641p+0, 0x1.8225ea5909b04p-53 },
|
||||||
0x1.5342b569d4f81p+0, 0x1.be1507893b0d5p-53,
|
{ 0x1.5342b569d4f81p+0, 0x1.be1507893b0d5p-53 },
|
||||||
0x1.551a4ca5d920ep+0, 0x1.8a5d8c4048699p-53,
|
{ 0x1.551a4ca5d920ep+0, 0x1.8a5d8c4048699p-53 },
|
||||||
0x1.56f4736b527dap+0, 0x1.9bb2c011d93adp-54,
|
{ 0x1.56f4736b527dap+0, 0x1.9bb2c011d93adp-54 },
|
||||||
0x1.58d12d497c7fdp+0, 0x1.295e15b9a1de8p-55,
|
{ 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1de8p-55 },
|
||||||
0x1.5ab07dd485429p+0, 0x1.6324c054647adp-54,
|
{ 0x1.5ab07dd485429p+0, 0x1.6324c054647adp-54 },
|
||||||
0x1.5c9268a5946b7p+0, 0x1.c4b1b816986a2p-60,
|
{ 0x1.5c9268a5946b7p+0, 0x1.c4b1b816986a2p-60 },
|
||||||
0x1.5e76f15ad2148p+0, 0x1.ba6f93080e65ep-54,
|
{ 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e65ep-54 },
|
||||||
0x1.605e1b976dc08p+0, 0x1.60edeb25490dcp-53,
|
{ 0x1.605e1b976dc08p+0, 0x1.60edeb25490dcp-53 },
|
||||||
0x1.6247eb03a5584p+0, 0x1.63e1f40dfa5b5p-53,
|
{ 0x1.6247eb03a5584p+0, 0x1.63e1f40dfa5b5p-53 },
|
||||||
0x1.6434634ccc31fp+0, 0x1.8edf0e2989db3p-53,
|
{ 0x1.6434634ccc31fp+0, 0x1.8edf0e2989db3p-53 },
|
||||||
0x1.6623882552224p+0, 0x1.224fb3c5371e6p-53,
|
{ 0x1.6623882552224p+0, 0x1.224fb3c5371e6p-53 },
|
||||||
0x1.68155d44ca973p+0, 0x1.038ae44f73e65p-57,
|
{ 0x1.68155d44ca973p+0, 0x1.038ae44f73e65p-57 },
|
||||||
0x1.6a09e667f3bccp+0, 0x1.21165f626cdd5p-53,
|
{ 0x1.6a09e667f3bccp+0, 0x1.21165f626cdd5p-53 },
|
||||||
0x1.6c012750bdabep+0, 0x1.daed533001e9ep-53,
|
{ 0x1.6c012750bdabep+0, 0x1.daed533001e9ep-53 },
|
||||||
0x1.6dfb23c651a2ep+0, 0x1.e441c597c3775p-53,
|
{ 0x1.6dfb23c651a2ep+0, 0x1.e441c597c3775p-53 },
|
||||||
0x1.6ff7df9519483p+0, 0x1.9f0fc369e7c42p-53,
|
{ 0x1.6ff7df9519483p+0, 0x1.9f0fc369e7c42p-53 },
|
||||||
0x1.71f75e8ec5f73p+0, 0x1.ba46e1e5de15ap-53,
|
{ 0x1.71f75e8ec5f73p+0, 0x1.ba46e1e5de15ap-53 },
|
||||||
0x1.73f9a48a58173p+0, 0x1.7ab9349cd1562p-53,
|
{ 0x1.73f9a48a58173p+0, 0x1.7ab9349cd1562p-53 },
|
||||||
0x1.75feb564267c8p+0, 0x1.7edd354674916p-53,
|
{ 0x1.75feb564267c8p+0, 0x1.7edd354674916p-53 },
|
||||||
0x1.780694fde5d3fp+0, 0x1.866b80a02162dp-54,
|
{ 0x1.780694fde5d3fp+0, 0x1.866b80a02162dp-54 },
|
||||||
0x1.7a11473eb0186p+0, 0x1.afaa2047ed9b4p-53,
|
{ 0x1.7a11473eb0186p+0, 0x1.afaa2047ed9b4p-53 },
|
||||||
0x1.7c1ed0130c132p+0, 0x1.f124cd1164dd6p-54,
|
{ 0x1.7c1ed0130c132p+0, 0x1.f124cd1164dd6p-54 },
|
||||||
0x1.7e2f336cf4e62p+0, 0x1.05d02ba15797ep-56,
|
{ 0x1.7e2f336cf4e62p+0, 0x1.05d02ba15797ep-56 },
|
||||||
0x1.80427543e1a11p+0, 0x1.6c1bccec9346bp-53,
|
{ 0x1.80427543e1a11p+0, 0x1.6c1bccec9346bp-53 },
|
||||||
0x1.82589994cce12p+0, 0x1.159f115f56694p-53,
|
{ 0x1.82589994cce12p+0, 0x1.159f115f56694p-53 },
|
||||||
0x1.8471a4623c7acp+0, 0x1.9ca5ed72f8c81p-53,
|
{ 0x1.8471a4623c7acp+0, 0x1.9ca5ed72f8c81p-53 },
|
||||||
0x1.868d99b4492ecp+0, 0x1.01c83b21584a3p-53,
|
{ 0x1.868d99b4492ecp+0, 0x1.01c83b21584a3p-53 },
|
||||||
0x1.88ac7d98a6699p+0, 0x1.994c2f37cb53ap-54,
|
{ 0x1.88ac7d98a6699p+0, 0x1.994c2f37cb53ap-54 },
|
||||||
0x1.8ace5422aa0dbp+0, 0x1.6e9f156864b27p-54,
|
{ 0x1.8ace5422aa0dbp+0, 0x1.6e9f156864b27p-54 },
|
||||||
0x1.8cf3216b5448bp+0, 0x1.de55439a2c38bp-53,
|
{ 0x1.8cf3216b5448bp+0, 0x1.de55439a2c38bp-53 },
|
||||||
0x1.8f1ae99157736p+0, 0x1.5cc13a2e3976cp-55,
|
{ 0x1.8f1ae99157736p+0, 0x1.5cc13a2e3976cp-55 },
|
||||||
0x1.9145b0b91ffc5p+0, 0x1.114c368d3ed6ep-53,
|
{ 0x1.9145b0b91ffc5p+0, 0x1.114c368d3ed6ep-53 },
|
||||||
0x1.93737b0cdc5e4p+0, 0x1.e8a0387e4a814p-53,
|
{ 0x1.93737b0cdc5e4p+0, 0x1.e8a0387e4a814p-53 },
|
||||||
0x1.95a44cbc8520ep+0, 0x1.d36906d2b41f9p-53,
|
{ 0x1.95a44cbc8520ep+0, 0x1.d36906d2b41f9p-53 },
|
||||||
0x1.97d829fde4e4fp+0, 0x1.173d241f23d18p-53,
|
{ 0x1.97d829fde4e4fp+0, 0x1.173d241f23d18p-53 },
|
||||||
0x1.9a0f170ca07b9p+0, 0x1.7462137188ce7p-53,
|
{ 0x1.9a0f170ca07b9p+0, 0x1.7462137188ce7p-53 },
|
||||||
0x1.9c49182a3f090p+0, 0x1.c7c46b071f2bep-56,
|
{ 0x1.9c49182a3f090p+0, 0x1.c7c46b071f2bep-56 },
|
||||||
0x1.9e86319e32323p+0, 0x1.824ca78e64c6ep-56,
|
{ 0x1.9e86319e32323p+0, 0x1.824ca78e64c6ep-56 },
|
||||||
0x1.a0c667b5de564p+0, 0x1.6535b51719567p-53,
|
{ 0x1.a0c667b5de564p+0, 0x1.6535b51719567p-53 },
|
||||||
0x1.a309bec4a2d33p+0, 0x1.6305c7ddc36abp-54,
|
{ 0x1.a309bec4a2d33p+0, 0x1.6305c7ddc36abp-54 },
|
||||||
0x1.a5503b23e255cp+0, 0x1.1684892395f0fp-53,
|
{ 0x1.a5503b23e255cp+0, 0x1.1684892395f0fp-53 },
|
||||||
0x1.a799e1330b358p+0, 0x1.bcb7ecac563c7p-54,
|
{ 0x1.a799e1330b358p+0, 0x1.bcb7ecac563c7p-54 },
|
||||||
0x1.a9e6b5579fdbfp+0, 0x1.0fac90ef7fd31p-54,
|
{ 0x1.a9e6b5579fdbfp+0, 0x1.0fac90ef7fd31p-54 },
|
||||||
0x1.ac36bbfd3f379p+0, 0x1.81b72cd4624ccp-53,
|
{ 0x1.ac36bbfd3f379p+0, 0x1.81b72cd4624ccp-53 },
|
||||||
0x1.ae89f995ad3adp+0, 0x1.7a1cd345dcc81p-54,
|
{ 0x1.ae89f995ad3adp+0, 0x1.7a1cd345dcc81p-54 },
|
||||||
0x1.b0e07298db665p+0, 0x1.2108559bf8deep-53,
|
{ 0x1.b0e07298db665p+0, 0x1.2108559bf8deep-53 },
|
||||||
0x1.b33a2b84f15fap+0, 0x1.ed7fa1cf7b290p-53,
|
{ 0x1.b33a2b84f15fap+0, 0x1.ed7fa1cf7b290p-53 },
|
||||||
0x1.b59728de55939p+0, 0x1.1c7102222c90ep-53,
|
{ 0x1.b59728de55939p+0, 0x1.1c7102222c90ep-53 },
|
||||||
0x1.b7f76f2fb5e46p+0, 0x1.d54f610356a79p-53,
|
{ 0x1.b7f76f2fb5e46p+0, 0x1.d54f610356a79p-53 },
|
||||||
0x1.ba5b030a10649p+0, 0x1.0819678d5eb69p-53,
|
{ 0x1.ba5b030a10649p+0, 0x1.0819678d5eb69p-53 },
|
||||||
0x1.bcc1e904bc1d2p+0, 0x1.23dd07a2d9e84p-55,
|
{ 0x1.bcc1e904bc1d2p+0, 0x1.23dd07a2d9e84p-55 },
|
||||||
0x1.bf2c25bd71e08p+0, 0x1.0811ae04a31c7p-53,
|
{ 0x1.bf2c25bd71e08p+0, 0x1.0811ae04a31c7p-53 },
|
||||||
0x1.c199bdd85529cp+0, 0x1.11065895048ddp-55,
|
{ 0x1.c199bdd85529cp+0, 0x1.11065895048ddp-55 },
|
||||||
0x1.c40ab5fffd07ap+0, 0x1.b4537e083c60ap-54,
|
{ 0x1.c40ab5fffd07ap+0, 0x1.b4537e083c60ap-54 },
|
||||||
0x1.c67f12e57d14bp+0, 0x1.2884dff483cadp-54,
|
{ 0x1.c67f12e57d14bp+0, 0x1.2884dff483cadp-54 },
|
||||||
0x1.c8f6d9406e7b5p+0, 0x1.1acbc48805c44p-56,
|
{ 0x1.c8f6d9406e7b5p+0, 0x1.1acbc48805c44p-56 },
|
||||||
0x1.cb720dcef9069p+0, 0x1.503cbd1e949dbp-56,
|
{ 0x1.cb720dcef9069p+0, 0x1.503cbd1e949dbp-56 },
|
||||||
0x1.cdf0b555dc3f9p+0, 0x1.889f12b1f58a3p-53,
|
{ 0x1.cdf0b555dc3f9p+0, 0x1.889f12b1f58a3p-53 },
|
||||||
0x1.d072d4a07897bp+0, 0x1.1a1e45e4342b2p-53,
|
{ 0x1.d072d4a07897bp+0, 0x1.1a1e45e4342b2p-53 },
|
||||||
0x1.d2f87080d89f1p+0, 0x1.15bc247313d44p-53,
|
{ 0x1.d2f87080d89f1p+0, 0x1.15bc247313d44p-53 },
|
||||||
0x1.d5818dcfba487p+0, 0x1.2ed02d75b3707p-55,
|
{ 0x1.d5818dcfba487p+0, 0x1.2ed02d75b3707p-55 },
|
||||||
0x1.d80e316c98397p+0, 0x1.7709f3a09100cp-53,
|
{ 0x1.d80e316c98397p+0, 0x1.7709f3a09100cp-53 },
|
||||||
0x1.da9e603db3285p+0, 0x1.c2300696db532p-54,
|
{ 0x1.da9e603db3285p+0, 0x1.c2300696db532p-54 },
|
||||||
0x1.dd321f301b460p+0, 0x1.2da5778f018c3p-54,
|
{ 0x1.dd321f301b460p+0, 0x1.2da5778f018c3p-54 },
|
||||||
0x1.dfc97337b9b5ep+0, 0x1.72d195873da52p-53,
|
{ 0x1.dfc97337b9b5ep+0, 0x1.72d195873da52p-53 },
|
||||||
0x1.e264614f5a128p+0, 0x1.424ec3f42f5b5p-53,
|
{ 0x1.e264614f5a128p+0, 0x1.424ec3f42f5b5p-53 },
|
||||||
0x1.e502ee78b3ff6p+0, 0x1.39e8980a9cc8fp-55,
|
{ 0x1.e502ee78b3ff6p+0, 0x1.39e8980a9cc8fp-55 },
|
||||||
0x1.e7a51fbc74c83p+0, 0x1.2d522ca0c8de2p-54,
|
{ 0x1.e7a51fbc74c83p+0, 0x1.2d522ca0c8de2p-54 },
|
||||||
0x1.ea4afa2a490d9p+0, 0x1.0b1ee7431ebb6p-53,
|
{ 0x1.ea4afa2a490d9p+0, 0x1.0b1ee7431ebb6p-53 },
|
||||||
0x1.ecf482d8e67f0p+0, 0x1.1b60625f7293ap-53,
|
{ 0x1.ecf482d8e67f0p+0, 0x1.1b60625f7293ap-53 },
|
||||||
0x1.efa1bee615a27p+0, 0x1.dc7f486a4b6b0p-54,
|
{ 0x1.efa1bee615a27p+0, 0x1.dc7f486a4b6b0p-54 },
|
||||||
0x1.f252b376bba97p+0, 0x1.3a1a5bf0d8e43p-54,
|
{ 0x1.f252b376bba97p+0, 0x1.3a1a5bf0d8e43p-54 },
|
||||||
0x1.f50765b6e4540p+0, 0x1.9d3e12dd8a18bp-54,
|
{ 0x1.f50765b6e4540p+0, 0x1.9d3e12dd8a18bp-54 },
|
||||||
0x1.f7bfdad9cbe13p+0, 0x1.1227697fce57bp-53,
|
{ 0x1.f7bfdad9cbe13p+0, 0x1.1227697fce57bp-53 },
|
||||||
0x1.fa7c1819e90d8p+0, 0x1.74853f3a5931ep-55,
|
{ 0x1.fa7c1819e90d8p+0, 0x1.74853f3a5931ep-55 },
|
||||||
0x1.fd3c22b8f71f1p+0, 0x1.2eb74966579e7p-57
|
{ 0x1.fd3c22b8f71f1p+0, 0x1.2eb74966579e7p-57 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -152,135 +152,135 @@ static const struct {
|
|||||||
* mainly to minimize the size of the table. Using all 24 bits
|
* mainly to minimize the size of the table. Using all 24 bits
|
||||||
* in a float for it automatically satisfies the above constraints.
|
* in a float for it automatically satisfies the above constraints.
|
||||||
*/
|
*/
|
||||||
0x800000.0p-23, 0, 0,
|
{ 0x800000.0p-23, 0, 0 },
|
||||||
0xfe0000.0p-24, 0x8080ac.0p-30, -0x14ee431dae6675.0p-84,
|
{ 0xfe0000.0p-24, 0x8080ac.0p-30, -0x14ee431dae6675.0p-84 },
|
||||||
0xfc0000.0p-24, 0x8102b3.0p-29, -0x1db29ee2d83718.0p-84,
|
{ 0xfc0000.0p-24, 0x8102b3.0p-29, -0x1db29ee2d83718.0p-84 },
|
||||||
0xfa0000.0p-24, 0xc24929.0p-29, 0x1191957d173698.0p-83,
|
{ 0xfa0000.0p-24, 0xc24929.0p-29, 0x1191957d173698.0p-83 },
|
||||||
0xf80000.0p-24, 0x820aec.0p-28, 0x13ce8888e02e79.0p-82,
|
{ 0xf80000.0p-24, 0x820aec.0p-28, 0x13ce8888e02e79.0p-82 },
|
||||||
0xf60000.0p-24, 0xa33577.0p-28, -0x17a4382ce6eb7c.0p-82,
|
{ 0xf60000.0p-24, 0xa33577.0p-28, -0x17a4382ce6eb7c.0p-82 },
|
||||||
0xf48000.0p-24, 0xbc42cb.0p-28, -0x172a21161a1076.0p-83,
|
{ 0xf48000.0p-24, 0xbc42cb.0p-28, -0x172a21161a1076.0p-83 },
|
||||||
0xf30000.0p-24, 0xd57797.0p-28, -0x1e09de07cb9589.0p-82,
|
{ 0xf30000.0p-24, 0xd57797.0p-28, -0x1e09de07cb9589.0p-82 },
|
||||||
0xf10000.0p-24, 0xf7518e.0p-28, 0x1ae1eec1b036c5.0p-91,
|
{ 0xf10000.0p-24, 0xf7518e.0p-28, 0x1ae1eec1b036c5.0p-91 },
|
||||||
0xef0000.0p-24, 0x8cb9df.0p-27, -0x1d7355325d560e.0p-81,
|
{ 0xef0000.0p-24, 0x8cb9df.0p-27, -0x1d7355325d560e.0p-81 },
|
||||||
0xed8000.0p-24, 0x999ec0.0p-27, -0x1f9f02d256d503.0p-82,
|
{ 0xed8000.0p-24, 0x999ec0.0p-27, -0x1f9f02d256d503.0p-82 },
|
||||||
0xec0000.0p-24, 0xa6988b.0p-27, -0x16fc0a9d12c17a.0p-83,
|
{ 0xec0000.0p-24, 0xa6988b.0p-27, -0x16fc0a9d12c17a.0p-83 },
|
||||||
0xea0000.0p-24, 0xb80698.0p-27, 0x15d581c1e8da9a.0p-81,
|
{ 0xea0000.0p-24, 0xb80698.0p-27, 0x15d581c1e8da9a.0p-81 },
|
||||||
0xe80000.0p-24, 0xc99af3.0p-27, -0x1535b3ba8f150b.0p-83,
|
{ 0xe80000.0p-24, 0xc99af3.0p-27, -0x1535b3ba8f150b.0p-83 },
|
||||||
0xe70000.0p-24, 0xd273b2.0p-27, 0x163786f5251af0.0p-85,
|
{ 0xe70000.0p-24, 0xd273b2.0p-27, 0x163786f5251af0.0p-85 },
|
||||||
0xe50000.0p-24, 0xe442c0.0p-27, 0x1bc4b2368e32d5.0p-84,
|
{ 0xe50000.0p-24, 0xe442c0.0p-27, 0x1bc4b2368e32d5.0p-84 },
|
||||||
0xe38000.0p-24, 0xf1b83f.0p-27, 0x1c6090f684e676.0p-81,
|
{ 0xe38000.0p-24, 0xf1b83f.0p-27, 0x1c6090f684e676.0p-81 },
|
||||||
0xe20000.0p-24, 0xff448a.0p-27, -0x1890aa69ac9f42.0p-82,
|
{ 0xe20000.0p-24, 0xff448a.0p-27, -0x1890aa69ac9f42.0p-82 },
|
||||||
0xe08000.0p-24, 0x8673f6.0p-26, 0x1b9985194b6b00.0p-80,
|
{ 0xe08000.0p-24, 0x8673f6.0p-26, 0x1b9985194b6b00.0p-80 },
|
||||||
0xdf0000.0p-24, 0x8d515c.0p-26, -0x1dc08d61c6ef1e.0p-83,
|
{ 0xdf0000.0p-24, 0x8d515c.0p-26, -0x1dc08d61c6ef1e.0p-83 },
|
||||||
0xdd8000.0p-24, 0x943a9e.0p-26, -0x1f72a2dac729b4.0p-82,
|
{ 0xdd8000.0p-24, 0x943a9e.0p-26, -0x1f72a2dac729b4.0p-82 },
|
||||||
0xdc0000.0p-24, 0x9b2fe6.0p-26, -0x1fd4dfd3a0afb9.0p-80,
|
{ 0xdc0000.0p-24, 0x9b2fe6.0p-26, -0x1fd4dfd3a0afb9.0p-80 },
|
||||||
0xda8000.0p-24, 0xa2315d.0p-26, -0x11b26121629c47.0p-82,
|
{ 0xda8000.0p-24, 0xa2315d.0p-26, -0x11b26121629c47.0p-82 },
|
||||||
0xd90000.0p-24, 0xa93f2f.0p-26, 0x1286d633e8e569.0p-81,
|
{ 0xd90000.0p-24, 0xa93f2f.0p-26, 0x1286d633e8e569.0p-81 },
|
||||||
0xd78000.0p-24, 0xb05988.0p-26, 0x16128eba936770.0p-84,
|
{ 0xd78000.0p-24, 0xb05988.0p-26, 0x16128eba936770.0p-84 },
|
||||||
0xd60000.0p-24, 0xb78094.0p-26, 0x16ead577390d32.0p-80,
|
{ 0xd60000.0p-24, 0xb78094.0p-26, 0x16ead577390d32.0p-80 },
|
||||||
0xd50000.0p-24, 0xbc4c6c.0p-26, 0x151131ccf7c7b7.0p-81,
|
{ 0xd50000.0p-24, 0xbc4c6c.0p-26, 0x151131ccf7c7b7.0p-81 },
|
||||||
0xd38000.0p-24, 0xc3890a.0p-26, -0x115e2cd714bd06.0p-80,
|
{ 0xd38000.0p-24, 0xc3890a.0p-26, -0x115e2cd714bd06.0p-80 },
|
||||||
0xd20000.0p-24, 0xcad2d7.0p-26, -0x1847f406ebd3b0.0p-82,
|
{ 0xd20000.0p-24, 0xcad2d7.0p-26, -0x1847f406ebd3b0.0p-82 },
|
||||||
0xd10000.0p-24, 0xcfb620.0p-26, 0x1c2259904d6866.0p-81,
|
{ 0xd10000.0p-24, 0xcfb620.0p-26, 0x1c2259904d6866.0p-81 },
|
||||||
0xcf8000.0p-24, 0xd71653.0p-26, 0x1ece57a8d5ae55.0p-80,
|
{ 0xcf8000.0p-24, 0xd71653.0p-26, 0x1ece57a8d5ae55.0p-80 },
|
||||||
0xce0000.0p-24, 0xde843a.0p-26, -0x1f109d4bc45954.0p-81,
|
{ 0xce0000.0p-24, 0xde843a.0p-26, -0x1f109d4bc45954.0p-81 },
|
||||||
0xcd0000.0p-24, 0xe37fde.0p-26, 0x1bc03dc271a74d.0p-81,
|
{ 0xcd0000.0p-24, 0xe37fde.0p-26, 0x1bc03dc271a74d.0p-81 },
|
||||||
0xcb8000.0p-24, 0xeb050c.0p-26, -0x1bf2badc0df842.0p-85,
|
{ 0xcb8000.0p-24, 0xeb050c.0p-26, -0x1bf2badc0df842.0p-85 },
|
||||||
0xca0000.0p-24, 0xf29878.0p-26, -0x18efededd89fbe.0p-87,
|
{ 0xca0000.0p-24, 0xf29878.0p-26, -0x18efededd89fbe.0p-87 },
|
||||||
0xc90000.0p-24, 0xf7ad6f.0p-26, 0x1373ff977baa69.0p-81,
|
{ 0xc90000.0p-24, 0xf7ad6f.0p-26, 0x1373ff977baa69.0p-81 },
|
||||||
0xc80000.0p-24, 0xfcc8e3.0p-26, 0x196766f2fb3283.0p-80,
|
{ 0xc80000.0p-24, 0xfcc8e3.0p-26, 0x196766f2fb3283.0p-80 },
|
||||||
0xc68000.0p-24, 0x823f30.0p-25, 0x19bd076f7c434e.0p-79,
|
{ 0xc68000.0p-24, 0x823f30.0p-25, 0x19bd076f7c434e.0p-79 },
|
||||||
0xc58000.0p-24, 0x84d52c.0p-25, -0x1a327257af0f46.0p-79,
|
{ 0xc58000.0p-24, 0x84d52c.0p-25, -0x1a327257af0f46.0p-79 },
|
||||||
0xc40000.0p-24, 0x88bc74.0p-25, 0x113f23def19c5a.0p-81,
|
{ 0xc40000.0p-24, 0x88bc74.0p-25, 0x113f23def19c5a.0p-81 },
|
||||||
0xc30000.0p-24, 0x8b5ae6.0p-25, 0x1759f6e6b37de9.0p-79,
|
{ 0xc30000.0p-24, 0x8b5ae6.0p-25, 0x1759f6e6b37de9.0p-79 },
|
||||||
0xc20000.0p-24, 0x8dfccb.0p-25, 0x1ad35ca6ed5148.0p-81,
|
{ 0xc20000.0p-24, 0x8dfccb.0p-25, 0x1ad35ca6ed5148.0p-81 },
|
||||||
0xc10000.0p-24, 0x90a22b.0p-25, 0x1a1d71a87deba4.0p-79,
|
{ 0xc10000.0p-24, 0x90a22b.0p-25, 0x1a1d71a87deba4.0p-79 },
|
||||||
0xbf8000.0p-24, 0x94a0d8.0p-25, -0x139e5210c2b731.0p-80,
|
{ 0xbf8000.0p-24, 0x94a0d8.0p-25, -0x139e5210c2b731.0p-80 },
|
||||||
0xbe8000.0p-24, 0x974f16.0p-25, -0x18f6ebcff3ed73.0p-81,
|
{ 0xbe8000.0p-24, 0x974f16.0p-25, -0x18f6ebcff3ed73.0p-81 },
|
||||||
0xbd8000.0p-24, 0x9a00f1.0p-25, -0x1aa268be39aab7.0p-79,
|
{ 0xbd8000.0p-24, 0x9a00f1.0p-25, -0x1aa268be39aab7.0p-79 },
|
||||||
0xbc8000.0p-24, 0x9cb672.0p-25, -0x14c8815839c566.0p-79,
|
{ 0xbc8000.0p-24, 0x9cb672.0p-25, -0x14c8815839c566.0p-79 },
|
||||||
0xbb0000.0p-24, 0xa0cda1.0p-25, 0x1eaf46390dbb24.0p-81,
|
{ 0xbb0000.0p-24, 0xa0cda1.0p-25, 0x1eaf46390dbb24.0p-81 },
|
||||||
0xba0000.0p-24, 0xa38c6e.0p-25, 0x138e20d831f698.0p-81,
|
{ 0xba0000.0p-24, 0xa38c6e.0p-25, 0x138e20d831f698.0p-81 },
|
||||||
0xb90000.0p-24, 0xa64f05.0p-25, -0x1e8d3c41123616.0p-82,
|
{ 0xb90000.0p-24, 0xa64f05.0p-25, -0x1e8d3c41123616.0p-82 },
|
||||||
0xb80000.0p-24, 0xa91570.0p-25, 0x1ce28f5f3840b2.0p-80,
|
{ 0xb80000.0p-24, 0xa91570.0p-25, 0x1ce28f5f3840b2.0p-80 },
|
||||||
0xb70000.0p-24, 0xabdfbb.0p-25, -0x186e5c0a424234.0p-79,
|
{ 0xb70000.0p-24, 0xabdfbb.0p-25, -0x186e5c0a424234.0p-79 },
|
||||||
0xb60000.0p-24, 0xaeadef.0p-25, -0x14d41a0b2a08a4.0p-83,
|
{ 0xb60000.0p-24, 0xaeadef.0p-25, -0x14d41a0b2a08a4.0p-83 },
|
||||||
0xb50000.0p-24, 0xb18018.0p-25, 0x16755892770634.0p-79,
|
{ 0xb50000.0p-24, 0xb18018.0p-25, 0x16755892770634.0p-79 },
|
||||||
0xb40000.0p-24, 0xb45642.0p-25, -0x16395ebe59b152.0p-82,
|
{ 0xb40000.0p-24, 0xb45642.0p-25, -0x16395ebe59b152.0p-82 },
|
||||||
0xb30000.0p-24, 0xb73077.0p-25, 0x1abc65c8595f09.0p-80,
|
{ 0xb30000.0p-24, 0xb73077.0p-25, 0x1abc65c8595f09.0p-80 },
|
||||||
0xb20000.0p-24, 0xba0ec4.0p-25, -0x1273089d3dad89.0p-79,
|
{ 0xb20000.0p-24, 0xba0ec4.0p-25, -0x1273089d3dad89.0p-79 },
|
||||||
0xb10000.0p-24, 0xbcf133.0p-25, 0x10f9f67b1f4bbf.0p-79,
|
{ 0xb10000.0p-24, 0xbcf133.0p-25, 0x10f9f67b1f4bbf.0p-79 },
|
||||||
0xb00000.0p-24, 0xbfd7d2.0p-25, -0x109fab90486409.0p-80,
|
{ 0xb00000.0p-24, 0xbfd7d2.0p-25, -0x109fab90486409.0p-80 },
|
||||||
0xaf0000.0p-24, 0xc2c2ac.0p-25, -0x1124680aa43333.0p-79,
|
{ 0xaf0000.0p-24, 0xc2c2ac.0p-25, -0x1124680aa43333.0p-79 },
|
||||||
0xae8000.0p-24, 0xc439b3.0p-25, -0x1f360cc4710fc0.0p-80,
|
{ 0xae8000.0p-24, 0xc439b3.0p-25, -0x1f360cc4710fc0.0p-80 },
|
||||||
0xad8000.0p-24, 0xc72afd.0p-25, -0x132d91f21d89c9.0p-80,
|
{ 0xad8000.0p-24, 0xc72afd.0p-25, -0x132d91f21d89c9.0p-80 },
|
||||||
0xac8000.0p-24, 0xca20a2.0p-25, -0x16bf9b4d1f8da8.0p-79,
|
{ 0xac8000.0p-24, 0xca20a2.0p-25, -0x16bf9b4d1f8da8.0p-79 },
|
||||||
0xab8000.0p-24, 0xcd1aae.0p-25, 0x19deb5ce6a6a87.0p-81,
|
{ 0xab8000.0p-24, 0xcd1aae.0p-25, 0x19deb5ce6a6a87.0p-81 },
|
||||||
0xaa8000.0p-24, 0xd0192f.0p-25, 0x1a29fb48f7d3cb.0p-79,
|
{ 0xaa8000.0p-24, 0xd0192f.0p-25, 0x1a29fb48f7d3cb.0p-79 },
|
||||||
0xaa0000.0p-24, 0xd19a20.0p-25, 0x1127d3c6457f9d.0p-81,
|
{ 0xaa0000.0p-24, 0xd19a20.0p-25, 0x1127d3c6457f9d.0p-81 },
|
||||||
0xa90000.0p-24, 0xd49f6a.0p-25, -0x1ba930e486a0ac.0p-81,
|
{ 0xa90000.0p-24, 0xd49f6a.0p-25, -0x1ba930e486a0ac.0p-81 },
|
||||||
0xa80000.0p-24, 0xd7a94b.0p-25, -0x1b6e645f31549e.0p-79,
|
{ 0xa80000.0p-24, 0xd7a94b.0p-25, -0x1b6e645f31549e.0p-79 },
|
||||||
0xa70000.0p-24, 0xdab7d0.0p-25, 0x1118a425494b61.0p-80,
|
{ 0xa70000.0p-24, 0xdab7d0.0p-25, 0x1118a425494b61.0p-80 },
|
||||||
0xa68000.0p-24, 0xdc40d5.0p-25, 0x1966f24d29d3a3.0p-80,
|
{ 0xa68000.0p-24, 0xdc40d5.0p-25, 0x1966f24d29d3a3.0p-80 },
|
||||||
0xa58000.0p-24, 0xdf566d.0p-25, -0x1d8e52eb2248f1.0p-82,
|
{ 0xa58000.0p-24, 0xdf566d.0p-25, -0x1d8e52eb2248f1.0p-82 },
|
||||||
0xa48000.0p-24, 0xe270ce.0p-25, -0x1ee370f96e6b68.0p-80,
|
{ 0xa48000.0p-24, 0xe270ce.0p-25, -0x1ee370f96e6b68.0p-80 },
|
||||||
0xa40000.0p-24, 0xe3ffce.0p-25, 0x1d155324911f57.0p-80,
|
{ 0xa40000.0p-24, 0xe3ffce.0p-25, 0x1d155324911f57.0p-80 },
|
||||||
0xa30000.0p-24, 0xe72179.0p-25, -0x1fe6e2f2f867d9.0p-80,
|
{ 0xa30000.0p-24, 0xe72179.0p-25, -0x1fe6e2f2f867d9.0p-80 },
|
||||||
0xa20000.0p-24, 0xea4812.0p-25, 0x1b7be9add7f4d4.0p-80,
|
{ 0xa20000.0p-24, 0xea4812.0p-25, 0x1b7be9add7f4d4.0p-80 },
|
||||||
0xa18000.0p-24, 0xebdd3d.0p-25, 0x1b3cfb3f7511dd.0p-79,
|
{ 0xa18000.0p-24, 0xebdd3d.0p-25, 0x1b3cfb3f7511dd.0p-79 },
|
||||||
0xa08000.0p-24, 0xef0b5b.0p-25, -0x1220de1f730190.0p-79,
|
{ 0xa08000.0p-24, 0xef0b5b.0p-25, -0x1220de1f730190.0p-79 },
|
||||||
0xa00000.0p-24, 0xf0a451.0p-25, -0x176364c9ac81cd.0p-80,
|
{ 0xa00000.0p-24, 0xf0a451.0p-25, -0x176364c9ac81cd.0p-80 },
|
||||||
0x9f0000.0p-24, 0xf3da16.0p-25, 0x1eed6b9aafac8d.0p-81,
|
{ 0x9f0000.0p-24, 0xf3da16.0p-25, 0x1eed6b9aafac8d.0p-81 },
|
||||||
0x9e8000.0p-24, 0xf576e9.0p-25, 0x1d593218675af2.0p-79,
|
{ 0x9e8000.0p-24, 0xf576e9.0p-25, 0x1d593218675af2.0p-79 },
|
||||||
0x9d8000.0p-24, 0xf8b47c.0p-25, -0x13e8eb7da053e0.0p-84,
|
{ 0x9d8000.0p-24, 0xf8b47c.0p-25, -0x13e8eb7da053e0.0p-84 },
|
||||||
0x9d0000.0p-24, 0xfa553f.0p-25, 0x1c063259bcade0.0p-79,
|
{ 0x9d0000.0p-24, 0xfa553f.0p-25, 0x1c063259bcade0.0p-79 },
|
||||||
0x9c0000.0p-24, 0xfd9ac5.0p-25, 0x1ef491085fa3c1.0p-79,
|
{ 0x9c0000.0p-24, 0xfd9ac5.0p-25, 0x1ef491085fa3c1.0p-79 },
|
||||||
0x9b8000.0p-24, 0xff3f8c.0p-25, 0x1d607a7c2b8c53.0p-79,
|
{ 0x9b8000.0p-24, 0xff3f8c.0p-25, 0x1d607a7c2b8c53.0p-79 },
|
||||||
0x9a8000.0p-24, 0x814697.0p-24, -0x12ad3817004f3f.0p-78,
|
{ 0x9a8000.0p-24, 0x814697.0p-24, -0x12ad3817004f3f.0p-78 },
|
||||||
0x9a0000.0p-24, 0x821b06.0p-24, -0x189fc53117f9e5.0p-81,
|
{ 0x9a0000.0p-24, 0x821b06.0p-24, -0x189fc53117f9e5.0p-81 },
|
||||||
0x990000.0p-24, 0x83c5f8.0p-24, 0x14cf15a048907b.0p-79,
|
{ 0x990000.0p-24, 0x83c5f8.0p-24, 0x14cf15a048907b.0p-79 },
|
||||||
0x988000.0p-24, 0x849c7d.0p-24, 0x1cbb1d35fb8287.0p-78,
|
{ 0x988000.0p-24, 0x849c7d.0p-24, 0x1cbb1d35fb8287.0p-78 },
|
||||||
0x978000.0p-24, 0x864ba6.0p-24, 0x1128639b814f9c.0p-78,
|
{ 0x978000.0p-24, 0x864ba6.0p-24, 0x1128639b814f9c.0p-78 },
|
||||||
0x970000.0p-24, 0x87244c.0p-24, 0x184733853300f0.0p-79,
|
{ 0x970000.0p-24, 0x87244c.0p-24, 0x184733853300f0.0p-79 },
|
||||||
0x968000.0p-24, 0x87fdaa.0p-24, 0x109d23aef77dd6.0p-80,
|
{ 0x968000.0p-24, 0x87fdaa.0p-24, 0x109d23aef77dd6.0p-80 },
|
||||||
0x958000.0p-24, 0x89b293.0p-24, -0x1a81ef367a59de.0p-78,
|
{ 0x958000.0p-24, 0x89b293.0p-24, -0x1a81ef367a59de.0p-78 },
|
||||||
0x950000.0p-24, 0x8a8e20.0p-24, -0x121ad3dbb2f452.0p-78,
|
{ 0x950000.0p-24, 0x8a8e20.0p-24, -0x121ad3dbb2f452.0p-78 },
|
||||||
0x948000.0p-24, 0x8b6a6a.0p-24, -0x1cfb981628af72.0p-79,
|
{ 0x948000.0p-24, 0x8b6a6a.0p-24, -0x1cfb981628af72.0p-79 },
|
||||||
0x938000.0p-24, 0x8d253a.0p-24, -0x1d21730ea76cfe.0p-79,
|
{ 0x938000.0p-24, 0x8d253a.0p-24, -0x1d21730ea76cfe.0p-79 },
|
||||||
0x930000.0p-24, 0x8e03c2.0p-24, 0x135cc00e566f77.0p-78,
|
{ 0x930000.0p-24, 0x8e03c2.0p-24, 0x135cc00e566f77.0p-78 },
|
||||||
0x928000.0p-24, 0x8ee30d.0p-24, -0x10fcb5df257a26.0p-80,
|
{ 0x928000.0p-24, 0x8ee30d.0p-24, -0x10fcb5df257a26.0p-80 },
|
||||||
0x918000.0p-24, 0x90a3ee.0p-24, -0x16e171b15433d7.0p-79,
|
{ 0x918000.0p-24, 0x90a3ee.0p-24, -0x16e171b15433d7.0p-79 },
|
||||||
0x910000.0p-24, 0x918587.0p-24, -0x1d050da07f3237.0p-79,
|
{ 0x910000.0p-24, 0x918587.0p-24, -0x1d050da07f3237.0p-79 },
|
||||||
0x908000.0p-24, 0x9267e7.0p-24, 0x1be03669a5268d.0p-79,
|
{ 0x908000.0p-24, 0x9267e7.0p-24, 0x1be03669a5268d.0p-79 },
|
||||||
0x8f8000.0p-24, 0x942f04.0p-24, 0x10b28e0e26c337.0p-79,
|
{ 0x8f8000.0p-24, 0x942f04.0p-24, 0x10b28e0e26c337.0p-79 },
|
||||||
0x8f0000.0p-24, 0x9513c3.0p-24, 0x1a1d820da57cf3.0p-78,
|
{ 0x8f0000.0p-24, 0x9513c3.0p-24, 0x1a1d820da57cf3.0p-78 },
|
||||||
0x8e8000.0p-24, 0x95f950.0p-24, -0x19ef8f13ae3cf1.0p-79,
|
{ 0x8e8000.0p-24, 0x95f950.0p-24, -0x19ef8f13ae3cf1.0p-79 },
|
||||||
0x8e0000.0p-24, 0x96dfab.0p-24, -0x109e417a6e507c.0p-78,
|
{ 0x8e0000.0p-24, 0x96dfab.0p-24, -0x109e417a6e507c.0p-78 },
|
||||||
0x8d0000.0p-24, 0x98aed2.0p-24, 0x10d01a2c5b0e98.0p-79,
|
{ 0x8d0000.0p-24, 0x98aed2.0p-24, 0x10d01a2c5b0e98.0p-79 },
|
||||||
0x8c8000.0p-24, 0x9997a2.0p-24, -0x1d6a50d4b61ea7.0p-78,
|
{ 0x8c8000.0p-24, 0x9997a2.0p-24, -0x1d6a50d4b61ea7.0p-78 },
|
||||||
0x8c0000.0p-24, 0x9a8145.0p-24, 0x1b3b190b83f952.0p-78,
|
{ 0x8c0000.0p-24, 0x9a8145.0p-24, 0x1b3b190b83f952.0p-78 },
|
||||||
0x8b8000.0p-24, 0x9b6bbf.0p-24, 0x13a69fad7e7abe.0p-78,
|
{ 0x8b8000.0p-24, 0x9b6bbf.0p-24, 0x13a69fad7e7abe.0p-78 },
|
||||||
0x8b0000.0p-24, 0x9c5711.0p-24, -0x11cd12316f576b.0p-78,
|
{ 0x8b0000.0p-24, 0x9c5711.0p-24, -0x11cd12316f576b.0p-78 },
|
||||||
0x8a8000.0p-24, 0x9d433b.0p-24, 0x1c95c444b807a2.0p-79,
|
{ 0x8a8000.0p-24, 0x9d433b.0p-24, 0x1c95c444b807a2.0p-79 },
|
||||||
0x898000.0p-24, 0x9f1e22.0p-24, -0x1b9c224ea698c3.0p-79,
|
{ 0x898000.0p-24, 0x9f1e22.0p-24, -0x1b9c224ea698c3.0p-79 },
|
||||||
0x890000.0p-24, 0xa00ce1.0p-24, 0x125ca93186cf0f.0p-81,
|
{ 0x890000.0p-24, 0xa00ce1.0p-24, 0x125ca93186cf0f.0p-81 },
|
||||||
0x888000.0p-24, 0xa0fc80.0p-24, -0x1ee38a7bc228b3.0p-79,
|
{ 0x888000.0p-24, 0xa0fc80.0p-24, -0x1ee38a7bc228b3.0p-79 },
|
||||||
0x880000.0p-24, 0xa1ed00.0p-24, -0x1a0db876613d20.0p-78,
|
{ 0x880000.0p-24, 0xa1ed00.0p-24, -0x1a0db876613d20.0p-78 },
|
||||||
0x878000.0p-24, 0xa2de62.0p-24, 0x193224e8516c01.0p-79,
|
{ 0x878000.0p-24, 0xa2de62.0p-24, 0x193224e8516c01.0p-79 },
|
||||||
0x870000.0p-24, 0xa3d0a9.0p-24, 0x1fa28b4d2541ad.0p-79,
|
{ 0x870000.0p-24, 0xa3d0a9.0p-24, 0x1fa28b4d2541ad.0p-79 },
|
||||||
0x868000.0p-24, 0xa4c3d6.0p-24, 0x1c1b5760fb4572.0p-78,
|
{ 0x868000.0p-24, 0xa4c3d6.0p-24, 0x1c1b5760fb4572.0p-78 },
|
||||||
0x858000.0p-24, 0xa6acea.0p-24, 0x1fed5d0f65949c.0p-80,
|
{ 0x858000.0p-24, 0xa6acea.0p-24, 0x1fed5d0f65949c.0p-80 },
|
||||||
0x850000.0p-24, 0xa7a2d4.0p-24, 0x1ad270c9d74936.0p-80,
|
{ 0x850000.0p-24, 0xa7a2d4.0p-24, 0x1ad270c9d74936.0p-80 },
|
||||||
0x848000.0p-24, 0xa899ab.0p-24, 0x199ff15ce53266.0p-79,
|
{ 0x848000.0p-24, 0xa899ab.0p-24, 0x199ff15ce53266.0p-79 },
|
||||||
0x840000.0p-24, 0xa99171.0p-24, 0x1a19e15ccc45d2.0p-79,
|
{ 0x840000.0p-24, 0xa99171.0p-24, 0x1a19e15ccc45d2.0p-79 },
|
||||||
0x838000.0p-24, 0xaa8a28.0p-24, -0x121a14ec532b36.0p-80,
|
{ 0x838000.0p-24, 0xaa8a28.0p-24, -0x121a14ec532b36.0p-80 },
|
||||||
0x830000.0p-24, 0xab83d1.0p-24, 0x1aee319980bff3.0p-79,
|
{ 0x830000.0p-24, 0xab83d1.0p-24, 0x1aee319980bff3.0p-79 },
|
||||||
0x828000.0p-24, 0xac7e6f.0p-24, -0x18ffd9e3900346.0p-80,
|
{ 0x828000.0p-24, 0xac7e6f.0p-24, -0x18ffd9e3900346.0p-80 },
|
||||||
0x820000.0p-24, 0xad7a03.0p-24, -0x1e4db102ce29f8.0p-80,
|
{ 0x820000.0p-24, 0xad7a03.0p-24, -0x1e4db102ce29f8.0p-80 },
|
||||||
0x818000.0p-24, 0xae768f.0p-24, 0x17c35c55a04a83.0p-81,
|
{ 0x818000.0p-24, 0xae768f.0p-24, 0x17c35c55a04a83.0p-81 },
|
||||||
0x810000.0p-24, 0xaf7415.0p-24, 0x1448324047019b.0p-78,
|
{ 0x810000.0p-24, 0xaf7415.0p-24, 0x1448324047019b.0p-78 },
|
||||||
0x808000.0p-24, 0xb07298.0p-24, -0x1750ee3915a198.0p-78,
|
{ 0x808000.0p-24, 0xb07298.0p-24, -0x1750ee3915a198.0p-78 },
|
||||||
0x800000.0p-24, 0xb17218.0p-24, -0x105c610ca86c39.0p-81,
|
{ 0x800000.0p-24, 0xb17218.0p-24, -0x105c610ca86c39.0p-81 },
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_UTAB
|
#ifdef USE_UTAB
|
||||||
@ -288,135 +288,135 @@ static const struct {
|
|||||||
float H; /* 1 + i/INTERVALS (exact) */
|
float H; /* 1 + i/INTERVALS (exact) */
|
||||||
float E; /* H(i) * G(i) - 1 (exact) */
|
float E; /* H(i) * G(i) - 1 (exact) */
|
||||||
} U[TSIZE] = {
|
} U[TSIZE] = {
|
||||||
0x800000.0p-23, 0,
|
{ 0x800000.0p-23, 0 },
|
||||||
0x810000.0p-23, -0x800000.0p-37,
|
{ 0x810000.0p-23, -0x800000.0p-37 },
|
||||||
0x820000.0p-23, -0x800000.0p-35,
|
{ 0x820000.0p-23, -0x800000.0p-35 },
|
||||||
0x830000.0p-23, -0x900000.0p-34,
|
{ 0x830000.0p-23, -0x900000.0p-34 },
|
||||||
0x840000.0p-23, -0x800000.0p-33,
|
{ 0x840000.0p-23, -0x800000.0p-33 },
|
||||||
0x850000.0p-23, -0xc80000.0p-33,
|
{ 0x850000.0p-23, -0xc80000.0p-33 },
|
||||||
0x860000.0p-23, -0xa00000.0p-36,
|
{ 0x860000.0p-23, -0xa00000.0p-36 },
|
||||||
0x870000.0p-23, 0x940000.0p-33,
|
{ 0x870000.0p-23, 0x940000.0p-33 },
|
||||||
0x880000.0p-23, 0x800000.0p-35,
|
{ 0x880000.0p-23, 0x800000.0p-35 },
|
||||||
0x890000.0p-23, -0xc80000.0p-34,
|
{ 0x890000.0p-23, -0xc80000.0p-34 },
|
||||||
0x8a0000.0p-23, 0xe00000.0p-36,
|
{ 0x8a0000.0p-23, 0xe00000.0p-36 },
|
||||||
0x8b0000.0p-23, 0x900000.0p-33,
|
{ 0x8b0000.0p-23, 0x900000.0p-33 },
|
||||||
0x8c0000.0p-23, -0x800000.0p-35,
|
{ 0x8c0000.0p-23, -0x800000.0p-35 },
|
||||||
0x8d0000.0p-23, -0xe00000.0p-33,
|
{ 0x8d0000.0p-23, -0xe00000.0p-33 },
|
||||||
0x8e0000.0p-23, 0x880000.0p-33,
|
{ 0x8e0000.0p-23, 0x880000.0p-33 },
|
||||||
0x8f0000.0p-23, -0xa80000.0p-34,
|
{ 0x8f0000.0p-23, -0xa80000.0p-34 },
|
||||||
0x900000.0p-23, -0x800000.0p-35,
|
{ 0x900000.0p-23, -0x800000.0p-35 },
|
||||||
0x910000.0p-23, 0x800000.0p-37,
|
{ 0x910000.0p-23, 0x800000.0p-37 },
|
||||||
0x920000.0p-23, 0x900000.0p-35,
|
{ 0x920000.0p-23, 0x900000.0p-35 },
|
||||||
0x930000.0p-23, 0xd00000.0p-35,
|
{ 0x930000.0p-23, 0xd00000.0p-35 },
|
||||||
0x940000.0p-23, 0xe00000.0p-35,
|
{ 0x940000.0p-23, 0xe00000.0p-35 },
|
||||||
0x950000.0p-23, 0xc00000.0p-35,
|
{ 0x950000.0p-23, 0xc00000.0p-35 },
|
||||||
0x960000.0p-23, 0xe00000.0p-36,
|
{ 0x960000.0p-23, 0xe00000.0p-36 },
|
||||||
0x970000.0p-23, -0x800000.0p-38,
|
{ 0x970000.0p-23, -0x800000.0p-38 },
|
||||||
0x980000.0p-23, -0xc00000.0p-35,
|
{ 0x980000.0p-23, -0xc00000.0p-35 },
|
||||||
0x990000.0p-23, -0xd00000.0p-34,
|
{ 0x990000.0p-23, -0xd00000.0p-34 },
|
||||||
0x9a0000.0p-23, 0x880000.0p-33,
|
{ 0x9a0000.0p-23, 0x880000.0p-33 },
|
||||||
0x9b0000.0p-23, 0xe80000.0p-35,
|
{ 0x9b0000.0p-23, 0xe80000.0p-35 },
|
||||||
0x9c0000.0p-23, -0x800000.0p-35,
|
{ 0x9c0000.0p-23, -0x800000.0p-35 },
|
||||||
0x9d0000.0p-23, 0xb40000.0p-33,
|
{ 0x9d0000.0p-23, 0xb40000.0p-33 },
|
||||||
0x9e0000.0p-23, 0x880000.0p-34,
|
{ 0x9e0000.0p-23, 0x880000.0p-34 },
|
||||||
0x9f0000.0p-23, -0xe00000.0p-35,
|
{ 0x9f0000.0p-23, -0xe00000.0p-35 },
|
||||||
0xa00000.0p-23, 0x800000.0p-33,
|
{ 0xa00000.0p-23, 0x800000.0p-33 },
|
||||||
0xa10000.0p-23, -0x900000.0p-36,
|
{ 0xa10000.0p-23, -0x900000.0p-36 },
|
||||||
0xa20000.0p-23, -0xb00000.0p-33,
|
{ 0xa20000.0p-23, -0xb00000.0p-33 },
|
||||||
0xa30000.0p-23, -0xa00000.0p-36,
|
{ 0xa30000.0p-23, -0xa00000.0p-36 },
|
||||||
0xa40000.0p-23, 0x800000.0p-33,
|
{ 0xa40000.0p-23, 0x800000.0p-33 },
|
||||||
0xa50000.0p-23, -0xf80000.0p-35,
|
{ 0xa50000.0p-23, -0xf80000.0p-35 },
|
||||||
0xa60000.0p-23, 0x880000.0p-34,
|
{ 0xa60000.0p-23, 0x880000.0p-34 },
|
||||||
0xa70000.0p-23, -0x900000.0p-33,
|
{ 0xa70000.0p-23, -0x900000.0p-33 },
|
||||||
0xa80000.0p-23, -0x800000.0p-35,
|
{ 0xa80000.0p-23, -0x800000.0p-35 },
|
||||||
0xa90000.0p-23, 0x900000.0p-34,
|
{ 0xa90000.0p-23, 0x900000.0p-34 },
|
||||||
0xaa0000.0p-23, 0xa80000.0p-33,
|
{ 0xaa0000.0p-23, 0xa80000.0p-33 },
|
||||||
0xab0000.0p-23, -0xac0000.0p-34,
|
{ 0xab0000.0p-23, -0xac0000.0p-34 },
|
||||||
0xac0000.0p-23, -0x800000.0p-37,
|
{ 0xac0000.0p-23, -0x800000.0p-37 },
|
||||||
0xad0000.0p-23, 0xf80000.0p-35,
|
{ 0xad0000.0p-23, 0xf80000.0p-35 },
|
||||||
0xae0000.0p-23, 0xf80000.0p-34,
|
{ 0xae0000.0p-23, 0xf80000.0p-34 },
|
||||||
0xaf0000.0p-23, -0xac0000.0p-33,
|
{ 0xaf0000.0p-23, -0xac0000.0p-33 },
|
||||||
0xb00000.0p-23, -0x800000.0p-33,
|
{ 0xb00000.0p-23, -0x800000.0p-33 },
|
||||||
0xb10000.0p-23, -0xb80000.0p-34,
|
{ 0xb10000.0p-23, -0xb80000.0p-34 },
|
||||||
0xb20000.0p-23, -0x800000.0p-34,
|
{ 0xb20000.0p-23, -0x800000.0p-34 },
|
||||||
0xb30000.0p-23, -0xb00000.0p-35,
|
{ 0xb30000.0p-23, -0xb00000.0p-35 },
|
||||||
0xb40000.0p-23, -0x800000.0p-35,
|
{ 0xb40000.0p-23, -0x800000.0p-35 },
|
||||||
0xb50000.0p-23, -0xe00000.0p-36,
|
{ 0xb50000.0p-23, -0xe00000.0p-36 },
|
||||||
0xb60000.0p-23, -0x800000.0p-35,
|
{ 0xb60000.0p-23, -0x800000.0p-35 },
|
||||||
0xb70000.0p-23, -0xb00000.0p-35,
|
{ 0xb70000.0p-23, -0xb00000.0p-35 },
|
||||||
0xb80000.0p-23, -0x800000.0p-34,
|
{ 0xb80000.0p-23, -0x800000.0p-34 },
|
||||||
0xb90000.0p-23, -0xb80000.0p-34,
|
{ 0xb90000.0p-23, -0xb80000.0p-34 },
|
||||||
0xba0000.0p-23, -0x800000.0p-33,
|
{ 0xba0000.0p-23, -0x800000.0p-33 },
|
||||||
0xbb0000.0p-23, -0xac0000.0p-33,
|
{ 0xbb0000.0p-23, -0xac0000.0p-33 },
|
||||||
0xbc0000.0p-23, 0x980000.0p-33,
|
{ 0xbc0000.0p-23, 0x980000.0p-33 },
|
||||||
0xbd0000.0p-23, 0xbc0000.0p-34,
|
{ 0xbd0000.0p-23, 0xbc0000.0p-34 },
|
||||||
0xbe0000.0p-23, 0xe00000.0p-36,
|
{ 0xbe0000.0p-23, 0xe00000.0p-36 },
|
||||||
0xbf0000.0p-23, -0xb80000.0p-35,
|
{ 0xbf0000.0p-23, -0xb80000.0p-35 },
|
||||||
0xc00000.0p-23, -0x800000.0p-33,
|
{ 0xc00000.0p-23, -0x800000.0p-33 },
|
||||||
0xc10000.0p-23, 0xa80000.0p-33,
|
{ 0xc10000.0p-23, 0xa80000.0p-33 },
|
||||||
0xc20000.0p-23, 0x900000.0p-34,
|
{ 0xc20000.0p-23, 0x900000.0p-34 },
|
||||||
0xc30000.0p-23, -0x800000.0p-35,
|
{ 0xc30000.0p-23, -0x800000.0p-35 },
|
||||||
0xc40000.0p-23, -0x900000.0p-33,
|
{ 0xc40000.0p-23, -0x900000.0p-33 },
|
||||||
0xc50000.0p-23, 0x820000.0p-33,
|
{ 0xc50000.0p-23, 0x820000.0p-33 },
|
||||||
0xc60000.0p-23, 0x800000.0p-38,
|
{ 0xc60000.0p-23, 0x800000.0p-38 },
|
||||||
0xc70000.0p-23, -0x820000.0p-33,
|
{ 0xc70000.0p-23, -0x820000.0p-33 },
|
||||||
0xc80000.0p-23, 0x800000.0p-33,
|
{ 0xc80000.0p-23, 0x800000.0p-33 },
|
||||||
0xc90000.0p-23, -0xa00000.0p-36,
|
{ 0xc90000.0p-23, -0xa00000.0p-36 },
|
||||||
0xca0000.0p-23, -0xb00000.0p-33,
|
{ 0xca0000.0p-23, -0xb00000.0p-33 },
|
||||||
0xcb0000.0p-23, 0x840000.0p-34,
|
{ 0xcb0000.0p-23, 0x840000.0p-34 },
|
||||||
0xcc0000.0p-23, -0xd00000.0p-34,
|
{ 0xcc0000.0p-23, -0xd00000.0p-34 },
|
||||||
0xcd0000.0p-23, 0x800000.0p-33,
|
{ 0xcd0000.0p-23, 0x800000.0p-33 },
|
||||||
0xce0000.0p-23, -0xe00000.0p-35,
|
{ 0xce0000.0p-23, -0xe00000.0p-35 },
|
||||||
0xcf0000.0p-23, 0xa60000.0p-33,
|
{ 0xcf0000.0p-23, 0xa60000.0p-33 },
|
||||||
0xd00000.0p-23, -0x800000.0p-35,
|
{ 0xd00000.0p-23, -0x800000.0p-35 },
|
||||||
0xd10000.0p-23, 0xb40000.0p-33,
|
{ 0xd10000.0p-23, 0xb40000.0p-33 },
|
||||||
0xd20000.0p-23, -0x800000.0p-35,
|
{ 0xd20000.0p-23, -0x800000.0p-35 },
|
||||||
0xd30000.0p-23, 0xaa0000.0p-33,
|
{ 0xd30000.0p-23, 0xaa0000.0p-33 },
|
||||||
0xd40000.0p-23, -0xe00000.0p-35,
|
{ 0xd40000.0p-23, -0xe00000.0p-35 },
|
||||||
0xd50000.0p-23, 0x880000.0p-33,
|
{ 0xd50000.0p-23, 0x880000.0p-33 },
|
||||||
0xd60000.0p-23, -0xd00000.0p-34,
|
{ 0xd60000.0p-23, -0xd00000.0p-34 },
|
||||||
0xd70000.0p-23, 0x9c0000.0p-34,
|
{ 0xd70000.0p-23, 0x9c0000.0p-34 },
|
||||||
0xd80000.0p-23, -0xb00000.0p-33,
|
{ 0xd80000.0p-23, -0xb00000.0p-33 },
|
||||||
0xd90000.0p-23, -0x800000.0p-38,
|
{ 0xd90000.0p-23, -0x800000.0p-38 },
|
||||||
0xda0000.0p-23, 0xa40000.0p-33,
|
{ 0xda0000.0p-23, 0xa40000.0p-33 },
|
||||||
0xdb0000.0p-23, -0xdc0000.0p-34,
|
{ 0xdb0000.0p-23, -0xdc0000.0p-34 },
|
||||||
0xdc0000.0p-23, 0xc00000.0p-35,
|
{ 0xdc0000.0p-23, 0xc00000.0p-35 },
|
||||||
0xdd0000.0p-23, 0xca0000.0p-33,
|
{ 0xdd0000.0p-23, 0xca0000.0p-33 },
|
||||||
0xde0000.0p-23, -0xb80000.0p-34,
|
{ 0xde0000.0p-23, -0xb80000.0p-34 },
|
||||||
0xdf0000.0p-23, 0xd00000.0p-35,
|
{ 0xdf0000.0p-23, 0xd00000.0p-35 },
|
||||||
0xe00000.0p-23, 0xc00000.0p-33,
|
{ 0xe00000.0p-23, 0xc00000.0p-33 },
|
||||||
0xe10000.0p-23, -0xf40000.0p-34,
|
{ 0xe10000.0p-23, -0xf40000.0p-34 },
|
||||||
0xe20000.0p-23, 0x800000.0p-37,
|
{ 0xe20000.0p-23, 0x800000.0p-37 },
|
||||||
0xe30000.0p-23, 0x860000.0p-33,
|
{ 0xe30000.0p-23, 0x860000.0p-33 },
|
||||||
0xe40000.0p-23, -0xc80000.0p-33,
|
{ 0xe40000.0p-23, -0xc80000.0p-33 },
|
||||||
0xe50000.0p-23, -0xa80000.0p-34,
|
{ 0xe50000.0p-23, -0xa80000.0p-34 },
|
||||||
0xe60000.0p-23, 0xe00000.0p-36,
|
{ 0xe60000.0p-23, 0xe00000.0p-36 },
|
||||||
0xe70000.0p-23, 0x880000.0p-33,
|
{ 0xe70000.0p-23, 0x880000.0p-33 },
|
||||||
0xe80000.0p-23, -0xe00000.0p-33,
|
{ 0xe80000.0p-23, -0xe00000.0p-33 },
|
||||||
0xe90000.0p-23, -0xfc0000.0p-34,
|
{ 0xe90000.0p-23, -0xfc0000.0p-34 },
|
||||||
0xea0000.0p-23, -0x800000.0p-35,
|
{ 0xea0000.0p-23, -0x800000.0p-35 },
|
||||||
0xeb0000.0p-23, 0xe80000.0p-35,
|
{ 0xeb0000.0p-23, 0xe80000.0p-35 },
|
||||||
0xec0000.0p-23, 0x900000.0p-33,
|
{ 0xec0000.0p-23, 0x900000.0p-33 },
|
||||||
0xed0000.0p-23, 0xe20000.0p-33,
|
{ 0xed0000.0p-23, 0xe20000.0p-33 },
|
||||||
0xee0000.0p-23, -0xac0000.0p-33,
|
{ 0xee0000.0p-23, -0xac0000.0p-33 },
|
||||||
0xef0000.0p-23, -0xc80000.0p-34,
|
{ 0xef0000.0p-23, -0xc80000.0p-34 },
|
||||||
0xf00000.0p-23, -0x800000.0p-35,
|
{ 0xf00000.0p-23, -0x800000.0p-35 },
|
||||||
0xf10000.0p-23, 0x800000.0p-35,
|
{ 0xf10000.0p-23, 0x800000.0p-35 },
|
||||||
0xf20000.0p-23, 0xb80000.0p-34,
|
{ 0xf20000.0p-23, 0xb80000.0p-34 },
|
||||||
0xf30000.0p-23, 0x940000.0p-33,
|
{ 0xf30000.0p-23, 0x940000.0p-33 },
|
||||||
0xf40000.0p-23, 0xc80000.0p-33,
|
{ 0xf40000.0p-23, 0xc80000.0p-33 },
|
||||||
0xf50000.0p-23, -0xf20000.0p-33,
|
{ 0xf50000.0p-23, -0xf20000.0p-33 },
|
||||||
0xf60000.0p-23, -0xc80000.0p-33,
|
{ 0xf60000.0p-23, -0xc80000.0p-33 },
|
||||||
0xf70000.0p-23, -0xa20000.0p-33,
|
{ 0xf70000.0p-23, -0xa20000.0p-33 },
|
||||||
0xf80000.0p-23, -0x800000.0p-33,
|
{ 0xf80000.0p-23, -0x800000.0p-33 },
|
||||||
0xf90000.0p-23, -0xc40000.0p-34,
|
{ 0xf90000.0p-23, -0xc40000.0p-34 },
|
||||||
0xfa0000.0p-23, -0x900000.0p-34,
|
{ 0xfa0000.0p-23, -0x900000.0p-34 },
|
||||||
0xfb0000.0p-23, -0xc80000.0p-35,
|
{ 0xfb0000.0p-23, -0xc80000.0p-35 },
|
||||||
0xfc0000.0p-23, -0x800000.0p-35,
|
{ 0xfc0000.0p-23, -0x800000.0p-35 },
|
||||||
0xfd0000.0p-23, -0x900000.0p-36,
|
{ 0xfd0000.0p-23, -0x900000.0p-36 },
|
||||||
0xfe0000.0p-23, -0x800000.0p-37,
|
{ 0xfe0000.0p-23, -0x800000.0p-37 },
|
||||||
0xff0000.0p-23, -0x800000.0p-39,
|
{ 0xff0000.0p-23, -0x800000.0p-39 },
|
||||||
0x800000.0p-22, 0,
|
{ 0x800000.0p-22, 0 },
|
||||||
};
|
};
|
||||||
#endif /* USE_UTAB */
|
#endif /* USE_UTAB */
|
||||||
|
|
||||||
|
@ -37,16 +37,20 @@
|
|||||||
#include <blacklist.h>
|
#include <blacklist.h>
|
||||||
|
|
||||||
static struct blacklist *blstate;
|
static struct blacklist *blstate;
|
||||||
|
extern int use_blacklist;
|
||||||
|
|
||||||
void
|
void
|
||||||
blacklist_init(void)
|
blacklist_init(void)
|
||||||
{
|
{
|
||||||
blstate = blacklist_open();
|
|
||||||
|
if (use_blacklist)
|
||||||
|
blstate = blacklist_open();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
blacklist_notify(int action, int fd, char *msg)
|
blacklist_notify(int action, int fd, char *msg)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (blstate == NULL)
|
if (blstate == NULL)
|
||||||
return;
|
return;
|
||||||
(void)blacklist_r(blstate, action, fd, msg);
|
(void)blacklist_r(blstate, action, fd, msg);
|
||||||
|
@ -28,5 +28,26 @@
|
|||||||
|
|
||||||
/* $FreeBSD$ */
|
/* $FreeBSD$ */
|
||||||
|
|
||||||
void blacklist_notify(int, int, char *);
|
#ifndef BLACKLIST_CLIENT_H
|
||||||
|
#define BLACKLIST_CLIENT_H
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BLACKLIST_AUTH_OK = 0,
|
||||||
|
BLACKLIST_AUTH_FAIL
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef USE_BLACKLIST
|
||||||
void blacklist_init(void);
|
void blacklist_init(void);
|
||||||
|
void blacklist_notify(int, int, char *);
|
||||||
|
|
||||||
|
#define BLACKLIST_INIT() blacklist_init()
|
||||||
|
#define BLACKLIST_NOTIFY(x, y, z) blacklist_notify(x, y, z)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define BLACKLIST_INIT()
|
||||||
|
#define BLACKLIST_NOTIFY(x, y, z)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* BLACKLIST_CLIENT_H */
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
.Nd Internet File Transfer Protocol server
|
.Nd Internet File Transfer Protocol server
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl 468ADdEhMmOoRrSUvW
|
.Op Fl 468ABDdEhMmOoRrSUvW
|
||||||
.Op Fl l Op Fl l
|
.Op Fl l Op Fl l
|
||||||
.Op Fl a Ar address
|
.Op Fl a Ar address
|
||||||
.Op Fl P Ar port
|
.Op Fl P Ar port
|
||||||
@ -95,6 +95,14 @@ When
|
|||||||
.Fl D
|
.Fl D
|
||||||
is specified, accept connections only on the specified
|
is specified, accept connections only on the specified
|
||||||
.Ar address .
|
.Ar address .
|
||||||
|
.It Fl B
|
||||||
|
With this option set,
|
||||||
|
.Nm
|
||||||
|
sends authentication success and failure messages to the
|
||||||
|
.Xr blacklistd 8
|
||||||
|
daemon. If this option is not specified, no communcation with the
|
||||||
|
.Xr blacklistd 8
|
||||||
|
daemon is attempted.
|
||||||
.It Fl D
|
.It Fl D
|
||||||
With this option set,
|
With this option set,
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -144,6 +144,7 @@ int noretr = 0; /* RETR command is disabled. */
|
|||||||
int noguestretr = 0; /* RETR command is disabled for anon users. */
|
int noguestretr = 0; /* RETR command is disabled for anon users. */
|
||||||
int noguestmkd = 0; /* MKD command is disabled for anon users. */
|
int noguestmkd = 0; /* MKD command is disabled for anon users. */
|
||||||
int noguestmod = 1; /* anon users may not modify existing files. */
|
int noguestmod = 1; /* anon users may not modify existing files. */
|
||||||
|
int use_blacklist = 0;
|
||||||
|
|
||||||
off_t file_size;
|
off_t file_size;
|
||||||
off_t byte_count;
|
off_t byte_count;
|
||||||
@ -305,7 +306,7 @@ main(int argc, char *argv[], char **envp)
|
|||||||
openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
|
openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv,
|
while ((ch = getopt(argc, argv,
|
||||||
"468a:AdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) {
|
"468a:ABdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '4':
|
case '4':
|
||||||
family = (family == AF_INET6) ? AF_UNSPEC : AF_INET;
|
family = (family == AF_INET6) ? AF_UNSPEC : AF_INET;
|
||||||
@ -327,6 +328,14 @@ main(int argc, char *argv[], char **envp)
|
|||||||
anon_only = 1;
|
anon_only = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'B':
|
||||||
|
#ifdef USE_BLACKLIST
|
||||||
|
use_blacklist = 1;
|
||||||
|
#else
|
||||||
|
syslog(LOG_WARNING, "not compiled with USE_BLACKLIST support");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
ftpdebug++;
|
ftpdebug++;
|
||||||
break;
|
break;
|
||||||
@ -644,9 +653,7 @@ main(int argc, char *argv[], char **envp)
|
|||||||
reply(220, "%s FTP server (%s) ready.", hostname, version);
|
reply(220, "%s FTP server (%s) ready.", hostname, version);
|
||||||
else
|
else
|
||||||
reply(220, "FTP server ready.");
|
reply(220, "FTP server ready.");
|
||||||
#ifdef USE_BLACKLIST
|
BLACKLIST_INIT();
|
||||||
blacklist_init();
|
|
||||||
#endif
|
|
||||||
for (;;)
|
for (;;)
|
||||||
(void) yyparse();
|
(void) yyparse();
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
@ -1422,9 +1429,7 @@ pass(char *passwd)
|
|||||||
*/
|
*/
|
||||||
if (rval) {
|
if (rval) {
|
||||||
reply(530, "Login incorrect.");
|
reply(530, "Login incorrect.");
|
||||||
#ifdef USE_BLACKLIST
|
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, STDIN_FILENO, "Login incorrect");
|
||||||
blacklist_notify(1, STDIN_FILENO, "Login incorrect");
|
|
||||||
#endif
|
|
||||||
if (logging) {
|
if (logging) {
|
||||||
syslog(LOG_NOTICE,
|
syslog(LOG_NOTICE,
|
||||||
"FTP LOGIN FAILED FROM %s",
|
"FTP LOGIN FAILED FROM %s",
|
||||||
@ -1441,12 +1446,9 @@ pass(char *passwd)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
BLACKLIST_NOTIFY(BLACKLIST_AUTH_OK, STDIN_FILENO, "Login successful");
|
||||||
}
|
}
|
||||||
#ifdef USE_BLACKLIST
|
|
||||||
else {
|
|
||||||
blacklist_notify(0, STDIN_FILENO, "Login successful");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
login_attempts = 0; /* this time successful */
|
login_attempts = 0; /* this time successful */
|
||||||
if (setegid(pw->pw_gid) < 0) {
|
if (setegid(pw->pw_gid) < 0) {
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
||||||
export PATH
|
export PATH
|
||||||
|
|
||||||
@ -31,10 +33,6 @@ fi
|
|||||||
echo '/dev/ufs/FreeBSD_Install / ufs ro,noatime 1 1' > ${1}/etc/fstab
|
echo '/dev/ufs/FreeBSD_Install / ufs ro,noatime 1 1' > ${1}/etc/fstab
|
||||||
echo 'root_rw_mount="NO"' > ${1}/etc/rc.conf.local
|
echo 'root_rw_mount="NO"' > ${1}/etc/rc.conf.local
|
||||||
makefs -B little -o label=FreeBSD_Install ${2}.part ${1}
|
makefs -B little -o label=FreeBSD_Install ${2}.part ${1}
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "makefs failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
rm ${1}/etc/fstab
|
rm ${1}/etc/fstab
|
||||||
rm ${1}/etc/rc.conf.local
|
rm ${1}/etc/rc.conf.local
|
||||||
|
|
||||||
|
@ -2716,11 +2716,6 @@ printathie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
|
|||||||
static void
|
static void
|
||||||
printmeshconf(const char *tag, const uint8_t *ie, size_t ielen, int maxlen)
|
printmeshconf(const char *tag, const uint8_t *ie, size_t ielen, int maxlen)
|
||||||
{
|
{
|
||||||
#define MATCHOUI(field, oui, string) \
|
|
||||||
do { \
|
|
||||||
if (memcmp(field, oui, 4) == 0) \
|
|
||||||
printf("%s", string); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
printf("%s", tag);
|
printf("%s", tag);
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
@ -2754,7 +2749,6 @@ do { \
|
|||||||
printf(" FORM:0x%x CAPS:0x%x>", mconf->conf_form,
|
printf(" FORM:0x%x CAPS:0x%x>", mconf->conf_form,
|
||||||
mconf->conf_cap);
|
mconf->conf_cap);
|
||||||
}
|
}
|
||||||
#undef MATCHOUI
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -250,7 +250,7 @@ copies:
|
|||||||
symlinks:
|
symlinks:
|
||||||
.for i in ${LDIRS}
|
.for i in ${LDIRS}
|
||||||
rm -rf ${DESTDIR}${BINDIR}/$i
|
rm -rf ${DESTDIR}${BINDIR}/$i
|
||||||
ln -s ${.CURDIR}/$i ${DESTDIR}${BINDIR}/$i
|
${INSTALL} ${TAG_ARGS} -l s ${.CURDIR}/$i ${DESTDIR}${BINDIR}/$i
|
||||||
.endfor
|
.endfor
|
||||||
|
|
||||||
etc-examples:
|
etc-examples:
|
||||||
|
@ -78,7 +78,7 @@ CTFFLAGS+= -g
|
|||||||
|
|
||||||
# prefer .s to a .c, add .po, remove stuff not used in the BSD libraries
|
# prefer .s to a .c, add .po, remove stuff not used in the BSD libraries
|
||||||
# .pico used for PIC object files
|
# .pico used for PIC object files
|
||||||
.SUFFIXES: .out .o .po .pico .S .asm .s .c .cc .cpp .cxx .C .f .y .l .ln
|
.SUFFIXES: .out .o .bc .ll .po .pico .S .asm .s .c .cc .cpp .cxx .C .f .y .l .ln
|
||||||
|
|
||||||
.if !defined(PICFLAG)
|
.if !defined(PICFLAG)
|
||||||
.if ${MACHINE_CPUARCH} == "sparc64"
|
.if ${MACHINE_CPUARCH} == "sparc64"
|
||||||
@ -199,6 +199,18 @@ lib${LIB_PRIVATE}${LIB}_p.a: ${POBJS}
|
|||||||
${RANLIB} ${RANLIBFLAGS} ${.TARGET}
|
${RANLIB} ${RANLIBFLAGS} ${.TARGET}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.if defined(LLVM_LINK)
|
||||||
|
BCOBJS= ${OBJS:.o=.bco} ${STATICOBJS:.o=.bco}
|
||||||
|
LLOBJS= ${OBJS:.o=.llo} ${STATICOBJS:.o=.llo}
|
||||||
|
CLEANFILES+= ${BCOBJS} ${LLOBJS}
|
||||||
|
|
||||||
|
lib${LIB_PRIVATE}${LIB}.bc: ${BCOBJS}
|
||||||
|
${LLVM_LINK} -o ${.TARGET} ${BCOBJS}
|
||||||
|
|
||||||
|
lib${LIB_PRIVATE}${LIB}.ll: ${LLOBJS}
|
||||||
|
${LLVM_LINK} -S -o ${.TARGET} ${LLOBJS}
|
||||||
|
.endif
|
||||||
|
|
||||||
.if defined(SHLIB_NAME) || \
|
.if defined(SHLIB_NAME) || \
|
||||||
defined(INSTALL_PIC_ARCHIVE) && defined(LIB) && !empty(LIB)
|
defined(INSTALL_PIC_ARCHIVE) && defined(LIB) && !empty(LIB)
|
||||||
SOBJS+= ${OBJS:.o=.pico}
|
SOBJS+= ${OBJS:.o=.pico}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
.include <bsd.init.mk>
|
.include <bsd.init.mk>
|
||||||
.include <bsd.compiler.mk>
|
.include <bsd.compiler.mk>
|
||||||
|
|
||||||
.SUFFIXES: .out .o .c .cc .cpp .cxx .C .m .y .l .ln .s .S .asm
|
.SUFFIXES: .out .o .bc .c .cc .cpp .cxx .C .m .y .l .ll .ln .s .S .asm
|
||||||
|
|
||||||
# XXX The use of COPTS in modern makefiles is discouraged.
|
# XXX The use of COPTS in modern makefiles is discouraged.
|
||||||
.if defined(COPTS)
|
.if defined(COPTS)
|
||||||
@ -147,6 +147,19 @@ ${PROGNAME}.debug: ${PROG_FULL}
|
|||||||
${OBJCOPY} --only-keep-debug ${PROG_FULL} ${.TARGET}
|
${OBJCOPY} --only-keep-debug ${PROG_FULL} ${.TARGET}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.if defined(LLVM_LINK)
|
||||||
|
# LLVM bitcode / textual IR representations of the program
|
||||||
|
BCOBJS= ${OBJS:.o=.bco}
|
||||||
|
LLOBJS= ${OBJS:.o=.llo}
|
||||||
|
|
||||||
|
${PROG_FULL}.bc: ${BCOBJS}
|
||||||
|
${LLVM_LINK} -o ${.TARGET} ${BCOBJS}
|
||||||
|
|
||||||
|
${PROG_FULL}.ll: ${LLOBJS}
|
||||||
|
${LLVM_LINK} -S -o ${.TARGET} ${LLOBJS}
|
||||||
|
|
||||||
|
.endif # defined(LLVM_LINK)
|
||||||
|
|
||||||
.if ${MK_MAN} != "no" && !defined(MAN) && \
|
.if ${MK_MAN} != "no" && !defined(MAN) && \
|
||||||
!defined(MAN1) && !defined(MAN2) && !defined(MAN3) && \
|
!defined(MAN1) && !defined(MAN2) && !defined(MAN3) && \
|
||||||
!defined(MAN4) && !defined(MAN5) && !defined(MAN6) && \
|
!defined(MAN4) && !defined(MAN5) && !defined(MAN6) && \
|
||||||
@ -166,14 +179,14 @@ all: all-man
|
|||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if defined(PROG)
|
.if defined(PROG)
|
||||||
CLEANFILES+= ${PROG}
|
CLEANFILES+= ${PROG} ${PROG}.bc ${PROG}.ll
|
||||||
.if ${MK_DEBUG_FILES} != "no"
|
.if ${MK_DEBUG_FILES} != "no"
|
||||||
CLEANFILES+= ${PROG_FULL} ${PROGNAME}.debug
|
CLEANFILES+= ${PROG_FULL} ${PROG_FULL}.bc ${PROGNAME}.debug ${PROG_FULL}.ll
|
||||||
.endif
|
.endif
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if defined(OBJS)
|
.if defined(OBJS)
|
||||||
CLEANFILES+= ${OBJS}
|
CLEANFILES+= ${OBJS} ${BCOBJS} ${LLOBJS}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.include <bsd.libnames.mk>
|
.include <bsd.libnames.mk>
|
||||||
|
@ -231,6 +231,8 @@ LINTLIBFLAGS ?= -cghapbxu -C ${LIB}
|
|||||||
MAKE ?= make
|
MAKE ?= make
|
||||||
|
|
||||||
.if !defined(%POSIX)
|
.if !defined(%POSIX)
|
||||||
|
LLVM_LINK ?= llvm-link
|
||||||
|
|
||||||
LORDER ?= lorder
|
LORDER ?= lorder
|
||||||
|
|
||||||
NM ?= nm
|
NM ?= nm
|
||||||
|
@ -83,7 +83,9 @@ options RCTL # Resource limits
|
|||||||
options KDB # Enable kernel debugger support.
|
options KDB # Enable kernel debugger support.
|
||||||
options KDB_TRACE # Print a stack trace for a panic.
|
options KDB_TRACE # Print a stack trace for a panic.
|
||||||
# For full debugger support use (turn off in stable branch):
|
# For full debugger support use (turn off in stable branch):
|
||||||
|
options BUF_TRACKING # Track buffer history
|
||||||
options DDB # Support DDB.
|
options DDB # Support DDB.
|
||||||
|
options FULL_BUF_TRACKING # Track more buffer history
|
||||||
options GDB # Support remote GDB.
|
options GDB # Support remote GDB.
|
||||||
options DEADLKRES # Enable the deadlock resolver
|
options DEADLKRES # Enable the deadlock resolver
|
||||||
options INVARIANTS # Enable calls of extra sanity checking
|
options INVARIANTS # Enable calls of extra sanity checking
|
||||||
|
@ -34,5 +34,7 @@ nooptions INVARIANTS
|
|||||||
nooptions INVARIANT_SUPPORT
|
nooptions INVARIANT_SUPPORT
|
||||||
nooptions WITNESS
|
nooptions WITNESS
|
||||||
nooptions WITNESS_SKIPSPIN
|
nooptions WITNESS_SKIPSPIN
|
||||||
|
nooptions BUF_TRACKING
|
||||||
nooptions DEADLKRES
|
nooptions DEADLKRES
|
||||||
|
nooptions FULL_BUF_TRACKING
|
||||||
|
|
||||||
|
@ -500,7 +500,8 @@ pmap_set_tex(void)
|
|||||||
|
|
||||||
/* Add shareable bits for normal memory in SMP case. */
|
/* Add shareable bits for normal memory in SMP case. */
|
||||||
#ifdef SMP
|
#ifdef SMP
|
||||||
prrr |= PRRR_NS1;
|
if (ARM_USE_MP_EXTENSIONS)
|
||||||
|
prrr |= PRRR_NS1;
|
||||||
#endif
|
#endif
|
||||||
cp15_prrr_set(prrr);
|
cp15_prrr_set(prrr);
|
||||||
cp15_nmrr_set(nmrr);
|
cp15_nmrr_set(nmrr);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
ident GENERIC
|
ident GENERIC
|
||||||
|
|
||||||
cpu CPU_CORTEXA_MP
|
cpu CPU_CORTEXA_MP
|
||||||
|
cpu CPU_CORTEXA8
|
||||||
machine arm armv6
|
machine arm armv6
|
||||||
makeoptions CONF_CFLAGS="-march=armv7a"
|
makeoptions CONF_CFLAGS="-march=armv7a"
|
||||||
|
|
||||||
@ -37,6 +38,8 @@ files "../broadcom/bcm2835/files.bcm2836"
|
|||||||
files "../broadcom/bcm2835/files.bcm283x"
|
files "../broadcom/bcm2835/files.bcm283x"
|
||||||
files "../nvidia/tegra124/files.tegra124"
|
files "../nvidia/tegra124/files.tegra124"
|
||||||
files "../qemu/files.qemu"
|
files "../qemu/files.qemu"
|
||||||
|
files "../ti/files.ti"
|
||||||
|
files "../ti/am335x/files.am335x"
|
||||||
|
|
||||||
options SOC_ALLWINNER_A20
|
options SOC_ALLWINNER_A20
|
||||||
options SOC_ALLWINNER_A31
|
options SOC_ALLWINNER_A31
|
||||||
@ -44,6 +47,7 @@ options SOC_ALLWINNER_A31S
|
|||||||
options SOC_ALLWINNER_A83T
|
options SOC_ALLWINNER_A83T
|
||||||
options SOC_ALLWINNER_H3
|
options SOC_ALLWINNER_H3
|
||||||
options SOC_BCM2836
|
options SOC_BCM2836
|
||||||
|
options SOC_TI_AM335X
|
||||||
|
|
||||||
options SCHED_ULE # ULE scheduler
|
options SCHED_ULE # ULE scheduler
|
||||||
options SMP # Enable multiple cores
|
options SMP # Enable multiple cores
|
||||||
@ -66,6 +70,9 @@ device cpufreq
|
|||||||
options INTRNG
|
options INTRNG
|
||||||
device gic
|
device gic
|
||||||
|
|
||||||
|
# PMU support (for CCNT).
|
||||||
|
device pmu
|
||||||
|
|
||||||
# ARM Generic Timer
|
# ARM Generic Timer
|
||||||
device generic_timer
|
device generic_timer
|
||||||
|
|
||||||
@ -113,9 +120,14 @@ device axp81x # AXP813/818 Power Management Unit
|
|||||||
device bcm2835_bsc
|
device bcm2835_bsc
|
||||||
device icee
|
device icee
|
||||||
device sy8106a # SY8106A Buck Regulator
|
device sy8106a # SY8106A Buck Regulator
|
||||||
|
device ti_i2c
|
||||||
|
device am335x_pmic # AM335x Power Management IC (TPC65217)
|
||||||
|
device am335x_rtc # RTC support (power management only)
|
||||||
|
#define am335x_dmtpps # Pulse Per Second capture driver
|
||||||
|
|
||||||
# GPIO
|
# GPIO
|
||||||
device gpio
|
device gpio
|
||||||
|
device gpiobacklight
|
||||||
device gpioled
|
device gpioled
|
||||||
device gpioregulator
|
device gpioregulator
|
||||||
|
|
||||||
@ -128,6 +140,16 @@ device aw_cir
|
|||||||
# SPI
|
# SPI
|
||||||
device spibus
|
device spibus
|
||||||
device bcm2835_spi
|
device bcm2835_spi
|
||||||
|
device ti_spi
|
||||||
|
|
||||||
|
# ADC support
|
||||||
|
device ti_adc
|
||||||
|
|
||||||
|
# Watchdog support
|
||||||
|
# If we don't enable the watchdog driver, the BealeBone could potentially
|
||||||
|
# reboot automatically because the boot loader might have enabled the
|
||||||
|
# watchdog.
|
||||||
|
device ti_wdt
|
||||||
|
|
||||||
device scbus # SCSI bus (required for ATA/SCSI)
|
device scbus # SCSI bus (required for ATA/SCSI)
|
||||||
device da # Direct Access (disks)
|
device da # Direct Access (disks)
|
||||||
@ -141,11 +163,16 @@ device usb
|
|||||||
device ohci
|
device ohci
|
||||||
device ehci
|
device ehci
|
||||||
device dwcotg # DWC OTG controller
|
device dwcotg # DWC OTG controller
|
||||||
|
device musb
|
||||||
|
|
||||||
device umass # Disks/Mass storage - Requires scbus and da
|
device umass # Disks/Mass storage - Requires scbus and da
|
||||||
device uhid # "Human Interface Devices"
|
device uhid # "Human Interface Devices"
|
||||||
device ukbd # Allow keyboard like HIDs to control console
|
device ukbd # Allow keyboard like HIDs to control console
|
||||||
|
|
||||||
|
# Device mode support and USFS template
|
||||||
|
device usb_template # Control of the gadget
|
||||||
|
device usfs
|
||||||
|
|
||||||
# Ethernet
|
# Ethernet
|
||||||
device loop
|
device loop
|
||||||
device ether
|
device ether
|
||||||
@ -176,6 +203,12 @@ device vchiq
|
|||||||
# Pinmux
|
# Pinmux
|
||||||
device fdt_pinctrl
|
device fdt_pinctrl
|
||||||
|
|
||||||
|
# TI Programmable Realtime Unit support
|
||||||
|
device ti_pruss
|
||||||
|
|
||||||
|
# Mailbox support
|
||||||
|
device ti_mbox
|
||||||
|
|
||||||
# Extensible Firmware Interface
|
# Extensible Firmware Interface
|
||||||
options EFI
|
options EFI
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ arm/freescale/imx/imx51_ccm.c standard
|
|||||||
dev/ata/chipsets/ata-fsl.c optional imxata
|
dev/ata/chipsets/ata-fsl.c optional imxata
|
||||||
|
|
||||||
# SDHCI/MMC
|
# SDHCI/MMC
|
||||||
arm/freescale/imx/imx_sdhci.c optional sdhci
|
dev/sdhci/fsl_sdhci.c optional sdhci
|
||||||
|
|
||||||
# USB OH3 controller (1 OTG, 3 EHCI)
|
# USB OH3 controller (1 OTG, 3 EHCI)
|
||||||
arm/freescale/imx/imx_nop_usbphy.c optional ehci
|
arm/freescale/imx/imx_nop_usbphy.c optional ehci
|
||||||
|
@ -32,7 +32,7 @@ arm/freescale/imx/imx6_ipu.c optional vt
|
|||||||
#
|
#
|
||||||
# Optional devices.
|
# Optional devices.
|
||||||
#
|
#
|
||||||
arm/freescale/imx/imx_sdhci.c optional sdhci
|
dev/sdhci/fsl_sdhci.c optional sdhci
|
||||||
|
|
||||||
arm/freescale/imx/imx_wdog.c optional imxwdt
|
arm/freescale/imx/imx_wdog.c optional imxwdt
|
||||||
|
|
||||||
|
@ -45,6 +45,21 @@
|
|||||||
|
|
||||||
#define CPU_ASID_KERNEL 0
|
#define CPU_ASID_KERNEL 0
|
||||||
|
|
||||||
|
#if __ARM_ARCH >= 7
|
||||||
|
#if !defined(SMP)
|
||||||
|
/* No SMP so no need to use the MP extensions */
|
||||||
|
#define ARM_USE_MP_EXTENSIONS 0
|
||||||
|
#elif defined(CPU_CORTEXA8) && \
|
||||||
|
(defined(CPU_CORTEXA_MP) || defined(CPU_KRAIT) || defined(CPU_MV_PJ4B))
|
||||||
|
#define ARM_USE_MP_EXTENSIONS (cpuinfo.mp_ext != 0)
|
||||||
|
#elif defined(CPU_CORTEXA8)
|
||||||
|
#define ARM_USE_MP_EXTENSIONS 0
|
||||||
|
#else
|
||||||
|
#define ARM_USE_MP_EXTENSIONS 1
|
||||||
|
#endif
|
||||||
|
#endif /* __ARM_ARCH >= 7 */
|
||||||
|
|
||||||
|
|
||||||
void dcache_wbinv_poc_all(void); /* !!! NOT SMP coherent function !!! */
|
void dcache_wbinv_poc_all(void); /* !!! NOT SMP coherent function !!! */
|
||||||
vm_offset_t dcache_wb_pou_checked(vm_offset_t, vm_size_t);
|
vm_offset_t dcache_wb_pou_checked(vm_offset_t, vm_size_t);
|
||||||
vm_offset_t icache_inv_pou_checked(vm_offset_t, vm_size_t);
|
vm_offset_t icache_inv_pou_checked(vm_offset_t, vm_size_t);
|
||||||
@ -111,15 +126,15 @@ fname(uint64_t reg) \
|
|||||||
/* TLB */
|
/* TLB */
|
||||||
|
|
||||||
_WF0(_CP15_TLBIALL, CP15_TLBIALL) /* Invalidate entire unified TLB */
|
_WF0(_CP15_TLBIALL, CP15_TLBIALL) /* Invalidate entire unified TLB */
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
_WF0(_CP15_TLBIALLIS, CP15_TLBIALLIS) /* Invalidate entire unified TLB IS */
|
_WF0(_CP15_TLBIALLIS, CP15_TLBIALLIS) /* Invalidate entire unified TLB IS */
|
||||||
#endif
|
#endif
|
||||||
_WF1(_CP15_TLBIASID, CP15_TLBIASID(%0)) /* Invalidate unified TLB by ASID */
|
_WF1(_CP15_TLBIASID, CP15_TLBIASID(%0)) /* Invalidate unified TLB by ASID */
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
_WF1(_CP15_TLBIASIDIS, CP15_TLBIASIDIS(%0)) /* Invalidate unified TLB by ASID IS */
|
_WF1(_CP15_TLBIASIDIS, CP15_TLBIASIDIS(%0)) /* Invalidate unified TLB by ASID IS */
|
||||||
#endif
|
#endif
|
||||||
_WF1(_CP15_TLBIMVAA, CP15_TLBIMVAA(%0)) /* Invalidate unified TLB by MVA, all ASID */
|
_WF1(_CP15_TLBIMVAA, CP15_TLBIMVAA(%0)) /* Invalidate unified TLB by MVA, all ASID */
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
_WF1(_CP15_TLBIMVAAIS, CP15_TLBIMVAAIS(%0)) /* Invalidate unified TLB by MVA, all ASID IS */
|
_WF1(_CP15_TLBIMVAAIS, CP15_TLBIMVAAIS(%0)) /* Invalidate unified TLB by MVA, all ASID IS */
|
||||||
#endif
|
#endif
|
||||||
_WF1(_CP15_TLBIMVA, CP15_TLBIMVA(%0)) /* Invalidate unified TLB by MVA */
|
_WF1(_CP15_TLBIMVA, CP15_TLBIMVA(%0)) /* Invalidate unified TLB by MVA */
|
||||||
@ -129,7 +144,7 @@ _WF1(_CP15_TTB_SET, CP15_TTBR0(%0))
|
|||||||
/* Cache and Branch predictor */
|
/* Cache and Branch predictor */
|
||||||
|
|
||||||
_WF0(_CP15_BPIALL, CP15_BPIALL) /* Branch predictor invalidate all */
|
_WF0(_CP15_BPIALL, CP15_BPIALL) /* Branch predictor invalidate all */
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
_WF0(_CP15_BPIALLIS, CP15_BPIALLIS) /* Branch predictor invalidate all IS */
|
_WF0(_CP15_BPIALLIS, CP15_BPIALLIS) /* Branch predictor invalidate all IS */
|
||||||
#endif
|
#endif
|
||||||
_WF1(_CP15_BPIMVA, CP15_BPIMVA(%0)) /* Branch predictor invalidate by MVA */
|
_WF1(_CP15_BPIMVA, CP15_BPIMVA(%0)) /* Branch predictor invalidate by MVA */
|
||||||
@ -143,7 +158,7 @@ _WF1(_CP15_DCCSW, CP15_DCCSW(%0)) /* Data cache clean by set/way */
|
|||||||
_WF1(_CP15_DCIMVAC, CP15_DCIMVAC(%0)) /* Data cache invalidate by MVA PoC */
|
_WF1(_CP15_DCIMVAC, CP15_DCIMVAC(%0)) /* Data cache invalidate by MVA PoC */
|
||||||
_WF1(_CP15_DCISW, CP15_DCISW(%0)) /* Data cache invalidate by set/way */
|
_WF1(_CP15_DCISW, CP15_DCISW(%0)) /* Data cache invalidate by set/way */
|
||||||
_WF0(_CP15_ICIALLU, CP15_ICIALLU) /* Instruction cache invalidate all PoU */
|
_WF0(_CP15_ICIALLU, CP15_ICIALLU) /* Instruction cache invalidate all PoU */
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
_WF0(_CP15_ICIALLUIS, CP15_ICIALLUIS) /* Instruction cache invalidate all PoU IS */
|
_WF0(_CP15_ICIALLUIS, CP15_ICIALLUIS) /* Instruction cache invalidate all PoU IS */
|
||||||
#endif
|
#endif
|
||||||
_WF1(_CP15_ICIMVAU, CP15_ICIMVAU(%0)) /* Instruction cache invalidate */
|
_WF1(_CP15_ICIMVAU, CP15_ICIMVAU(%0)) /* Instruction cache invalidate */
|
||||||
@ -345,20 +360,14 @@ tlb_flush_range_local(vm_offset_t va, vm_size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Broadcasting operations. */
|
/* Broadcasting operations. */
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
|
|
||||||
#if defined(CPU_CORTEXA8)
|
|
||||||
#define ARM_HAVE_MP_EXTENSIONS (cpuinfo.mp_ext != 0)
|
|
||||||
#else
|
|
||||||
#define ARM_HAVE_MP_EXTENSIONS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
tlb_flush_all(void)
|
tlb_flush_all(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
if (ARM_HAVE_MP_EXTENSIONS)
|
if (ARM_USE_MP_EXTENSIONS)
|
||||||
_CP15_TLBIALLIS();
|
_CP15_TLBIALLIS();
|
||||||
else
|
else
|
||||||
_CP15_TLBIALL();
|
_CP15_TLBIALL();
|
||||||
@ -370,7 +379,7 @@ tlb_flush_all_ng(void)
|
|||||||
{
|
{
|
||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
if (ARM_HAVE_MP_EXTENSIONS)
|
if (ARM_USE_MP_EXTENSIONS)
|
||||||
_CP15_TLBIASIDIS(CPU_ASID_KERNEL);
|
_CP15_TLBIASIDIS(CPU_ASID_KERNEL);
|
||||||
else
|
else
|
||||||
_CP15_TLBIASID(CPU_ASID_KERNEL);
|
_CP15_TLBIASID(CPU_ASID_KERNEL);
|
||||||
@ -384,7 +393,7 @@ tlb_flush(vm_offset_t va)
|
|||||||
KASSERT((va & PAGE_MASK) == 0, ("%s: va %#x not aligned", __func__, va));
|
KASSERT((va & PAGE_MASK) == 0, ("%s: va %#x not aligned", __func__, va));
|
||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
if (ARM_HAVE_MP_EXTENSIONS)
|
if (ARM_USE_MP_EXTENSIONS)
|
||||||
_CP15_TLBIMVAAIS(va);
|
_CP15_TLBIMVAAIS(va);
|
||||||
else
|
else
|
||||||
_CP15_TLBIMVA(va | CPU_ASID_KERNEL);
|
_CP15_TLBIMVA(va | CPU_ASID_KERNEL);
|
||||||
@ -401,7 +410,7 @@ tlb_flush_range(vm_offset_t va, vm_size_t size)
|
|||||||
size));
|
size));
|
||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
if (ARM_HAVE_MP_EXTENSIONS) {
|
if (ARM_USE_MP_EXTENSIONS) {
|
||||||
for (; va < eva; va += PAGE_SIZE)
|
for (; va < eva; va += PAGE_SIZE)
|
||||||
_CP15_TLBIMVAAIS(va);
|
_CP15_TLBIMVAAIS(va);
|
||||||
} else {
|
} else {
|
||||||
@ -410,14 +419,14 @@ tlb_flush_range(vm_offset_t va, vm_size_t size)
|
|||||||
}
|
}
|
||||||
dsb();
|
dsb();
|
||||||
}
|
}
|
||||||
#else /* SMP */
|
#else /* __ARM_ARCH < 7 */
|
||||||
|
|
||||||
#define tlb_flush_all() tlb_flush_all_local()
|
#define tlb_flush_all() tlb_flush_all_local()
|
||||||
#define tlb_flush_all_ng() tlb_flush_all_ng_local()
|
#define tlb_flush_all_ng() tlb_flush_all_ng_local()
|
||||||
#define tlb_flush(va) tlb_flush_local(va)
|
#define tlb_flush(va) tlb_flush_local(va)
|
||||||
#define tlb_flush_range(va, size) tlb_flush_range_local(va, size)
|
#define tlb_flush_range(va, size) tlb_flush_range_local(va, size)
|
||||||
|
|
||||||
#endif /* SMP */
|
#endif /* __ARM_ARCH < 7 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cache maintenance operations.
|
* Cache maintenance operations.
|
||||||
@ -431,8 +440,8 @@ icache_sync(vm_offset_t va, vm_size_t size)
|
|||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
va &= ~cpuinfo.dcache_line_mask;
|
va &= ~cpuinfo.dcache_line_mask;
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
if (ARM_HAVE_MP_EXTENSIONS) {
|
if (ARM_USE_MP_EXTENSIONS) {
|
||||||
for ( ; va < eva; va += cpuinfo.dcache_line_size)
|
for ( ; va < eva; va += cpuinfo.dcache_line_size)
|
||||||
_CP15_DCCMVAU(va);
|
_CP15_DCCMVAU(va);
|
||||||
} else
|
} else
|
||||||
@ -442,8 +451,8 @@ icache_sync(vm_offset_t va, vm_size_t size)
|
|||||||
_CP15_DCCMVAC(va);
|
_CP15_DCCMVAC(va);
|
||||||
}
|
}
|
||||||
dsb();
|
dsb();
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
if (ARM_HAVE_MP_EXTENSIONS)
|
if (ARM_USE_MP_EXTENSIONS)
|
||||||
_CP15_ICIALLUIS();
|
_CP15_ICIALLUIS();
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -456,8 +465,8 @@ icache_sync(vm_offset_t va, vm_size_t size)
|
|||||||
static __inline void
|
static __inline void
|
||||||
icache_inv_all(void)
|
icache_inv_all(void)
|
||||||
{
|
{
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
if (ARM_HAVE_MP_EXTENSIONS)
|
if (ARM_USE_MP_EXTENSIONS)
|
||||||
_CP15_ICIALLUIS();
|
_CP15_ICIALLUIS();
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -470,8 +479,8 @@ icache_inv_all(void)
|
|||||||
static __inline void
|
static __inline void
|
||||||
bpb_inv_all(void)
|
bpb_inv_all(void)
|
||||||
{
|
{
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
if (ARM_HAVE_MP_EXTENSIONS)
|
if (ARM_USE_MP_EXTENSIONS)
|
||||||
_CP15_BPIALLIS();
|
_CP15_BPIALLIS();
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -488,8 +497,8 @@ dcache_wb_pou(vm_offset_t va, vm_size_t size)
|
|||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
va &= ~cpuinfo.dcache_line_mask;
|
va &= ~cpuinfo.dcache_line_mask;
|
||||||
#if __ARM_ARCH >= 7 && defined SMP
|
#if __ARM_ARCH >= 7
|
||||||
if (ARM_HAVE_MP_EXTENSIONS) {
|
if (ARM_USE_MP_EXTENSIONS) {
|
||||||
for ( ; va < eva; va += cpuinfo.dcache_line_size)
|
for ( ; va < eva; va += cpuinfo.dcache_line_size)
|
||||||
_CP15_DCCMVAU(va);
|
_CP15_DCCMVAU(va);
|
||||||
} else
|
} else
|
||||||
|
@ -140,7 +140,7 @@
|
|||||||
/*
|
/*
|
||||||
* CP15 C7 registers
|
* CP15 C7 registers
|
||||||
*/
|
*/
|
||||||
#if __ARM_ARCH >= 7 && defined(SMP)
|
#if __ARM_ARCH >= 7
|
||||||
/* From ARMv7: */
|
/* From ARMv7: */
|
||||||
#define CP15_ICIALLUIS p15, 0, r0, c7, c1, 0 /* Instruction cache invalidate all PoU, IS */
|
#define CP15_ICIALLUIS p15, 0, r0, c7, c1, 0 /* Instruction cache invalidate all PoU, IS */
|
||||||
#define CP15_BPIALLIS p15, 0, r0, c7, c1, 6 /* Branch predictor invalidate all IS */
|
#define CP15_BPIALLIS p15, 0, r0, c7, c1, 6 /* Branch predictor invalidate all IS */
|
||||||
@ -205,7 +205,7 @@
|
|||||||
/*
|
/*
|
||||||
* CP15 C8 registers
|
* CP15 C8 registers
|
||||||
*/
|
*/
|
||||||
#if __ARM_ARCH >= 7 && defined(SMP)
|
#if __ARM_ARCH >= 7
|
||||||
/* From ARMv7: */
|
/* From ARMv7: */
|
||||||
#define CP15_TLBIALLIS p15, 0, r0, c8, c3, 0 /* Invalidate entire unified TLB IS */
|
#define CP15_TLBIALLIS p15, 0, r0, c8, c3, 0 /* Invalidate entire unified TLB IS */
|
||||||
#define CP15_TLBIMVAIS(rr) p15, 0, rr, c8, c3, 1 /* Invalidate unified TLB by MVA IS */
|
#define CP15_TLBIMVAIS(rr) p15, 0, rr, c8, c3, 1 /* Invalidate unified TLB by MVA IS */
|
||||||
|
@ -357,10 +357,12 @@ efinet_dev_print(int verbose)
|
|||||||
for (unit = 0, h = efi_find_handle(&efinet_dev, 0);
|
for (unit = 0, h = efi_find_handle(&efinet_dev, 0);
|
||||||
h != NULL; h = efi_find_handle(&efinet_dev, ++unit)) {
|
h != NULL; h = efi_find_handle(&efinet_dev, ++unit)) {
|
||||||
printf(" %s%d:", efinet_dev.dv_name, unit);
|
printf(" %s%d:", efinet_dev.dv_name, unit);
|
||||||
text = efi_devpath_name(efi_lookup_devpath(h));
|
if (verbose) {
|
||||||
if (text != NULL) {
|
text = efi_devpath_name(efi_lookup_devpath(h));
|
||||||
printf(" %S", text);
|
if (text != NULL) {
|
||||||
efi_free_devpath_name(text);
|
printf(" %S", text);
|
||||||
|
efi_free_devpath_name(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (pager_output("\n"))
|
if (pager_output("\n"))
|
||||||
break;
|
break;
|
||||||
|
@ -744,6 +744,9 @@ struct ccb_scsiio {
|
|||||||
#define CAM_TAG_ACTION_NONE 0x00
|
#define CAM_TAG_ACTION_NONE 0x00
|
||||||
u_int tag_id; /* tag id from initator (target mode) */
|
u_int tag_id; /* tag id from initator (target mode) */
|
||||||
u_int init_id; /* initiator id of who selected */
|
u_int init_id; /* initiator id of who selected */
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
struct bio *bio; /* Associated bio */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static __inline uint8_t *
|
static __inline uint8_t *
|
||||||
@ -1335,6 +1338,9 @@ cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
|
|||||||
csio->sense_len = sense_len;
|
csio->sense_len = sense_len;
|
||||||
csio->cdb_len = cdb_len;
|
csio->cdb_len = cdb_len;
|
||||||
csio->tag_action = tag_action;
|
csio->tag_action = tag_action;
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
csio->bio = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
|
@ -1427,6 +1427,11 @@ camperiphscsisenseerror(union ccb *ccb, union ccb **orig,
|
|||||||
union ccb *orig_ccb = ccb;
|
union ccb *orig_ccb = ccb;
|
||||||
int error, recoveryccb;
|
int error, recoveryccb;
|
||||||
|
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
if (ccb->ccb_h.func_code == XPT_SCSI_IO && ccb->csio.bio != NULL)
|
||||||
|
biotrack(ccb->csio.bio, __func__);
|
||||||
|
#endif
|
||||||
|
|
||||||
periph = xpt_path_periph(ccb->ccb_h.path);
|
periph = xpt_path_periph(ccb->ccb_h.path);
|
||||||
recoveryccb = (ccb->ccb_h.cbfcnp == camperiphdone);
|
recoveryccb = (ccb->ccb_h.cbfcnp == camperiphdone);
|
||||||
if ((periph->flags & CAM_PERIPH_RECOVERY_INPROG) && !recoveryccb) {
|
if ((periph->flags & CAM_PERIPH_RECOVERY_INPROG) && !recoveryccb) {
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/bio.h>
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -4471,6 +4472,12 @@ xpt_done(union ccb *done_ccb)
|
|||||||
struct cam_doneq *queue;
|
struct cam_doneq *queue;
|
||||||
int run, hash;
|
int run, hash;
|
||||||
|
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
if (done_ccb->ccb_h.func_code == XPT_SCSI_IO &&
|
||||||
|
done_ccb->csio.bio != NULL)
|
||||||
|
biotrack(done_ccb->csio.bio, __func__);
|
||||||
|
#endif
|
||||||
|
|
||||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE,
|
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE,
|
||||||
("xpt_done: func= %#x %s status %#x\n",
|
("xpt_done: func= %#x %s status %#x\n",
|
||||||
done_ccb->ccb_h.func_code,
|
done_ccb->ccb_h.func_code,
|
||||||
@ -5189,6 +5196,16 @@ xpt_done_process(struct ccb_hdr *ccb_h)
|
|||||||
struct cam_devq *devq;
|
struct cam_devq *devq;
|
||||||
struct mtx *mtx = NULL;
|
struct mtx *mtx = NULL;
|
||||||
|
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
struct ccb_scsiio *csio;
|
||||||
|
|
||||||
|
if (ccb_h->func_code == XPT_SCSI_IO) {
|
||||||
|
csio = &((union ccb *)ccb_h)->csio;
|
||||||
|
if (csio->bio != NULL)
|
||||||
|
biotrack(csio->bio, __func__);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ccb_h->flags & CAM_HIGH_POWER) {
|
if (ccb_h->flags & CAM_HIGH_POWER) {
|
||||||
struct highpowerlist *hphead;
|
struct highpowerlist *hphead;
|
||||||
struct cam_ed *device;
|
struct cam_ed *device;
|
||||||
|
@ -2949,6 +2949,8 @@ dastart(struct cam_periph *periph, union ccb *start_ccb)
|
|||||||
void *data_ptr;
|
void *data_ptr;
|
||||||
int rw_op;
|
int rw_op;
|
||||||
|
|
||||||
|
biotrack(bp, __func__);
|
||||||
|
|
||||||
if (bp->bio_cmd == BIO_WRITE) {
|
if (bp->bio_cmd == BIO_WRITE) {
|
||||||
softc->flags |= DA_FLAG_DIRTY;
|
softc->flags |= DA_FLAG_DIRTY;
|
||||||
rw_op = SCSI_RW_WRITE;
|
rw_op = SCSI_RW_WRITE;
|
||||||
@ -2976,6 +2978,9 @@ dastart(struct cam_periph *periph, union ccb *start_ccb)
|
|||||||
/*dxfer_len*/ bp->bio_bcount,
|
/*dxfer_len*/ bp->bio_bcount,
|
||||||
/*sense_len*/SSD_FULL_SIZE,
|
/*sense_len*/SSD_FULL_SIZE,
|
||||||
da_default_timeout * 1000);
|
da_default_timeout * 1000);
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
start_ccb->csio.bio = bp;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BIO_FLUSH:
|
case BIO_FLUSH:
|
||||||
@ -4008,6 +4013,10 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
|||||||
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone\n"));
|
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone\n"));
|
||||||
|
|
||||||
csio = &done_ccb->csio;
|
csio = &done_ccb->csio;
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
if (csio->bio != NULL)
|
||||||
|
biotrack(csio->bio, __func__);
|
||||||
|
#endif
|
||||||
state = csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK;
|
state = csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case DA_CCB_BUFFER_IO:
|
case DA_CCB_BUFFER_IO:
|
||||||
@ -4106,6 +4115,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
biotrack(bp, __func__);
|
||||||
LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
|
LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
|
||||||
if (LIST_EMPTY(&softc->pending_ccbs))
|
if (LIST_EMPTY(&softc->pending_ccbs))
|
||||||
softc->flags |= DA_FLAG_WAS_OTAG;
|
softc->flags |= DA_FLAG_WAS_OTAG;
|
||||||
@ -5219,6 +5229,11 @@ daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
|
|||||||
struct cam_periph *periph;
|
struct cam_periph *periph;
|
||||||
int error, error_code, sense_key, asc, ascq;
|
int error, error_code, sense_key, asc, ascq;
|
||||||
|
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
if (ccb->csio.bio != NULL)
|
||||||
|
biotrack(ccb->csio.bio, __func__);
|
||||||
|
#endif
|
||||||
|
|
||||||
periph = xpt_path_periph(ccb->ccb_h.path);
|
periph = xpt_path_periph(ccb->ccb_h.path);
|
||||||
softc = (struct da_softc *)periph->softc;
|
softc = (struct da_softc *)periph->softc;
|
||||||
|
|
||||||
|
@ -405,6 +405,7 @@ extern itx_t *zil_itx_create(uint64_t txtype, size_t lrsize);
|
|||||||
extern void zil_itx_destroy(itx_t *itx);
|
extern void zil_itx_destroy(itx_t *itx);
|
||||||
extern void zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx);
|
extern void zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx);
|
||||||
|
|
||||||
|
extern void zil_async_to_sync(zilog_t *zilog, uint64_t oid);
|
||||||
extern void zil_commit(zilog_t *zilog, uint64_t oid);
|
extern void zil_commit(zilog_t *zilog, uint64_t oid);
|
||||||
|
|
||||||
extern int zil_vdev_offline(const char *osname, void *txarg);
|
extern int zil_vdev_offline(const char *osname, void *txarg);
|
||||||
|
@ -90,8 +90,6 @@ SYSCTL_INT(_vfs_zfs_trim, OID_AUTO, enabled, CTLFLAG_RDTUN, &zfs_trim_enabled, 0
|
|||||||
|
|
||||||
static kmem_cache_t *zil_lwb_cache;
|
static kmem_cache_t *zil_lwb_cache;
|
||||||
|
|
||||||
static void zil_async_to_sync(zilog_t *zilog, uint64_t foid);
|
|
||||||
|
|
||||||
#define LWB_EMPTY(lwb) ((BP_GET_LSIZE(&lwb->lwb_blk) - \
|
#define LWB_EMPTY(lwb) ((BP_GET_LSIZE(&lwb->lwb_blk) - \
|
||||||
sizeof (zil_chain_t)) == (lwb->lwb_sz - lwb->lwb_nused))
|
sizeof (zil_chain_t)) == (lwb->lwb_sz - lwb->lwb_nused))
|
||||||
|
|
||||||
@ -1421,7 +1419,7 @@ zil_get_commit_list(zilog_t *zilog)
|
|||||||
/*
|
/*
|
||||||
* Move the async itxs for a specified object to commit into sync lists.
|
* Move the async itxs for a specified object to commit into sync lists.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
zil_async_to_sync(zilog_t *zilog, uint64_t foid)
|
zil_async_to_sync(zilog_t *zilog, uint64_t foid)
|
||||||
{
|
{
|
||||||
uint64_t otxg, txg;
|
uint64_t otxg, txg;
|
||||||
|
@ -169,6 +169,7 @@ typedef struct zvol_state {
|
|||||||
uint32_t zv_open_count[OTYPCNT]; /* open counts */
|
uint32_t zv_open_count[OTYPCNT]; /* open counts */
|
||||||
#endif
|
#endif
|
||||||
uint32_t zv_total_opens; /* total open count */
|
uint32_t zv_total_opens; /* total open count */
|
||||||
|
uint32_t zv_sync_cnt; /* synchronous open count */
|
||||||
zilog_t *zv_zilog; /* ZIL handle */
|
zilog_t *zv_zilog; /* ZIL handle */
|
||||||
list_t zv_extents; /* List of extents for dump */
|
list_t zv_extents; /* List of extents for dump */
|
||||||
znode_t zv_znode; /* for range locking */
|
znode_t zv_znode; /* for range locking */
|
||||||
@ -1441,7 +1442,9 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t resid,
|
|||||||
BP_ZERO(&lr->lr_blkptr);
|
BP_ZERO(&lr->lr_blkptr);
|
||||||
|
|
||||||
itx->itx_private = zv;
|
itx->itx_private = zv;
|
||||||
itx->itx_sync = sync;
|
|
||||||
|
if (!sync && (zv->zv_sync_cnt == 0))
|
||||||
|
itx->itx_sync = B_FALSE;
|
||||||
|
|
||||||
zil_itx_assign(zilog, itx, tx);
|
zil_itx_assign(zilog, itx, tx);
|
||||||
|
|
||||||
@ -1674,7 +1677,7 @@ zvol_strategy(struct bio *bp)
|
|||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
dmu_tx_abort(tx);
|
dmu_tx_abort(tx);
|
||||||
} else {
|
} else {
|
||||||
zvol_log_truncate(zv, tx, off, resid, B_TRUE);
|
zvol_log_truncate(zv, tx, off, resid, sync);
|
||||||
dmu_tx_commit(tx);
|
dmu_tx_commit(tx);
|
||||||
error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ,
|
error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ,
|
||||||
off, resid);
|
off, resid);
|
||||||
@ -2083,7 +2086,7 @@ zvol_log_truncate(zvol_state_t *zv, dmu_tx_t *tx, uint64_t off, uint64_t len,
|
|||||||
lr->lr_offset = off;
|
lr->lr_offset = off;
|
||||||
lr->lr_length = len;
|
lr->lr_length = len;
|
||||||
|
|
||||||
itx->itx_sync = sync;
|
itx->itx_sync = (sync || zv->zv_sync_cnt != 0);
|
||||||
zil_itx_assign(zilog, itx, tx);
|
zil_itx_assign(zilog, itx, tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3075,6 +3078,11 @@ zvol_d_open(struct cdev *dev, int flags, int fmt, struct thread *td)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
zv->zv_total_opens++;
|
zv->zv_total_opens++;
|
||||||
|
if (flags & (FSYNC | FDSYNC)) {
|
||||||
|
zv->zv_sync_cnt++;
|
||||||
|
if (zv->zv_sync_cnt == 1)
|
||||||
|
zil_async_to_sync(zv->zv_zilog, ZVOL_OBJ);
|
||||||
|
}
|
||||||
mutex_exit(&zfsdev_state_lock);
|
mutex_exit(&zfsdev_state_lock);
|
||||||
return (err);
|
return (err);
|
||||||
out:
|
out:
|
||||||
@ -3105,6 +3113,8 @@ zvol_d_close(struct cdev *dev, int flags, int fmt, struct thread *td)
|
|||||||
* You may get multiple opens, but only one close.
|
* You may get multiple opens, but only one close.
|
||||||
*/
|
*/
|
||||||
zv->zv_total_opens--;
|
zv->zv_total_opens--;
|
||||||
|
if (flags & (FSYNC | FDSYNC))
|
||||||
|
zv->zv_sync_cnt--;
|
||||||
|
|
||||||
if (zv->zv_total_opens == 0)
|
if (zv->zv_total_opens == 0)
|
||||||
zvol_last_close(zv);
|
zvol_last_close(zv);
|
||||||
@ -3118,9 +3128,9 @@ zvol_d_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct threa
|
|||||||
{
|
{
|
||||||
zvol_state_t *zv;
|
zvol_state_t *zv;
|
||||||
rl_t *rl;
|
rl_t *rl;
|
||||||
off_t offset, length, chunk;
|
off_t offset, length;
|
||||||
int i, error;
|
int i, error;
|
||||||
u_int u;
|
boolean_t sync;
|
||||||
|
|
||||||
zv = dev->si_drv2;
|
zv = dev->si_drv2;
|
||||||
|
|
||||||
@ -3158,15 +3168,17 @@ zvol_d_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct threa
|
|||||||
dmu_tx_t *tx = dmu_tx_create(zv->zv_objset);
|
dmu_tx_t *tx = dmu_tx_create(zv->zv_objset);
|
||||||
error = dmu_tx_assign(tx, TXG_WAIT);
|
error = dmu_tx_assign(tx, TXG_WAIT);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
|
sync = FALSE;
|
||||||
dmu_tx_abort(tx);
|
dmu_tx_abort(tx);
|
||||||
} else {
|
} else {
|
||||||
zvol_log_truncate(zv, tx, offset, length, B_TRUE);
|
sync = (zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS);
|
||||||
|
zvol_log_truncate(zv, tx, offset, length, sync);
|
||||||
dmu_tx_commit(tx);
|
dmu_tx_commit(tx);
|
||||||
error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ,
|
error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ,
|
||||||
offset, length);
|
offset, length);
|
||||||
}
|
}
|
||||||
zfs_range_unlock(rl);
|
zfs_range_unlock(rl);
|
||||||
if (zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS)
|
if (sync)
|
||||||
zil_commit(zv->zv_zilog, ZVOL_OBJ);
|
zil_commit(zv->zv_zilog, ZVOL_OBJ);
|
||||||
break;
|
break;
|
||||||
case DIOCGSTRIPESIZE:
|
case DIOCGSTRIPESIZE:
|
||||||
|
@ -293,7 +293,7 @@ dev/hwpmc/hwpmc_tsc.c optional hwpmc
|
|||||||
dev/hwpmc/hwpmc_x86.c optional hwpmc
|
dev/hwpmc/hwpmc_x86.c optional hwpmc
|
||||||
dev/hyperv/netvsc/hn_nvs.c optional hyperv
|
dev/hyperv/netvsc/hn_nvs.c optional hyperv
|
||||||
dev/hyperv/netvsc/hn_rndis.c optional hyperv
|
dev/hyperv/netvsc/hn_rndis.c optional hyperv
|
||||||
dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv
|
dev/hyperv/netvsc/if_hn.c optional hyperv
|
||||||
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
|
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
|
||||||
dev/hyperv/utilities/hv_heartbeat.c optional hyperv
|
dev/hyperv/utilities/hv_heartbeat.c optional hyperv
|
||||||
dev/hyperv/utilities/hv_kvp.c optional hyperv
|
dev/hyperv/utilities/hv_kvp.c optional hyperv
|
||||||
|
@ -250,7 +250,7 @@ dev/hwpmc/hwpmc_tsc.c optional hwpmc
|
|||||||
dev/hwpmc/hwpmc_x86.c optional hwpmc
|
dev/hwpmc/hwpmc_x86.c optional hwpmc
|
||||||
dev/hyperv/netvsc/hn_nvs.c optional hyperv
|
dev/hyperv/netvsc/hn_nvs.c optional hyperv
|
||||||
dev/hyperv/netvsc/hn_rndis.c optional hyperv
|
dev/hyperv/netvsc/hn_rndis.c optional hyperv
|
||||||
dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv
|
dev/hyperv/netvsc/if_hn.c optional hyperv
|
||||||
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
|
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
|
||||||
dev/hyperv/utilities/hv_heartbeat.c optional hyperv
|
dev/hyperv/utilities/hv_heartbeat.c optional hyperv
|
||||||
dev/hyperv/utilities/hv_kvp.c optional hyperv
|
dev/hyperv/utilities/hv_kvp.c optional hyperv
|
||||||
|
@ -63,6 +63,7 @@ dev/ofw/ofw_subr.c optional aim powerpc
|
|||||||
dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac
|
dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac
|
||||||
dev/quicc/quicc_bfe_fdt.c optional quicc mpc85xx
|
dev/quicc/quicc_bfe_fdt.c optional quicc mpc85xx
|
||||||
dev/scc/scc_bfe_macio.c optional scc powermac
|
dev/scc/scc_bfe_macio.c optional scc powermac
|
||||||
|
dev/sdhci/fsl_sdhci.c optional mpc85xx sdhci
|
||||||
dev/sec/sec.c optional sec mpc85xx
|
dev/sec/sec.c optional sec mpc85xx
|
||||||
dev/sound/macio/aoa.c optional snd_davbus | snd_ai2s powermac
|
dev/sound/macio/aoa.c optional snd_davbus | snd_ai2s powermac
|
||||||
dev/sound/macio/davbus.c optional snd_davbus powermac
|
dev/sound/macio/davbus.c optional snd_davbus powermac
|
||||||
@ -137,7 +138,6 @@ powerpc/mpc85xx/atpic.c optional mpc85xx isa
|
|||||||
powerpc/mpc85xx/ds1553_bus_fdt.c optional ds1553 fdt
|
powerpc/mpc85xx/ds1553_bus_fdt.c optional ds1553 fdt
|
||||||
powerpc/mpc85xx/ds1553_core.c optional ds1553
|
powerpc/mpc85xx/ds1553_core.c optional ds1553
|
||||||
powerpc/mpc85xx/fsl_diu.c optional mpc85xx diu
|
powerpc/mpc85xx/fsl_diu.c optional mpc85xx diu
|
||||||
powerpc/mpc85xx/fsl_sdhc.c optional mpc85xx sdhc
|
|
||||||
powerpc/mpc85xx/i2c.c optional iicbus fdt
|
powerpc/mpc85xx/i2c.c optional iicbus fdt
|
||||||
powerpc/mpc85xx/isa.c optional mpc85xx isa
|
powerpc/mpc85xx/isa.c optional mpc85xx isa
|
||||||
powerpc/mpc85xx/lbc.c optional mpc85xx
|
powerpc/mpc85xx/lbc.c optional mpc85xx
|
||||||
|
@ -50,12 +50,14 @@ TWA_FLASH_FIRMWARE opt_twa.h
|
|||||||
# Debugging options.
|
# Debugging options.
|
||||||
ALT_BREAK_TO_DEBUGGER opt_kdb.h
|
ALT_BREAK_TO_DEBUGGER opt_kdb.h
|
||||||
BREAK_TO_DEBUGGER opt_kdb.h
|
BREAK_TO_DEBUGGER opt_kdb.h
|
||||||
|
BUF_TRACKING opt_global.h
|
||||||
DDB
|
DDB
|
||||||
DDB_BUFR_SIZE opt_ddb.h
|
DDB_BUFR_SIZE opt_ddb.h
|
||||||
DDB_CAPTURE_DEFAULTBUFSIZE opt_ddb.h
|
DDB_CAPTURE_DEFAULTBUFSIZE opt_ddb.h
|
||||||
DDB_CAPTURE_MAXBUFSIZE opt_ddb.h
|
DDB_CAPTURE_MAXBUFSIZE opt_ddb.h
|
||||||
DDB_CTF opt_ddb.h
|
DDB_CTF opt_ddb.h
|
||||||
DDB_NUMSYM opt_ddb.h
|
DDB_NUMSYM opt_ddb.h
|
||||||
|
FULL_BUF_TRACKING opt_global.h
|
||||||
GDB
|
GDB
|
||||||
KDB opt_global.h
|
KDB opt_global.h
|
||||||
KDB_TRACE opt_kdb.h
|
KDB_TRACE opt_kdb.h
|
||||||
|
@ -1062,27 +1062,15 @@ doopen(struct psm_softc *sc, int command_byte)
|
|||||||
*/
|
*/
|
||||||
if (sc->hw.model == MOUSE_MODEL_GENERIC) {
|
if (sc->hw.model == MOUSE_MODEL_GENERIC) {
|
||||||
if (tap_enabled > 0) {
|
if (tap_enabled > 0) {
|
||||||
/*
|
|
||||||
* Enable tap & drag gestures. We use a Mode Byte
|
|
||||||
* and clear the DisGest bit (see §2.5 of Synaptics
|
|
||||||
* TouchPad Interfacing Guide).
|
|
||||||
*/
|
|
||||||
VLOG(2, (LOG_DEBUG,
|
VLOG(2, (LOG_DEBUG,
|
||||||
"psm%d: enable tap and drag gestures\n",
|
"psm%d: enable tap and drag gestures\n",
|
||||||
sc->unit));
|
sc->unit));
|
||||||
mouse_ext_command(sc->kbdc, 0x00);
|
synaptics_set_mode(sc, synaptics_preferred_mode(sc));
|
||||||
set_mouse_sampling_rate(sc->kbdc, 20);
|
|
||||||
} else if (tap_enabled == 0) {
|
} else if (tap_enabled == 0) {
|
||||||
/*
|
|
||||||
* Disable tap & drag gestures. We use a Mode Byte
|
|
||||||
* and set the DisGest bit (see §2.5 of Synaptics
|
|
||||||
* TouchPad Interfacing Guide).
|
|
||||||
*/
|
|
||||||
VLOG(2, (LOG_DEBUG,
|
VLOG(2, (LOG_DEBUG,
|
||||||
"psm%d: disable tap and drag gestures\n",
|
"psm%d: disable tap and drag gestures\n",
|
||||||
sc->unit));
|
sc->unit));
|
||||||
mouse_ext_command(sc->kbdc, 0x04);
|
synaptics_set_mode(sc, synaptics_preferred_mode(sc));
|
||||||
set_mouse_sampling_rate(sc->kbdc, 20);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5364,6 +5352,24 @@ static int
|
|||||||
synaptics_preferred_mode(struct psm_softc *sc) {
|
synaptics_preferred_mode(struct psm_softc *sc) {
|
||||||
int mode_byte;
|
int mode_byte;
|
||||||
|
|
||||||
|
/* Check if we are in relative mode */
|
||||||
|
if (sc->hw.model != MOUSE_MODEL_SYNAPTICS) {
|
||||||
|
if (tap_enabled == 0)
|
||||||
|
/*
|
||||||
|
* Disable tap & drag gestures. We use a Mode Byte
|
||||||
|
* and set the DisGest bit (see §2.5 of Synaptics
|
||||||
|
* TouchPad Interfacing Guide).
|
||||||
|
*/
|
||||||
|
return (0x04);
|
||||||
|
else
|
||||||
|
/*
|
||||||
|
* Enable tap & drag gestures. We use a Mode Byte
|
||||||
|
* and clear the DisGest bit (see §2.5 of Synaptics
|
||||||
|
* TouchPad Interfacing Guide).
|
||||||
|
*/
|
||||||
|
return (0x00);
|
||||||
|
}
|
||||||
|
|
||||||
mode_byte = 0xc4;
|
mode_byte = 0xc4;
|
||||||
|
|
||||||
/* request wmode where available */
|
/* request wmode where available */
|
||||||
@ -5382,10 +5388,10 @@ synaptics_set_mode(struct psm_softc *sc, int mode_byte) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable advanced gestures mode if supported and we are not entering
|
* Enable advanced gestures mode if supported and we are not entering
|
||||||
* passthrough mode.
|
* passthrough or relative mode.
|
||||||
*/
|
*/
|
||||||
if ((sc->synhw.capAdvancedGestures || sc->synhw.capReportsV) &&
|
if ((sc->synhw.capAdvancedGestures || sc->synhw.capReportsV) &&
|
||||||
!(mode_byte & (1 << 5))) {
|
sc->hw.model == MOUSE_MODEL_SYNAPTICS && !(mode_byte & (1 << 5))) {
|
||||||
mouse_ext_command(sc->kbdc, 3);
|
mouse_ext_command(sc->kbdc, 3);
|
||||||
set_mouse_sampling_rate(sc->kbdc, 0xc8);
|
set_mouse_sampling_rate(sc->kbdc, 0xc8);
|
||||||
}
|
}
|
||||||
@ -5698,6 +5704,9 @@ enable_synaptics(struct psm_softc *sc, enum probearg arg)
|
|||||||
if (!synaptics_support)
|
if (!synaptics_support)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
|
/* Set mouse type just now for synaptics_set_mode() */
|
||||||
|
sc->hw.model = MOUSE_MODEL_SYNAPTICS;
|
||||||
|
|
||||||
synaptics_set_mode(sc, synaptics_preferred_mode(sc));
|
synaptics_set_mode(sc, synaptics_preferred_mode(sc));
|
||||||
|
|
||||||
if (trackpoint_support && synhw.capPassthrough) {
|
if (trackpoint_support && synhw.capPassthrough) {
|
||||||
|
@ -70,8 +70,6 @@
|
|||||||
|
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
|
||||||
#include "opt_global.h"
|
|
||||||
|
|
||||||
#define BHND_ERROR_LEVEL 0x00
|
#define BHND_ERROR_LEVEL 0x00
|
||||||
#define BHND_ERROR_MSG "ERROR"
|
#define BHND_ERROR_MSG "ERROR"
|
||||||
#define BHND_WARN_LEVEL 0x10
|
#define BHND_WARN_LEVEL 0x10
|
||||||
|
@ -57,7 +57,7 @@ static d_ioctl_t cpuctl_ioctl;
|
|||||||
|
|
||||||
#define CPUCTL_VERSION 1
|
#define CPUCTL_VERSION 1
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef CPUCTL_DEBUG
|
||||||
# define DPRINTF(format,...) printf(format, __VA_ARGS__);
|
# define DPRINTF(format,...) printf(format, __VA_ARGS__);
|
||||||
#else
|
#else
|
||||||
# define DPRINTF(...)
|
# define DPRINTF(...)
|
||||||
@ -377,13 +377,24 @@ update_intel(int cpu, cpuctl_update_args_t *args, struct thread *td)
|
|||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NB: MSR 0xc0010020, MSR_K8_UCODE_UPDATE, is not documented by AMD.
|
||||||
|
* Coreboot, illumos and Linux source code was used to understand
|
||||||
|
* its workings.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
amd_ucode_wrmsr(void *ucode_ptr)
|
||||||
|
{
|
||||||
|
uint32_t tmp[4];
|
||||||
|
|
||||||
|
wrmsr_safe(MSR_K8_UCODE_UPDATE, (uintptr_t)ucode_ptr);
|
||||||
|
do_cpuid(0, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td)
|
update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td)
|
||||||
{
|
{
|
||||||
void *ptr = NULL;
|
void *ptr;
|
||||||
uint32_t tmp[4];
|
|
||||||
int is_bound = 0;
|
|
||||||
int oldcpu;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (args->size == 0 || args->data == NULL) {
|
if (args->size == 0 || args->data == NULL) {
|
||||||
@ -394,41 +405,23 @@ update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td)
|
|||||||
DPRINTF("[cpuctl,%d]: firmware image too large", __LINE__);
|
DPRINTF("[cpuctl,%d]: firmware image too large", __LINE__);
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX Might not require contignous address space - needs check
|
* 16 byte alignment required. Rely on the fact that
|
||||||
|
* malloc(9) always returns the pointer aligned at least on
|
||||||
|
* the size of the allocation.
|
||||||
*/
|
*/
|
||||||
ptr = contigmalloc(args->size, M_CPUCTL, 0, 0, 0xffffffff, 16, 0);
|
ptr = malloc(args->size + 16, M_CPUCTL, M_ZERO | M_WAITOK);
|
||||||
if (ptr == NULL) {
|
|
||||||
DPRINTF("[cpuctl,%d]: cannot allocate %zd bytes of memory",
|
|
||||||
__LINE__, args->size);
|
|
||||||
return (ENOMEM);
|
|
||||||
}
|
|
||||||
if (copyin(args->data, ptr, args->size) != 0) {
|
if (copyin(args->data, ptr, args->size) != 0) {
|
||||||
DPRINTF("[cpuctl,%d]: copyin %p->%p of %zd bytes failed",
|
DPRINTF("[cpuctl,%d]: copyin %p->%p of %zd bytes failed",
|
||||||
__LINE__, args->data, ptr, args->size);
|
__LINE__, args->data, ptr, args->size);
|
||||||
ret = EFAULT;
|
ret = EFAULT;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
oldcpu = td->td_oncpu;
|
smp_rendezvous(NULL, amd_ucode_wrmsr, NULL, ptr);
|
||||||
is_bound = cpu_sched_is_bound(td);
|
|
||||||
set_cpu(cpu, td);
|
|
||||||
critical_enter();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform update.
|
|
||||||
*/
|
|
||||||
wrmsr_safe(MSR_K8_UCODE_UPDATE, (uintptr_t)ptr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Serialize instruction flow.
|
|
||||||
*/
|
|
||||||
do_cpuid(0, tmp);
|
|
||||||
critical_exit();
|
|
||||||
restore_cpu(oldcpu, is_bound, td);
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
fail:
|
fail:
|
||||||
if (ptr != NULL)
|
free(ptr, M_CPUCTL);
|
||||||
contigfree(ptr, args->size, M_CPUCTL);
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +365,6 @@ MODULE_DEPEND(em, netmap, 1, 1, 1);
|
|||||||
|
|
||||||
#define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000)
|
#define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000)
|
||||||
#define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024)
|
#define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024)
|
||||||
#define M_TSO_LEN 66
|
|
||||||
|
|
||||||
#define MAX_INTS_PER_SEC 8000
|
#define MAX_INTS_PER_SEC 8000
|
||||||
#define DEFAULT_ITR (1000000000/(MAX_INTS_PER_SEC * 256))
|
#define DEFAULT_ITR (1000000000/(MAX_INTS_PER_SEC * 256))
|
||||||
|
@ -44,15 +44,4 @@ struct hyperv_guid {
|
|||||||
|
|
||||||
int hyperv_guid2str(const struct hyperv_guid *, char *, size_t);
|
int hyperv_guid2str(const struct hyperv_guid *, char *, size_t);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get physical address from virtual
|
|
||||||
*/
|
|
||||||
static inline unsigned long
|
|
||||||
hv_get_phys_addr(void *virt)
|
|
||||||
{
|
|
||||||
unsigned long ret;
|
|
||||||
ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK));
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _HYPERV_H_ */
|
#endif /* _HYPERV_H_ */
|
||||||
|
@ -146,8 +146,6 @@ int vmbus_chan_gpadl_disconnect(struct vmbus_channel *chan,
|
|||||||
|
|
||||||
void vmbus_chan_cpu_set(struct vmbus_channel *chan, int cpu);
|
void vmbus_chan_cpu_set(struct vmbus_channel *chan, int cpu);
|
||||||
void vmbus_chan_cpu_rr(struct vmbus_channel *chan);
|
void vmbus_chan_cpu_rr(struct vmbus_channel *chan);
|
||||||
struct vmbus_channel *
|
|
||||||
vmbus_chan_cpu2chan(struct vmbus_channel *chan, int cpu);
|
|
||||||
void vmbus_chan_set_readbatch(struct vmbus_channel *chan, bool on);
|
void vmbus_chan_set_readbatch(struct vmbus_channel *chan, bool on);
|
||||||
|
|
||||||
struct vmbus_channel **
|
struct vmbus_channel **
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -72,8 +72,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
/* hv_kvp defines */
|
/* hv_kvp defines */
|
||||||
#define BUFFERSIZE sizeof(struct hv_kvp_msg)
|
#define BUFFERSIZE sizeof(struct hv_kvp_msg)
|
||||||
#define KVP_SUCCESS 0
|
|
||||||
#define KVP_ERROR 1
|
|
||||||
#define kvp_hdr hdr.kvp_hdr
|
#define kvp_hdr hdr.kvp_hdr
|
||||||
|
|
||||||
#define KVP_FWVER_MAJOR 3
|
#define KVP_FWVER_MAJOR 3
|
||||||
@ -480,7 +478,7 @@ hv_kvp_convert_usermsg_to_hostmsg(struct hv_kvp_msg *umsg, struct hv_kvp_msg *hm
|
|||||||
case HV_KVP_OP_SET_IP_INFO:
|
case HV_KVP_OP_SET_IP_INFO:
|
||||||
case HV_KVP_OP_SET:
|
case HV_KVP_OP_SET:
|
||||||
case HV_KVP_OP_DELETE:
|
case HV_KVP_OP_DELETE:
|
||||||
return (KVP_SUCCESS);
|
return (0);
|
||||||
|
|
||||||
case HV_KVP_OP_ENUMERATE:
|
case HV_KVP_OP_ENUMERATE:
|
||||||
host_exchg_data = &hmsg->body.kvp_enum_data.data;
|
host_exchg_data = &hmsg->body.kvp_enum_data.data;
|
||||||
@ -501,9 +499,9 @@ hv_kvp_convert_usermsg_to_hostmsg(struct hv_kvp_msg *umsg, struct hv_kvp_msg *hm
|
|||||||
host_exchg_data->value_type = HV_REG_SZ;
|
host_exchg_data->value_type = HV_REG_SZ;
|
||||||
|
|
||||||
if ((hkey_len < 0) || (hvalue_len < 0))
|
if ((hkey_len < 0) || (hvalue_len < 0))
|
||||||
return (HV_KVP_E_FAIL);
|
return (EINVAL);
|
||||||
|
|
||||||
return (KVP_SUCCESS);
|
return (0);
|
||||||
|
|
||||||
case HV_KVP_OP_GET:
|
case HV_KVP_OP_GET:
|
||||||
host_exchg_data = &hmsg->body.kvp_get.data;
|
host_exchg_data = &hmsg->body.kvp_get.data;
|
||||||
@ -519,12 +517,12 @@ hv_kvp_convert_usermsg_to_hostmsg(struct hv_kvp_msg *umsg, struct hv_kvp_msg *hm
|
|||||||
host_exchg_data->value_type = HV_REG_SZ;
|
host_exchg_data->value_type = HV_REG_SZ;
|
||||||
|
|
||||||
if ((hkey_len < 0) || (hvalue_len < 0))
|
if ((hkey_len < 0) || (hvalue_len < 0))
|
||||||
return (HV_KVP_E_FAIL);
|
return (EINVAL);
|
||||||
|
|
||||||
return (KVP_SUCCESS);
|
return (0);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (HV_KVP_E_FAIL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,16 +531,13 @@ hv_kvp_convert_usermsg_to_hostmsg(struct hv_kvp_msg *umsg, struct hv_kvp_msg *hm
|
|||||||
* Send the response back to the host.
|
* Send the response back to the host.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
hv_kvp_respond_host(hv_kvp_sc *sc, int error)
|
hv_kvp_respond_host(hv_kvp_sc *sc, uint32_t error)
|
||||||
{
|
{
|
||||||
struct hv_vmbus_icmsg_hdr *hv_icmsg_hdrp;
|
struct hv_vmbus_icmsg_hdr *hv_icmsg_hdrp;
|
||||||
|
|
||||||
hv_icmsg_hdrp = (struct hv_vmbus_icmsg_hdr *)
|
hv_icmsg_hdrp = (struct hv_vmbus_icmsg_hdr *)
|
||||||
&sc->rcv_buf[sizeof(struct hv_vmbus_pipe_hdr)];
|
&sc->rcv_buf[sizeof(struct hv_vmbus_pipe_hdr)];
|
||||||
|
|
||||||
if (error)
|
|
||||||
error = HV_KVP_E_FAIL;
|
|
||||||
|
|
||||||
hv_icmsg_hdrp->status = error;
|
hv_icmsg_hdrp->status = error;
|
||||||
hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
|
hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
|
||||||
HV_ICMSGHDRFLAG_RESPONSE;
|
HV_ICMSGHDRFLAG_RESPONSE;
|
||||||
@ -612,8 +607,10 @@ hv_kvp_process_request(void *context, int pending)
|
|||||||
error = vmbus_ic_negomsg(&sc->util_sc,
|
error = vmbus_ic_negomsg(&sc->util_sc,
|
||||||
kvp_buf, &recvlen, KVP_FWVER, KVP_MSGVER);
|
kvp_buf, &recvlen, KVP_FWVER, KVP_MSGVER);
|
||||||
/* XXX handle vmbus_ic_negomsg failure. */
|
/* XXX handle vmbus_ic_negomsg failure. */
|
||||||
hv_kvp_respond_host(sc, error);
|
if (!error)
|
||||||
|
hv_kvp_respond_host(sc, HV_S_OK);
|
||||||
|
else
|
||||||
|
hv_kvp_respond_host(sc, HV_E_FAIL);
|
||||||
/*
|
/*
|
||||||
* It is ok to not acquire the mutex before setting
|
* It is ok to not acquire the mutex before setting
|
||||||
* req_in_progress here because negotiation is the
|
* req_in_progress here because negotiation is the
|
||||||
@ -657,7 +654,7 @@ hv_kvp_process_request(void *context, int pending)
|
|||||||
*/
|
*/
|
||||||
if (hv_kvp_req_in_progress(sc)) {
|
if (hv_kvp_req_in_progress(sc)) {
|
||||||
hv_kvp_log_info("%s: request was still active after wait so failing\n", __func__);
|
hv_kvp_log_info("%s: request was still active after wait so failing\n", __func__);
|
||||||
hv_kvp_respond_host(sc, HV_KVP_E_FAIL);
|
hv_kvp_respond_host(sc, HV_E_FAIL);
|
||||||
sc->req_in_progress = false;
|
sc->req_in_progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,9 +734,9 @@ hv_kvp_dev_daemon_read(struct cdev *dev, struct uio *uio, int ioflag __unused)
|
|||||||
struct hv_kvp_msg *hv_kvp_dev_buf;
|
struct hv_kvp_msg *hv_kvp_dev_buf;
|
||||||
hv_kvp_sc *sc = (hv_kvp_sc*)dev->si_drv1;
|
hv_kvp_sc *sc = (hv_kvp_sc*)dev->si_drv1;
|
||||||
|
|
||||||
/* Check hv_kvp daemon registration status*/
|
/* Read is not allowed util registering is done. */
|
||||||
if (!sc->register_done)
|
if (!sc->register_done)
|
||||||
return (KVP_ERROR);
|
return (EPERM);
|
||||||
|
|
||||||
sema_wait(&sc->dev_sema);
|
sema_wait(&sc->dev_sema);
|
||||||
|
|
||||||
@ -789,7 +786,7 @@ hv_kvp_dev_daemon_write(struct cdev *dev, struct uio *uio, int ioflag __unused)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hv_kvp_log_info("%s, KVP Registration Failed\n", __func__);
|
hv_kvp_log_info("%s, KVP Registration Failed\n", __func__);
|
||||||
return (KVP_ERROR);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -799,10 +796,15 @@ hv_kvp_dev_daemon_write(struct cdev *dev, struct uio *uio, int ioflag __unused)
|
|||||||
struct hv_kvp_msg *hmsg = sc->host_kvp_msg;
|
struct hv_kvp_msg *hmsg = sc->host_kvp_msg;
|
||||||
struct hv_kvp_msg *umsg = &sc->daemon_kvp_msg;
|
struct hv_kvp_msg *umsg = &sc->daemon_kvp_msg;
|
||||||
|
|
||||||
hv_kvp_convert_usermsg_to_hostmsg(umsg, hmsg);
|
error = hv_kvp_convert_usermsg_to_hostmsg(umsg, hmsg);
|
||||||
hv_kvp_respond_host(sc, KVP_SUCCESS);
|
hv_kvp_respond_host(sc, umsg->hdr.error);
|
||||||
wakeup(sc);
|
wakeup(sc);
|
||||||
sc->req_in_progress = false;
|
sc->req_in_progress = false;
|
||||||
|
if (umsg->hdr.error != HV_S_OK)
|
||||||
|
hv_kvp_log_info("%s, Error 0x%x from daemon\n",
|
||||||
|
__func__, umsg->hdr.error);
|
||||||
|
if (error)
|
||||||
|
hv_kvp_log_info("%s, Error from convert\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
sc->daemon_busy = false;
|
sc->daemon_busy = false;
|
||||||
@ -865,7 +867,7 @@ hv_kvp_attach(device_t dev)
|
|||||||
child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
|
child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
|
||||||
|
|
||||||
SYSCTL_ADD_INT(ctx, child, OID_AUTO, "hv_kvp_log",
|
SYSCTL_ADD_INT(ctx, child, OID_AUTO, "hv_kvp_log",
|
||||||
CTLFLAG_RW, &hv_kvp_log, 0, "Hyperv KVP service log level");
|
CTLFLAG_RWTUN, &hv_kvp_log, 0, "Hyperv KVP service log level");
|
||||||
|
|
||||||
TASK_INIT(&sc->task, 0, hv_kvp_process_request, sc);
|
TASK_INIT(&sc->task, 0, hv_kvp_process_request, sc);
|
||||||
|
|
||||||
|
@ -144,19 +144,6 @@ enum hv_kvp_exchg_pool {
|
|||||||
HV_KVP_POOL_COUNT /* Number of pools, must be last. */
|
HV_KVP_POOL_COUNT /* Number of pools, must be last. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some Hyper-V status codes.
|
|
||||||
*/
|
|
||||||
#define HV_KVP_S_OK 0x00000000
|
|
||||||
#define HV_KVP_E_FAIL 0x80004005
|
|
||||||
#define HV_KVP_S_CONT 0x80070103
|
|
||||||
#define HV_ERROR_NOT_SUPPORTED 0x80070032
|
|
||||||
#define HV_ERROR_MACHINE_LOCKED 0x800704F7
|
|
||||||
#define HV_ERROR_DEVICE_NOT_CONNECTED 0x8007048F
|
|
||||||
#define HV_INVALIDARG 0x80070057
|
|
||||||
#define HV_KVP_GUID_NOTFOUND 0x80041002
|
|
||||||
|
|
||||||
#define ADDR_FAMILY_NONE 0x00
|
#define ADDR_FAMILY_NONE 0x00
|
||||||
#define ADDR_FAMILY_IPV4 0x01
|
#define ADDR_FAMILY_IPV4 0x01
|
||||||
#define ADDR_FAMILY_IPV6 0x02
|
#define ADDR_FAMILY_IPV6 0x02
|
||||||
|
@ -29,10 +29,17 @@
|
|||||||
#ifndef _HV_UTILREG_H_
|
#ifndef _HV_UTILREG_H_
|
||||||
#define _HV_UTILREG_H_
|
#define _HV_UTILREG_H_
|
||||||
|
|
||||||
#define HV_S_OK 0x00000000
|
/*
|
||||||
#define HV_E_FAIL 0x80004005
|
* Some Hyper-V status codes.
|
||||||
#define HV_ERROR_NOT_SUPPORTED 0x80070032
|
*/
|
||||||
#define HV_ERROR_MACHINE_LOCKED 0x800704F7
|
#define HV_S_OK 0x00000000
|
||||||
|
#define HV_E_FAIL 0x80004005
|
||||||
|
#define HV_S_CONT 0x80070103
|
||||||
|
#define HV_ERROR_NOT_SUPPORTED 0x80070032
|
||||||
|
#define HV_ERROR_MACHINE_LOCKED 0x800704F7
|
||||||
|
#define HV_ERROR_DEVICE_NOT_CONNECTED 0x8007048F
|
||||||
|
#define HV_INVALIDARG 0x80070057
|
||||||
|
#define HV_GUID_NOTFOUND 0x80041002
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common defines for Hyper-V ICs
|
* Common defines for Hyper-V ICs
|
||||||
|
@ -926,28 +926,28 @@ vmbus_chan_recv(struct vmbus_channel *chan, void *data, int *dlen0,
|
|||||||
|
|
||||||
int
|
int
|
||||||
vmbus_chan_recv_pkt(struct vmbus_channel *chan,
|
vmbus_chan_recv_pkt(struct vmbus_channel *chan,
|
||||||
struct vmbus_chanpkt_hdr *pkt0, int *pktlen0)
|
struct vmbus_chanpkt_hdr *pkt, int *pktlen0)
|
||||||
{
|
{
|
||||||
struct vmbus_chanpkt_hdr pkt;
|
int error, pktlen, pkt_hlen;
|
||||||
int error, pktlen;
|
|
||||||
|
|
||||||
error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt));
|
pkt_hlen = sizeof(*pkt);
|
||||||
|
error = vmbus_rxbr_peek(&chan->ch_rxbr, pkt, pkt_hlen);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
|
if (__predict_false(pkt->cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
|
||||||
vmbus_chan_printf(chan, "invalid hlen %u\n", pkt.cph_hlen);
|
vmbus_chan_printf(chan, "invalid hlen %u\n", pkt->cph_hlen);
|
||||||
/* XXX this channel is dead actually. */
|
/* XXX this channel is dead actually. */
|
||||||
return (EIO);
|
return (EIO);
|
||||||
}
|
}
|
||||||
if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) {
|
if (__predict_false(pkt->cph_hlen > pkt->cph_tlen)) {
|
||||||
vmbus_chan_printf(chan, "invalid hlen %u and tlen %u\n",
|
vmbus_chan_printf(chan, "invalid hlen %u and tlen %u\n",
|
||||||
pkt.cph_hlen, pkt.cph_tlen);
|
pkt->cph_hlen, pkt->cph_tlen);
|
||||||
/* XXX this channel is dead actually. */
|
/* XXX this channel is dead actually. */
|
||||||
return (EIO);
|
return (EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
pktlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen);
|
pktlen = VMBUS_CHANPKT_GETLEN(pkt->cph_tlen);
|
||||||
if (*pktlen0 < pktlen) {
|
if (*pktlen0 < pktlen) {
|
||||||
/* Return the size of this packet. */
|
/* Return the size of this packet. */
|
||||||
*pktlen0 = pktlen;
|
*pktlen0 = pktlen;
|
||||||
@ -955,8 +955,12 @@ vmbus_chan_recv_pkt(struct vmbus_channel *chan,
|
|||||||
}
|
}
|
||||||
*pktlen0 = pktlen;
|
*pktlen0 = pktlen;
|
||||||
|
|
||||||
/* Include packet header */
|
/*
|
||||||
error = vmbus_rxbr_read(&chan->ch_rxbr, pkt0, pktlen, 0);
|
* Skip the fixed-size packet header, which has been filled
|
||||||
|
* by the above vmbus_rxbr_peek().
|
||||||
|
*/
|
||||||
|
error = vmbus_rxbr_read(&chan->ch_rxbr, pkt + 1,
|
||||||
|
pktlen - pkt_hlen, pkt_hlen);
|
||||||
KASSERT(!error, ("vmbus_rxbr_read failed"));
|
KASSERT(!error, ("vmbus_rxbr_read failed"));
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -1530,65 +1534,6 @@ vmbus_chan_destroy_all(struct vmbus_softc *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The channel whose vcpu binding is closest to the currect vcpu will
|
|
||||||
* be selected.
|
|
||||||
* If no multi-channel, always select primary channel.
|
|
||||||
*/
|
|
||||||
struct vmbus_channel *
|
|
||||||
vmbus_chan_cpu2chan(struct vmbus_channel *prichan, int cpu)
|
|
||||||
{
|
|
||||||
struct vmbus_channel *sel, *chan;
|
|
||||||
uint32_t vcpu, sel_dist;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpuid %d", cpu));
|
|
||||||
if (TAILQ_EMPTY(&prichan->ch_subchans))
|
|
||||||
return prichan;
|
|
||||||
|
|
||||||
vcpu = VMBUS_PCPU_GET(prichan->ch_vmbus, vcpuid, cpu);
|
|
||||||
|
|
||||||
#define CHAN_VCPU_DIST(ch, vcpu) \
|
|
||||||
(((ch)->ch_vcpuid > (vcpu)) ? \
|
|
||||||
((ch)->ch_vcpuid - (vcpu)) : ((vcpu) - (ch)->ch_vcpuid))
|
|
||||||
|
|
||||||
#define CHAN_SELECT(ch) \
|
|
||||||
do { \
|
|
||||||
sel = ch; \
|
|
||||||
sel_dist = CHAN_VCPU_DIST(ch, vcpu); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
CHAN_SELECT(prichan);
|
|
||||||
|
|
||||||
mtx_lock(&prichan->ch_subchan_lock);
|
|
||||||
TAILQ_FOREACH(chan, &prichan->ch_subchans, ch_sublink) {
|
|
||||||
uint32_t dist;
|
|
||||||
|
|
||||||
KASSERT(chan->ch_stflags & VMBUS_CHAN_ST_OPENED,
|
|
||||||
("chan%u is not opened", chan->ch_id));
|
|
||||||
|
|
||||||
if (chan->ch_vcpuid == vcpu) {
|
|
||||||
/* Exact match; done */
|
|
||||||
CHAN_SELECT(chan);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dist = CHAN_VCPU_DIST(chan, vcpu);
|
|
||||||
if (sel_dist <= dist) {
|
|
||||||
/* Far or same distance; skip */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Select the closer channel. */
|
|
||||||
CHAN_SELECT(chan);
|
|
||||||
}
|
|
||||||
mtx_unlock(&prichan->ch_subchan_lock);
|
|
||||||
|
|
||||||
#undef CHAN_SELECT
|
|
||||||
#undef CHAN_VCPU_DIST
|
|
||||||
|
|
||||||
return sel;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vmbus_channel **
|
struct vmbus_channel **
|
||||||
vmbus_subchan_get(struct vmbus_channel *pri_chan, int subchan_cnt)
|
vmbus_subchan_get(struct vmbus_channel *pri_chan, int subchan_cnt)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intel fourth generation mobile cpus integrated I2C device, smbus driver.
|
* Intel fourth generation mobile cpus integrated I2C device.
|
||||||
*
|
*
|
||||||
* See ig4_reg.h for datasheet reference and notes.
|
* See ig4_reg.h for datasheet reference and notes.
|
||||||
* See ig4_var.h for locking semantics.
|
* See ig4_var.h for locking semantics.
|
||||||
@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <dev/pci/pcivar.h>
|
#include <dev/pci/pcivar.h>
|
||||||
#include <dev/pci/pcireg.h>
|
#include <dev/pci/pcireg.h>
|
||||||
#include <dev/smbus/smbconf.h>
|
|
||||||
#include <dev/iicbus/iicbus.h>
|
#include <dev/iicbus/iicbus.h>
|
||||||
#include <dev/iicbus/iiconf.h>
|
#include <dev/iicbus/iiconf.h>
|
||||||
|
|
||||||
@ -236,18 +235,13 @@ data_read(ig4iic_softc_t *sc)
|
|||||||
* the target address for when the controller later issues a START.
|
* the target address for when the controller later issues a START.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
set_slave_addr(ig4iic_softc_t *sc, uint8_t slave, int trans_op)
|
set_slave_addr(ig4iic_softc_t *sc, uint8_t slave)
|
||||||
{
|
{
|
||||||
uint32_t tar;
|
uint32_t tar;
|
||||||
uint32_t ctl;
|
uint32_t ctl;
|
||||||
int use_10bit;
|
int use_10bit;
|
||||||
|
|
||||||
use_10bit = sc->use_10bit;
|
use_10bit = 0;
|
||||||
if (trans_op & SMB_TRANS_7BIT)
|
|
||||||
use_10bit = 0;
|
|
||||||
if (trans_op & SMB_TRANS_10BIT)
|
|
||||||
use_10bit = 1;
|
|
||||||
|
|
||||||
if (sc->slave_valid && sc->last_slave == slave &&
|
if (sc->slave_valid && sc->last_slave == slave &&
|
||||||
sc->use_10bit == use_10bit) {
|
sc->use_10bit == use_10bit) {
|
||||||
return;
|
return;
|
||||||
@ -290,209 +284,13 @@ set_slave_addr(ig4iic_softc_t *sc, uint8_t slave, int trans_op)
|
|||||||
sc->last_slave = slave;
|
sc->last_slave = slave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Issue START with byte command, possible count, and a variable length
|
|
||||||
* read or write buffer, then possible turn-around read. The read also
|
|
||||||
* has a possible count received.
|
|
||||||
*
|
|
||||||
* For SMBUS -
|
|
||||||
*
|
|
||||||
* Quick: START+ADDR+RD/WR STOP
|
|
||||||
*
|
|
||||||
* Normal: START+ADDR+WR CMD DATA..DATA STOP
|
|
||||||
*
|
|
||||||
* START+ADDR+RD CMD
|
|
||||||
* RESTART+ADDR RDATA..RDATA STOP
|
|
||||||
* (can also be used for I2C transactions)
|
|
||||||
*
|
|
||||||
* Process Call: START+ADDR+WR CMD DATAL DATAH
|
|
||||||
* RESTART+ADDR+RD RDATAL RDATAH STOP
|
|
||||||
*
|
|
||||||
* Block: START+ADDR+RD CMD
|
|
||||||
* RESTART+ADDR+RD RCOUNT DATA... STOP
|
|
||||||
*
|
|
||||||
* START+ADDR+WR CMD
|
|
||||||
* RESTART+ADDR+WR WCOUNT DATA... STOP
|
|
||||||
*
|
|
||||||
* For I2C - basically, no *COUNT fields, possibly no *CMD field. If the
|
|
||||||
* sender needs to issue a 2-byte command it will incorporate it
|
|
||||||
* into the write buffer and also set NOCMD.
|
|
||||||
*
|
|
||||||
* Generally speaking, the START+ADDR / RESTART+ADDR is handled automatically
|
|
||||||
* by the controller at the beginning of a command sequence or on a data
|
|
||||||
* direction turn-around, and we only need to tell it when to issue the STOP.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
smb_transaction(ig4iic_softc_t *sc, char cmd, int op,
|
|
||||||
char *wbuf, int wcount, char *rbuf, int rcount, int *actualp)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
int unit;
|
|
||||||
uint32_t last;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Debugging - dump registers
|
|
||||||
*/
|
|
||||||
if (ig4_dump) {
|
|
||||||
unit = device_get_unit(sc->dev);
|
|
||||||
if (ig4_dump & (1 << unit)) {
|
|
||||||
ig4_dump &= ~(1 << unit);
|
|
||||||
ig4iic_dump(sc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Issue START or RESTART with next data byte, clear any previous
|
|
||||||
* abort condition that may have been holding the txfifo in reset.
|
|
||||||
*/
|
|
||||||
last = IG4_DATA_RESTART;
|
|
||||||
reg_read(sc, IG4_REG_CLR_TX_ABORT);
|
|
||||||
if (actualp)
|
|
||||||
*actualp = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Issue command if not told otherwise (smbus).
|
|
||||||
*/
|
|
||||||
if ((op & SMB_TRANS_NOCMD) == 0) {
|
|
||||||
error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
|
|
||||||
if (error)
|
|
||||||
goto done;
|
|
||||||
last |= (u_char)cmd;
|
|
||||||
if (wcount == 0 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0)
|
|
||||||
last |= IG4_DATA_STOP;
|
|
||||||
reg_write(sc, IG4_REG_DATA_CMD, last);
|
|
||||||
last = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Clean out any previously received data.
|
|
||||||
*/
|
|
||||||
if (sc->rpos != sc->rnext &&
|
|
||||||
(op & SMB_TRANS_NOREPORT) == 0) {
|
|
||||||
device_printf(sc->dev,
|
|
||||||
"discarding %d bytes of spurious data\n",
|
|
||||||
sc->rnext - sc->rpos);
|
|
||||||
}
|
|
||||||
sc->rpos = 0;
|
|
||||||
sc->rnext = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If writing and not told otherwise, issue the write count (smbus).
|
|
||||||
*/
|
|
||||||
if (wcount && (op & SMB_TRANS_NOCNT) == 0) {
|
|
||||||
error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
|
|
||||||
if (error)
|
|
||||||
goto done;
|
|
||||||
last |= (u_char)cmd;
|
|
||||||
reg_write(sc, IG4_REG_DATA_CMD, last);
|
|
||||||
last = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bulk write (i2c)
|
|
||||||
*/
|
|
||||||
while (wcount) {
|
|
||||||
error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
|
|
||||||
if (error)
|
|
||||||
goto done;
|
|
||||||
last |= (u_char)*wbuf;
|
|
||||||
if (wcount == 1 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0)
|
|
||||||
last |= IG4_DATA_STOP;
|
|
||||||
reg_write(sc, IG4_REG_DATA_CMD, last);
|
|
||||||
--wcount;
|
|
||||||
++wbuf;
|
|
||||||
last = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Issue reads to xmit FIFO (strange, I know) to tell the controller
|
|
||||||
* to clock in data. At the moment just issue one read ahead to
|
|
||||||
* pipeline the incoming data.
|
|
||||||
*
|
|
||||||
* NOTE: In the case of NOCMD and wcount == 0 we still issue a
|
|
||||||
* RESTART here, even if the data direction has not changed
|
|
||||||
* from the previous CHAINing call. This we force the RESTART.
|
|
||||||
* (A new START is issued automatically by the controller in
|
|
||||||
* the other nominal cases such as a data direction change or
|
|
||||||
* a previous STOP was issued).
|
|
||||||
*
|
|
||||||
* If this will be the last byte read we must also issue the STOP
|
|
||||||
* at the end of the read.
|
|
||||||
*/
|
|
||||||
if (rcount) {
|
|
||||||
last = IG4_DATA_RESTART | IG4_DATA_COMMAND_RD;
|
|
||||||
if (rcount == 1 &&
|
|
||||||
(op & (SMB_TRANS_NOSTOP | SMB_TRANS_NOCNT)) ==
|
|
||||||
SMB_TRANS_NOCNT) {
|
|
||||||
last |= IG4_DATA_STOP;
|
|
||||||
}
|
|
||||||
reg_write(sc, IG4_REG_DATA_CMD, last);
|
|
||||||
last = IG4_DATA_COMMAND_RD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bulk read (i2c) and count field handling (smbus)
|
|
||||||
*/
|
|
||||||
while (rcount) {
|
|
||||||
/*
|
|
||||||
* Maintain a pipeline by queueing the allowance for the next
|
|
||||||
* read before waiting for the current read.
|
|
||||||
*/
|
|
||||||
if (rcount > 1) {
|
|
||||||
if (op & SMB_TRANS_NOCNT)
|
|
||||||
last = (rcount == 2) ? IG4_DATA_STOP : 0;
|
|
||||||
else
|
|
||||||
last = 0;
|
|
||||||
reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD |
|
|
||||||
last);
|
|
||||||
}
|
|
||||||
error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
|
|
||||||
if (error) {
|
|
||||||
if ((op & SMB_TRANS_NOREPORT) == 0) {
|
|
||||||
device_printf(sc->dev,
|
|
||||||
"rx timeout addr 0x%02x\n",
|
|
||||||
sc->last_slave);
|
|
||||||
}
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
last = data_read(sc);
|
|
||||||
|
|
||||||
if (op & SMB_TRANS_NOCNT) {
|
|
||||||
*rbuf = (u_char)last;
|
|
||||||
++rbuf;
|
|
||||||
--rcount;
|
|
||||||
if (actualp)
|
|
||||||
++*actualp;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Handle count field (smbus), which is not part of
|
|
||||||
* the rcount'ed buffer. The first read data in a
|
|
||||||
* bulk transfer is the count.
|
|
||||||
*
|
|
||||||
* XXX if rcount is loaded as 0 how do I generate a
|
|
||||||
* STOP now without issuing another RD or WR?
|
|
||||||
*/
|
|
||||||
if (rcount > (u_char)last)
|
|
||||||
rcount = (u_char)last;
|
|
||||||
op |= SMB_TRANS_NOCNT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error = 0;
|
|
||||||
done:
|
|
||||||
/* XXX wait for xmit buffer to become empty */
|
|
||||||
last = reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
|
|
||||||
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IICBUS API FUNCTIONS
|
* IICBUS API FUNCTIONS
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave)
|
ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave)
|
||||||
{
|
{
|
||||||
/* XXX 10-bit address support? */
|
set_slave_addr(sc, slave >> 1);
|
||||||
set_slave_addr(sc, slave >> 1, 0);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,7 +504,7 @@ ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
|||||||
/* TODO handle speed configuration? */
|
/* TODO handle speed configuration? */
|
||||||
if (oldaddr != NULL)
|
if (oldaddr != NULL)
|
||||||
*oldaddr = sc->last_slave << 1;
|
*oldaddr = sc->last_slave << 1;
|
||||||
set_slave_addr(sc, addr >> 1, 0);
|
set_slave_addr(sc, addr >> 1);
|
||||||
if (addr == IIC_UNKNOWN)
|
if (addr == IIC_UNKNOWN)
|
||||||
sc->slave_valid = false;
|
sc->slave_valid = false;
|
||||||
|
|
||||||
@ -716,8 +514,6 @@ ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SMBUS API FUNCTIONS
|
|
||||||
*
|
|
||||||
* Called from ig4iic_pci_attach/detach()
|
* Called from ig4iic_pci_attach/detach()
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@ -836,7 +632,6 @@ ig4iic_start(void *xdev)
|
|||||||
|
|
||||||
config_intrhook_disestablish(&sc->enum_hook);
|
config_intrhook_disestablish(&sc->enum_hook);
|
||||||
|
|
||||||
/* Attach us to the smbus */
|
|
||||||
error = bus_generic_attach(sc->dev);
|
error = bus_generic_attach(sc->dev);
|
||||||
if (error) {
|
if (error) {
|
||||||
device_printf(sc->dev,
|
device_printf(sc->dev,
|
||||||
@ -844,8 +639,6 @@ ig4iic_start(void *xdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ig4iic_detach(ig4iic_softc_t *sc)
|
ig4iic_detach(ig4iic_softc_t *sc)
|
||||||
{
|
{
|
||||||
@ -874,276 +667,6 @@ ig4iic_detach(ig4iic_softc_t *sc)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
ig4iic_smb_callback(device_t dev, int index, void *data)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
switch (index) {
|
|
||||||
case SMB_REQUEST_BUS:
|
|
||||||
error = 0;
|
|
||||||
break;
|
|
||||||
case SMB_RELEASE_BUS:
|
|
||||||
error = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = SMB_EABORT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Quick command. i.e. START + cmd + R/W + STOP and no data. It is
|
|
||||||
* unclear to me how I could implement this with the intel i2c controller
|
|
||||||
* because the controller sends STARTs and STOPs automatically with data.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ig4iic_smb_quick(device_t dev, u_char slave, int how)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (SMB_ENOTSUPP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Incremental send byte without stop (?). It is unclear why the slave
|
|
||||||
* address is specified if this presumably is used in combination with
|
|
||||||
* ig4iic_smb_quick().
|
|
||||||
*
|
|
||||||
* (Also, how would this work anyway? Issue the last byte with writeb()?)
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ig4iic_smb_sendb(device_t dev, u_char slave, char byte)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
uint32_t cmd;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, 0);
|
|
||||||
cmd = byte;
|
|
||||||
if (wait_status(sc, IG4_STATUS_TX_NOTFULL) == 0) {
|
|
||||||
reg_write(sc, IG4_REG_DATA_CMD, cmd);
|
|
||||||
error = 0;
|
|
||||||
} else {
|
|
||||||
error = SMB_ETIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Incremental receive byte without stop (?). It is unclear why the slave
|
|
||||||
* address is specified if this presumably is used in combination with
|
|
||||||
* ig4iic_smb_quick().
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ig4iic_smb_recvb(device_t dev, u_char slave, char *byte)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, 0);
|
|
||||||
reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD);
|
|
||||||
if (wait_status(sc, IG4_STATUS_RX_NOTEMPTY) == 0) {
|
|
||||||
*byte = data_read(sc);
|
|
||||||
error = 0;
|
|
||||||
} else {
|
|
||||||
*byte = 0;
|
|
||||||
error = SMB_ETIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write command and single byte in transaction.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ig4iic_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, 0);
|
|
||||||
error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
|
|
||||||
&byte, 1, NULL, 0, NULL);
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write command and single word in transaction.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ig4iic_smb_writew(device_t dev, u_char slave, char cmd, short word)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
char buf[2];
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, 0);
|
|
||||||
buf[0] = word & 0xFF;
|
|
||||||
buf[1] = word >> 8;
|
|
||||||
error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
|
|
||||||
buf, 2, NULL, 0, NULL);
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* write command and read single byte in transaction.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ig4iic_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, 0);
|
|
||||||
error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
|
|
||||||
NULL, 0, byte, 1, NULL);
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* write command and read word in transaction.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ig4iic_smb_readw(device_t dev, u_char slave, char cmd, short *word)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
char buf[2];
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, 0);
|
|
||||||
if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
|
|
||||||
NULL, 0, buf, 2, NULL)) == 0) {
|
|
||||||
*word = (u_char)buf[0] | ((u_char)buf[1] << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* write command and word and read word in transaction
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ig4iic_smb_pcall(device_t dev, u_char slave, char cmd,
|
|
||||||
short sdata, short *rdata)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
char rbuf[2];
|
|
||||||
char wbuf[2];
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, 0);
|
|
||||||
wbuf[0] = sdata & 0xFF;
|
|
||||||
wbuf[1] = sdata >> 8;
|
|
||||||
if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
|
|
||||||
wbuf, 2, rbuf, 2, NULL)) == 0) {
|
|
||||||
*rdata = (u_char)rbuf[0] | ((u_char)rbuf[1] << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ig4iic_smb_bwrite(device_t dev, u_char slave, char cmd,
|
|
||||||
u_char wcount, char *buf)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, 0);
|
|
||||||
error = smb_transaction(sc, cmd, 0,
|
|
||||||
buf, wcount, NULL, 0, NULL);
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ig4iic_smb_bread(device_t dev, u_char slave, char cmd,
|
|
||||||
u_char *countp_char, char *buf)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
int rcount = *countp_char;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, 0);
|
|
||||||
error = smb_transaction(sc, cmd, 0,
|
|
||||||
NULL, 0, buf, rcount, &rcount);
|
|
||||||
*countp_char = rcount;
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ig4iic_smb_trans(device_t dev, int slave, char cmd, int op,
|
|
||||||
char *wbuf, int wcount, char *rbuf, int rcount,
|
|
||||||
int *actualp)
|
|
||||||
{
|
|
||||||
ig4iic_softc_t *sc = device_get_softc(dev);
|
|
||||||
int error;
|
|
||||||
|
|
||||||
sx_xlock(&sc->call_lock);
|
|
||||||
mtx_lock(&sc->io_lock);
|
|
||||||
|
|
||||||
set_slave_addr(sc, slave, op);
|
|
||||||
error = smb_transaction(sc, cmd, op,
|
|
||||||
wbuf, wcount, rbuf, rcount, actualp);
|
|
||||||
|
|
||||||
mtx_unlock(&sc->io_lock);
|
|
||||||
sx_xunlock(&sc->call_lock);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupt Operation, see ig4_var.h for locking semantics.
|
* Interrupt Operation, see ig4_var.h for locking semantics.
|
||||||
*/
|
*/
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intel fourth generation mobile cpus integrated I2C device, smbus driver.
|
* Intel fourth generation mobile cpus integrated I2C device.
|
||||||
*
|
*
|
||||||
* See ig4_reg.h for datasheet reference and notes.
|
* See ig4_reg.h for datasheet reference and notes.
|
||||||
*/
|
*/
|
||||||
@ -59,11 +59,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <dev/pci/pcivar.h>
|
#include <dev/pci/pcivar.h>
|
||||||
#include <dev/pci/pcireg.h>
|
#include <dev/pci/pcireg.h>
|
||||||
#include <dev/smbus/smbconf.h>
|
|
||||||
#include <dev/iicbus/iiconf.h>
|
#include <dev/iicbus/iiconf.h>
|
||||||
|
|
||||||
#include "smbus_if.h"
|
|
||||||
|
|
||||||
#include <dev/ichiic/ig4_reg.h>
|
#include <dev/ichiic/ig4_reg.h>
|
||||||
#include <dev/ichiic/ig4_var.h>
|
#include <dev/ichiic/ig4_var.h>
|
||||||
|
|
||||||
@ -167,20 +164,6 @@ static device_method_t ig4iic_pci_methods[] = {
|
|||||||
DEVMETHOD(device_attach, ig4iic_pci_attach),
|
DEVMETHOD(device_attach, ig4iic_pci_attach),
|
||||||
DEVMETHOD(device_detach, ig4iic_pci_detach),
|
DEVMETHOD(device_detach, ig4iic_pci_detach),
|
||||||
|
|
||||||
/* SMBus methods from ig4_smb.c */
|
|
||||||
DEVMETHOD(smbus_callback, ig4iic_smb_callback),
|
|
||||||
DEVMETHOD(smbus_quick, ig4iic_smb_quick),
|
|
||||||
DEVMETHOD(smbus_sendb, ig4iic_smb_sendb),
|
|
||||||
DEVMETHOD(smbus_recvb, ig4iic_smb_recvb),
|
|
||||||
DEVMETHOD(smbus_writeb, ig4iic_smb_writeb),
|
|
||||||
DEVMETHOD(smbus_writew, ig4iic_smb_writew),
|
|
||||||
DEVMETHOD(smbus_readb, ig4iic_smb_readb),
|
|
||||||
DEVMETHOD(smbus_readw, ig4iic_smb_readw),
|
|
||||||
DEVMETHOD(smbus_pcall, ig4iic_smb_pcall),
|
|
||||||
DEVMETHOD(smbus_bwrite, ig4iic_smb_bwrite),
|
|
||||||
DEVMETHOD(smbus_bread, ig4iic_smb_bread),
|
|
||||||
DEVMETHOD(smbus_trans, ig4iic_smb_trans),
|
|
||||||
|
|
||||||
DEVMETHOD(iicbus_transfer, ig4iic_transfer),
|
DEVMETHOD(iicbus_transfer, ig4iic_transfer),
|
||||||
DEVMETHOD(iicbus_reset, ig4iic_reset),
|
DEVMETHOD(iicbus_reset, ig4iic_reset),
|
||||||
DEVMETHOD(iicbus_callback, iicbus_null_callback),
|
DEVMETHOD(iicbus_callback, iicbus_null_callback),
|
||||||
@ -199,6 +182,5 @@ static devclass_t ig4iic_pci_devclass;
|
|||||||
DRIVER_MODULE_ORDERED(ig4iic, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0,
|
DRIVER_MODULE_ORDERED(ig4iic, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0,
|
||||||
SI_ORDER_ANY);
|
SI_ORDER_ANY);
|
||||||
MODULE_DEPEND(ig4iic, pci, 1, 1, 1);
|
MODULE_DEPEND(ig4iic, pci, 1, 1, 1);
|
||||||
MODULE_DEPEND(ig4iic, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
|
||||||
MODULE_DEPEND(ig4iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
MODULE_DEPEND(ig4iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||||
MODULE_VERSION(ig4iic, 1);
|
MODULE_VERSION(ig4iic, 1);
|
||||||
|
@ -47,14 +47,14 @@
|
|||||||
* I am also using the linux driver code as a reference to help resolve any
|
* I am also using the linux driver code as a reference to help resolve any
|
||||||
* issues that come. These will be specifically documented in the code.
|
* issues that come. These will be specifically documented in the code.
|
||||||
*
|
*
|
||||||
* Please see protocol notes in section 5.21. This controller is an I2C
|
* This controller is an I2C master only and cannot act as a slave. The IO
|
||||||
* master only and cannot act as a slave. The IO voltage should be set by
|
* voltage should be set by the BIOS. Standard (100Kb/s) and Fast (400Kb/s)
|
||||||
* the BIOS. Standard (100Kb/s) and Fast (400Kb/s) and fast mode plus
|
* and fast mode plus (1MB/s) is supported. High speed mode (3.4 MB/s) is NOT
|
||||||
* (1MB/s) is supported. High speed mode (3.4 MB/s) is NOT supported.
|
* supported.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _BUS_SMBUS_INTELGEN4_IG4_REG_H_
|
#ifndef _ICHIIC_IG4_REG_H_
|
||||||
#define _BUS_SMBUS_INTELGEN4_IG4_REG_H_
|
#define _ICHIIC_IG4_REG_H_
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 22.2 MMIO registers can be accessed through BAR0 in PCI mode or through
|
* 22.2 MMIO registers can be accessed through BAR0 in PCI mode or through
|
||||||
@ -619,4 +619,4 @@
|
|||||||
#define IG4_SWLTR_SNOOP_VALUE_DECODE(v) ((v) & 0x3F)
|
#define IG4_SWLTR_SNOOP_VALUE_DECODE(v) ((v) & 0x3F)
|
||||||
#define IG4_SWLTR_SNOOP_VALUE_ENCODE(v) ((v) & 0x3F)
|
#define IG4_SWLTR_SNOOP_VALUE_ENCODE(v) ((v) & 0x3F)
|
||||||
|
|
||||||
#endif
|
#endif /* _ICHIIC_IG4_REG_H_ */
|
||||||
|
@ -35,13 +35,12 @@
|
|||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _BUS_SMBUS_INTELGEN4_IG4_VAR_H_
|
#ifndef _ICHIIC_IG4_VAR_H_
|
||||||
#define _BUS_SMBUS_INTELGEN4_IG4_VAR_H_
|
#define _ICHIIC_IG4_VAR_H_
|
||||||
|
|
||||||
#include "bus_if.h"
|
#include "bus_if.h"
|
||||||
#include "device_if.h"
|
#include "device_if.h"
|
||||||
#include "pci_if.h"
|
#include "pci_if.h"
|
||||||
#include "smbus_if.h"
|
|
||||||
#include "iicbus_if.h"
|
#include "iicbus_if.h"
|
||||||
|
|
||||||
#define IG4_RBUFSIZE 128
|
#define IG4_RBUFSIZE 128
|
||||||
@ -75,12 +74,12 @@ struct ig4iic_softc {
|
|||||||
/*
|
/*
|
||||||
* Locking semantics:
|
* Locking semantics:
|
||||||
*
|
*
|
||||||
* Functions implementing the smbus interface that interact
|
* Functions implementing the icbus interface that interact
|
||||||
* with the controller acquire an exclusive lock on call_lock
|
* with the controller acquire an exclusive lock on call_lock
|
||||||
* to prevent interleaving of calls to the interface and a lock on
|
* to prevent interleaving of calls to the interface and a lock on
|
||||||
* io_lock right afterwards, to synchronize controller I/O activity.
|
* io_lock right afterwards, to synchronize controller I/O activity.
|
||||||
*
|
*
|
||||||
* The interrupt handler can only read data while no ig4iic_smb_* call
|
* The interrupt handler can only read data while no iicbus call
|
||||||
* is in progress or while io_lock is dropped during mtx_sleep in
|
* is in progress or while io_lock is dropped during mtx_sleep in
|
||||||
* wait_status and set_controller. It is safe to drop io_lock in those
|
* wait_status and set_controller. It is safe to drop io_lock in those
|
||||||
* places, because the interrupt handler only accesses those registers:
|
* places, because the interrupt handler only accesses those registers:
|
||||||
@ -91,7 +90,7 @@ struct ig4iic_softc {
|
|||||||
*
|
*
|
||||||
* Locking outside of those places is required to make the content
|
* Locking outside of those places is required to make the content
|
||||||
* of rpos/rnext predictable (e.g. whenever data_read is called and in
|
* of rpos/rnext predictable (e.g. whenever data_read is called and in
|
||||||
* smb_transaction).
|
* ig4iic_transfer).
|
||||||
*/
|
*/
|
||||||
struct sx call_lock;
|
struct sx call_lock;
|
||||||
struct mtx io_lock;
|
struct mtx io_lock;
|
||||||
@ -103,20 +102,8 @@ typedef struct ig4iic_softc ig4iic_softc_t;
|
|||||||
int ig4iic_attach(ig4iic_softc_t *sc);
|
int ig4iic_attach(ig4iic_softc_t *sc);
|
||||||
int ig4iic_detach(ig4iic_softc_t *sc);
|
int ig4iic_detach(ig4iic_softc_t *sc);
|
||||||
|
|
||||||
/* SMBus methods */
|
/* iicbus methods */
|
||||||
extern smbus_callback_t ig4iic_smb_callback;
|
|
||||||
extern smbus_quick_t ig4iic_smb_quick;
|
|
||||||
extern smbus_sendb_t ig4iic_smb_sendb;
|
|
||||||
extern smbus_recvb_t ig4iic_smb_recvb;
|
|
||||||
extern smbus_writeb_t ig4iic_smb_writeb;
|
|
||||||
extern smbus_writew_t ig4iic_smb_writew;
|
|
||||||
extern smbus_readb_t ig4iic_smb_readb;
|
|
||||||
extern smbus_readw_t ig4iic_smb_readw;
|
|
||||||
extern smbus_pcall_t ig4iic_smb_pcall;
|
|
||||||
extern smbus_bwrite_t ig4iic_smb_bwrite;
|
|
||||||
extern smbus_bread_t ig4iic_smb_bread;
|
|
||||||
extern smbus_trans_t ig4iic_smb_trans;
|
|
||||||
extern iicbus_transfer_t ig4iic_transfer;
|
extern iicbus_transfer_t ig4iic_transfer;
|
||||||
extern iicbus_reset_t ig4iic_reset;
|
extern iicbus_reset_t ig4iic_reset;
|
||||||
|
|
||||||
#endif
|
#endif /* _ICHIIC_IG4_VAR_H_ */
|
||||||
|
@ -63,7 +63,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define BUS_SPACE_MAXADDR_40BIT 0xFFFFFFFFFFULL
|
#define BUS_SPACE_MAXADDR_40BIT 0xFFFFFFFFFFULL
|
||||||
#endif
|
#endif
|
||||||
#define IOAT_REFLK (&ioat->submit_lock)
|
#define IOAT_REFLK (&ioat->submit_lock)
|
||||||
#define IOAT_SHRINK_PERIOD (10 * hz)
|
|
||||||
|
|
||||||
static int ioat_probe(device_t device);
|
static int ioat_probe(device_t device);
|
||||||
static int ioat_attach(device_t device);
|
static int ioat_attach(device_t device);
|
||||||
@ -82,23 +81,14 @@ static void ioat_process_events(struct ioat_softc *ioat);
|
|||||||
static inline uint32_t ioat_get_active(struct ioat_softc *ioat);
|
static inline uint32_t ioat_get_active(struct ioat_softc *ioat);
|
||||||
static inline uint32_t ioat_get_ring_space(struct ioat_softc *ioat);
|
static inline uint32_t ioat_get_ring_space(struct ioat_softc *ioat);
|
||||||
static void ioat_free_ring(struct ioat_softc *, uint32_t size,
|
static void ioat_free_ring(struct ioat_softc *, uint32_t size,
|
||||||
struct ioat_descriptor **);
|
struct ioat_descriptor *);
|
||||||
static void ioat_free_ring_entry(struct ioat_softc *ioat,
|
|
||||||
struct ioat_descriptor *desc);
|
|
||||||
static struct ioat_descriptor *ioat_alloc_ring_entry(struct ioat_softc *,
|
|
||||||
int mflags);
|
|
||||||
static int ioat_reserve_space(struct ioat_softc *, uint32_t, int mflags);
|
static int ioat_reserve_space(struct ioat_softc *, uint32_t, int mflags);
|
||||||
static struct ioat_descriptor *ioat_get_ring_entry(struct ioat_softc *ioat,
|
static union ioat_hw_descriptor *ioat_get_descriptor(struct ioat_softc *,
|
||||||
|
uint32_t index);
|
||||||
|
static struct ioat_descriptor *ioat_get_ring_entry(struct ioat_softc *,
|
||||||
uint32_t index);
|
uint32_t index);
|
||||||
static struct ioat_descriptor **ioat_prealloc_ring(struct ioat_softc *,
|
|
||||||
uint32_t size, boolean_t need_dscr, int mflags);
|
|
||||||
static int ring_grow(struct ioat_softc *, uint32_t oldorder,
|
|
||||||
struct ioat_descriptor **);
|
|
||||||
static int ring_shrink(struct ioat_softc *, uint32_t oldorder,
|
|
||||||
struct ioat_descriptor **);
|
|
||||||
static void ioat_halted_debug(struct ioat_softc *, uint32_t);
|
static void ioat_halted_debug(struct ioat_softc *, uint32_t);
|
||||||
static void ioat_poll_timer_callback(void *arg);
|
static void ioat_poll_timer_callback(void *arg);
|
||||||
static void ioat_shrink_timer_callback(void *arg);
|
|
||||||
static void dump_descriptor(void *hw_desc);
|
static void dump_descriptor(void *hw_desc);
|
||||||
static void ioat_submit_single(struct ioat_softc *ioat);
|
static void ioat_submit_single(struct ioat_softc *ioat);
|
||||||
static void ioat_comp_update_map(void *arg, bus_dma_segment_t *seg, int nseg,
|
static void ioat_comp_update_map(void *arg, bus_dma_segment_t *seg, int nseg,
|
||||||
@ -135,6 +125,10 @@ int g_ioat_debug_level = 0;
|
|||||||
SYSCTL_INT(_hw_ioat, OID_AUTO, debug_level, CTLFLAG_RWTUN, &g_ioat_debug_level,
|
SYSCTL_INT(_hw_ioat, OID_AUTO, debug_level, CTLFLAG_RWTUN, &g_ioat_debug_level,
|
||||||
0, "Set log level (0-3) for ioat(4). Higher is more verbose.");
|
0, "Set log level (0-3) for ioat(4). Higher is more verbose.");
|
||||||
|
|
||||||
|
unsigned g_ioat_ring_order = 13;
|
||||||
|
SYSCTL_UINT(_hw_ioat, OID_AUTO, ring_order, CTLFLAG_RDTUN, &g_ioat_ring_order,
|
||||||
|
0, "Set IOAT ring order. (1 << this) == ring size.");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OS <-> Driver interface structures
|
* OS <-> Driver interface structures
|
||||||
*/
|
*/
|
||||||
@ -336,7 +330,6 @@ ioat_detach(device_t device)
|
|||||||
|
|
||||||
ioat_teardown_intr(ioat);
|
ioat_teardown_intr(ioat);
|
||||||
callout_drain(&ioat->poll_timer);
|
callout_drain(&ioat->poll_timer);
|
||||||
callout_drain(&ioat->shrink_timer);
|
|
||||||
|
|
||||||
pci_disable_busmaster(device);
|
pci_disable_busmaster(device);
|
||||||
|
|
||||||
@ -354,7 +347,12 @@ ioat_detach(device_t device)
|
|||||||
bus_dma_tag_destroy(ioat->comp_update_tag);
|
bus_dma_tag_destroy(ioat->comp_update_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bus_dma_tag_destroy(ioat->hw_desc_tag);
|
if (ioat->hw_desc_ring != NULL) {
|
||||||
|
bus_dmamap_unload(ioat->hw_desc_tag, ioat->hw_desc_map);
|
||||||
|
bus_dmamem_free(ioat->hw_desc_tag, ioat->hw_desc_ring,
|
||||||
|
ioat->hw_desc_map);
|
||||||
|
bus_dma_tag_destroy(ioat->hw_desc_tag);
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -388,8 +386,8 @@ ioat_start_channel(struct ioat_softc *ioat)
|
|||||||
|
|
||||||
/* Submit 'NULL' operation manually to avoid quiescing flag */
|
/* Submit 'NULL' operation manually to avoid quiescing flag */
|
||||||
desc = ioat_get_ring_entry(ioat, ioat->head);
|
desc = ioat_get_ring_entry(ioat, ioat->head);
|
||||||
|
hw_desc = &ioat_get_descriptor(ioat, ioat->head)->dma;
|
||||||
dmadesc = &desc->bus_dmadesc;
|
dmadesc = &desc->bus_dmadesc;
|
||||||
hw_desc = desc->u.dma;
|
|
||||||
|
|
||||||
dmadesc->callback_fn = NULL;
|
dmadesc->callback_fn = NULL;
|
||||||
dmadesc->callback_arg = NULL;
|
dmadesc->callback_arg = NULL;
|
||||||
@ -426,9 +424,10 @@ static int
|
|||||||
ioat3_attach(device_t device)
|
ioat3_attach(device_t device)
|
||||||
{
|
{
|
||||||
struct ioat_softc *ioat;
|
struct ioat_softc *ioat;
|
||||||
struct ioat_descriptor **ring;
|
struct ioat_descriptor *ring;
|
||||||
struct ioat_descriptor *next;
|
|
||||||
struct ioat_dma_hw_descriptor *dma_hw_desc;
|
struct ioat_dma_hw_descriptor *dma_hw_desc;
|
||||||
|
void *hw_desc;
|
||||||
|
size_t ringsz;
|
||||||
int i, num_descriptors;
|
int i, num_descriptors;
|
||||||
int error;
|
int error;
|
||||||
uint8_t xfercap;
|
uint8_t xfercap;
|
||||||
@ -453,7 +452,6 @@ ioat3_attach(device_t device)
|
|||||||
mtx_init(&ioat->submit_lock, "ioat_submit", NULL, MTX_DEF);
|
mtx_init(&ioat->submit_lock, "ioat_submit", NULL, MTX_DEF);
|
||||||
mtx_init(&ioat->cleanup_lock, "ioat_cleanup", NULL, MTX_DEF);
|
mtx_init(&ioat->cleanup_lock, "ioat_cleanup", NULL, MTX_DEF);
|
||||||
callout_init(&ioat->poll_timer, 1);
|
callout_init(&ioat->poll_timer, 1);
|
||||||
callout_init(&ioat->shrink_timer, 1);
|
|
||||||
TASK_INIT(&ioat->reset_task, 0, ioat_reset_hw_task, ioat);
|
TASK_INIT(&ioat->reset_task, 0, ioat_reset_hw_task, ioat);
|
||||||
|
|
||||||
/* Establish lock order for Witness */
|
/* Establish lock order for Witness */
|
||||||
@ -462,7 +460,6 @@ ioat3_attach(device_t device)
|
|||||||
mtx_unlock(&ioat->cleanup_lock);
|
mtx_unlock(&ioat->cleanup_lock);
|
||||||
mtx_unlock(&ioat->submit_lock);
|
mtx_unlock(&ioat->submit_lock);
|
||||||
|
|
||||||
ioat->is_resize_pending = FALSE;
|
|
||||||
ioat->is_submitter_processing = FALSE;
|
ioat->is_submitter_processing = FALSE;
|
||||||
ioat->is_completion_pending = FALSE;
|
ioat->is_completion_pending = FALSE;
|
||||||
ioat->is_reset_pending = FALSE;
|
ioat->is_reset_pending = FALSE;
|
||||||
@ -484,37 +481,42 @@ ioat3_attach(device_t device)
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
ioat->ring_size_order = IOAT_MIN_ORDER;
|
ioat->ring_size_order = g_ioat_ring_order;
|
||||||
|
|
||||||
num_descriptors = 1 << ioat->ring_size_order;
|
num_descriptors = 1 << ioat->ring_size_order;
|
||||||
|
ringsz = sizeof(struct ioat_dma_hw_descriptor) * num_descriptors;
|
||||||
|
|
||||||
bus_dma_tag_create(bus_get_dma_tag(ioat->device), 0x40, 0x0,
|
error = bus_dma_tag_create(bus_get_dma_tag(ioat->device),
|
||||||
BUS_SPACE_MAXADDR_40BIT, BUS_SPACE_MAXADDR, NULL, NULL,
|
2 * 1024 * 1024, 0x0, BUS_SPACE_MAXADDR_40BIT, BUS_SPACE_MAXADDR,
|
||||||
sizeof(struct ioat_dma_hw_descriptor), 1,
|
NULL, NULL, ringsz, 1, ringsz, 0, NULL, NULL, &ioat->hw_desc_tag);
|
||||||
sizeof(struct ioat_dma_hw_descriptor), 0, NULL, NULL,
|
if (error != 0)
|
||||||
&ioat->hw_desc_tag);
|
return (error);
|
||||||
|
|
||||||
|
error = bus_dmamem_alloc(ioat->hw_desc_tag, &hw_desc,
|
||||||
|
BUS_DMA_ZERO | BUS_DMA_WAITOK, &ioat->hw_desc_map);
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
error = bus_dmamap_load(ioat->hw_desc_tag, ioat->hw_desc_map, hw_desc,
|
||||||
|
ringsz, ioat_dmamap_cb, &ioat->hw_desc_bus_addr, BUS_DMA_WAITOK);
|
||||||
|
if (error)
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
ioat->hw_desc_ring = hw_desc;
|
||||||
|
|
||||||
ioat->ring = malloc(num_descriptors * sizeof(*ring), M_IOAT,
|
ioat->ring = malloc(num_descriptors * sizeof(*ring), M_IOAT,
|
||||||
M_ZERO | M_WAITOK);
|
M_ZERO | M_WAITOK);
|
||||||
|
|
||||||
ring = ioat->ring;
|
ring = ioat->ring;
|
||||||
for (i = 0; i < num_descriptors; i++) {
|
for (i = 0; i < num_descriptors; i++) {
|
||||||
ring[i] = ioat_alloc_ring_entry(ioat, M_WAITOK);
|
memset(&ring[i].bus_dmadesc, 0, sizeof(ring[i].bus_dmadesc));
|
||||||
if (ring[i] == NULL)
|
ring[i].id = i;
|
||||||
return (ENOMEM);
|
|
||||||
|
|
||||||
ring[i]->id = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_descriptors - 1; i++) {
|
for (i = 0; i < num_descriptors; i++) {
|
||||||
next = ring[i + 1];
|
dma_hw_desc = &ioat->hw_desc_ring[i].dma;
|
||||||
dma_hw_desc = ring[i]->u.dma;
|
dma_hw_desc->next = RING_PHYS_ADDR(ioat, i + 1);
|
||||||
|
|
||||||
dma_hw_desc->next = next->hw_desc_bus_addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ring[i]->u.dma->next = ring[0]->hw_desc_bus_addr;
|
|
||||||
|
|
||||||
ioat->head = ioat->hw_head = 0;
|
ioat->head = ioat->hw_head = 0;
|
||||||
ioat->tail = 0;
|
ioat->tail = 0;
|
||||||
ioat->last_seen = 0;
|
ioat->last_seen = 0;
|
||||||
@ -680,6 +682,12 @@ ioat_process_events(struct ioat_softc *ioat)
|
|||||||
comp_update = *ioat->comp_update;
|
comp_update = *ioat->comp_update;
|
||||||
status = comp_update & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK;
|
status = comp_update & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK;
|
||||||
|
|
||||||
|
if (status < ioat->hw_desc_bus_addr ||
|
||||||
|
status >= ioat->hw_desc_bus_addr + (1 << ioat->ring_size_order) *
|
||||||
|
sizeof(struct ioat_generic_hw_descriptor))
|
||||||
|
panic("Bogus completion address %jx (channel %u)",
|
||||||
|
(uintmax_t)status, ioat->chan_idx);
|
||||||
|
|
||||||
if (status == ioat->last_seen) {
|
if (status == ioat->last_seen) {
|
||||||
/*
|
/*
|
||||||
* If we landed in process_events and nothing has been
|
* If we landed in process_events and nothing has been
|
||||||
@ -690,8 +698,7 @@ ioat_process_events(struct ioat_softc *ioat)
|
|||||||
CTR4(KTR_IOAT, "%s channel=%u hw_status=0x%lx last_seen=0x%lx",
|
CTR4(KTR_IOAT, "%s channel=%u hw_status=0x%lx last_seen=0x%lx",
|
||||||
__func__, ioat->chan_idx, comp_update, ioat->last_seen);
|
__func__, ioat->chan_idx, comp_update, ioat->last_seen);
|
||||||
|
|
||||||
desc = ioat_get_ring_entry(ioat, ioat->tail - 1);
|
while (RING_PHYS_ADDR(ioat, ioat->tail - 1) != status) {
|
||||||
while (desc->hw_desc_bus_addr != status) {
|
|
||||||
desc = ioat_get_ring_entry(ioat, ioat->tail);
|
desc = ioat_get_ring_entry(ioat, ioat->tail);
|
||||||
dmadesc = &desc->bus_dmadesc;
|
dmadesc = &desc->bus_dmadesc;
|
||||||
CTR5(KTR_IOAT, "channel=%u completing desc idx %u (%p) ok cb %p(%p)",
|
CTR5(KTR_IOAT, "channel=%u completing desc idx %u (%p) ok cb %p(%p)",
|
||||||
@ -708,7 +715,7 @@ ioat_process_events(struct ioat_softc *ioat)
|
|||||||
ioat->chan_idx, ioat->head, ioat->tail, ioat_get_active(ioat));
|
ioat->chan_idx, ioat->head, ioat->tail, ioat_get_active(ioat));
|
||||||
|
|
||||||
if (completed != 0) {
|
if (completed != 0) {
|
||||||
ioat->last_seen = desc->hw_desc_bus_addr;
|
ioat->last_seen = RING_PHYS_ADDR(ioat, ioat->tail - 1);
|
||||||
ioat->stats.descriptors_processed += completed;
|
ioat->stats.descriptors_processed += completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,8 +732,6 @@ ioat_process_events(struct ioat_softc *ioat)
|
|||||||
pending = (ioat_get_active(ioat) != 0);
|
pending = (ioat_get_active(ioat) != 0);
|
||||||
if (!pending && ioat->is_completion_pending) {
|
if (!pending && ioat->is_completion_pending) {
|
||||||
ioat->is_completion_pending = FALSE;
|
ioat->is_completion_pending = FALSE;
|
||||||
callout_reset(&ioat->shrink_timer, IOAT_SHRINK_PERIOD,
|
|
||||||
ioat_shrink_timer_callback, ioat);
|
|
||||||
callout_stop(&ioat->poll_timer);
|
callout_stop(&ioat->poll_timer);
|
||||||
}
|
}
|
||||||
mtx_unlock(&ioat->submit_lock);
|
mtx_unlock(&ioat->submit_lock);
|
||||||
@ -781,8 +786,6 @@ ioat_process_events(struct ioat_softc *ioat)
|
|||||||
|
|
||||||
if (ioat->is_completion_pending) {
|
if (ioat->is_completion_pending) {
|
||||||
ioat->is_completion_pending = FALSE;
|
ioat->is_completion_pending = FALSE;
|
||||||
callout_reset(&ioat->shrink_timer, IOAT_SHRINK_PERIOD,
|
|
||||||
ioat_shrink_timer_callback, ioat);
|
|
||||||
callout_stop(&ioat->poll_timer);
|
callout_stop(&ioat->poll_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -964,7 +967,6 @@ ioat_release(bus_dmaengine_t dmaengine)
|
|||||||
ioat->is_completion_pending = TRUE;
|
ioat->is_completion_pending = TRUE;
|
||||||
callout_reset(&ioat->poll_timer, 1, ioat_poll_timer_callback,
|
callout_reset(&ioat->poll_timer, 1, ioat_poll_timer_callback,
|
||||||
ioat);
|
ioat);
|
||||||
callout_stop(&ioat->shrink_timer);
|
|
||||||
}
|
}
|
||||||
mtx_unlock(&ioat->submit_lock);
|
mtx_unlock(&ioat->submit_lock);
|
||||||
}
|
}
|
||||||
@ -998,7 +1000,7 @@ ioat_op_generic(struct ioat_softc *ioat, uint8_t op,
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
desc = ioat_get_ring_entry(ioat, ioat->head);
|
desc = ioat_get_ring_entry(ioat, ioat->head);
|
||||||
hw_desc = desc->u.generic;
|
hw_desc = &ioat_get_descriptor(ioat, ioat->head)->generic;
|
||||||
|
|
||||||
hw_desc->u.control_raw = 0;
|
hw_desc->u.control_raw = 0;
|
||||||
hw_desc->u.control_generic.op = op;
|
hw_desc->u.control_generic.op = op;
|
||||||
@ -1034,7 +1036,7 @@ ioat_null(bus_dmaengine_t dmaengine, bus_dmaengine_callback_t callback_fn,
|
|||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
hw_desc = desc->u.dma;
|
hw_desc = &ioat_get_descriptor(ioat, desc->id)->dma;
|
||||||
hw_desc->u.control.null = 1;
|
hw_desc->u.control.null = 1;
|
||||||
ioat_submit_single(ioat);
|
ioat_submit_single(ioat);
|
||||||
return (&desc->bus_dmadesc);
|
return (&desc->bus_dmadesc);
|
||||||
@ -1062,7 +1064,7 @@ ioat_copy(bus_dmaengine_t dmaengine, bus_addr_t dst,
|
|||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
hw_desc = desc->u.dma;
|
hw_desc = &ioat_get_descriptor(ioat, desc->id)->dma;
|
||||||
if (g_ioat_debug_level >= 3)
|
if (g_ioat_debug_level >= 3)
|
||||||
dump_descriptor(hw_desc);
|
dump_descriptor(hw_desc);
|
||||||
|
|
||||||
@ -1100,7 +1102,7 @@ ioat_copy_8k_aligned(bus_dmaengine_t dmaengine, bus_addr_t dst1,
|
|||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
hw_desc = desc->u.dma;
|
hw_desc = &ioat_get_descriptor(ioat, desc->id)->dma;
|
||||||
if (src2 != src1 + PAGE_SIZE) {
|
if (src2 != src1 + PAGE_SIZE) {
|
||||||
hw_desc->u.control.src_page_break = 1;
|
hw_desc->u.control.src_page_break = 1;
|
||||||
hw_desc->next_src_addr = src2;
|
hw_desc->next_src_addr = src2;
|
||||||
@ -1177,7 +1179,7 @@ ioat_copy_crc(bus_dmaengine_t dmaengine, bus_addr_t dst, bus_addr_t src,
|
|||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
hw_desc = desc->u.crc32;
|
hw_desc = &ioat_get_descriptor(ioat, desc->id)->crc32;
|
||||||
|
|
||||||
if ((flags & DMA_CRC_INLINE) == 0)
|
if ((flags & DMA_CRC_INLINE) == 0)
|
||||||
hw_desc->crc_address = crcptr;
|
hw_desc->crc_address = crcptr;
|
||||||
@ -1256,7 +1258,7 @@ ioat_crc(bus_dmaengine_t dmaengine, bus_addr_t src, bus_size_t len,
|
|||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
hw_desc = desc->u.crc32;
|
hw_desc = &ioat_get_descriptor(ioat, desc->id)->crc32;
|
||||||
|
|
||||||
if ((flags & DMA_CRC_INLINE) == 0)
|
if ((flags & DMA_CRC_INLINE) == 0)
|
||||||
hw_desc->crc_address = crcptr;
|
hw_desc->crc_address = crcptr;
|
||||||
@ -1304,7 +1306,7 @@ ioat_blockfill(bus_dmaengine_t dmaengine, bus_addr_t dst, uint64_t fillpattern,
|
|||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
hw_desc = desc->u.fill;
|
hw_desc = &ioat_get_descriptor(ioat, desc->id)->fill;
|
||||||
if (g_ioat_debug_level >= 3)
|
if (g_ioat_debug_level >= 3)
|
||||||
dump_descriptor(hw_desc);
|
dump_descriptor(hw_desc);
|
||||||
|
|
||||||
@ -1329,60 +1331,6 @@ ioat_get_ring_space(struct ioat_softc *ioat)
|
|||||||
return ((1 << ioat->ring_size_order) - ioat_get_active(ioat) - 1);
|
return ((1 << ioat->ring_size_order) - ioat_get_active(ioat) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ioat_descriptor *
|
|
||||||
ioat_alloc_ring_entry(struct ioat_softc *ioat, int mflags)
|
|
||||||
{
|
|
||||||
struct ioat_generic_hw_descriptor *hw_desc;
|
|
||||||
struct ioat_descriptor *desc;
|
|
||||||
int error, busdmaflag;
|
|
||||||
|
|
||||||
error = ENOMEM;
|
|
||||||
hw_desc = NULL;
|
|
||||||
|
|
||||||
if ((mflags & M_WAITOK) != 0)
|
|
||||||
busdmaflag = BUS_DMA_WAITOK;
|
|
||||||
else
|
|
||||||
busdmaflag = BUS_DMA_NOWAIT;
|
|
||||||
|
|
||||||
desc = malloc(sizeof(*desc), M_IOAT, mflags);
|
|
||||||
if (desc == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
bus_dmamem_alloc(ioat->hw_desc_tag, (void **)&hw_desc,
|
|
||||||
BUS_DMA_ZERO | busdmaflag, &ioat->hw_desc_map);
|
|
||||||
if (hw_desc == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
memset(&desc->bus_dmadesc, 0, sizeof(desc->bus_dmadesc));
|
|
||||||
desc->u.generic = hw_desc;
|
|
||||||
|
|
||||||
error = bus_dmamap_load(ioat->hw_desc_tag, ioat->hw_desc_map, hw_desc,
|
|
||||||
sizeof(*hw_desc), ioat_dmamap_cb, &desc->hw_desc_bus_addr,
|
|
||||||
busdmaflag);
|
|
||||||
if (error)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (error) {
|
|
||||||
ioat_free_ring_entry(ioat, desc);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
return (desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ioat_free_ring_entry(struct ioat_softc *ioat, struct ioat_descriptor *desc)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (desc == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (desc->u.generic)
|
|
||||||
bus_dmamem_free(ioat->hw_desc_tag, desc->u.generic,
|
|
||||||
ioat->hw_desc_map);
|
|
||||||
free(desc, M_IOAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reserves space in this IOAT descriptor ring by ensuring enough slots remain
|
* Reserves space in this IOAT descriptor ring by ensuring enough slots remain
|
||||||
* for 'num_descs'.
|
* for 'num_descs'.
|
||||||
@ -1402,8 +1350,6 @@ ioat_free_ring_entry(struct ioat_softc *ioat, struct ioat_descriptor *desc)
|
|||||||
static int
|
static int
|
||||||
ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags)
|
ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags)
|
||||||
{
|
{
|
||||||
struct ioat_descriptor **new_ring;
|
|
||||||
uint32_t order;
|
|
||||||
boolean_t dug;
|
boolean_t dug;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -1411,7 +1357,7 @@ ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags)
|
|||||||
error = 0;
|
error = 0;
|
||||||
dug = FALSE;
|
dug = FALSE;
|
||||||
|
|
||||||
if (num_descs < 1 || num_descs >= (1 << IOAT_MAX_ORDER)) {
|
if (num_descs < 1 || num_descs >= (1 << ioat->ring_size_order)) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1428,8 +1374,7 @@ ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags)
|
|||||||
CTR3(KTR_IOAT, "%s channel=%u starved (%u)", __func__,
|
CTR3(KTR_IOAT, "%s channel=%u starved (%u)", __func__,
|
||||||
ioat->chan_idx, num_descs);
|
ioat->chan_idx, num_descs);
|
||||||
|
|
||||||
if (!dug && !ioat->is_submitter_processing &&
|
if (!dug && !ioat->is_submitter_processing) {
|
||||||
(1 << ioat->ring_size_order) > num_descs) {
|
|
||||||
ioat->is_submitter_processing = TRUE;
|
ioat->is_submitter_processing = TRUE;
|
||||||
mtx_unlock(&ioat->submit_lock);
|
mtx_unlock(&ioat->submit_lock);
|
||||||
|
|
||||||
@ -1446,46 +1391,15 @@ ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
order = ioat->ring_size_order;
|
if ((mflags & M_WAITOK) == 0) {
|
||||||
if (ioat->is_resize_pending || order == IOAT_MAX_ORDER) {
|
|
||||||
if ((mflags & M_WAITOK) != 0) {
|
|
||||||
CTR2(KTR_IOAT, "%s channel=%u blocking on completions",
|
|
||||||
__func__, ioat->chan_idx);
|
|
||||||
msleep(&ioat->tail, &ioat->submit_lock, 0,
|
|
||||||
"ioat_rsz", 0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = EAGAIN;
|
error = EAGAIN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
CTR2(KTR_IOAT, "%s channel=%u blocking on completions",
|
||||||
ioat->is_resize_pending = TRUE;
|
__func__, ioat->chan_idx);
|
||||||
for (;;) {
|
msleep(&ioat->tail, &ioat->submit_lock, 0,
|
||||||
mtx_unlock(&ioat->submit_lock);
|
"ioat_full", 0);
|
||||||
|
continue;
|
||||||
new_ring = ioat_prealloc_ring(ioat, 1 << (order + 1),
|
|
||||||
TRUE, mflags);
|
|
||||||
|
|
||||||
mtx_lock(&ioat->submit_lock);
|
|
||||||
KASSERT(ioat->ring_size_order == order,
|
|
||||||
("is_resize_pending should protect order"));
|
|
||||||
|
|
||||||
if (new_ring == NULL) {
|
|
||||||
KASSERT((mflags & M_WAITOK) == 0,
|
|
||||||
("allocation failed"));
|
|
||||||
error = EAGAIN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = ring_grow(ioat, order, new_ring);
|
|
||||||
if (error == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ioat->is_resize_pending = FALSE;
|
|
||||||
wakeup(&ioat->tail);
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -1495,49 +1409,11 @@ ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ioat_descriptor **
|
|
||||||
ioat_prealloc_ring(struct ioat_softc *ioat, uint32_t size, boolean_t need_dscr,
|
|
||||||
int mflags)
|
|
||||||
{
|
|
||||||
struct ioat_descriptor **ring;
|
|
||||||
uint32_t i;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
KASSERT(size > 0 && powerof2(size), ("bogus size"));
|
|
||||||
|
|
||||||
ring = malloc(size * sizeof(*ring), M_IOAT, M_ZERO | mflags);
|
|
||||||
if (ring == NULL)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
if (need_dscr) {
|
|
||||||
error = ENOMEM;
|
|
||||||
for (i = size / 2; i < size; i++) {
|
|
||||||
ring[i] = ioat_alloc_ring_entry(ioat, mflags);
|
|
||||||
if (ring[i] == NULL)
|
|
||||||
goto out;
|
|
||||||
ring[i]->id = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error = 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (error != 0 && ring != NULL) {
|
|
||||||
ioat_free_ring(ioat, size, ring);
|
|
||||||
ring = NULL;
|
|
||||||
}
|
|
||||||
return (ring);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ioat_free_ring(struct ioat_softc *ioat, uint32_t size,
|
ioat_free_ring(struct ioat_softc *ioat, uint32_t size,
|
||||||
struct ioat_descriptor **ring)
|
struct ioat_descriptor *ring)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
|
||||||
if (ring[i] != NULL)
|
|
||||||
ioat_free_ring_entry(ioat, ring[i]);
|
|
||||||
}
|
|
||||||
free(ring, M_IOAT);
|
free(ring, M_IOAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1545,188 +1421,20 @@ static struct ioat_descriptor *
|
|||||||
ioat_get_ring_entry(struct ioat_softc *ioat, uint32_t index)
|
ioat_get_ring_entry(struct ioat_softc *ioat, uint32_t index)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (ioat->ring[index % (1 << ioat->ring_size_order)]);
|
return (&ioat->ring[index % (1 << ioat->ring_size_order)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static union ioat_hw_descriptor *
|
||||||
ring_grow(struct ioat_softc *ioat, uint32_t oldorder,
|
ioat_get_descriptor(struct ioat_softc *ioat, uint32_t index)
|
||||||
struct ioat_descriptor **newring)
|
|
||||||
{
|
{
|
||||||
struct ioat_descriptor *tmp, *next;
|
|
||||||
struct ioat_dma_hw_descriptor *hw;
|
|
||||||
uint32_t oldsize, newsize, head, tail, i, end;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
CTR2(KTR_IOAT, "%s channel=%u", __func__, ioat->chan_idx);
|
return (&ioat->hw_desc_ring[index % (1 << ioat->ring_size_order)]);
|
||||||
|
|
||||||
mtx_assert(&ioat->submit_lock, MA_OWNED);
|
|
||||||
|
|
||||||
if (oldorder != ioat->ring_size_order || oldorder >= IOAT_MAX_ORDER) {
|
|
||||||
error = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
oldsize = (1 << oldorder);
|
|
||||||
newsize = (1 << (oldorder + 1));
|
|
||||||
|
|
||||||
mtx_lock(&ioat->cleanup_lock);
|
|
||||||
|
|
||||||
head = ioat->head & (oldsize - 1);
|
|
||||||
tail = ioat->tail & (oldsize - 1);
|
|
||||||
|
|
||||||
/* Copy old descriptors to new ring */
|
|
||||||
for (i = 0; i < oldsize; i++)
|
|
||||||
newring[i] = ioat->ring[i];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If head has wrapped but tail hasn't, we must swap some descriptors
|
|
||||||
* around so that tail can increment directly to head.
|
|
||||||
*/
|
|
||||||
if (head < tail) {
|
|
||||||
for (i = 0; i <= head; i++) {
|
|
||||||
tmp = newring[oldsize + i];
|
|
||||||
|
|
||||||
newring[oldsize + i] = newring[i];
|
|
||||||
newring[oldsize + i]->id = oldsize + i;
|
|
||||||
|
|
||||||
newring[i] = tmp;
|
|
||||||
newring[i]->id = i;
|
|
||||||
}
|
|
||||||
head += oldsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
KASSERT(head >= tail, ("invariants"));
|
|
||||||
|
|
||||||
/* Head didn't wrap; we only need to link in oldsize..newsize */
|
|
||||||
if (head < oldsize) {
|
|
||||||
i = oldsize - 1;
|
|
||||||
end = newsize;
|
|
||||||
} else {
|
|
||||||
/* Head did wrap; link newhead..newsize and 0..oldhead */
|
|
||||||
i = head;
|
|
||||||
end = newsize + (head - oldsize) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fix up hardware ring, being careful not to trample the active
|
|
||||||
* section (tail -> head).
|
|
||||||
*/
|
|
||||||
for (; i < end; i++) {
|
|
||||||
KASSERT((i & (newsize - 1)) < tail ||
|
|
||||||
(i & (newsize - 1)) >= head, ("trampling snake"));
|
|
||||||
|
|
||||||
next = newring[(i + 1) & (newsize - 1)];
|
|
||||||
hw = newring[i & (newsize - 1)]->u.dma;
|
|
||||||
hw->next = next->hw_desc_bus_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef INVARIANTS
|
|
||||||
for (i = 0; i < newsize; i++) {
|
|
||||||
next = newring[(i + 1) & (newsize - 1)];
|
|
||||||
hw = newring[i & (newsize - 1)]->u.dma;
|
|
||||||
|
|
||||||
KASSERT(hw->next == next->hw_desc_bus_addr,
|
|
||||||
("mismatch at i:%u (oldsize:%u); next=%p nextaddr=0x%lx"
|
|
||||||
" (tail:%u)", i, oldsize, next, next->hw_desc_bus_addr,
|
|
||||||
tail));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free(ioat->ring, M_IOAT);
|
|
||||||
ioat->ring = newring;
|
|
||||||
ioat->ring_size_order = oldorder + 1;
|
|
||||||
ioat->tail = tail;
|
|
||||||
ioat->head = head;
|
|
||||||
error = 0;
|
|
||||||
|
|
||||||
mtx_unlock(&ioat->cleanup_lock);
|
|
||||||
out:
|
|
||||||
if (error)
|
|
||||||
ioat_free_ring(ioat, (1 << (oldorder + 1)), newring);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
ring_shrink(struct ioat_softc *ioat, uint32_t oldorder,
|
|
||||||
struct ioat_descriptor **newring)
|
|
||||||
{
|
|
||||||
struct ioat_dma_hw_descriptor *hw;
|
|
||||||
struct ioat_descriptor *ent, *next;
|
|
||||||
uint32_t oldsize, newsize, current_idx, new_idx, i;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
CTR2(KTR_IOAT, "%s channel=%u", __func__, ioat->chan_idx);
|
|
||||||
|
|
||||||
mtx_assert(&ioat->submit_lock, MA_OWNED);
|
|
||||||
|
|
||||||
if (oldorder != ioat->ring_size_order || oldorder <= IOAT_MIN_ORDER) {
|
|
||||||
error = EINVAL;
|
|
||||||
goto out_unlocked;
|
|
||||||
}
|
|
||||||
|
|
||||||
oldsize = (1 << oldorder);
|
|
||||||
newsize = (1 << (oldorder - 1));
|
|
||||||
|
|
||||||
mtx_lock(&ioat->cleanup_lock);
|
|
||||||
|
|
||||||
/* Can't shrink below current active set! */
|
|
||||||
if (ioat_get_active(ioat) >= newsize) {
|
|
||||||
error = ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy current descriptors to the new ring, dropping the removed
|
|
||||||
* descriptors.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < newsize; i++) {
|
|
||||||
current_idx = (ioat->tail + i) & (oldsize - 1);
|
|
||||||
new_idx = (ioat->tail + i) & (newsize - 1);
|
|
||||||
|
|
||||||
newring[new_idx] = ioat->ring[current_idx];
|
|
||||||
newring[new_idx]->id = new_idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free deleted descriptors */
|
|
||||||
for (i = newsize; i < oldsize; i++) {
|
|
||||||
ent = ioat_get_ring_entry(ioat, ioat->tail + i);
|
|
||||||
ioat_free_ring_entry(ioat, ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fix up hardware ring. */
|
|
||||||
hw = newring[(ioat->tail + newsize - 1) & (newsize - 1)]->u.dma;
|
|
||||||
next = newring[(ioat->tail + newsize) & (newsize - 1)];
|
|
||||||
hw->next = next->hw_desc_bus_addr;
|
|
||||||
|
|
||||||
#ifdef INVARIANTS
|
|
||||||
for (i = 0; i < newsize; i++) {
|
|
||||||
next = newring[(i + 1) & (newsize - 1)];
|
|
||||||
hw = newring[i & (newsize - 1)]->u.dma;
|
|
||||||
|
|
||||||
KASSERT(hw->next == next->hw_desc_bus_addr,
|
|
||||||
("mismatch at i:%u (newsize:%u); next=%p nextaddr=0x%lx "
|
|
||||||
"(tail:%u)", i, newsize, next, next->hw_desc_bus_addr,
|
|
||||||
ioat->tail));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free(ioat->ring, M_IOAT);
|
|
||||||
ioat->ring = newring;
|
|
||||||
ioat->ring_size_order = oldorder - 1;
|
|
||||||
error = 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
mtx_unlock(&ioat->cleanup_lock);
|
|
||||||
out_unlocked:
|
|
||||||
if (error)
|
|
||||||
ioat_free_ring(ioat, (1 << (oldorder - 1)), newring);
|
|
||||||
return (error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ioat_halted_debug(struct ioat_softc *ioat, uint32_t chanerr)
|
ioat_halted_debug(struct ioat_softc *ioat, uint32_t chanerr)
|
||||||
{
|
{
|
||||||
struct ioat_descriptor *desc;
|
union ioat_hw_descriptor *desc;
|
||||||
|
|
||||||
ioat_log_message(0, "Channel halted (%b)\n", (int)chanerr,
|
ioat_log_message(0, "Channel halted (%b)\n", (int)chanerr,
|
||||||
IOAT_CHANERR_STR);
|
IOAT_CHANERR_STR);
|
||||||
@ -1735,11 +1443,11 @@ ioat_halted_debug(struct ioat_softc *ioat, uint32_t chanerr)
|
|||||||
|
|
||||||
mtx_assert(&ioat->cleanup_lock, MA_OWNED);
|
mtx_assert(&ioat->cleanup_lock, MA_OWNED);
|
||||||
|
|
||||||
desc = ioat_get_ring_entry(ioat, ioat->tail + 0);
|
desc = ioat_get_descriptor(ioat, ioat->tail + 0);
|
||||||
dump_descriptor(desc->u.raw);
|
dump_descriptor(desc);
|
||||||
|
|
||||||
desc = ioat_get_ring_entry(ioat, ioat->tail + 1);
|
desc = ioat_get_descriptor(ioat, ioat->tail + 1);
|
||||||
dump_descriptor(desc->u.raw);
|
dump_descriptor(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1753,55 +1461,6 @@ ioat_poll_timer_callback(void *arg)
|
|||||||
ioat_process_events(ioat);
|
ioat_process_events(ioat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ioat_shrink_timer_callback(void *arg)
|
|
||||||
{
|
|
||||||
struct ioat_descriptor **newring;
|
|
||||||
struct ioat_softc *ioat;
|
|
||||||
uint32_t order;
|
|
||||||
|
|
||||||
ioat = arg;
|
|
||||||
ioat_log_message(1, "%s\n", __func__);
|
|
||||||
|
|
||||||
/* Slowly scale the ring down if idle. */
|
|
||||||
mtx_lock(&ioat->submit_lock);
|
|
||||||
|
|
||||||
/* Don't run while the hardware is being reset. */
|
|
||||||
if (ioat->resetting) {
|
|
||||||
mtx_unlock(&ioat->submit_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
order = ioat->ring_size_order;
|
|
||||||
if (ioat->is_completion_pending || ioat->is_resize_pending ||
|
|
||||||
order == IOAT_MIN_ORDER) {
|
|
||||||
mtx_unlock(&ioat->submit_lock);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ioat->is_resize_pending = TRUE;
|
|
||||||
mtx_unlock(&ioat->submit_lock);
|
|
||||||
|
|
||||||
newring = ioat_prealloc_ring(ioat, 1 << (order - 1), FALSE,
|
|
||||||
M_NOWAIT);
|
|
||||||
|
|
||||||
mtx_lock(&ioat->submit_lock);
|
|
||||||
KASSERT(ioat->ring_size_order == order,
|
|
||||||
("resize_pending protects order"));
|
|
||||||
|
|
||||||
if (newring != NULL && !ioat->is_completion_pending)
|
|
||||||
ring_shrink(ioat, order, newring);
|
|
||||||
else if (newring != NULL)
|
|
||||||
ioat_free_ring(ioat, (1 << (order - 1)), newring);
|
|
||||||
|
|
||||||
ioat->is_resize_pending = FALSE;
|
|
||||||
mtx_unlock(&ioat->submit_lock);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (ioat->ring_size_order > IOAT_MIN_ORDER)
|
|
||||||
callout_reset(&ioat->shrink_timer, IOAT_SHRINK_PERIOD,
|
|
||||||
ioat_shrink_timer_callback, ioat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Support Functions
|
* Support Functions
|
||||||
*/
|
*/
|
||||||
@ -1946,7 +1605,7 @@ ioat_reset_hw(struct ioat_softc *ioat)
|
|||||||
|
|
||||||
ioat_write_chanctrl(ioat, IOAT_CHANCTRL_RUN);
|
ioat_write_chanctrl(ioat, IOAT_CHANCTRL_RUN);
|
||||||
ioat_write_chancmp(ioat, ioat->comp_update_bus_addr);
|
ioat_write_chancmp(ioat, ioat->comp_update_bus_addr);
|
||||||
ioat_write_chainaddr(ioat, ioat->ring[0]->hw_desc_bus_addr);
|
ioat_write_chainaddr(ioat, RING_PHYS_ADDR(ioat, 0));
|
||||||
error = 0;
|
error = 0;
|
||||||
CTR2(KTR_IOAT, "%s channel=%u configured channel", __func__,
|
CTR2(KTR_IOAT, "%s channel=%u configured channel", __func__,
|
||||||
ioat->chan_idx);
|
ioat->chan_idx);
|
||||||
@ -2128,8 +1787,6 @@ ioat_setup_sysctl(device_t device)
|
|||||||
SYSCTL_ADD_UQUAD(ctx, state, OID_AUTO, "last_completion", CTLFLAG_RD,
|
SYSCTL_ADD_UQUAD(ctx, state, OID_AUTO, "last_completion", CTLFLAG_RD,
|
||||||
ioat->comp_update, "HW addr of last completion");
|
ioat->comp_update, "HW addr of last completion");
|
||||||
|
|
||||||
SYSCTL_ADD_INT(ctx, state, OID_AUTO, "is_resize_pending", CTLFLAG_RD,
|
|
||||||
&ioat->is_resize_pending, 0, "resize pending");
|
|
||||||
SYSCTL_ADD_INT(ctx, state, OID_AUTO, "is_submitter_processing",
|
SYSCTL_ADD_INT(ctx, state, OID_AUTO, "is_submitter_processing",
|
||||||
CTLFLAG_RD, &ioat->is_submitter_processing, 0,
|
CTLFLAG_RD, &ioat->is_submitter_processing, 0,
|
||||||
"submitter processing");
|
"submitter processing");
|
||||||
@ -2307,16 +1964,8 @@ DB_SHOW_COMMAND(ioat, db_show_ioat)
|
|||||||
db_printf(" c_lock: %p\n", sc->poll_timer.c_lock);
|
db_printf(" c_lock: %p\n", sc->poll_timer.c_lock);
|
||||||
db_printf(" c_flags: 0x%x\n", (unsigned)sc->poll_timer.c_flags);
|
db_printf(" c_flags: 0x%x\n", (unsigned)sc->poll_timer.c_flags);
|
||||||
|
|
||||||
db_printf(" shrink_timer:\n");
|
|
||||||
db_printf(" c_time: %ju\n", (uintmax_t)sc->shrink_timer.c_time);
|
|
||||||
db_printf(" c_arg: %p\n", sc->shrink_timer.c_arg);
|
|
||||||
db_printf(" c_func: %p\n", sc->shrink_timer.c_func);
|
|
||||||
db_printf(" c_lock: %p\n", sc->shrink_timer.c_lock);
|
|
||||||
db_printf(" c_flags: 0x%x\n", (unsigned)sc->shrink_timer.c_flags);
|
|
||||||
|
|
||||||
db_printf(" quiescing: %d\n", (int)sc->quiescing);
|
db_printf(" quiescing: %d\n", (int)sc->quiescing);
|
||||||
db_printf(" destroying: %d\n", (int)sc->destroying);
|
db_printf(" destroying: %d\n", (int)sc->destroying);
|
||||||
db_printf(" is_resize_pending: %d\n", (int)sc->is_resize_pending);
|
|
||||||
db_printf(" is_submitter_processing: %d\n",
|
db_printf(" is_submitter_processing: %d\n",
|
||||||
(int)sc->is_submitter_processing);
|
(int)sc->is_submitter_processing);
|
||||||
db_printf(" is_completion_pending: %d\n", (int)sc->is_completion_pending);
|
db_printf(" is_completion_pending: %d\n", (int)sc->is_completion_pending);
|
||||||
@ -2331,34 +1980,37 @@ DB_SHOW_COMMAND(ioat, db_show_ioat)
|
|||||||
db_printf(" ring_size_order: %u\n", sc->ring_size_order);
|
db_printf(" ring_size_order: %u\n", sc->ring_size_order);
|
||||||
db_printf(" last_seen: 0x%lx\n", sc->last_seen);
|
db_printf(" last_seen: 0x%lx\n", sc->last_seen);
|
||||||
db_printf(" ring: %p\n", sc->ring);
|
db_printf(" ring: %p\n", sc->ring);
|
||||||
|
db_printf(" descriptors: %p\n", sc->hw_desc_ring);
|
||||||
|
db_printf(" descriptors (phys): 0x%jx\n",
|
||||||
|
(uintmax_t)sc->hw_desc_bus_addr);
|
||||||
|
|
||||||
db_printf(" ring[%u] (tail):\n", sc->tail %
|
db_printf(" ring[%u] (tail):\n", sc->tail %
|
||||||
(1 << sc->ring_size_order));
|
(1 << sc->ring_size_order));
|
||||||
db_printf(" id: %u\n", ioat_get_ring_entry(sc, sc->tail)->id);
|
db_printf(" id: %u\n", ioat_get_ring_entry(sc, sc->tail)->id);
|
||||||
db_printf(" addr: 0x%lx\n",
|
db_printf(" addr: 0x%lx\n",
|
||||||
ioat_get_ring_entry(sc, sc->tail)->hw_desc_bus_addr);
|
RING_PHYS_ADDR(sc, sc->tail));
|
||||||
db_printf(" next: 0x%lx\n",
|
db_printf(" next: 0x%lx\n",
|
||||||
ioat_get_ring_entry(sc, sc->tail)->u.generic->next);
|
ioat_get_descriptor(sc, sc->tail)->generic.next);
|
||||||
|
|
||||||
db_printf(" ring[%u] (head - 1):\n", (sc->head - 1) %
|
db_printf(" ring[%u] (head - 1):\n", (sc->head - 1) %
|
||||||
(1 << sc->ring_size_order));
|
(1 << sc->ring_size_order));
|
||||||
db_printf(" id: %u\n", ioat_get_ring_entry(sc, sc->head - 1)->id);
|
db_printf(" id: %u\n", ioat_get_ring_entry(sc, sc->head - 1)->id);
|
||||||
db_printf(" addr: 0x%lx\n",
|
db_printf(" addr: 0x%lx\n",
|
||||||
ioat_get_ring_entry(sc, sc->head - 1)->hw_desc_bus_addr);
|
RING_PHYS_ADDR(sc, sc->head - 1));
|
||||||
db_printf(" next: 0x%lx\n",
|
db_printf(" next: 0x%lx\n",
|
||||||
ioat_get_ring_entry(sc, sc->head - 1)->u.generic->next);
|
ioat_get_descriptor(sc, sc->head - 1)->generic.next);
|
||||||
|
|
||||||
db_printf(" ring[%u] (head):\n", (sc->head) %
|
db_printf(" ring[%u] (head):\n", (sc->head) %
|
||||||
(1 << sc->ring_size_order));
|
(1 << sc->ring_size_order));
|
||||||
db_printf(" id: %u\n", ioat_get_ring_entry(sc, sc->head)->id);
|
db_printf(" id: %u\n", ioat_get_ring_entry(sc, sc->head)->id);
|
||||||
db_printf(" addr: 0x%lx\n",
|
db_printf(" addr: 0x%lx\n",
|
||||||
ioat_get_ring_entry(sc, sc->head)->hw_desc_bus_addr);
|
RING_PHYS_ADDR(sc, sc->head));
|
||||||
db_printf(" next: 0x%lx\n",
|
db_printf(" next: 0x%lx\n",
|
||||||
ioat_get_ring_entry(sc, sc->head)->u.generic->next);
|
ioat_get_descriptor(sc, sc->head)->generic.next);
|
||||||
|
|
||||||
for (idx = 0; idx < (1 << sc->ring_size_order); idx++)
|
for (idx = 0; idx < (1 << sc->ring_size_order); idx++)
|
||||||
if ((*sc->comp_update & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK)
|
if ((*sc->comp_update & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK)
|
||||||
== ioat_get_ring_entry(sc, idx)->hw_desc_bus_addr)
|
== RING_PHYS_ADDR(sc, idx))
|
||||||
db_printf(" ring[%u] == hardware tail\n", idx);
|
db_printf(" ring[%u] == hardware tail\n", idx);
|
||||||
|
|
||||||
db_printf(" cleanup_lock: ");
|
db_printf(" cleanup_lock: ");
|
||||||
|
@ -413,19 +413,7 @@ struct bus_dmadesc {
|
|||||||
|
|
||||||
struct ioat_descriptor {
|
struct ioat_descriptor {
|
||||||
struct bus_dmadesc bus_dmadesc;
|
struct bus_dmadesc bus_dmadesc;
|
||||||
union {
|
|
||||||
struct ioat_generic_hw_descriptor *generic;
|
|
||||||
struct ioat_dma_hw_descriptor *dma;
|
|
||||||
struct ioat_fill_hw_descriptor *fill;
|
|
||||||
struct ioat_crc32_hw_descriptor *crc32;
|
|
||||||
struct ioat_xor_hw_descriptor *xor;
|
|
||||||
struct ioat_xor_ext_hw_descriptor *xor_ext;
|
|
||||||
struct ioat_pq_hw_descriptor *pq;
|
|
||||||
struct ioat_pq_ext_hw_descriptor *pq_ext;
|
|
||||||
struct ioat_raw_hw_descriptor *raw;
|
|
||||||
} u;
|
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
bus_addr_t hw_desc_bus_addr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Unused by this driver at this time. */
|
/* Unused by this driver at this time. */
|
||||||
@ -487,7 +475,6 @@ struct ioat_softc {
|
|||||||
boolean_t quiescing;
|
boolean_t quiescing;
|
||||||
boolean_t destroying;
|
boolean_t destroying;
|
||||||
boolean_t is_submitter_processing;
|
boolean_t is_submitter_processing;
|
||||||
boolean_t is_resize_pending;
|
|
||||||
boolean_t is_completion_pending; /* submit_lock */
|
boolean_t is_completion_pending; /* submit_lock */
|
||||||
boolean_t is_reset_pending;
|
boolean_t is_reset_pending;
|
||||||
boolean_t is_channel_running;
|
boolean_t is_channel_running;
|
||||||
@ -501,7 +488,22 @@ struct ioat_softc {
|
|||||||
uint32_t ring_size_order;
|
uint32_t ring_size_order;
|
||||||
bus_addr_t last_seen;
|
bus_addr_t last_seen;
|
||||||
|
|
||||||
struct ioat_descriptor **ring;
|
struct ioat_descriptor *ring;
|
||||||
|
|
||||||
|
union ioat_hw_descriptor {
|
||||||
|
struct ioat_generic_hw_descriptor generic;
|
||||||
|
struct ioat_dma_hw_descriptor dma;
|
||||||
|
struct ioat_fill_hw_descriptor fill;
|
||||||
|
struct ioat_crc32_hw_descriptor crc32;
|
||||||
|
struct ioat_xor_hw_descriptor xor;
|
||||||
|
struct ioat_xor_ext_hw_descriptor xor_ext;
|
||||||
|
struct ioat_pq_hw_descriptor pq;
|
||||||
|
struct ioat_pq_ext_hw_descriptor pq_ext;
|
||||||
|
struct ioat_raw_hw_descriptor raw;
|
||||||
|
} *hw_desc_ring;
|
||||||
|
bus_addr_t hw_desc_bus_addr;
|
||||||
|
#define RING_PHYS_ADDR(sc, i) (sc)->hw_desc_bus_addr + \
|
||||||
|
(((i) % (1 << (sc)->ring_size_order)) * sizeof(struct ioat_dma_hw_descriptor))
|
||||||
|
|
||||||
struct mtx cleanup_lock;
|
struct mtx cleanup_lock;
|
||||||
volatile uint32_t refcnt;
|
volatile uint32_t refcnt;
|
||||||
|
@ -5071,18 +5071,6 @@ iwm_nic_error(struct iwm_softc *sc)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SYNC_RESP_STRUCT(_var_, _pkt_) \
|
|
||||||
do { \
|
|
||||||
bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);\
|
|
||||||
_var_ = (void *)((_pkt_)+1); \
|
|
||||||
} while (/*CONSTCOND*/0)
|
|
||||||
|
|
||||||
#define SYNC_RESP_PTR(_ptr_, _len_, _pkt_) \
|
|
||||||
do { \
|
|
||||||
bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);\
|
|
||||||
_ptr_ = (void *)((_pkt_)+1); \
|
|
||||||
} while (/*CONSTCOND*/0)
|
|
||||||
|
|
||||||
#define ADVANCE_RXQ(sc) (sc->rxq.cur = (sc->rxq.cur + 1) % IWM_RX_RING_COUNT);
|
#define ADVANCE_RXQ(sc) (sc->rxq.cur = (sc->rxq.cur + 1) % IWM_RX_RING_COUNT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5105,12 +5093,12 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
*/
|
*/
|
||||||
while (sc->rxq.cur != hw) {
|
while (sc->rxq.cur != hw) {
|
||||||
struct iwm_rx_ring *ring = &sc->rxq;
|
struct iwm_rx_ring *ring = &sc->rxq;
|
||||||
struct iwm_rx_data *data = &sc->rxq.data[sc->rxq.cur];
|
struct iwm_rx_data *data = &ring->data[ring->cur];
|
||||||
struct iwm_rx_packet *pkt;
|
struct iwm_rx_packet *pkt;
|
||||||
struct iwm_cmd_response *cresp;
|
struct iwm_cmd_response *cresp;
|
||||||
int qid, idx, code;
|
int qid, idx, code;
|
||||||
|
|
||||||
bus_dmamap_sync(sc->rxq.data_dmat, data->map,
|
bus_dmamap_sync(ring->data_dmat, data->map,
|
||||||
BUS_DMASYNC_POSTREAD);
|
BUS_DMASYNC_POSTREAD);
|
||||||
pkt = mtod(data->m, struct iwm_rx_packet *);
|
pkt = mtod(data->m, struct iwm_rx_packet *);
|
||||||
|
|
||||||
@ -5120,7 +5108,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
code = IWM_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
|
code = IWM_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
|
||||||
IWM_DPRINTF(sc, IWM_DEBUG_INTR,
|
IWM_DPRINTF(sc, IWM_DEBUG_INTR,
|
||||||
"rx packet qid=%d idx=%d type=%x %d %d\n",
|
"rx packet qid=%d idx=%d type=%x %d %d\n",
|
||||||
pkt->hdr.qid & ~0x80, pkt->hdr.idx, code, sc->rxq.cur, hw);
|
pkt->hdr.qid & ~0x80, pkt->hdr.idx, code, ring->cur, hw);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* randomly get these from the firmware, no idea why.
|
* randomly get these from the firmware, no idea why.
|
||||||
@ -5152,7 +5140,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
/* XXX look at mac_id to determine interface ID */
|
/* XXX look at mac_id to determine interface ID */
|
||||||
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
||||||
|
|
||||||
SYNC_RESP_STRUCT(resp, pkt);
|
resp = (void *)pkt->data;
|
||||||
missed = le32toh(resp->consec_missed_beacons);
|
missed = le32toh(resp->consec_missed_beacons);
|
||||||
|
|
||||||
IWM_DPRINTF(sc, IWM_DEBUG_BEACON | IWM_DEBUG_STATE,
|
IWM_DPRINTF(sc, IWM_DEBUG_BEACON | IWM_DEBUG_STATE,
|
||||||
@ -5192,7 +5180,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
struct iwm_mvm_alive_resp_v3 *resp3;
|
struct iwm_mvm_alive_resp_v3 *resp3;
|
||||||
|
|
||||||
if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp1)) {
|
if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp1)) {
|
||||||
SYNC_RESP_STRUCT(resp1, pkt);
|
resp1 = (void *)pkt->data;
|
||||||
sc->sc_uc.uc_error_event_table
|
sc->sc_uc.uc_error_event_table
|
||||||
= le32toh(resp1->error_event_table_ptr);
|
= le32toh(resp1->error_event_table_ptr);
|
||||||
sc->sc_uc.uc_log_event_table
|
sc->sc_uc.uc_log_event_table
|
||||||
@ -5205,7 +5193,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp2)) {
|
if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp2)) {
|
||||||
SYNC_RESP_STRUCT(resp2, pkt);
|
resp2 = (void *)pkt->data;
|
||||||
sc->sc_uc.uc_error_event_table
|
sc->sc_uc.uc_error_event_table
|
||||||
= le32toh(resp2->error_event_table_ptr);
|
= le32toh(resp2->error_event_table_ptr);
|
||||||
sc->sc_uc.uc_log_event_table
|
sc->sc_uc.uc_log_event_table
|
||||||
@ -5220,7 +5208,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp3)) {
|
if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp3)) {
|
||||||
SYNC_RESP_STRUCT(resp3, pkt);
|
resp3 = (void *)pkt->data;
|
||||||
sc->sc_uc.uc_error_event_table
|
sc->sc_uc.uc_error_event_table
|
||||||
= le32toh(resp3->error_event_table_ptr);
|
= le32toh(resp3->error_event_table_ptr);
|
||||||
sc->sc_uc.uc_log_event_table
|
sc->sc_uc.uc_log_event_table
|
||||||
@ -5240,7 +5228,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
|
|
||||||
case IWM_CALIB_RES_NOTIF_PHY_DB: {
|
case IWM_CALIB_RES_NOTIF_PHY_DB: {
|
||||||
struct iwm_calib_res_notif_phy_db *phy_db_notif;
|
struct iwm_calib_res_notif_phy_db *phy_db_notif;
|
||||||
SYNC_RESP_STRUCT(phy_db_notif, pkt);
|
phy_db_notif = (void *)pkt->data;
|
||||||
|
|
||||||
iwm_phy_db_set_section(sc, phy_db_notif);
|
iwm_phy_db_set_section(sc, phy_db_notif);
|
||||||
|
|
||||||
@ -5248,7 +5236,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
|
|
||||||
case IWM_STATISTICS_NOTIFICATION: {
|
case IWM_STATISTICS_NOTIFICATION: {
|
||||||
struct iwm_notif_statistics *stats;
|
struct iwm_notif_statistics *stats;
|
||||||
SYNC_RESP_STRUCT(stats, pkt);
|
stats = (void *)pkt->data;
|
||||||
memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
|
memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
|
||||||
sc->sc_noise = iwm_get_noise(sc, &stats->rx.general);
|
sc->sc_noise = iwm_get_noise(sc, &stats->rx.general);
|
||||||
break; }
|
break; }
|
||||||
@ -5256,8 +5244,6 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
case IWM_NVM_ACCESS_CMD:
|
case IWM_NVM_ACCESS_CMD:
|
||||||
case IWM_MCC_UPDATE_CMD:
|
case IWM_MCC_UPDATE_CMD:
|
||||||
if (sc->sc_wantresp == ((qid << 16) | idx)) {
|
if (sc->sc_wantresp == ((qid << 16) | idx)) {
|
||||||
bus_dmamap_sync(sc->rxq.data_dmat, data->map,
|
|
||||||
BUS_DMASYNC_POSTREAD);
|
|
||||||
memcpy(sc->sc_cmd_resp,
|
memcpy(sc->sc_cmd_resp,
|
||||||
pkt, sizeof(sc->sc_cmd_resp));
|
pkt, sizeof(sc->sc_cmd_resp));
|
||||||
}
|
}
|
||||||
@ -5265,7 +5251,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
|
|
||||||
case IWM_MCC_CHUB_UPDATE_CMD: {
|
case IWM_MCC_CHUB_UPDATE_CMD: {
|
||||||
struct iwm_mcc_chub_notif *notif;
|
struct iwm_mcc_chub_notif *notif;
|
||||||
SYNC_RESP_STRUCT(notif, pkt);
|
notif = (void *)pkt->data;
|
||||||
|
|
||||||
sc->sc_fw_mcc[0] = (notif->mcc & 0xff00) >> 8;
|
sc->sc_fw_mcc[0] = (notif->mcc & 0xff00) >> 8;
|
||||||
sc->sc_fw_mcc[1] = notif->mcc & 0xff;
|
sc->sc_fw_mcc[1] = notif->mcc & 0xff;
|
||||||
@ -5298,7 +5284,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
case IWM_LQ_CMD:
|
case IWM_LQ_CMD:
|
||||||
case IWM_BT_CONFIG:
|
case IWM_BT_CONFIG:
|
||||||
case IWM_REPLY_THERMAL_MNG_BACKOFF:
|
case IWM_REPLY_THERMAL_MNG_BACKOFF:
|
||||||
SYNC_RESP_STRUCT(cresp, pkt);
|
cresp = (void *)pkt->data;
|
||||||
if (sc->sc_wantresp == ((qid << 16) | idx)) {
|
if (sc->sc_wantresp == ((qid << 16) | idx)) {
|
||||||
memcpy(sc->sc_cmd_resp,
|
memcpy(sc->sc_cmd_resp,
|
||||||
pkt, sizeof(*pkt)+sizeof(*cresp));
|
pkt, sizeof(*pkt)+sizeof(*cresp));
|
||||||
@ -5316,20 +5302,20 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
|
|
||||||
case IWM_SCAN_OFFLOAD_COMPLETE: {
|
case IWM_SCAN_OFFLOAD_COMPLETE: {
|
||||||
struct iwm_periodic_scan_complete *notif;
|
struct iwm_periodic_scan_complete *notif;
|
||||||
SYNC_RESP_STRUCT(notif, pkt);
|
notif = (void *)pkt->data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IWM_SCAN_ITERATION_COMPLETE: {
|
case IWM_SCAN_ITERATION_COMPLETE: {
|
||||||
struct iwm_lmac_scan_complete_notif *notif;
|
struct iwm_lmac_scan_complete_notif *notif;
|
||||||
SYNC_RESP_STRUCT(notif, pkt);
|
notif = (void *)pkt->data;
|
||||||
ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task);
|
ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IWM_SCAN_COMPLETE_UMAC: {
|
case IWM_SCAN_COMPLETE_UMAC: {
|
||||||
struct iwm_umac_scan_complete *notif;
|
struct iwm_umac_scan_complete *notif;
|
||||||
SYNC_RESP_STRUCT(notif, pkt);
|
notif = (void *)pkt->data;
|
||||||
|
|
||||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||||
"UMAC scan complete, status=0x%x\n",
|
"UMAC scan complete, status=0x%x\n",
|
||||||
@ -5342,7 +5328,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
|
|
||||||
case IWM_SCAN_ITERATION_COMPLETE_UMAC: {
|
case IWM_SCAN_ITERATION_COMPLETE_UMAC: {
|
||||||
struct iwm_umac_scan_iter_complete_notif *notif;
|
struct iwm_umac_scan_iter_complete_notif *notif;
|
||||||
SYNC_RESP_STRUCT(notif, pkt);
|
notif = (void *)pkt->data;
|
||||||
|
|
||||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "UMAC scan iteration "
|
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "UMAC scan iteration "
|
||||||
"complete, status=0x%x, %d channels scanned\n",
|
"complete, status=0x%x, %d channels scanned\n",
|
||||||
@ -5353,7 +5339,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
|
|
||||||
case IWM_REPLY_ERROR: {
|
case IWM_REPLY_ERROR: {
|
||||||
struct iwm_error_resp *resp;
|
struct iwm_error_resp *resp;
|
||||||
SYNC_RESP_STRUCT(resp, pkt);
|
resp = (void *)pkt->data;
|
||||||
|
|
||||||
device_printf(sc->sc_dev,
|
device_printf(sc->sc_dev,
|
||||||
"firmware error 0x%x, cmd 0x%x\n",
|
"firmware error 0x%x, cmd 0x%x\n",
|
||||||
@ -5364,7 +5350,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
|
|
||||||
case IWM_TIME_EVENT_NOTIFICATION: {
|
case IWM_TIME_EVENT_NOTIFICATION: {
|
||||||
struct iwm_time_event_notif *notif;
|
struct iwm_time_event_notif *notif;
|
||||||
SYNC_RESP_STRUCT(notif, pkt);
|
notif = (void *)pkt->data;
|
||||||
|
|
||||||
IWM_DPRINTF(sc, IWM_DEBUG_INTR,
|
IWM_DPRINTF(sc, IWM_DEBUG_INTR,
|
||||||
"TE notif status = 0x%x action = 0x%x\n",
|
"TE notif status = 0x%x action = 0x%x\n",
|
||||||
@ -5377,7 +5363,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
|||||||
|
|
||||||
case IWM_SCD_QUEUE_CFG: {
|
case IWM_SCD_QUEUE_CFG: {
|
||||||
struct iwm_scd_txq_cfg_rsp *rsp;
|
struct iwm_scd_txq_cfg_rsp *rsp;
|
||||||
SYNC_RESP_STRUCT(rsp, pkt);
|
rsp = (void *)pkt->data;
|
||||||
|
|
||||||
IWM_DPRINTF(sc, IWM_DEBUG_CMD,
|
IWM_DPRINTF(sc, IWM_DEBUG_CMD,
|
||||||
"queue cfg token=0x%x sta_id=%d "
|
"queue cfg token=0x%x sta_id=%d "
|
||||||
@ -5893,6 +5879,8 @@ iwm_attach(device_t dev)
|
|||||||
IEEE80211_C_SHPREAMBLE /* short preamble supported */
|
IEEE80211_C_SHPREAMBLE /* short preamble supported */
|
||||||
// IEEE80211_C_BGSCAN /* capable of bg scanning */
|
// IEEE80211_C_BGSCAN /* capable of bg scanning */
|
||||||
;
|
;
|
||||||
|
/* Advertise full-offload scanning */
|
||||||
|
ic->ic_flags_ext = IEEE80211_FEXT_SCAN_OFFLOAD;
|
||||||
for (i = 0; i < nitems(sc->sc_phyctxt); i++) {
|
for (i = 0; i < nitems(sc->sc_phyctxt); i++) {
|
||||||
sc->sc_phyctxt[i].id = i;
|
sc->sc_phyctxt[i].id = i;
|
||||||
sc->sc_phyctxt[i].color = 0;
|
sc->sc_phyctxt[i].color = 0;
|
||||||
|
@ -1376,6 +1376,7 @@ mpr_get_tunables(struct mpr_softc *sc)
|
|||||||
sc->max_io_pages = MPR_MAXIO_PAGES;
|
sc->max_io_pages = MPR_MAXIO_PAGES;
|
||||||
sc->enable_ssu = MPR_SSU_ENABLE_SSD_DISABLE_HDD;
|
sc->enable_ssu = MPR_SSU_ENABLE_SSD_DISABLE_HDD;
|
||||||
sc->spinup_wait_time = DEFAULT_SPINUP_WAIT;
|
sc->spinup_wait_time = DEFAULT_SPINUP_WAIT;
|
||||||
|
sc->use_phynum = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Grab the global variables.
|
* Grab the global variables.
|
||||||
@ -1387,6 +1388,7 @@ mpr_get_tunables(struct mpr_softc *sc)
|
|||||||
TUNABLE_INT_FETCH("hw.mpr.max_io_pages", &sc->max_io_pages);
|
TUNABLE_INT_FETCH("hw.mpr.max_io_pages", &sc->max_io_pages);
|
||||||
TUNABLE_INT_FETCH("hw.mpr.enable_ssu", &sc->enable_ssu);
|
TUNABLE_INT_FETCH("hw.mpr.enable_ssu", &sc->enable_ssu);
|
||||||
TUNABLE_INT_FETCH("hw.mpr.spinup_wait_time", &sc->spinup_wait_time);
|
TUNABLE_INT_FETCH("hw.mpr.spinup_wait_time", &sc->spinup_wait_time);
|
||||||
|
TUNABLE_INT_FETCH("hw.mpr.use_phy_num", &sc->use_phynum);
|
||||||
|
|
||||||
/* Grab the unit-instance variables */
|
/* Grab the unit-instance variables */
|
||||||
snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.debug_level",
|
snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.debug_level",
|
||||||
@ -1421,6 +1423,10 @@ mpr_get_tunables(struct mpr_softc *sc)
|
|||||||
snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.spinup_wait_time",
|
snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.spinup_wait_time",
|
||||||
device_get_unit(sc->mpr_dev));
|
device_get_unit(sc->mpr_dev));
|
||||||
TUNABLE_INT_FETCH(tmpstr, &sc->spinup_wait_time);
|
TUNABLE_INT_FETCH(tmpstr, &sc->spinup_wait_time);
|
||||||
|
|
||||||
|
snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.use_phy_num",
|
||||||
|
device_get_unit(sc->mpr_dev));
|
||||||
|
TUNABLE_INT_FETCH(tmpstr, &sc->use_phynum);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1510,6 +1516,10 @@ mpr_setup_sysctl(struct mpr_softc *sc)
|
|||||||
OID_AUTO, "spinup_wait_time", CTLFLAG_RD,
|
OID_AUTO, "spinup_wait_time", CTLFLAG_RD,
|
||||||
&sc->spinup_wait_time, DEFAULT_SPINUP_WAIT, "seconds to wait for "
|
&sc->spinup_wait_time, DEFAULT_SPINUP_WAIT, "seconds to wait for "
|
||||||
"spinup after SATA ID error");
|
"spinup after SATA ID error");
|
||||||
|
|
||||||
|
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||||
|
OID_AUTO, "use_phy_num", CTLFLAG_RD, &sc->use_phynum, 0,
|
||||||
|
"Use the phy number for enumeration");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -757,13 +757,24 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
id = mpr_mapping_get_sas_id(sc, sas_address, handle);
|
/*
|
||||||
|
* use_phynum:
|
||||||
|
* 1 - use the PhyNum field as a fallback to the mapping logic
|
||||||
|
* 0 - never use the PhyNum field
|
||||||
|
* -1 - only use the PhyNum field
|
||||||
|
*/
|
||||||
|
id = MPR_MAP_BAD_ID;
|
||||||
|
if (sc->use_phynum != -1)
|
||||||
|
id = mpr_mapping_get_sas_id(sc, sas_address, handle);
|
||||||
if (id == MPR_MAP_BAD_ID) {
|
if (id == MPR_MAP_BAD_ID) {
|
||||||
printf("failure at %s:%d/%s()! Could not get ID for device "
|
if ((sc->use_phynum == 0)
|
||||||
"with handle 0x%04x\n", __FILE__, __LINE__, __func__,
|
|| ((id = config_page.PhyNum) > sassc->maxtargets)) {
|
||||||
handle);
|
mpr_dprint(sc, MPR_INFO, "failure at %s:%d/%s()! "
|
||||||
error = ENXIO;
|
"Could not get ID for device with handle 0x%04x\n",
|
||||||
goto out;
|
__FILE__, __LINE__, __func__, handle);
|
||||||
|
error = ENXIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mprsas_check_id(sassc, id) != 0) {
|
if (mprsas_check_id(sassc, id) != 0) {
|
||||||
@ -772,9 +783,16 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targ = &sassc->targets[id];
|
||||||
|
if (targ->handle != 0x0) {
|
||||||
|
mpr_dprint(sc, MPR_MAPPING, "Attempting to reuse target id "
|
||||||
|
"%d handle 0x%04x\n", id, targ->handle);
|
||||||
|
error = ENXIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
mpr_dprint(sc, MPR_MAPPING, "SAS Address from SAS device page0 = %jx\n",
|
mpr_dprint(sc, MPR_MAPPING, "SAS Address from SAS device page0 = %jx\n",
|
||||||
sas_address);
|
sas_address);
|
||||||
targ = &sassc->targets[id];
|
|
||||||
targ->devinfo = device_info;
|
targ->devinfo = device_info;
|
||||||
targ->devname = le32toh(config_page.DeviceName.High);
|
targ->devname = le32toh(config_page.DeviceName.High);
|
||||||
targ->devname = (targ->devname << 32) |
|
targ->devname = (targ->devname << 32) |
|
||||||
|
@ -271,6 +271,7 @@ struct mpr_softc {
|
|||||||
uint16_t chain_seg_size;
|
uint16_t chain_seg_size;
|
||||||
u_int enable_ssu;
|
u_int enable_ssu;
|
||||||
int spinup_wait_time;
|
int spinup_wait_time;
|
||||||
|
int use_phynum;
|
||||||
uint64_t chain_alloc_fail;
|
uint64_t chain_alloc_fail;
|
||||||
struct sysctl_ctx_list sysctl_ctx;
|
struct sysctl_ctx_list sysctl_ctx;
|
||||||
struct sysctl_oid *sysctl_tree;
|
struct sysctl_oid *sysctl_tree;
|
||||||
|
@ -1353,6 +1353,7 @@ mps_get_tunables(struct mps_softc *sc)
|
|||||||
sc->max_io_pages = MPS_MAXIO_PAGES;
|
sc->max_io_pages = MPS_MAXIO_PAGES;
|
||||||
sc->enable_ssu = MPS_SSU_ENABLE_SSD_DISABLE_HDD;
|
sc->enable_ssu = MPS_SSU_ENABLE_SSD_DISABLE_HDD;
|
||||||
sc->spinup_wait_time = DEFAULT_SPINUP_WAIT;
|
sc->spinup_wait_time = DEFAULT_SPINUP_WAIT;
|
||||||
|
sc->use_phynum = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Grab the global variables.
|
* Grab the global variables.
|
||||||
@ -1364,6 +1365,7 @@ mps_get_tunables(struct mps_softc *sc)
|
|||||||
TUNABLE_INT_FETCH("hw.mps.max_io_pages", &sc->max_io_pages);
|
TUNABLE_INT_FETCH("hw.mps.max_io_pages", &sc->max_io_pages);
|
||||||
TUNABLE_INT_FETCH("hw.mps.enable_ssu", &sc->enable_ssu);
|
TUNABLE_INT_FETCH("hw.mps.enable_ssu", &sc->enable_ssu);
|
||||||
TUNABLE_INT_FETCH("hw.mps.spinup_wait_time", &sc->spinup_wait_time);
|
TUNABLE_INT_FETCH("hw.mps.spinup_wait_time", &sc->spinup_wait_time);
|
||||||
|
TUNABLE_INT_FETCH("hw.mps.use_phy_num", &sc->use_phynum);
|
||||||
|
|
||||||
/* Grab the unit-instance variables */
|
/* Grab the unit-instance variables */
|
||||||
snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.debug_level",
|
snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.debug_level",
|
||||||
@ -1398,6 +1400,10 @@ mps_get_tunables(struct mps_softc *sc)
|
|||||||
snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.spinup_wait_time",
|
snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.spinup_wait_time",
|
||||||
device_get_unit(sc->mps_dev));
|
device_get_unit(sc->mps_dev));
|
||||||
TUNABLE_INT_FETCH(tmpstr, &sc->spinup_wait_time);
|
TUNABLE_INT_FETCH(tmpstr, &sc->spinup_wait_time);
|
||||||
|
|
||||||
|
snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.use_phy_num",
|
||||||
|
device_get_unit(sc->mps_dev));
|
||||||
|
TUNABLE_INT_FETCH(tmpstr, &sc->use_phynum);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1495,6 +1501,10 @@ mps_setup_sysctl(struct mps_softc *sc)
|
|||||||
SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||||
OID_AUTO, "encl_table_dump", CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
|
OID_AUTO, "encl_table_dump", CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
|
||||||
mps_mapping_encl_dump, "A", "Enclosure Table Dump");
|
mps_mapping_encl_dump, "A", "Enclosure Table Dump");
|
||||||
|
|
||||||
|
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||||
|
OID_AUTO, "use_phy_num", CTLFLAG_RD, &sc->use_phynum, 0,
|
||||||
|
"Use the phy number for enumeration");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1872,6 +1872,10 @@ mpssas_action_scsiio(struct mpssas_softc *sassc, union ccb *ccb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
if (csio->bio != NULL)
|
||||||
|
biotrack(csio->bio, __func__);
|
||||||
|
#endif
|
||||||
callout_reset_sbt(&cm->cm_callout, SBT_1MS * ccb->ccb_h.timeout, 0,
|
callout_reset_sbt(&cm->cm_callout, SBT_1MS * ccb->ccb_h.timeout, 0,
|
||||||
mpssas_scsiio_timeout, cm, 0);
|
mpssas_scsiio_timeout, cm, 0);
|
||||||
|
|
||||||
@ -2125,6 +2129,11 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
|
|||||||
TAILQ_REMOVE(&cm->cm_targ->commands, cm, cm_link);
|
TAILQ_REMOVE(&cm->cm_targ->commands, cm, cm_link);
|
||||||
ccb->ccb_h.status &= ~(CAM_STATUS_MASK | CAM_SIM_QUEUED);
|
ccb->ccb_h.status &= ~(CAM_STATUS_MASK | CAM_SIM_QUEUED);
|
||||||
|
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
if (ccb->csio.bio != NULL)
|
||||||
|
biotrack(ccb->csio.bio, __func__);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (cm->cm_state == MPS_CM_STATE_TIMEDOUT) {
|
if (cm->cm_state == MPS_CM_STATE_TIMEDOUT) {
|
||||||
TAILQ_REMOVE(&cm->cm_targ->timedout_commands, cm, cm_recovery);
|
TAILQ_REMOVE(&cm->cm_targ->timedout_commands, cm, cm_recovery);
|
||||||
if (cm->cm_reply != NULL)
|
if (cm->cm_reply != NULL)
|
||||||
|
@ -669,13 +669,24 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
id = mps_mapping_get_sas_id(sc, sas_address, handle);
|
/*
|
||||||
|
* use_phynum:
|
||||||
|
* 1 - use the PhyNum field as a fallback to the mapping logic
|
||||||
|
* 0 - never use the PhyNum field
|
||||||
|
* -1 - only use the PhyNum field
|
||||||
|
*/
|
||||||
|
id = MPS_MAP_BAD_ID;
|
||||||
|
if (sc->use_phynum != -1)
|
||||||
|
id = mps_mapping_get_sas_id(sc, sas_address, handle);
|
||||||
if (id == MPS_MAP_BAD_ID) {
|
if (id == MPS_MAP_BAD_ID) {
|
||||||
printf("failure at %s:%d/%s()! Could not get ID for device "
|
if ((sc->use_phynum == 0)
|
||||||
"with handle 0x%04x\n", __FILE__, __LINE__, __func__,
|
|| ((id = config_page.PhyNum) > sassc->maxtargets)) {
|
||||||
handle);
|
mps_dprint(sc, MPS_INFO, "failure at %s:%d/%s()! "
|
||||||
error = ENXIO;
|
"Could not get ID for device with handle 0x%04x\n",
|
||||||
goto out;
|
__FILE__, __LINE__, __func__, handle);
|
||||||
|
error = ENXIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpssas_check_id(sassc, id) != 0) {
|
if (mpssas_check_id(sassc, id) != 0) {
|
||||||
@ -684,9 +695,16 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targ = &sassc->targets[id];
|
||||||
|
if (targ->handle != 0x0) {
|
||||||
|
mps_dprint(sc, MPS_MAPPING, "Attempting to reuse target id "
|
||||||
|
"%d handle 0x%04x\n", id, targ->handle);
|
||||||
|
error = ENXIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
mps_dprint(sc, MPS_MAPPING, "SAS Address from SAS device page0 = %jx\n",
|
mps_dprint(sc, MPS_MAPPING, "SAS Address from SAS device page0 = %jx\n",
|
||||||
sas_address);
|
sas_address);
|
||||||
targ = &sassc->targets[id];
|
|
||||||
targ->devinfo = device_info;
|
targ->devinfo = device_info;
|
||||||
targ->devname = le32toh(config_page.DeviceName.High);
|
targ->devname = le32toh(config_page.DeviceName.High);
|
||||||
targ->devname = (targ->devname << 32) |
|
targ->devname = (targ->devname << 32) |
|
||||||
|
@ -285,6 +285,7 @@ struct mps_softc {
|
|||||||
int chain_free_lowwater;
|
int chain_free_lowwater;
|
||||||
u_int enable_ssu;
|
u_int enable_ssu;
|
||||||
int spinup_wait_time;
|
int spinup_wait_time;
|
||||||
|
int use_phynum;
|
||||||
uint64_t chain_alloc_fail;
|
uint64_t chain_alloc_fail;
|
||||||
struct sysctl_ctx_list sysctl_ctx;
|
struct sysctl_ctx_list sysctl_ctx;
|
||||||
struct sysctl_oid *sysctl_tree;
|
struct sysctl_oid *sysctl_tree;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SDHCI driver glue for Freescale i.MX SoC family.
|
* SDHCI driver glue for Freescale i.MX SoC and QorIQ families.
|
||||||
*
|
*
|
||||||
* This supports both eSDHC (earlier SoCs) and uSDHC (more recent SoCs).
|
* This supports both eSDHC (earlier SoCs) and uSDHC (more recent SoCs).
|
||||||
*/
|
*/
|
||||||
@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
#include <sys/callout.h>
|
#include <sys/callout.h>
|
||||||
|
#include <sys/endian.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/libkern.h>
|
#include <sys/libkern.h>
|
||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
@ -52,9 +53,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
#include <machine/resource.h>
|
#include <machine/resource.h>
|
||||||
|
#ifdef __arm__
|
||||||
#include <machine/intr.h>
|
#include <machine/intr.h>
|
||||||
|
|
||||||
#include <arm/freescale/imx/imx_ccmvar.h>
|
#include <arm/freescale/imx/imx_ccmvar.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <dev/ofw/ofw_bus.h>
|
#include <dev/ofw/ofw_bus.h>
|
||||||
#include <dev/ofw/ofw_bus_subr.h>
|
#include <dev/ofw/ofw_bus_subr.h>
|
||||||
@ -66,7 +69,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/sdhci/sdhci.h>
|
#include <dev/sdhci/sdhci.h>
|
||||||
#include "sdhci_if.h"
|
#include "sdhci_if.h"
|
||||||
|
|
||||||
struct imx_sdhci_softc {
|
struct fsl_sdhci_softc {
|
||||||
device_t dev;
|
device_t dev;
|
||||||
struct resource * mem_res;
|
struct resource * mem_res;
|
||||||
struct resource * irq_res;
|
struct resource * irq_res;
|
||||||
@ -88,8 +91,8 @@ struct imx_sdhci_softc {
|
|||||||
#define R1BFIX_AC12 2 /* Wait for busy after auto command 12. */
|
#define R1BFIX_AC12 2 /* Wait for busy after auto command 12. */
|
||||||
|
|
||||||
#define HWTYPE_NONE 0 /* Hardware not recognized/supported. */
|
#define HWTYPE_NONE 0 /* Hardware not recognized/supported. */
|
||||||
#define HWTYPE_ESDHC 1 /* imx5x and earlier. */
|
#define HWTYPE_ESDHC 1 /* fsl5x and earlier. */
|
||||||
#define HWTYPE_USDHC 2 /* imx6. */
|
#define HWTYPE_USDHC 2 /* fsl6. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Freescale-specific registers, or in some cases the layout of bits within the
|
* Freescale-specific registers, or in some cases the layout of bits within the
|
||||||
@ -146,7 +149,6 @@ struct imx_sdhci_softc {
|
|||||||
#define SDHC_PROT_CDSS (1 << 7)
|
#define SDHC_PROT_CDSS (1 << 7)
|
||||||
|
|
||||||
#define SDHC_SYS_CTRL 0x2c
|
#define SDHC_SYS_CTRL 0x2c
|
||||||
#define SDHC_INT_STATUS 0x30
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The clock enable bits exist in different registers for ESDHC vs USDHC, but
|
* The clock enable bits exist in different registers for ESDHC vs USDHC, but
|
||||||
@ -169,31 +171,32 @@ static struct ofw_compat_data compat_data[] = {
|
|||||||
{"fsl,imx6sl-usdhc", HWTYPE_USDHC},
|
{"fsl,imx6sl-usdhc", HWTYPE_USDHC},
|
||||||
{"fsl,imx53-esdhc", HWTYPE_ESDHC},
|
{"fsl,imx53-esdhc", HWTYPE_ESDHC},
|
||||||
{"fsl,imx51-esdhc", HWTYPE_ESDHC},
|
{"fsl,imx51-esdhc", HWTYPE_ESDHC},
|
||||||
|
{"fsl,esdhc", HWTYPE_ESDHC},
|
||||||
{NULL, HWTYPE_NONE},
|
{NULL, HWTYPE_NONE},
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint16_t imx_sdhc_get_clock(struct imx_sdhci_softc *sc);
|
static uint16_t fsl_sdhc_get_clock(struct fsl_sdhci_softc *sc);
|
||||||
static void imx_sdhc_set_clock(struct imx_sdhci_softc *sc, uint16_t val);
|
static void fsl_sdhc_set_clock(struct fsl_sdhci_softc *sc, uint16_t val);
|
||||||
static void imx_sdhci_r1bfix_func(void *arg);
|
static void fsl_sdhci_r1bfix_func(void *arg);
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
RD4(struct imx_sdhci_softc *sc, bus_size_t off)
|
RD4(struct fsl_sdhci_softc *sc, bus_size_t off)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (bus_read_4(sc->mem_res, off));
|
return (bus_read_4(sc->mem_res, off));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
WR4(struct imx_sdhci_softc *sc, bus_size_t off, uint32_t val)
|
WR4(struct fsl_sdhci_softc *sc, bus_size_t off, uint32_t val)
|
||||||
{
|
{
|
||||||
|
|
||||||
bus_write_4(sc->mem_res, off, val);
|
bus_write_4(sc->mem_res, off, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
imx_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
fsl_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||||
uint32_t val32, wrk32;
|
uint32_t val32, wrk32;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -246,9 +249,9 @@ imx_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t
|
static uint16_t
|
||||||
imx_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
fsl_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||||
uint32_t val32;
|
uint32_t val32;
|
||||||
|
|
||||||
if (sc->hwtype == HWTYPE_USDHC) {
|
if (sc->hwtype == HWTYPE_USDHC) {
|
||||||
@ -297,16 +300,16 @@ imx_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
|||||||
* hardware type, complex enough to have their own function.
|
* hardware type, complex enough to have their own function.
|
||||||
*/
|
*/
|
||||||
if (off == SDHCI_CLOCK_CONTROL) {
|
if (off == SDHCI_CLOCK_CONTROL) {
|
||||||
return (imx_sdhc_get_clock(sc));
|
return (fsl_sdhc_get_clock(sc));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xffff);
|
return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
fsl_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||||
uint32_t val32, wrk32;
|
uint32_t val32, wrk32;
|
||||||
|
|
||||||
val32 = RD4(sc, off);
|
val32 = RD4(sc, off);
|
||||||
@ -348,7 +351,7 @@ imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* imx_sdhci_intr() can synthesize a DATA_END interrupt following a
|
* fsl_sdhci_intr() can synthesize a DATA_END interrupt following a
|
||||||
* command with an R1B response, mix it into the hardware status.
|
* command with an R1B response, mix it into the hardware status.
|
||||||
*/
|
*/
|
||||||
if (off == SDHCI_INT_STATUS) {
|
if (off == SDHCI_INT_STATUS) {
|
||||||
@ -359,18 +362,18 @@ imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
imx_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
|
fsl_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
|
||||||
uint32_t *data, bus_size_t count)
|
uint32_t *data, bus_size_t count)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||||
|
|
||||||
bus_read_multi_4(sc->mem_res, off, data, count);
|
bus_read_multi_4(sc->mem_res, off, data, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
imx_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val)
|
fsl_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||||
uint32_t val32;
|
uint32_t val32;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -397,6 +400,11 @@ imx_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t
|
|||||||
if (off == SDHCI_POWER_CONTROL) {
|
if (off == SDHCI_POWER_CONTROL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef __powerpc__
|
||||||
|
/* XXX Reset doesn't seem to work as expected. Do nothing for now. */
|
||||||
|
if (off == SDHCI_SOFTWARE_RESET)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
val32 = RD4(sc, off & ~3);
|
val32 = RD4(sc, off & ~3);
|
||||||
val32 &= ~(0xff << (off & 3) * 8);
|
val32 &= ~(0xff << (off & 3) * 8);
|
||||||
@ -406,9 +414,9 @@ imx_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
imx_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val)
|
fsl_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||||
uint32_t val32;
|
uint32_t val32;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -416,7 +424,7 @@ imx_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_
|
|||||||
* that can handle the ESDHC versus USDHC differences.
|
* that can handle the ESDHC versus USDHC differences.
|
||||||
*/
|
*/
|
||||||
if (off == SDHCI_CLOCK_CONTROL) {
|
if (off == SDHCI_CLOCK_CONTROL) {
|
||||||
imx_sdhc_set_clock(sc, val);
|
fsl_sdhc_set_clock(sc, val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +440,7 @@ imx_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_
|
|||||||
* there's a control bit for it (bit 3) in the vendor register.
|
* there's a control bit for it (bit 3) in the vendor register.
|
||||||
* When we're starting a command that needs a manual DAT0 line check at
|
* When we're starting a command that needs a manual DAT0 line check at
|
||||||
* interrupt time, we leave ourselves a note in r1bfix_type so that we
|
* interrupt time, we leave ourselves a note in r1bfix_type so that we
|
||||||
* can do the extra work in imx_sdhci_intr().
|
* can do the extra work in fsl_sdhci_intr().
|
||||||
*/
|
*/
|
||||||
if (off == SDHCI_COMMAND_FLAGS) {
|
if (off == SDHCI_COMMAND_FLAGS) {
|
||||||
if (val & SDHCI_CMD_DATA) {
|
if (val & SDHCI_CMD_DATA) {
|
||||||
@ -485,9 +493,9 @@ imx_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
imx_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val)
|
fsl_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||||
|
|
||||||
/* Clear synthesized interrupts, then pass the value to the hardware. */
|
/* Clear synthesized interrupts, then pass the value to the hardware. */
|
||||||
if (off == SDHCI_INT_STATUS) {
|
if (off == SDHCI_INT_STATUS) {
|
||||||
@ -498,16 +506,16 @@ imx_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
imx_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
|
fsl_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
|
||||||
uint32_t *data, bus_size_t count)
|
uint32_t *data, bus_size_t count)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||||
|
|
||||||
bus_write_multi_4(sc->mem_res, off, data, count);
|
bus_write_multi_4(sc->mem_res, off, data, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t
|
static uint16_t
|
||||||
imx_sdhc_get_clock(struct imx_sdhci_softc *sc)
|
fsl_sdhc_get_clock(struct fsl_sdhci_softc *sc)
|
||||||
{
|
{
|
||||||
uint16_t val;
|
uint16_t val;
|
||||||
|
|
||||||
@ -531,17 +539,20 @@ imx_sdhc_get_clock(struct imx_sdhci_softc *sc)
|
|||||||
val |= SDHCI_CLOCK_INT_STABLE;
|
val |= SDHCI_CLOCK_INT_STABLE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On ESDHC hardware the card bus clock enable is in the usual sdhci
|
* On i.MX ESDHC hardware the card bus clock enable is in the usual
|
||||||
* register but it's a different bit, so transcribe it (note the
|
* sdhci register but it's a different bit, so transcribe it (note the
|
||||||
* difference between standard SDHCI_ and Freescale SDHC_ prefixes
|
* difference between standard SDHCI_ and Freescale SDHC_ prefixes
|
||||||
* here). On USDHC hardware there is a force-on bit, but no force-off
|
* here). On USDHC and QorIQ ESDHC hardware there is a force-on bit, but
|
||||||
* for the card bus clock (the hardware runs the clock when transfers
|
* no force-off for the card bus clock (the hardware runs the clock when
|
||||||
* are active no matter what), so we always say the clock is on.
|
* transfers are active no matter what), so we always say the clock is
|
||||||
|
* on.
|
||||||
* XXX Maybe we should say it's in whatever state the sdhci driver last
|
* XXX Maybe we should say it's in whatever state the sdhci driver last
|
||||||
* set it to.
|
* set it to.
|
||||||
*/
|
*/
|
||||||
if (sc->hwtype == HWTYPE_ESDHC) {
|
if (sc->hwtype == HWTYPE_ESDHC) {
|
||||||
|
#ifdef __arm__
|
||||||
if (RD4(sc, SDHC_SYS_CTRL) & SDHC_CLK_SDCLKEN)
|
if (RD4(sc, SDHC_SYS_CTRL) & SDHC_CLK_SDCLKEN)
|
||||||
|
#endif
|
||||||
val |= SDHCI_CLOCK_CARD_EN;
|
val |= SDHCI_CLOCK_CARD_EN;
|
||||||
} else {
|
} else {
|
||||||
val |= SDHCI_CLOCK_CARD_EN;
|
val |= SDHCI_CLOCK_CARD_EN;
|
||||||
@ -551,7 +562,7 @@ imx_sdhc_get_clock(struct imx_sdhci_softc *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
imx_sdhc_set_clock(struct imx_sdhci_softc *sc, uint16_t val)
|
fsl_sdhc_set_clock(struct fsl_sdhci_softc *sc, uint16_t val)
|
||||||
{
|
{
|
||||||
uint32_t divisor, freq, prescale, val32;
|
uint32_t divisor, freq, prescale, val32;
|
||||||
|
|
||||||
@ -565,15 +576,18 @@ imx_sdhc_set_clock(struct imx_sdhci_softc *sc, uint16_t val)
|
|||||||
sc->sdclockreg_freq_bits = val & SDHCI_DIVIDERS_MASK;
|
sc->sdclockreg_freq_bits = val & SDHCI_DIVIDERS_MASK;
|
||||||
if (sc->hwtype == HWTYPE_ESDHC) {
|
if (sc->hwtype == HWTYPE_ESDHC) {
|
||||||
/*
|
/*
|
||||||
* The ESDHC hardware requires the driver to manually start and
|
* The i.MX5 ESDHC hardware requires the driver to manually
|
||||||
* stop the sd bus clock. If the enable bit is not set, turn
|
* start and stop the sd bus clock. If the enable bit is not
|
||||||
* off the clock in hardware and we're done, otherwise decode
|
* set, turn off the clock in hardware and we're done, otherwise
|
||||||
* the requested frequency. ESDHC hardware is sdhci 2.0; the
|
* decode the requested frequency. ESDHC hardware is sdhci 2.0;
|
||||||
* sdhci driver will use the original 8-bit divisor field and
|
* the sdhci driver will use the original 8-bit divisor field
|
||||||
* the "base / 2^N" divisor scheme.
|
* and the "base / 2^N" divisor scheme.
|
||||||
*/
|
*/
|
||||||
if ((val & SDHCI_CLOCK_CARD_EN) == 0) {
|
if ((val & SDHCI_CLOCK_CARD_EN) == 0) {
|
||||||
|
#ifdef __arm__
|
||||||
|
/* On QorIQ, this is a reserved bit. */
|
||||||
WR4(sc, SDHCI_CLOCK_CONTROL, val32 & ~SDHC_CLK_SDCLKEN);
|
WR4(sc, SDHCI_CLOCK_CONTROL, val32 & ~SDHC_CLK_SDCLKEN);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -625,11 +639,12 @@ imx_sdhc_set_clock(struct imx_sdhci_softc *sc, uint16_t val)
|
|||||||
val32 &= ~(SDHC_CLK_DIVISOR_MASK | SDHC_CLK_PRESCALE_MASK);
|
val32 &= ~(SDHC_CLK_DIVISOR_MASK | SDHC_CLK_PRESCALE_MASK);
|
||||||
val32 |= divisor << SDHC_CLK_DIVISOR_SHIFT;
|
val32 |= divisor << SDHC_CLK_DIVISOR_SHIFT;
|
||||||
val32 |= prescale << SDHC_CLK_PRESCALE_SHIFT;
|
val32 |= prescale << SDHC_CLK_PRESCALE_SHIFT;
|
||||||
|
val32 |= SDHC_CLK_IPGEN;
|
||||||
WR4(sc, SDHCI_CLOCK_CONTROL, val32);
|
WR4(sc, SDHCI_CLOCK_CONTROL, val32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean_t
|
static boolean_t
|
||||||
imx_sdhci_r1bfix_is_wait_done(struct imx_sdhci_softc *sc)
|
fsl_sdhci_r1bfix_is_wait_done(struct fsl_sdhci_softc *sc)
|
||||||
{
|
{
|
||||||
uint32_t inhibit;
|
uint32_t inhibit;
|
||||||
|
|
||||||
@ -646,7 +661,7 @@ imx_sdhci_r1bfix_is_wait_done(struct imx_sdhci_softc *sc)
|
|||||||
|
|
||||||
if (inhibit && getsbinuptime() < sc->r1bfix_timeout_at) {
|
if (inhibit && getsbinuptime() < sc->r1bfix_timeout_at) {
|
||||||
callout_reset_sbt(&sc->r1bfix_callout, SBT_1MS, 0,
|
callout_reset_sbt(&sc->r1bfix_callout, SBT_1MS, 0,
|
||||||
imx_sdhci_r1bfix_func, sc, 0);
|
fsl_sdhci_r1bfix_func, sc, 0);
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,22 +685,22 @@ imx_sdhci_r1bfix_is_wait_done(struct imx_sdhci_softc *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
imx_sdhci_r1bfix_func(void * arg)
|
fsl_sdhci_r1bfix_func(void * arg)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = arg;
|
struct fsl_sdhci_softc *sc = arg;
|
||||||
boolean_t r1bwait_done;
|
boolean_t r1bwait_done;
|
||||||
|
|
||||||
mtx_lock(&sc->slot.mtx);
|
mtx_lock(&sc->slot.mtx);
|
||||||
r1bwait_done = imx_sdhci_r1bfix_is_wait_done(sc);
|
r1bwait_done = fsl_sdhci_r1bfix_is_wait_done(sc);
|
||||||
mtx_unlock(&sc->slot.mtx);
|
mtx_unlock(&sc->slot.mtx);
|
||||||
if (r1bwait_done)
|
if (r1bwait_done)
|
||||||
sdhci_generic_intr(&sc->slot);
|
sdhci_generic_intr(&sc->slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
imx_sdhci_intr(void *arg)
|
fsl_sdhci_intr(void *arg)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = arg;
|
struct fsl_sdhci_softc *sc = arg;
|
||||||
uint32_t intmask;
|
uint32_t intmask;
|
||||||
|
|
||||||
mtx_lock(&sc->slot.mtx);
|
mtx_lock(&sc->slot.mtx);
|
||||||
@ -710,10 +725,10 @@ imx_sdhci_intr(void *arg)
|
|||||||
*/
|
*/
|
||||||
switch (sc->r1bfix_type) {
|
switch (sc->r1bfix_type) {
|
||||||
case R1BFIX_NODATA:
|
case R1BFIX_NODATA:
|
||||||
intmask = RD4(sc, SDHC_INT_STATUS) & SDHCI_INT_RESPONSE;
|
intmask = RD4(sc, SDHCI_INT_STATUS) & SDHCI_INT_RESPONSE;
|
||||||
break;
|
break;
|
||||||
case R1BFIX_AC12:
|
case R1BFIX_AC12:
|
||||||
intmask = RD4(sc, SDHC_INT_STATUS) & SDHCI_INT_DATA_END;
|
intmask = RD4(sc, SDHCI_INT_STATUS) & SDHCI_INT_DATA_END;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
intmask = 0;
|
intmask = 0;
|
||||||
@ -721,9 +736,9 @@ imx_sdhci_intr(void *arg)
|
|||||||
}
|
}
|
||||||
if (intmask) {
|
if (intmask) {
|
||||||
sc->r1bfix_timeout_at = getsbinuptime() + 250 * SBT_1MS;
|
sc->r1bfix_timeout_at = getsbinuptime() + 250 * SBT_1MS;
|
||||||
if (!imx_sdhci_r1bfix_is_wait_done(sc)) {
|
if (!fsl_sdhci_r1bfix_is_wait_done(sc)) {
|
||||||
WR4(sc, SDHC_INT_STATUS, intmask);
|
WR4(sc, SDHCI_INT_STATUS, intmask);
|
||||||
bus_barrier(sc->mem_res, SDHC_INT_STATUS, 4,
|
bus_barrier(sc->mem_res, SDHCI_INT_STATUS, 4,
|
||||||
BUS_SPACE_BARRIER_WRITE);
|
BUS_SPACE_BARRIER_WRITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -733,31 +748,76 @@ imx_sdhci_intr(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
imx_sdhci_get_ro(device_t bus, device_t child)
|
fsl_sdhci_get_ro(device_t bus, device_t child)
|
||||||
{
|
{
|
||||||
|
struct fsl_sdhci_softc *sc = device_get_softc(bus);
|
||||||
|
|
||||||
return (false);
|
if (RD4(sc, SDHCI_PRESENT_STATE) & SDHC_PRES_WPSPL)
|
||||||
|
return (false);
|
||||||
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __powerpc__
|
||||||
|
static uint32_t
|
||||||
|
fsl_sdhci_get_platform_clock(device_t dev)
|
||||||
|
{
|
||||||
|
device_t parent;
|
||||||
|
phandle_t node;
|
||||||
|
uint32_t clock;
|
||||||
|
|
||||||
|
node = ofw_bus_get_node(dev);
|
||||||
|
|
||||||
|
/* Get sdhci node properties */
|
||||||
|
if((OF_getprop(node, "clock-frequency", (void *)&clock,
|
||||||
|
sizeof(clock)) <= 0) || (clock == 0)) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trying to get clock from parent device (soc) if correct
|
||||||
|
* clock cannot be acquired from sdhci node.
|
||||||
|
*/
|
||||||
|
parent = device_get_parent(dev);
|
||||||
|
node = ofw_bus_get_node(parent);
|
||||||
|
|
||||||
|
/* Get soc properties */
|
||||||
|
if ((OF_getprop(node, "bus-frequency", (void *)&clock,
|
||||||
|
sizeof(clock)) <= 0) || (clock == 0)) {
|
||||||
|
device_printf(dev,"Cannot acquire correct sdhci "
|
||||||
|
"frequency from DTS.\n");
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
/* eSDHC clock is 1/2 platform clock. */
|
||||||
|
clock /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bootverbose)
|
||||||
|
device_printf(dev, "Acquired clock: %d from DTS\n", clock);
|
||||||
|
|
||||||
|
return (clock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
imx_sdhci_detach(device_t dev)
|
fsl_sdhci_detach(device_t dev)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (EBUSY);
|
return (EBUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
imx_sdhci_attach(device_t dev)
|
fsl_sdhci_attach(device_t dev)
|
||||||
{
|
{
|
||||||
struct imx_sdhci_softc *sc = device_get_softc(dev);
|
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||||
int rid, err;
|
int rid, err;
|
||||||
phandle_t node;
|
phandle_t node;
|
||||||
|
uint32_t protctl;
|
||||||
|
|
||||||
sc->dev = dev;
|
sc->dev = dev;
|
||||||
|
|
||||||
sc->hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
|
sc->hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
|
||||||
if (sc->hwtype == HWTYPE_NONE)
|
if (sc->hwtype == HWTYPE_NONE)
|
||||||
panic("Impossible: not compatible in imx_sdhci_attach()");
|
panic("Impossible: not compatible in fsl_sdhci_attach()");
|
||||||
|
|
||||||
rid = 0;
|
rid = 0;
|
||||||
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
|
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
|
||||||
@ -778,7 +838,7 @@ imx_sdhci_attach(device_t dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
|
if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
|
||||||
NULL, imx_sdhci_intr, sc, &sc->intr_cookie)) {
|
NULL, fsl_sdhci_intr, sc, &sc->intr_cookie)) {
|
||||||
device_printf(dev, "cannot setup interrupt handler\n");
|
device_printf(dev, "cannot setup interrupt handler\n");
|
||||||
err = ENXIO;
|
err = ENXIO;
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -807,9 +867,23 @@ imx_sdhci_attach(device_t dev)
|
|||||||
*
|
*
|
||||||
* XXX need named constants for this stuff.
|
* XXX need named constants for this stuff.
|
||||||
*/
|
*/
|
||||||
WR4(sc, SDHC_WTMK_LVL, 0x08800880);
|
#ifdef __powerpc__
|
||||||
|
/* P1022 has the '*_BRST_LEN' fields as reserved, always reading 0x10 */
|
||||||
|
if ((SVR_VER(mfspr(SPR_SVR)) & 0xfff6) == SVR_P1022 )
|
||||||
|
WR4(sc, SDHC_WTMK_LVL, 0x10801080);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
WR4(sc, SDHC_WTMK_LVL, 0x08800880);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We read in native byte order in the main driver, but the register
|
||||||
|
* defaults to little endian.
|
||||||
|
*/
|
||||||
|
#ifdef __powerpc__
|
||||||
|
sc->baseclk_hz = fsl_sdhci_get_platform_clock(dev);
|
||||||
|
#else
|
||||||
sc->baseclk_hz = imx_ccm_sdhci_hz();
|
sc->baseclk_hz = imx_ccm_sdhci_hz();
|
||||||
|
#endif
|
||||||
sc->slot.max_clk = sc->baseclk_hz;
|
sc->slot.max_clk = sc->baseclk_hz;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -830,6 +904,16 @@ imx_sdhci_attach(device_t dev)
|
|||||||
/* XXX put real gpio hookup here. */
|
/* XXX put real gpio hookup here. */
|
||||||
sc->force_card_present = true;
|
sc->force_card_present = true;
|
||||||
}
|
}
|
||||||
|
#ifdef __powerpc__
|
||||||
|
/* Default to big-endian on powerpc */
|
||||||
|
protctl = RD4(sc, SDHC_PROT_CTRL);
|
||||||
|
protctl &= ~SDHC_PROT_EMODE_MASK;
|
||||||
|
if (OF_hasprop(node, "little-endian"))
|
||||||
|
protctl |= SDHC_PROT_EMODE_LITTLE;
|
||||||
|
else
|
||||||
|
protctl |= SDHC_PROT_EMODE_BIG;
|
||||||
|
WR4(sc, SDHC_PROT_CTRL, protctl);
|
||||||
|
#endif
|
||||||
|
|
||||||
callout_init(&sc->r1bfix_callout, 1);
|
callout_init(&sc->r1bfix_callout, 1);
|
||||||
sdhci_init_slot(dev, &sc->slot, 0);
|
sdhci_init_slot(dev, &sc->slot, 0);
|
||||||
@ -853,7 +937,7 @@ imx_sdhci_attach(device_t dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
imx_sdhci_probe(device_t dev)
|
fsl_sdhci_probe(device_t dev)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!ofw_bus_status_okay(dev))
|
if (!ofw_bus_status_okay(dev))
|
||||||
@ -872,11 +956,11 @@ imx_sdhci_probe(device_t dev)
|
|||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static device_method_t imx_sdhci_methods[] = {
|
static device_method_t fsl_sdhci_methods[] = {
|
||||||
/* Device interface */
|
/* Device interface */
|
||||||
DEVMETHOD(device_probe, imx_sdhci_probe),
|
DEVMETHOD(device_probe, fsl_sdhci_probe),
|
||||||
DEVMETHOD(device_attach, imx_sdhci_attach),
|
DEVMETHOD(device_attach, fsl_sdhci_attach),
|
||||||
DEVMETHOD(device_detach, imx_sdhci_detach),
|
DEVMETHOD(device_detach, fsl_sdhci_detach),
|
||||||
|
|
||||||
/* Bus interface */
|
/* Bus interface */
|
||||||
DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar),
|
DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar),
|
||||||
@ -886,32 +970,32 @@ static device_method_t imx_sdhci_methods[] = {
|
|||||||
/* MMC bridge interface */
|
/* MMC bridge interface */
|
||||||
DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios),
|
DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios),
|
||||||
DEVMETHOD(mmcbr_request, sdhci_generic_request),
|
DEVMETHOD(mmcbr_request, sdhci_generic_request),
|
||||||
DEVMETHOD(mmcbr_get_ro, imx_sdhci_get_ro),
|
DEVMETHOD(mmcbr_get_ro, fsl_sdhci_get_ro),
|
||||||
DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host),
|
DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host),
|
||||||
DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host),
|
DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host),
|
||||||
|
|
||||||
/* SDHCI registers accessors */
|
/* SDHCI registers accessors */
|
||||||
DEVMETHOD(sdhci_read_1, imx_sdhci_read_1),
|
DEVMETHOD(sdhci_read_1, fsl_sdhci_read_1),
|
||||||
DEVMETHOD(sdhci_read_2, imx_sdhci_read_2),
|
DEVMETHOD(sdhci_read_2, fsl_sdhci_read_2),
|
||||||
DEVMETHOD(sdhci_read_4, imx_sdhci_read_4),
|
DEVMETHOD(sdhci_read_4, fsl_sdhci_read_4),
|
||||||
DEVMETHOD(sdhci_read_multi_4, imx_sdhci_read_multi_4),
|
DEVMETHOD(sdhci_read_multi_4, fsl_sdhci_read_multi_4),
|
||||||
DEVMETHOD(sdhci_write_1, imx_sdhci_write_1),
|
DEVMETHOD(sdhci_write_1, fsl_sdhci_write_1),
|
||||||
DEVMETHOD(sdhci_write_2, imx_sdhci_write_2),
|
DEVMETHOD(sdhci_write_2, fsl_sdhci_write_2),
|
||||||
DEVMETHOD(sdhci_write_4, imx_sdhci_write_4),
|
DEVMETHOD(sdhci_write_4, fsl_sdhci_write_4),
|
||||||
DEVMETHOD(sdhci_write_multi_4, imx_sdhci_write_multi_4),
|
DEVMETHOD(sdhci_write_multi_4, fsl_sdhci_write_multi_4),
|
||||||
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static devclass_t imx_sdhci_devclass;
|
static devclass_t fsl_sdhci_devclass;
|
||||||
|
|
||||||
static driver_t imx_sdhci_driver = {
|
static driver_t fsl_sdhci_driver = {
|
||||||
"sdhci_imx",
|
"sdhci_fsl",
|
||||||
imx_sdhci_methods,
|
fsl_sdhci_methods,
|
||||||
sizeof(struct imx_sdhci_softc),
|
sizeof(struct fsl_sdhci_softc),
|
||||||
};
|
};
|
||||||
|
|
||||||
DRIVER_MODULE(sdhci_imx, simplebus, imx_sdhci_driver, imx_sdhci_devclass, 0, 0);
|
DRIVER_MODULE(sdhci_fsl, simplebus, fsl_sdhci_driver, fsl_sdhci_devclass, 0, 0);
|
||||||
MODULE_DEPEND(sdhci_imx, sdhci, 1, 1, 1);
|
MODULE_DEPEND(sdhci_fsl, sdhci, 1, 1, 1);
|
||||||
DRIVER_MODULE(mmc, sdhci_imx, mmc_driver, mmc_devclass, NULL, NULL);
|
DRIVER_MODULE(mmc, sdhci_fsl, mmc_driver, mmc_devclass, NULL, NULL);
|
||||||
MODULE_DEPEND(sdhci_imx, mmc, 1, 1, 1);
|
MODULE_DEPEND(sdhci_fsl, mmc, 1, 1, 1);
|
@ -1309,7 +1309,7 @@ sdhci_acmd_irq(struct sdhci_slot *slot)
|
|||||||
void
|
void
|
||||||
sdhci_generic_intr(struct sdhci_slot *slot)
|
sdhci_generic_intr(struct sdhci_slot *slot)
|
||||||
{
|
{
|
||||||
uint32_t intmask;
|
uint32_t intmask, present;
|
||||||
|
|
||||||
SDHCI_LOCK(slot);
|
SDHCI_LOCK(slot);
|
||||||
/* Read slot interrupt status. */
|
/* Read slot interrupt status. */
|
||||||
@ -1323,6 +1323,13 @@ sdhci_generic_intr(struct sdhci_slot *slot)
|
|||||||
|
|
||||||
/* Handle card presence interrupts. */
|
/* Handle card presence interrupts. */
|
||||||
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
|
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
|
||||||
|
present = RD4(slot, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT;
|
||||||
|
slot->intmask &=
|
||||||
|
~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
|
||||||
|
slot->intmask |= present ? SDHCI_INT_CARD_REMOVE :
|
||||||
|
SDHCI_INT_CARD_INSERT;
|
||||||
|
WR4(slot, SDHCI_INT_ENABLE, slot->intmask);
|
||||||
|
WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask);
|
||||||
WR4(slot, SDHCI_INT_STATUS, intmask &
|
WR4(slot, SDHCI_INT_STATUS, intmask &
|
||||||
(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE));
|
(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE));
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ struct smbus_ivar
|
|||||||
/*
|
/*
|
||||||
* Autoconfiguration and support routines for System Management bus
|
* Autoconfiguration and support routines for System Management bus
|
||||||
*/
|
*/
|
||||||
static void smbus_probe_device(device_t dev, u_char addr);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
smbus_probe(device_t dev)
|
smbus_probe(device_t dev)
|
||||||
@ -65,13 +64,9 @@ static int
|
|||||||
smbus_attach(device_t dev)
|
smbus_attach(device_t dev)
|
||||||
{
|
{
|
||||||
struct smbus_softc *sc = device_get_softc(dev);
|
struct smbus_softc *sc = device_get_softc(dev);
|
||||||
unsigned char addr;
|
|
||||||
|
|
||||||
mtx_init(&sc->lock, device_get_nameunit(dev), "smbus", MTX_DEF);
|
mtx_init(&sc->lock, device_get_nameunit(dev), "smbus", MTX_DEF);
|
||||||
bus_generic_probe(dev);
|
bus_generic_probe(dev);
|
||||||
for (addr = SMBUS_ADDR_MIN; addr < SMBUS_ADDR_MAX; ++addr) {
|
|
||||||
smbus_probe_device(dev, addr);
|
|
||||||
}
|
|
||||||
bus_enumerate_hinted_children(dev);
|
bus_enumerate_hinted_children(dev);
|
||||||
bus_generic_attach(dev);
|
bus_generic_attach(dev);
|
||||||
|
|
||||||
@ -98,30 +93,6 @@ smbus_generic_intr(device_t dev, u_char devaddr, char low, char high, int err)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
smbus_probe_device(device_t dev, u_char addr)
|
|
||||||
{
|
|
||||||
device_t child;
|
|
||||||
int error;
|
|
||||||
u_char cmd;
|
|
||||||
u_char buf[2];
|
|
||||||
struct smbus_ivar *devi;
|
|
||||||
|
|
||||||
cmd = 0x01;
|
|
||||||
error = smbus_trans(dev, addr, cmd,
|
|
||||||
SMB_TRANS_NOCNT | SMB_TRANS_NOREPORT,
|
|
||||||
NULL, 0, buf, 1, NULL);
|
|
||||||
if (error == 0) {
|
|
||||||
if (bootverbose)
|
|
||||||
device_printf(dev, "Probed address 0x%02x\n", addr);
|
|
||||||
child = BUS_ADD_CHILD(dev, SMBUS_ORDER_PNP, NULL, -1);
|
|
||||||
if (child == NULL)
|
|
||||||
return;
|
|
||||||
devi = device_get_ivars(child);
|
|
||||||
devi->addr = addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static device_t
|
static device_t
|
||||||
smbus_add_child(device_t dev, u_int order, const char *name, int unit)
|
smbus_add_child(device_t dev, u_int order, const char *name, int unit)
|
||||||
{
|
{
|
||||||
|
@ -330,10 +330,13 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
|
|||||||
dx, dy, dz, dt, dw, buttons);
|
dx, dy, dz, dt, dw, buttons);
|
||||||
|
|
||||||
/* translate T-axis into button presses until further */
|
/* translate T-axis into button presses until further */
|
||||||
if (dt > 0)
|
if (dt > 0) {
|
||||||
|
ums_put_queue(sc, 0, 0, 0, 0, buttons);
|
||||||
buttons |= 1UL << 5;
|
buttons |= 1UL << 5;
|
||||||
else if (dt < 0)
|
} else if (dt < 0) {
|
||||||
|
ums_put_queue(sc, 0, 0, 0, 0, buttons);
|
||||||
buttons |= 1UL << 6;
|
buttons |= 1UL << 6;
|
||||||
|
}
|
||||||
|
|
||||||
sc->sc_status.button = buttons;
|
sc->sc_status.button = buttons;
|
||||||
sc->sc_status.dx += dx;
|
sc->sc_status.dx += dx;
|
||||||
|
@ -350,7 +350,7 @@ nfsvno_namei(struct nfsrv_descript *nd, struct nameidata *ndp,
|
|||||||
|
|
||||||
*retdirp = NULL;
|
*retdirp = NULL;
|
||||||
cnp->cn_nameptr = cnp->cn_pnbuf;
|
cnp->cn_nameptr = cnp->cn_pnbuf;
|
||||||
ndp->ni_strictrelative = 0;
|
ndp->ni_lcf = 0;
|
||||||
/*
|
/*
|
||||||
* Extract and set starting directory.
|
* Extract and set starting directory.
|
||||||
*/
|
*/
|
||||||
|
@ -668,6 +668,7 @@ g_dev_strategy(struct bio *bp)
|
|||||||
sc = cp->private;
|
sc = cp->private;
|
||||||
KASSERT(cp->acr || cp->acw,
|
KASSERT(cp->acr || cp->acw,
|
||||||
("Consumer with zero access count in g_dev_strategy"));
|
("Consumer with zero access count in g_dev_strategy"));
|
||||||
|
biotrack(bp, __func__);
|
||||||
#ifdef INVARIANTS
|
#ifdef INVARIANTS
|
||||||
if ((bp->bio_offset % cp->provider->sectorsize) != 0 ||
|
if ((bp->bio_offset % cp->provider->sectorsize) != 0 ||
|
||||||
(bp->bio_bcount % cp->provider->sectorsize) != 0) {
|
(bp->bio_bcount % cp->provider->sectorsize) != 0) {
|
||||||
|
@ -421,6 +421,8 @@ g_disk_start(struct bio *bp)
|
|||||||
int error;
|
int error;
|
||||||
off_t off;
|
off_t off;
|
||||||
|
|
||||||
|
biotrack(bp, __func__);
|
||||||
|
|
||||||
sc = bp->bio_to->private;
|
sc = bp->bio_to->private;
|
||||||
if (sc == NULL || (dp = sc->dp) == NULL || dp->d_destroyed) {
|
if (sc == NULL || (dp = sc->dp) == NULL || dp->d_destroyed) {
|
||||||
g_io_deliver(bp, ENXIO);
|
g_io_deliver(bp, ENXIO);
|
||||||
|
@ -223,6 +223,9 @@ g_clone_bio(struct bio *bp)
|
|||||||
/* Inherit classification info from the parent */
|
/* Inherit classification info from the parent */
|
||||||
bp2->bio_classifier1 = bp->bio_classifier1;
|
bp2->bio_classifier1 = bp->bio_classifier1;
|
||||||
bp2->bio_classifier2 = bp->bio_classifier2;
|
bp2->bio_classifier2 = bp->bio_classifier2;
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
bp2->bio_track_bp = bp->bio_track_bp;
|
||||||
|
#endif
|
||||||
bp->bio_children++;
|
bp->bio_children++;
|
||||||
}
|
}
|
||||||
#ifdef KTR
|
#ifdef KTR
|
||||||
@ -362,6 +365,8 @@ g_io_check(struct bio *bp)
|
|||||||
off_t excess;
|
off_t excess;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
biotrack(bp, __func__);
|
||||||
|
|
||||||
cp = bp->bio_from;
|
cp = bp->bio_from;
|
||||||
pp = bp->bio_to;
|
pp = bp->bio_to;
|
||||||
|
|
||||||
@ -503,6 +508,8 @@ g_run_classifiers(struct bio *bp)
|
|||||||
struct g_classifier_hook *hook;
|
struct g_classifier_hook *hook;
|
||||||
int classified = 0;
|
int classified = 0;
|
||||||
|
|
||||||
|
biotrack(bp, __func__);
|
||||||
|
|
||||||
TAILQ_FOREACH(hook, &g_classifier_tailq, link)
|
TAILQ_FOREACH(hook, &g_classifier_tailq, link)
|
||||||
classified |= hook->func(hook->arg, bp);
|
classified |= hook->func(hook->arg, bp);
|
||||||
|
|
||||||
@ -518,6 +525,8 @@ g_io_request(struct bio *bp, struct g_consumer *cp)
|
|||||||
int direct, error, first;
|
int direct, error, first;
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
|
|
||||||
|
biotrack(bp, __func__);
|
||||||
|
|
||||||
KASSERT(cp != NULL, ("NULL cp in g_io_request"));
|
KASSERT(cp != NULL, ("NULL cp in g_io_request"));
|
||||||
KASSERT(bp != NULL, ("NULL bp in g_io_request"));
|
KASSERT(bp != NULL, ("NULL bp in g_io_request"));
|
||||||
pp = cp->provider;
|
pp = cp->provider;
|
||||||
@ -644,6 +653,8 @@ g_io_deliver(struct bio *bp, int error)
|
|||||||
struct mtx *mtxp;
|
struct mtx *mtxp;
|
||||||
int direct, first;
|
int direct, first;
|
||||||
|
|
||||||
|
biotrack(bp, __func__);
|
||||||
|
|
||||||
KASSERT(bp != NULL, ("NULL bp in g_io_deliver"));
|
KASSERT(bp != NULL, ("NULL bp in g_io_deliver"));
|
||||||
pp = bp->bio_to;
|
pp = bp->bio_to;
|
||||||
KASSERT(pp != NULL, ("NULL bio_to in g_io_deliver"));
|
KASSERT(pp != NULL, ("NULL bio_to in g_io_deliver"));
|
||||||
@ -835,6 +846,7 @@ g_io_schedule_down(struct thread *tp __unused)
|
|||||||
}
|
}
|
||||||
CTR0(KTR_GEOM, "g_down has work to do");
|
CTR0(KTR_GEOM, "g_down has work to do");
|
||||||
g_bioq_unlock(&g_bio_run_down);
|
g_bioq_unlock(&g_bio_run_down);
|
||||||
|
biotrack(bp, __func__);
|
||||||
if (pace != 0) {
|
if (pace != 0) {
|
||||||
/*
|
/*
|
||||||
* There has been at least one memory allocation
|
* There has been at least one memory allocation
|
||||||
|
@ -1531,6 +1531,10 @@ DB_SHOW_COMMAND(bio, db_show_bio)
|
|||||||
db_printf(" caller2: %p\n", bp->bio_caller2);
|
db_printf(" caller2: %p\n", bp->bio_caller2);
|
||||||
db_printf(" bio_from: %p\n", bp->bio_from);
|
db_printf(" bio_from: %p\n", bp->bio_from);
|
||||||
db_printf(" bio_to: %p\n", bp->bio_to);
|
db_printf(" bio_to: %p\n", bp->bio_to);
|
||||||
|
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
db_printf(" bio_track_bp: %p\n", bp->bio_track_bp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +192,10 @@ g_vfs_strategy(struct bufobj *bo, struct buf *bp)
|
|||||||
}
|
}
|
||||||
bip->bio_done = g_vfs_done;
|
bip->bio_done = g_vfs_done;
|
||||||
bip->bio_caller2 = bp;
|
bip->bio_caller2 = bp;
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
buf_track(bp, __func__);
|
||||||
|
bip->bio_track_bp = bp;
|
||||||
|
#endif
|
||||||
g_io_request(bip, cp);
|
g_io_request(bip, cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2154,6 +2154,8 @@ g_part_start(struct bio *bp)
|
|||||||
struct g_provider *pp;
|
struct g_provider *pp;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
|
biotrack(bp, __func__);
|
||||||
|
|
||||||
pp = bp->bio_to;
|
pp = bp->bio_to;
|
||||||
gp = pp->geom;
|
gp = pp->geom;
|
||||||
table = gp->softc;
|
table = gp->softc;
|
||||||
|
@ -1952,6 +1952,7 @@ bufwrite(struct buf *bp)
|
|||||||
if (oldflags & B_ASYNC)
|
if (oldflags & B_ASYNC)
|
||||||
BUF_KERNPROC(bp);
|
BUF_KERNPROC(bp);
|
||||||
bp->b_iooffset = dbtob(bp->b_blkno);
|
bp->b_iooffset = dbtob(bp->b_blkno);
|
||||||
|
buf_track(bp, __func__);
|
||||||
bstrategy(bp);
|
bstrategy(bp);
|
||||||
|
|
||||||
if ((oldflags & B_ASYNC) == 0) {
|
if ((oldflags & B_ASYNC) == 0) {
|
||||||
@ -2078,6 +2079,8 @@ bdwrite(struct buf *bp)
|
|||||||
VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL);
|
VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf_track(bp, __func__);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the *dirty* buffer range based upon the VM system dirty
|
* Set the *dirty* buffer range based upon the VM system dirty
|
||||||
* pages.
|
* pages.
|
||||||
@ -2386,6 +2389,8 @@ brelse(struct buf *bp)
|
|||||||
brelvp(bp);
|
brelvp(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf_track(bp, __func__);
|
||||||
|
|
||||||
/* buffers with no memory */
|
/* buffers with no memory */
|
||||||
if (bp->b_bufsize == 0) {
|
if (bp->b_bufsize == 0) {
|
||||||
buf_free(bp);
|
buf_free(bp);
|
||||||
@ -2470,6 +2475,7 @@ bqrelse(struct buf *bp)
|
|||||||
binsfree(bp, qindex);
|
binsfree(bp, qindex);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
buf_track(bp, __func__);
|
||||||
/* unlock */
|
/* unlock */
|
||||||
BUF_UNLOCK(bp);
|
BUF_UNLOCK(bp);
|
||||||
if (qindex == QUEUE_CLEAN)
|
if (qindex == QUEUE_CLEAN)
|
||||||
@ -3716,6 +3722,7 @@ getblk(struct vnode *vp, daddr_t blkno, int size, int slpflag, int slptimeo,
|
|||||||
CTR4(KTR_BUF, "getblk(%p, %ld, %d) = %p", vp, (long)blkno, size, bp);
|
CTR4(KTR_BUF, "getblk(%p, %ld, %d) = %p", vp, (long)blkno, size, bp);
|
||||||
BUF_ASSERT_HELD(bp);
|
BUF_ASSERT_HELD(bp);
|
||||||
end:
|
end:
|
||||||
|
buf_track(bp, __func__);
|
||||||
KASSERT(bp->b_bufobj == bo,
|
KASSERT(bp->b_bufobj == bo,
|
||||||
("bp %p wrong b_bufobj %p should be %p", bp, bp->b_bufobj, bo));
|
("bp %p wrong b_bufobj %p should be %p", bp, bp->b_bufobj, bo));
|
||||||
return (bp);
|
return (bp);
|
||||||
@ -3892,6 +3899,7 @@ biodone(struct bio *bp)
|
|||||||
void (*done)(struct bio *);
|
void (*done)(struct bio *);
|
||||||
vm_offset_t start, end;
|
vm_offset_t start, end;
|
||||||
|
|
||||||
|
biotrack(bp, __func__);
|
||||||
if ((bp->bio_flags & BIO_TRANSIENT_MAPPING) != 0) {
|
if ((bp->bio_flags & BIO_TRANSIENT_MAPPING) != 0) {
|
||||||
bp->bio_flags &= ~BIO_TRANSIENT_MAPPING;
|
bp->bio_flags &= ~BIO_TRANSIENT_MAPPING;
|
||||||
bp->bio_flags |= BIO_UNMAPPED;
|
bp->bio_flags |= BIO_UNMAPPED;
|
||||||
@ -3948,6 +3956,15 @@ biofinish(struct bio *bp, struct devstat *stat, int error)
|
|||||||
biodone(bp);
|
biodone(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
void
|
||||||
|
biotrack_buf(struct bio *bp, const char *location)
|
||||||
|
{
|
||||||
|
|
||||||
|
buf_track(bp->bio_track_bp, location);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bufwait:
|
* bufwait:
|
||||||
*
|
*
|
||||||
@ -3998,6 +4015,7 @@ bufdone(struct buf *bp)
|
|||||||
struct bufobj *dropobj;
|
struct bufobj *dropobj;
|
||||||
void (*biodone)(struct buf *);
|
void (*biodone)(struct buf *);
|
||||||
|
|
||||||
|
buf_track(bp, __func__);
|
||||||
CTR3(KTR_BUF, "bufdone(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags);
|
CTR3(KTR_BUF, "bufdone(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags);
|
||||||
dropobj = NULL;
|
dropobj = NULL;
|
||||||
|
|
||||||
@ -4801,6 +4819,9 @@ DB_SHOW_COMMAND(buffer, db_show_buffer)
|
|||||||
{
|
{
|
||||||
/* get args */
|
/* get args */
|
||||||
struct buf *bp = (struct buf *)addr;
|
struct buf *bp = (struct buf *)addr;
|
||||||
|
#ifdef FULL_BUF_TRACKING
|
||||||
|
uint32_t i, j;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!have_addr) {
|
if (!have_addr) {
|
||||||
db_printf("usage: show buffer <addr>\n");
|
db_printf("usage: show buffer <addr>\n");
|
||||||
@ -4837,6 +4858,16 @@ DB_SHOW_COMMAND(buffer, db_show_buffer)
|
|||||||
}
|
}
|
||||||
db_printf("\n");
|
db_printf("\n");
|
||||||
}
|
}
|
||||||
|
#if defined(FULL_BUF_TRACKING)
|
||||||
|
db_printf("b_io_tracking: b_io_tcnt = %u\n", bp->b_io_tcnt);
|
||||||
|
|
||||||
|
i = bp->b_io_tcnt % BUF_TRACKING_SIZE;
|
||||||
|
for (j = 1; j <= BUF_TRACKING_SIZE; j++)
|
||||||
|
db_printf(" %2u: %s\n", j,
|
||||||
|
bp->b_io_tracking[BUF_TRACKING_ENTRY(i - j)]);
|
||||||
|
#elif defined(BUF_TRACKING)
|
||||||
|
db_printf("b_io_tracking: %s\n", bp->b_io_tracking);
|
||||||
|
#endif
|
||||||
db_printf(" ");
|
db_printf(" ");
|
||||||
BUF_LOCKPRINTINFO(bp);
|
BUF_LOCKPRINTINFO(bp);
|
||||||
}
|
}
|
||||||
|
@ -1008,6 +1008,7 @@ cluster_wbuild(struct vnode *vp, long size, daddr_t start_lbn, int len,
|
|||||||
reassignbuf(tbp); /* put on clean list */
|
reassignbuf(tbp); /* put on clean list */
|
||||||
bufobj_wref(tbp->b_bufobj);
|
bufobj_wref(tbp->b_bufobj);
|
||||||
BUF_KERNPROC(tbp);
|
BUF_KERNPROC(tbp);
|
||||||
|
buf_track(tbp, __func__);
|
||||||
TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head,
|
TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head,
|
||||||
tbp, b_cluster.cluster_entry);
|
tbp, b_cluster.cluster_entry);
|
||||||
}
|
}
|
||||||
|
@ -73,21 +73,28 @@ SDT_PROBE_DEFINE3(vfs, namei, lookup, entry, "struct vnode *", "char *",
|
|||||||
"unsigned long");
|
"unsigned long");
|
||||||
SDT_PROBE_DEFINE2(vfs, namei, lookup, return, "int", "struct vnode *");
|
SDT_PROBE_DEFINE2(vfs, namei, lookup, return, "int", "struct vnode *");
|
||||||
|
|
||||||
/*
|
/* Allocation zone for namei. */
|
||||||
* Allocation zone for namei
|
|
||||||
*/
|
|
||||||
uma_zone_t namei_zone;
|
uma_zone_t namei_zone;
|
||||||
/*
|
|
||||||
* Placeholder vnode for mp traversal
|
/* Placeholder vnode for mp traversal. */
|
||||||
*/
|
|
||||||
static struct vnode *vp_crossmp;
|
static struct vnode *vp_crossmp;
|
||||||
|
|
||||||
|
struct nameicap_tracker {
|
||||||
|
struct vnode *dp;
|
||||||
|
TAILQ_ENTRY(nameicap_tracker) nm_link;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Zone for cap mode tracker elements used for dotdot capability checks. */
|
||||||
|
static uma_zone_t nt_zone;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nameiinit(void *dummy __unused)
|
nameiinit(void *dummy __unused)
|
||||||
{
|
{
|
||||||
|
|
||||||
namei_zone = uma_zcreate("NAMEI", MAXPATHLEN, NULL, NULL, NULL, NULL,
|
namei_zone = uma_zcreate("NAMEI", MAXPATHLEN, NULL, NULL, NULL, NULL,
|
||||||
UMA_ALIGN_PTR, 0);
|
UMA_ALIGN_PTR, 0);
|
||||||
|
nt_zone = uma_zcreate("rentr", sizeof(struct nameicap_tracker),
|
||||||
|
NULL, NULL, NULL, NULL, sizeof(void *), 0);
|
||||||
getnewvnode("crossmp", NULL, &dead_vnodeops, &vp_crossmp);
|
getnewvnode("crossmp", NULL, &dead_vnodeops, &vp_crossmp);
|
||||||
vn_lock(vp_crossmp, LK_EXCLUSIVE);
|
vn_lock(vp_crossmp, LK_EXCLUSIVE);
|
||||||
VN_LOCK_ASHARE(vp_crossmp);
|
VN_LOCK_ASHARE(vp_crossmp);
|
||||||
@ -97,11 +104,82 @@ SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL);
|
|||||||
|
|
||||||
static int lookup_shared = 1;
|
static int lookup_shared = 1;
|
||||||
SYSCTL_INT(_vfs, OID_AUTO, lookup_shared, CTLFLAG_RWTUN, &lookup_shared, 0,
|
SYSCTL_INT(_vfs, OID_AUTO, lookup_shared, CTLFLAG_RWTUN, &lookup_shared, 0,
|
||||||
"Enables/Disables shared locks for path name translation");
|
"enables shared locks for path name translation");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Intent is that lookup_cap_dotdot becomes unconditionally enabled,
|
||||||
|
* but it defaults to the disabled state until verification efforts
|
||||||
|
* are complete.
|
||||||
|
*/
|
||||||
|
static int lookup_cap_dotdot = 0;
|
||||||
|
SYSCTL_INT(_vfs, OID_AUTO, lookup_cap_dotdot, CTLFLAG_RWTUN,
|
||||||
|
&lookup_cap_dotdot, 0,
|
||||||
|
"enables \"..\" components in path lookup in capability mode");
|
||||||
|
static int lookup_cap_dotdot_nonlocal = 0;
|
||||||
|
SYSCTL_INT(_vfs, OID_AUTO, lookup_cap_dotdot_nonlocal, CTLFLAG_RWTUN,
|
||||||
|
&lookup_cap_dotdot_nonlocal, 0,
|
||||||
|
"enables \"..\" components in path lookup in capability mode "
|
||||||
|
"on non-local mount");
|
||||||
|
|
||||||
|
static void
|
||||||
|
nameicap_tracker_add(struct nameidata *ndp, struct vnode *dp)
|
||||||
|
{
|
||||||
|
struct nameicap_tracker *nt;
|
||||||
|
|
||||||
|
if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0 || dp->v_type != VDIR)
|
||||||
|
return;
|
||||||
|
nt = uma_zalloc(nt_zone, M_WAITOK);
|
||||||
|
vhold(dp);
|
||||||
|
nt->dp = dp;
|
||||||
|
TAILQ_INSERT_TAIL(&ndp->ni_cap_tracker, nt, nm_link);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nameicap_cleanup(struct nameidata *ndp)
|
||||||
|
{
|
||||||
|
struct nameicap_tracker *nt, *nt1;
|
||||||
|
|
||||||
|
KASSERT(TAILQ_EMPTY(&ndp->ni_cap_tracker) ||
|
||||||
|
(ndp->ni_lcf & NI_LCF_CAP_DOTDOT) != 0, ("not strictrelative"));
|
||||||
|
TAILQ_FOREACH_SAFE(nt, &ndp->ni_cap_tracker, nm_link, nt1) {
|
||||||
|
TAILQ_REMOVE(&ndp->ni_cap_tracker, nt, nm_link);
|
||||||
|
vdrop(nt->dp);
|
||||||
|
uma_zfree(nt_zone, nt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For dotdot lookups in capability mode, only allow the component
|
||||||
|
* lookup to succeed if the resulting directory was already traversed
|
||||||
|
* during the operation. Also fail dotdot lookups for non-local
|
||||||
|
* filesystems, where external agents might assist local lookups to
|
||||||
|
* escape the compartment.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
nameicap_check_dotdot(struct nameidata *ndp, struct vnode *dp)
|
||||||
|
{
|
||||||
|
struct nameicap_tracker *nt;
|
||||||
|
struct mount *mp;
|
||||||
|
|
||||||
|
if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0 || dp == NULL ||
|
||||||
|
dp->v_type != VDIR)
|
||||||
|
return (0);
|
||||||
|
mp = dp->v_mount;
|
||||||
|
if (lookup_cap_dotdot_nonlocal == 0 && mp != NULL &&
|
||||||
|
(mp->mnt_flag & MNT_LOCAL) == 0)
|
||||||
|
return (ENOTCAPABLE);
|
||||||
|
TAILQ_FOREACH_REVERSE(nt, &ndp->ni_cap_tracker, nameicap_tracker_head,
|
||||||
|
nm_link) {
|
||||||
|
if (dp == nt->dp)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (ENOTCAPABLE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
namei_cleanup_cnp(struct componentname *cnp)
|
namei_cleanup_cnp(struct componentname *cnp)
|
||||||
{
|
{
|
||||||
|
|
||||||
uma_zfree(namei_zone, cnp->cn_pnbuf);
|
uma_zfree(namei_zone, cnp->cn_pnbuf);
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
cnp->cn_pnbuf = NULL;
|
cnp->cn_pnbuf = NULL;
|
||||||
@ -115,7 +193,7 @@ namei_handle_root(struct nameidata *ndp, struct vnode **dpp)
|
|||||||
struct componentname *cnp;
|
struct componentname *cnp;
|
||||||
|
|
||||||
cnp = &ndp->ni_cnd;
|
cnp = &ndp->ni_cnd;
|
||||||
if (ndp->ni_strictrelative != 0) {
|
if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0) {
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
if (KTRPOINT(curthread, KTR_CAPFAIL))
|
if (KTRPOINT(curthread, KTR_CAPFAIL))
|
||||||
ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
|
ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
|
||||||
@ -158,12 +236,16 @@ namei(struct nameidata *ndp)
|
|||||||
char *cp; /* pointer into pathname argument */
|
char *cp; /* pointer into pathname argument */
|
||||||
struct vnode *dp; /* the directory we are searching */
|
struct vnode *dp; /* the directory we are searching */
|
||||||
struct iovec aiov; /* uio for reading symbolic links */
|
struct iovec aiov; /* uio for reading symbolic links */
|
||||||
|
struct componentname *cnp;
|
||||||
|
struct thread *td;
|
||||||
|
struct proc *p;
|
||||||
|
cap_rights_t rights;
|
||||||
struct uio auio;
|
struct uio auio;
|
||||||
int error, linklen, startdir_used;
|
int error, linklen, startdir_used;
|
||||||
struct componentname *cnp = &ndp->ni_cnd;
|
|
||||||
struct thread *td = cnp->cn_thread;
|
|
||||||
struct proc *p = td->td_proc;
|
|
||||||
|
|
||||||
|
cnp = &ndp->ni_cnd;
|
||||||
|
td = cnp->cn_thread;
|
||||||
|
p = td->td_proc;
|
||||||
ndp->ni_cnd.cn_cred = ndp->ni_cnd.cn_thread->td_ucred;
|
ndp->ni_cnd.cn_cred = ndp->ni_cnd.cn_thread->td_ucred;
|
||||||
KASSERT(cnp->cn_cred && p, ("namei: bad cred/proc"));
|
KASSERT(cnp->cn_cred && p, ("namei: bad cred/proc"));
|
||||||
KASSERT((cnp->cn_nameiop & (~OPMASK)) == 0,
|
KASSERT((cnp->cn_nameiop & (~OPMASK)) == 0,
|
||||||
@ -175,6 +257,8 @@ namei(struct nameidata *ndp)
|
|||||||
if (!lookup_shared)
|
if (!lookup_shared)
|
||||||
cnp->cn_flags &= ~LOCKSHARED;
|
cnp->cn_flags &= ~LOCKSHARED;
|
||||||
fdp = p->p_fd;
|
fdp = p->p_fd;
|
||||||
|
TAILQ_INIT(&ndp->ni_cap_tracker);
|
||||||
|
ndp->ni_lcf = 0;
|
||||||
|
|
||||||
/* We will set this ourselves if we need it. */
|
/* We will set this ourselves if we need it. */
|
||||||
cnp->cn_flags &= ~TRAILINGSLASH;
|
cnp->cn_flags &= ~TRAILINGSLASH;
|
||||||
@ -186,11 +270,11 @@ namei(struct nameidata *ndp)
|
|||||||
if ((cnp->cn_flags & HASBUF) == 0)
|
if ((cnp->cn_flags & HASBUF) == 0)
|
||||||
cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
|
cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
|
||||||
if (ndp->ni_segflg == UIO_SYSSPACE)
|
if (ndp->ni_segflg == UIO_SYSSPACE)
|
||||||
error = copystr(ndp->ni_dirp, cnp->cn_pnbuf,
|
error = copystr(ndp->ni_dirp, cnp->cn_pnbuf, MAXPATHLEN,
|
||||||
MAXPATHLEN, (size_t *)&ndp->ni_pathlen);
|
&ndp->ni_pathlen);
|
||||||
else
|
else
|
||||||
error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf,
|
error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf, MAXPATHLEN,
|
||||||
MAXPATHLEN, (size_t *)&ndp->ni_pathlen);
|
&ndp->ni_pathlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't allow empty pathnames.
|
* Don't allow empty pathnames.
|
||||||
@ -200,13 +284,21 @@ namei(struct nameidata *ndp)
|
|||||||
|
|
||||||
#ifdef CAPABILITY_MODE
|
#ifdef CAPABILITY_MODE
|
||||||
/*
|
/*
|
||||||
* In capability mode, lookups must be "strictly relative" (i.e.
|
* In capability mode, lookups must be restricted to happen in
|
||||||
* not an absolute path, and not containing '..' components) to
|
* the subtree with the root specified by the file descriptor:
|
||||||
* a real file descriptor, not the pseudo-descriptor AT_FDCWD.
|
* - The root must be real file descriptor, not the pseudo-descriptor
|
||||||
|
* AT_FDCWD.
|
||||||
|
* - The passed path must be relative and not absolute.
|
||||||
|
* - If lookup_cap_dotdot is disabled, path must not contain the
|
||||||
|
* '..' components.
|
||||||
|
* - If lookup_cap_dotdot is enabled, we verify that all '..'
|
||||||
|
* components lookups result in the directories which were
|
||||||
|
* previously walked by us, which prevents an escape from
|
||||||
|
* the relative root.
|
||||||
*/
|
*/
|
||||||
if (error == 0 && IN_CAPABILITY_MODE(td) &&
|
if (error == 0 && IN_CAPABILITY_MODE(td) &&
|
||||||
(cnp->cn_flags & NOCAPCHECK) == 0) {
|
(cnp->cn_flags & NOCAPCHECK) == 0) {
|
||||||
ndp->ni_strictrelative = 1;
|
ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
|
||||||
if (ndp->ni_dirfd == AT_FDCWD) {
|
if (ndp->ni_dirfd == AT_FDCWD) {
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
if (KTRPOINT(td, KTR_CAPFAIL))
|
if (KTRPOINT(td, KTR_CAPFAIL))
|
||||||
@ -258,8 +350,6 @@ namei(struct nameidata *ndp)
|
|||||||
dp = fdp->fd_cdir;
|
dp = fdp->fd_cdir;
|
||||||
VREF(dp);
|
VREF(dp);
|
||||||
} else {
|
} else {
|
||||||
cap_rights_t rights;
|
|
||||||
|
|
||||||
rights = ndp->ni_rightsneeded;
|
rights = ndp->ni_rightsneeded;
|
||||||
cap_rights_set(&rights, CAP_LOOKUP);
|
cap_rights_set(&rights, CAP_LOOKUP);
|
||||||
|
|
||||||
@ -282,7 +372,7 @@ namei(struct nameidata *ndp)
|
|||||||
&rights) ||
|
&rights) ||
|
||||||
ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
|
ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
|
||||||
ndp->ni_filecaps.fc_nioctls != -1) {
|
ndp->ni_filecaps.fc_nioctls != -1) {
|
||||||
ndp->ni_strictrelative = 1;
|
ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -297,6 +387,9 @@ namei(struct nameidata *ndp)
|
|||||||
vrele(dp);
|
vrele(dp);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0 &&
|
||||||
|
lookup_cap_dotdot != 0)
|
||||||
|
ndp->ni_lcf |= NI_LCF_CAP_DOTDOT;
|
||||||
SDT_PROBE3(vfs, namei, lookup, entry, dp, cnp->cn_pnbuf,
|
SDT_PROBE3(vfs, namei, lookup, entry, dp, cnp->cn_pnbuf,
|
||||||
cnp->cn_flags);
|
cnp->cn_flags);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -313,7 +406,7 @@ namei(struct nameidata *ndp)
|
|||||||
namei_cleanup_cnp(cnp);
|
namei_cleanup_cnp(cnp);
|
||||||
} else
|
} else
|
||||||
cnp->cn_flags |= HASBUF;
|
cnp->cn_flags |= HASBUF;
|
||||||
|
nameicap_cleanup(ndp);
|
||||||
SDT_PROBE2(vfs, namei, lookup, return, 0, ndp->ni_vp);
|
SDT_PROBE2(vfs, namei, lookup, return, 0, ndp->ni_vp);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -387,6 +480,7 @@ namei(struct nameidata *ndp)
|
|||||||
out:
|
out:
|
||||||
vrele(ndp->ni_rootdir);
|
vrele(ndp->ni_rootdir);
|
||||||
namei_cleanup_cnp(cnp);
|
namei_cleanup_cnp(cnp);
|
||||||
|
nameicap_cleanup(ndp);
|
||||||
SDT_PROBE2(vfs, namei, lookup, return, error, NULL);
|
SDT_PROBE2(vfs, namei, lookup, return, error, NULL);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -583,6 +677,8 @@ lookup(struct nameidata *ndp)
|
|||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nameicap_tracker_add(ndp, dp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for degenerate name (e.g. / or "")
|
* Check for degenerate name (e.g. / or "")
|
||||||
* which is a way of talking about a directory,
|
* which is a way of talking about a directory,
|
||||||
@ -618,9 +714,8 @@ lookup(struct nameidata *ndp)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle "..": five special cases.
|
* Handle "..": five special cases.
|
||||||
* 0. If doing a capability lookup, return ENOTCAPABLE (this is a
|
* 0. If doing a capability lookup and lookup_cap_dotdot is
|
||||||
* fairly conservative design choice, but it's the only one that we
|
* disabled, return ENOTCAPABLE.
|
||||||
* are satisfied guarantees the property we're looking for).
|
|
||||||
* 1. Return an error if this is the last component of
|
* 1. Return an error if this is the last component of
|
||||||
* the name and the operation is DELETE or RENAME.
|
* the name and the operation is DELETE or RENAME.
|
||||||
* 2. If at root directory (e.g. after chroot)
|
* 2. If at root directory (e.g. after chroot)
|
||||||
@ -632,9 +727,15 @@ lookup(struct nameidata *ndp)
|
|||||||
* .. in the other filesystem.
|
* .. in the other filesystem.
|
||||||
* 4. If the vnode is the top directory of
|
* 4. If the vnode is the top directory of
|
||||||
* the jail or chroot, don't let them out.
|
* the jail or chroot, don't let them out.
|
||||||
|
* 5. If doing a capability lookup and lookup_cap_dotdot is
|
||||||
|
* enabled, return ENOTCAPABLE if the lookup would escape
|
||||||
|
* from the initial file descriptor directory. Checks are
|
||||||
|
* done by ensuring that namei() already traversed the
|
||||||
|
* result of dotdot lookup.
|
||||||
*/
|
*/
|
||||||
if (cnp->cn_flags & ISDOTDOT) {
|
if (cnp->cn_flags & ISDOTDOT) {
|
||||||
if (ndp->ni_strictrelative != 0) {
|
if ((ndp->ni_lcf & (NI_LCF_STRICTRELATIVE | NI_LCF_CAP_DOTDOT))
|
||||||
|
== NI_LCF_STRICTRELATIVE) {
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
if (KTRPOINT(curthread, KTR_CAPFAIL))
|
if (KTRPOINT(curthread, KTR_CAPFAIL))
|
||||||
ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
|
ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
|
||||||
@ -676,6 +777,14 @@ lookup(struct nameidata *ndp)
|
|||||||
vn_lock(dp,
|
vn_lock(dp,
|
||||||
compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags |
|
compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags |
|
||||||
LK_RETRY, ISDOTDOT));
|
LK_RETRY, ISDOTDOT));
|
||||||
|
error = nameicap_check_dotdot(ndp, dp);
|
||||||
|
if (error != 0) {
|
||||||
|
#ifdef KTRACE
|
||||||
|
if (KTRPOINT(curthread, KTR_CAPFAIL))
|
||||||
|
ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
|
||||||
|
#endif
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -735,6 +844,7 @@ lookup(struct nameidata *ndp)
|
|||||||
vn_lock(dp,
|
vn_lock(dp,
|
||||||
compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags |
|
compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags |
|
||||||
LK_RETRY, cnp->cn_flags));
|
LK_RETRY, cnp->cn_flags));
|
||||||
|
nameicap_tracker_add(ndp, dp);
|
||||||
goto unionlookup;
|
goto unionlookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -855,6 +965,16 @@ lookup(struct nameidata *ndp)
|
|||||||
vrele(ndp->ni_dvp);
|
vrele(ndp->ni_dvp);
|
||||||
goto dirloop;
|
goto dirloop;
|
||||||
}
|
}
|
||||||
|
if (cnp->cn_flags & ISDOTDOT) {
|
||||||
|
error = nameicap_check_dotdot(ndp, ndp->ni_vp);
|
||||||
|
if (error != 0) {
|
||||||
|
#ifdef KTRACE
|
||||||
|
if (KTRPOINT(curthread, KTR_CAPFAIL))
|
||||||
|
ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
|
||||||
|
#endif
|
||||||
|
goto bad2;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (*ndp->ni_next == '/') {
|
if (*ndp->ni_next == '/') {
|
||||||
cnp->cn_nameptr = ndp->ni_next;
|
cnp->cn_nameptr = ndp->ni_next;
|
||||||
while (*cnp->cn_nameptr == '/') {
|
while (*cnp->cn_nameptr == '/') {
|
||||||
@ -1081,7 +1201,6 @@ NDINIT_ALL(struct nameidata *ndp, u_long op, u_long flags, enum uio_seg segflg,
|
|||||||
ndp->ni_dirp = namep;
|
ndp->ni_dirp = namep;
|
||||||
ndp->ni_dirfd = dirfd;
|
ndp->ni_dirfd = dirfd;
|
||||||
ndp->ni_startdir = startdir;
|
ndp->ni_startdir = startdir;
|
||||||
ndp->ni_strictrelative = 0;
|
|
||||||
if (rightsp != NULL)
|
if (rightsp != NULL)
|
||||||
ndp->ni_rightsneeded = *rightsp;
|
ndp->ni_rightsneeded = *rightsp;
|
||||||
else
|
else
|
||||||
|
@ -446,16 +446,19 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
|
|||||||
size_t *countp, enum uio_seg bufseg, int flags)
|
size_t *countp, enum uio_seg bufseg, int flags)
|
||||||
{
|
{
|
||||||
struct mount *mp, *nmp;
|
struct mount *mp, *nmp;
|
||||||
struct statfs *sfsp, *sp, sb;
|
struct statfs *sfsp, *sp, sb, *tofree;
|
||||||
size_t count, maxcount;
|
size_t count, maxcount;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
restart:
|
||||||
maxcount = bufsize / sizeof(struct statfs);
|
maxcount = bufsize / sizeof(struct statfs);
|
||||||
if (bufsize == 0)
|
if (bufsize == 0) {
|
||||||
sfsp = NULL;
|
sfsp = NULL;
|
||||||
else if (bufseg == UIO_USERSPACE)
|
tofree = NULL;
|
||||||
|
} else if (bufseg == UIO_USERSPACE) {
|
||||||
sfsp = *buf;
|
sfsp = *buf;
|
||||||
else /* if (bufseg == UIO_SYSSPACE) */ {
|
tofree = NULL;
|
||||||
|
} else /* if (bufseg == UIO_SYSSPACE) */ {
|
||||||
count = 0;
|
count = 0;
|
||||||
mtx_lock(&mountlist_mtx);
|
mtx_lock(&mountlist_mtx);
|
||||||
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
|
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
|
||||||
@ -464,8 +467,8 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
|
|||||||
mtx_unlock(&mountlist_mtx);
|
mtx_unlock(&mountlist_mtx);
|
||||||
if (maxcount > count)
|
if (maxcount > count)
|
||||||
maxcount = count;
|
maxcount = count;
|
||||||
sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_TEMP,
|
tofree = sfsp = *buf = malloc(maxcount * sizeof(struct statfs),
|
||||||
M_WAITOK);
|
M_TEMP, M_WAITOK);
|
||||||
}
|
}
|
||||||
count = 0;
|
count = 0;
|
||||||
mtx_lock(&mountlist_mtx);
|
mtx_lock(&mountlist_mtx);
|
||||||
@ -480,9 +483,24 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) {
|
if (flags == MNT_WAIT) {
|
||||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
if (vfs_busy(mp, MBF_MNTLSTLOCK) != 0) {
|
||||||
continue;
|
/*
|
||||||
|
* If vfs_busy() failed, and MBF_NOWAIT
|
||||||
|
* wasn't passed, then the mp is gone.
|
||||||
|
* Furthermore, because of MBF_MNTLSTLOCK,
|
||||||
|
* the mountlist_mtx was dropped. We have
|
||||||
|
* no other choice than to start over.
|
||||||
|
*/
|
||||||
|
mtx_unlock(&mountlist_mtx);
|
||||||
|
free(tofree, M_TEMP);
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK) != 0) {
|
||||||
|
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sfsp && count < maxcount) {
|
if (sfsp && count < maxcount) {
|
||||||
sp = &mp->mnt_stat;
|
sp = &mp->mnt_stat;
|
||||||
@ -1012,7 +1030,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
|
|||||||
* understand exactly what would happen, and we don't think
|
* understand exactly what would happen, and we don't think
|
||||||
* that it ever should.
|
* that it ever should.
|
||||||
*/
|
*/
|
||||||
if (nd.ni_strictrelative == 0 &&
|
if ((nd.ni_lcf & NI_LCF_STRICTRELATIVE) == 0 &&
|
||||||
(error == ENODEV || error == ENXIO) &&
|
(error == ENODEV || error == ENXIO) &&
|
||||||
td->td_dupfd >= 0) {
|
td->td_dupfd >= 0) {
|
||||||
error = dupfdopen(td, fdp, td->td_dupfd, flags, error,
|
error = dupfdopen(td, fdp, td->td_dupfd, flags, error,
|
||||||
@ -1058,7 +1076,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
|
|||||||
struct filecaps *fcaps;
|
struct filecaps *fcaps;
|
||||||
|
|
||||||
#ifdef CAPABILITIES
|
#ifdef CAPABILITIES
|
||||||
if (nd.ni_strictrelative == 1)
|
if ((nd.ni_lcf & NI_LCF_STRICTRELATIVE) != 0)
|
||||||
fcaps = &nd.ni_filecaps;
|
fcaps = &nd.ni_filecaps;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
${.CURDIR}/../../../dev/hyperv/vmbus
|
${.CURDIR}/../../../dev/hyperv/vmbus
|
||||||
|
|
||||||
KMOD= hv_netvsc
|
KMOD= hv_netvsc
|
||||||
SRCS= hn_nvs.c hn_rndis.c hv_netvsc_drv_freebsd.c
|
SRCS= hn_nvs.c hn_rndis.c if_hn.c
|
||||||
SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h vmbus_if.h
|
SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h vmbus_if.h
|
||||||
|
|
||||||
CFLAGS+= -I${.CURDIR}/../../../dev/hyperv/netvsc
|
CFLAGS+= -I${.CURDIR}/../../../dev/hyperv/netvsc
|
||||||
|
@ -474,7 +474,9 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type)
|
|||||||
ENTER_RECOVERY(CCV(ccv, t_flags));
|
ENTER_RECOVERY(CCV(ccv, t_flags));
|
||||||
break;
|
break;
|
||||||
case CC_RTO:
|
case CC_RTO:
|
||||||
CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2);
|
CCV(ccv, snd_ssthresh) =
|
||||||
|
max((CCV(ccv, snd_max) - CCV(ccv, snd_una)) / 2 / mss, 2)
|
||||||
|
* mss;
|
||||||
CCV(ccv, snd_cwnd) = mss;
|
CCV(ccv, snd_cwnd) = mss;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -330,13 +330,11 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type)
|
|||||||
struct ertt *e_t;
|
struct ertt *e_t;
|
||||||
struct chd *chd_data;
|
struct chd *chd_data;
|
||||||
int qdly;
|
int qdly;
|
||||||
uint32_t cwin;
|
|
||||||
u_int mss;
|
u_int mss;
|
||||||
|
|
||||||
e_t = khelp_get_osd(CCV(ccv, osd), ertt_id);
|
e_t = khelp_get_osd(CCV(ccv, osd), ertt_id);
|
||||||
chd_data = ccv->cc_data;
|
chd_data = ccv->cc_data;
|
||||||
qdly = imax(e_t->rtt, chd_data->maxrtt_in_rtt) - e_t->minrtt;
|
qdly = imax(e_t->rtt, chd_data->maxrtt_in_rtt) - e_t->minrtt;
|
||||||
cwin = CCV(ccv, snd_cwnd);
|
|
||||||
mss = CCV(ccv, t_maxseg);
|
mss = CCV(ccv, t_maxseg);
|
||||||
|
|
||||||
switch(signal_type) {
|
switch(signal_type) {
|
||||||
@ -378,7 +376,9 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type)
|
|||||||
ENTER_FASTRECOVERY(CCV(ccv, t_flags));
|
ENTER_FASTRECOVERY(CCV(ccv, t_flags));
|
||||||
break;
|
break;
|
||||||
case CC_RTO:
|
case CC_RTO:
|
||||||
CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2);
|
CCV(ccv, snd_ssthresh) =
|
||||||
|
max((CCV(ccv, snd_max) - CCV(ccv, snd_una)) / 2 / mss, 2)
|
||||||
|
* mss;
|
||||||
CCV(ccv, snd_cwnd) = mss;
|
CCV(ccv, snd_cwnd) = mss;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -230,19 +230,21 @@ static void
|
|||||||
dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
|
dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
|
||||||
{
|
{
|
||||||
struct dctcp *dctcp_data;
|
struct dctcp *dctcp_data;
|
||||||
uint32_t cwin;
|
uint32_t cwin, ssthresh_on_loss;
|
||||||
u_int mss;
|
u_int mss;
|
||||||
|
|
||||||
dctcp_data = ccv->cc_data;
|
dctcp_data = ccv->cc_data;
|
||||||
cwin = CCV(ccv, snd_cwnd);
|
cwin = CCV(ccv, snd_cwnd);
|
||||||
mss = CCV(ccv, t_maxseg);
|
mss = CCV(ccv, t_maxseg);
|
||||||
|
ssthresh_on_loss =
|
||||||
|
max((CCV(ccv, snd_max) - CCV(ccv, snd_una)) / 2 / mss, 2)
|
||||||
|
* mss;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CC_NDUPACK:
|
case CC_NDUPACK:
|
||||||
if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
|
if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
|
||||||
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
|
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
|
||||||
CCV(ccv, snd_ssthresh) = mss *
|
CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
|
||||||
max(cwin / 2 / mss, 2);
|
|
||||||
dctcp_data->num_cong_events++;
|
dctcp_data->num_cong_events++;
|
||||||
} else {
|
} else {
|
||||||
/* cwnd has already updated as congestion
|
/* cwnd has already updated as congestion
|
||||||
@ -250,8 +252,7 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
|
|||||||
* snd_cwnd_prev and recalculate snd_ssthresh
|
* snd_cwnd_prev and recalculate snd_ssthresh
|
||||||
*/
|
*/
|
||||||
cwin = CCV(ccv, snd_cwnd_prev);
|
cwin = CCV(ccv, snd_cwnd_prev);
|
||||||
CCV(ccv, snd_ssthresh) =
|
CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
|
||||||
max(cwin / 2 / mss, 2) * mss;
|
|
||||||
}
|
}
|
||||||
ENTER_RECOVERY(CCV(ccv, t_flags));
|
ENTER_RECOVERY(CCV(ccv, t_flags));
|
||||||
}
|
}
|
||||||
@ -265,8 +266,7 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
|
|||||||
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
|
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
|
||||||
if (V_dctcp_slowstart &&
|
if (V_dctcp_slowstart &&
|
||||||
dctcp_data->num_cong_events++ == 0) {
|
dctcp_data->num_cong_events++ == 0) {
|
||||||
CCV(ccv, snd_ssthresh) =
|
CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
|
||||||
mss * max(cwin / 2 / mss, 2);
|
|
||||||
dctcp_data->alpha = MAX_ALPHA_VALUE;
|
dctcp_data->alpha = MAX_ALPHA_VALUE;
|
||||||
dctcp_data->bytes_ecn = 0;
|
dctcp_data->bytes_ecn = 0;
|
||||||
dctcp_data->bytes_total = 0;
|
dctcp_data->bytes_total = 0;
|
||||||
@ -285,7 +285,7 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
|
|||||||
dctcp_update_alpha(ccv);
|
dctcp_update_alpha(ccv);
|
||||||
dctcp_data->save_sndnxt += CCV(ccv, t_maxseg);
|
dctcp_data->save_sndnxt += CCV(ccv, t_maxseg);
|
||||||
dctcp_data->num_cong_events++;
|
dctcp_data->num_cong_events++;
|
||||||
CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2);
|
CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
|
||||||
CCV(ccv, snd_cwnd) = mss;
|
CCV(ccv, snd_cwnd) = mss;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -325,7 +325,9 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type)
|
|||||||
*/
|
*/
|
||||||
if (CCV(ccv, t_rxtshift) >= 2)
|
if (CCV(ccv, t_rxtshift) >= 2)
|
||||||
htcp_data->t_last_cong = ticks;
|
htcp_data->t_last_cong = ticks;
|
||||||
CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2);
|
CCV(ccv, snd_ssthresh) =
|
||||||
|
max((CCV(ccv, snd_max) - CCV(ccv, snd_una)) / 2 / mss, 2)
|
||||||
|
* mss;
|
||||||
CCV(ccv, snd_cwnd) = mss;
|
CCV(ccv, snd_cwnd) = mss;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -518,6 +520,10 @@ htcp_ssthresh_update(struct cc_var *ccv)
|
|||||||
CCV(ccv, snd_ssthresh) = ((u_long)CCV(ccv, snd_cwnd) *
|
CCV(ccv, snd_ssthresh) = ((u_long)CCV(ccv, snd_cwnd) *
|
||||||
htcp_data->beta) >> HTCP_SHIFT;
|
htcp_data->beta) >> HTCP_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Align ssthresh to MSS boundary */
|
||||||
|
CCV(ccv, snd_ssthresh) = (CCV(ccv, snd_ssthresh) / CCV(ccv, t_maxseg))
|
||||||
|
* CCV(ccv, t_maxseg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,23 +182,26 @@ newreno_after_idle(struct cc_var *ccv)
|
|||||||
static void
|
static void
|
||||||
newreno_cong_signal(struct cc_var *ccv, uint32_t type)
|
newreno_cong_signal(struct cc_var *ccv, uint32_t type)
|
||||||
{
|
{
|
||||||
uint32_t cwin;
|
uint32_t cwin, ssthresh_on_loss;
|
||||||
u_int mss;
|
u_int mss;
|
||||||
|
|
||||||
cwin = CCV(ccv, snd_cwnd);
|
cwin = CCV(ccv, snd_cwnd);
|
||||||
mss = CCV(ccv, t_maxseg);
|
mss = CCV(ccv, t_maxseg);
|
||||||
|
ssthresh_on_loss =
|
||||||
|
max((CCV(ccv, snd_max) - CCV(ccv, snd_una)) / 2 / mss, 2)
|
||||||
|
* mss;
|
||||||
|
|
||||||
/* Catch algos which mistakenly leak private signal types. */
|
/* Catch algos which mistakenly leak private signal types. */
|
||||||
KASSERT((type & CC_SIGPRIVMASK) == 0,
|
KASSERT((type & CC_SIGPRIVMASK) == 0,
|
||||||
("%s: congestion signal type 0x%08x is private\n", __func__, type));
|
("%s: congestion signal type 0x%08x is private\n", __func__, type));
|
||||||
|
|
||||||
cwin = max(2*mss, cwin/2);
|
cwin = max(cwin / 2 / mss, 2) * mss;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CC_NDUPACK:
|
case CC_NDUPACK:
|
||||||
if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
|
if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
|
||||||
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
|
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
|
||||||
CCV(ccv, snd_ssthresh) = cwin;
|
CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
|
||||||
CCV(ccv, snd_cwnd) = cwin;
|
CCV(ccv, snd_cwnd) = cwin;
|
||||||
}
|
}
|
||||||
ENTER_RECOVERY(CCV(ccv, t_flags));
|
ENTER_RECOVERY(CCV(ccv, t_flags));
|
||||||
@ -206,13 +209,13 @@ newreno_cong_signal(struct cc_var *ccv, uint32_t type)
|
|||||||
break;
|
break;
|
||||||
case CC_ECN:
|
case CC_ECN:
|
||||||
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
|
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
|
||||||
CCV(ccv, snd_ssthresh) = cwin;
|
CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
|
||||||
CCV(ccv, snd_cwnd) = cwin;
|
CCV(ccv, snd_cwnd) = cwin;
|
||||||
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
|
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CC_RTO:
|
case CC_RTO:
|
||||||
CCV(ccv, snd_ssthresh) = cwin;
|
CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
|
||||||
CCV(ccv, snd_cwnd) = mss;
|
CCV(ccv, snd_cwnd) = mss;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +444,8 @@ cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type)
|
|||||||
* ssthresh = max (FlightSize / 2, 2*SMSS) eq (4)
|
* ssthresh = max (FlightSize / 2, 2*SMSS) eq (4)
|
||||||
*/
|
*/
|
||||||
tp->snd_ssthresh =
|
tp->snd_ssthresh =
|
||||||
max((tp->snd_max - tp->snd_una) / 2, 2 * maxseg);
|
max((tp->snd_max - tp->snd_una) / 2 / maxseg, 2)
|
||||||
|
* maxseg;
|
||||||
tp->snd_cwnd = maxseg;
|
tp->snd_cwnd = maxseg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -303,11 +303,9 @@ ipfw_check_packet(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* ipfw processing for ethernet packets (in and out).
|
* ipfw processing for ethernet packets (in and out).
|
||||||
* Inteface is NULL from ether_demux, and ifp from
|
|
||||||
* ether_output_frame.
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
|
ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
|
||||||
struct inpcb *inp)
|
struct inpcb *inp)
|
||||||
{
|
{
|
||||||
struct ether_header *eh;
|
struct ether_header *eh;
|
||||||
@ -348,7 +346,7 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
|
|||||||
m_adj(m, ETHER_HDR_LEN); /* strip ethernet header */
|
m_adj(m, ETHER_HDR_LEN); /* strip ethernet header */
|
||||||
|
|
||||||
args.m = m; /* the packet we are looking at */
|
args.m = m; /* the packet we are looking at */
|
||||||
args.oif = dir == PFIL_OUT ? dst: NULL; /* destination, if any */
|
args.oif = dir == PFIL_OUT ? ifp: NULL; /* destination, if any */
|
||||||
args.next_hop = NULL; /* we do not support forward yet */
|
args.next_hop = NULL; /* we do not support forward yet */
|
||||||
args.next_hop6 = NULL; /* we do not support forward yet */
|
args.next_hop6 = NULL; /* we do not support forward yet */
|
||||||
args.eh = &save_eh; /* MAC header for bridged/MAC packets */
|
args.eh = &save_eh; /* MAC header for bridged/MAC packets */
|
||||||
@ -383,14 +381,13 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
|
|||||||
|
|
||||||
case IP_FW_DUMMYNET:
|
case IP_FW_DUMMYNET:
|
||||||
ret = EACCES;
|
ret = EACCES;
|
||||||
int dir;
|
|
||||||
|
|
||||||
if (ip_dn_io_ptr == NULL)
|
if (ip_dn_io_ptr == NULL)
|
||||||
break; /* i.e. drop */
|
break; /* i.e. drop */
|
||||||
|
|
||||||
*m0 = NULL;
|
*m0 = NULL;
|
||||||
dir = PROTO_LAYER2 | (dst ? DIR_OUT : DIR_IN);
|
dir = (dir == PFIL_IN) ? DIR_IN : DIR_OUT;
|
||||||
ip_dn_io_ptr(&m, dir, &args);
|
ip_dn_io_ptr(&m, dir | PROTO_LAYER2, &args);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -698,8 +698,12 @@
|
|||||||
#define SVR_MPC8572E 0x80e8
|
#define SVR_MPC8572E 0x80e8
|
||||||
#define SVR_P1011 0x80e5
|
#define SVR_P1011 0x80e5
|
||||||
#define SVR_P1011E 0x80ed
|
#define SVR_P1011E 0x80ed
|
||||||
|
#define SVR_P1013 0x80e7
|
||||||
|
#define SVR_P1013E 0x80ef
|
||||||
#define SVR_P1020 0x80e4
|
#define SVR_P1020 0x80e4
|
||||||
#define SVR_P1020E 0x80ec
|
#define SVR_P1020E 0x80ec
|
||||||
|
#define SVR_P1022 0x80e6
|
||||||
|
#define SVR_P1022E 0x80ee
|
||||||
#define SVR_P2010 0x80e3
|
#define SVR_P2010 0x80e3
|
||||||
#define SVR_P2010E 0x80eb
|
#define SVR_P2010E 0x80eb
|
||||||
#define SVR_P2020 0x80e2
|
#define SVR_P2020 0x80e2
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,297 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2011-2012 Semihalf
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FSL_SDHC_H_
|
|
||||||
#define FSL_SDHC_H_
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/bus.h>
|
|
||||||
#include <sys/kernel.h>
|
|
||||||
#include <sys/lock.h>
|
|
||||||
#include <sys/module.h>
|
|
||||||
#include <sys/mutex.h>
|
|
||||||
#include <sys/rman.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
#include <sys/taskqueue.h>
|
|
||||||
|
|
||||||
#include <machine/bus.h>
|
|
||||||
|
|
||||||
#include <dev/mmc/bridge.h>
|
|
||||||
#include <dev/mmc/mmcreg.h>
|
|
||||||
#include <dev/mmc/mmcvar.h>
|
|
||||||
#include <dev/mmc/mmcbrvar.h>
|
|
||||||
|
|
||||||
#include "mmcbr_if.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Private defines
|
|
||||||
*****************************************************************************/
|
|
||||||
struct slot {
|
|
||||||
uint32_t clock;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fsl_sdhc_softc {
|
|
||||||
device_t self;
|
|
||||||
device_t child;
|
|
||||||
|
|
||||||
bus_space_handle_t bsh;
|
|
||||||
bus_space_tag_t bst;
|
|
||||||
|
|
||||||
struct resource *mem_resource;
|
|
||||||
int mem_rid;
|
|
||||||
struct resource *irq_resource;
|
|
||||||
int irq_rid;
|
|
||||||
void *ihl;
|
|
||||||
|
|
||||||
bus_dma_tag_t dma_tag;
|
|
||||||
bus_dmamap_t dma_map;
|
|
||||||
uint32_t* dma_mem;
|
|
||||||
bus_addr_t dma_phys;
|
|
||||||
|
|
||||||
struct mtx mtx;
|
|
||||||
|
|
||||||
struct task card_detect_task;
|
|
||||||
struct callout card_detect_callout;
|
|
||||||
|
|
||||||
struct mmc_host mmc_host;
|
|
||||||
|
|
||||||
struct slot slot;
|
|
||||||
uint32_t bus_busy;
|
|
||||||
uint32_t platform_clock;
|
|
||||||
|
|
||||||
struct mmc_request *request;
|
|
||||||
int data_done;
|
|
||||||
int command_done;
|
|
||||||
int use_dma;
|
|
||||||
uint32_t* data_ptr;
|
|
||||||
uint32_t data_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define FSL_SDHC_RESET_DELAY 50
|
|
||||||
|
|
||||||
#define FSL_SDHC_BASE_CLOCK_DIV (2)
|
|
||||||
#define FSL_SDHC_MAX_DIV (FSL_SDHC_BASE_CLOCK_DIV * 256 * 16)
|
|
||||||
#define FSL_SDHC_MIN_DIV (FSL_SDHC_BASE_CLOCK_DIV * 2)
|
|
||||||
#define FSL_SDHC_MAX_CLOCK (50000000)
|
|
||||||
|
|
||||||
#define FSL_SDHC_MAX_BLOCK_COUNT (65535)
|
|
||||||
#define FSL_SDHC_MAX_BLOCK_SIZE (4096)
|
|
||||||
|
|
||||||
#define FSL_SDHC_FIFO_BUF_SIZE (64) /* Water-mark level. */
|
|
||||||
#define FSL_SDHC_FIFO_BUF_WORDS (FSL_SDHC_FIFO_BUF_SIZE / 4)
|
|
||||||
|
|
||||||
#define FSL_SDHC_DMA_SEGMENT_SIZE (1024)
|
|
||||||
#define FSL_SDHC_DMA_ALIGNMENT (4)
|
|
||||||
#define FSL_SDHC_DMA_BLOCK_SIZE FSL_SDHC_MAX_BLOCK_SIZE
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Offsets of SD HC registers
|
|
||||||
*/
|
|
||||||
enum sdhc_reg_off {
|
|
||||||
SDHC_DSADDR = 0x000,
|
|
||||||
SDHC_BLKATTR = 0x004,
|
|
||||||
SDHC_CMDARG = 0x008,
|
|
||||||
SDHC_XFERTYP = 0x00c,
|
|
||||||
SDHC_CMDRSP0 = 0x010,
|
|
||||||
SDHC_CMDRSP1 = 0x014,
|
|
||||||
SDHC_CMDRSP2 = 0x018,
|
|
||||||
SDHC_CMDRSP3 = 0x01c,
|
|
||||||
SDHC_DATPORT = 0x020,
|
|
||||||
SDHC_PRSSTAT = 0x024,
|
|
||||||
SDHC_PROCTL = 0x028,
|
|
||||||
SDHC_SYSCTL = 0x02c,
|
|
||||||
SDHC_IRQSTAT = 0x030,
|
|
||||||
SDHC_IRQSTATEN = 0x034,
|
|
||||||
SDHC_IRQSIGEN = 0x038,
|
|
||||||
SDHC_AUTOC12ERR = 0x03c,
|
|
||||||
SDHC_HOSTCAPBLT = 0x040,
|
|
||||||
SDHC_WML = 0x044,
|
|
||||||
SDHC_FEVT = 0x050,
|
|
||||||
SDHC_HOSTVER = 0x0fc,
|
|
||||||
SDHC_DCR = 0x40c
|
|
||||||
};
|
|
||||||
|
|
||||||
enum sysctl_bit {
|
|
||||||
SYSCTL_INITA = 0x08000000,
|
|
||||||
SYSCTL_RSTD = 0x04000000,
|
|
||||||
SYSCTL_RSTC = 0x02000000,
|
|
||||||
SYSCTL_RSTA = 0x01000000,
|
|
||||||
SYSCTL_DTOCV = 0x000f0000,
|
|
||||||
SYSCTL_SDCLKFS = 0x0000ff00,
|
|
||||||
SYSCTL_DVS = 0x000000f0,
|
|
||||||
SYSCTL_PEREN = 0x00000004,
|
|
||||||
SYSCTL_HCKEN = 0x00000002,
|
|
||||||
SYSCTL_IPGEN = 0x00000001
|
|
||||||
};
|
|
||||||
|
|
||||||
#define HEX_LEFT_SHIFT(x) (4 * x)
|
|
||||||
enum sysctl_shift {
|
|
||||||
SHIFT_DTOCV = HEX_LEFT_SHIFT(4),
|
|
||||||
SHIFT_SDCLKFS = HEX_LEFT_SHIFT(2),
|
|
||||||
SHIFT_DVS = HEX_LEFT_SHIFT(1)
|
|
||||||
};
|
|
||||||
|
|
||||||
enum proctl_bit {
|
|
||||||
PROCTL_WECRM = 0x04000000,
|
|
||||||
PROCTL_WECINS = 0x02000000,
|
|
||||||
PROCTL_WECINT = 0x01000000,
|
|
||||||
PROCTL_RWCTL = 0x00040000,
|
|
||||||
PROCTL_CREQ = 0x00020000,
|
|
||||||
PROCTL_SABGREQ = 0x00010000,
|
|
||||||
PROCTL_CDSS = 0x00000080,
|
|
||||||
PROCTL_CDTL = 0x00000040,
|
|
||||||
PROCTL_EMODE = 0x00000030,
|
|
||||||
PROCTL_D3CD = 0x00000008,
|
|
||||||
PROCTL_DTW = 0x00000006
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dtw {
|
|
||||||
DTW_1 = 0x00000000,
|
|
||||||
DTW_4 = 0x00000002,
|
|
||||||
DTW_8 = 0x00000004
|
|
||||||
};
|
|
||||||
|
|
||||||
enum prsstat_bit {
|
|
||||||
PRSSTAT_DLSL = 0xff000000,
|
|
||||||
PRSSTAT_CLSL = 0x00800000,
|
|
||||||
PRSSTAT_WPSPL = 0x00080000,
|
|
||||||
PRSSTAT_CDPL = 0x00040000,
|
|
||||||
PRSSTAT_CINS = 0x00010000,
|
|
||||||
PRSSTAT_BREN = 0x00000800,
|
|
||||||
PRSSTAT_BWEN = 0x00000400,
|
|
||||||
PRSSTAT_RTA = 0x00000200,
|
|
||||||
PRSSTAT_WTA = 0x00000100,
|
|
||||||
PRSSTAT_SDOFF = 0x00000080,
|
|
||||||
PRSSTAT_PEROFF = 0x00000040,
|
|
||||||
PRSSTAT_HCKOFF = 0x00000020,
|
|
||||||
PRSSTAT_IPGOFF = 0x00000010,
|
|
||||||
PRSSTAT_DLA = 0x00000004,
|
|
||||||
PRSSTAT_CDIHB = 0x00000002,
|
|
||||||
PRSSTAT_CIHB = 0x00000001
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
enum irq_bits {
|
|
||||||
IRQ_DMAE = 0x10000000,
|
|
||||||
IRQ_AC12E = 0x01000000,
|
|
||||||
IRQ_DEBE = 0x00400000,
|
|
||||||
IRQ_DCE = 0x00200000,
|
|
||||||
IRQ_DTOE = 0x00100000,
|
|
||||||
IRQ_CIE = 0x00080000,
|
|
||||||
IRQ_CEBE = 0x00040000,
|
|
||||||
IRQ_CCE = 0x00020000,
|
|
||||||
IRQ_CTOE = 0x00010000,
|
|
||||||
IRQ_CINT = 0x00000100,
|
|
||||||
IRQ_CRM = 0x00000080,
|
|
||||||
IRQ_CINS = 0x00000040,
|
|
||||||
IRQ_BRR = 0x00000020,
|
|
||||||
IRQ_BWR = 0x00000010,
|
|
||||||
IRQ_DINT = 0x00000008,
|
|
||||||
IRQ_BGE = 0x00000004,
|
|
||||||
IRQ_TC = 0x00000002,
|
|
||||||
IRQ_CC = 0x00000001
|
|
||||||
};
|
|
||||||
|
|
||||||
enum irq_masks {
|
|
||||||
IRQ_ERROR_DATA_MASK = IRQ_DMAE | IRQ_DEBE | IRQ_DCE | IRQ_DTOE,
|
|
||||||
IRQ_ERROR_CMD_MASK = IRQ_AC12E | IRQ_CIE | IRQ_CTOE | IRQ_CCE |
|
|
||||||
IRQ_CEBE
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dcr_bits {
|
|
||||||
DCR_PRI = 0x0000c000,
|
|
||||||
DCR_SNOOP = 0x00000040,
|
|
||||||
DCR_AHB2MAG_BYPASS = 0x00000020,
|
|
||||||
DCR_RD_SAFE = 0x00000004,
|
|
||||||
DCR_RD_PFE = 0x00000002,
|
|
||||||
DCR_RD_PF_SIZE = 0x00000001
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DCR_PRI_SHIFT (14)
|
|
||||||
|
|
||||||
enum xfertyp_bits {
|
|
||||||
XFERTYP_CMDINX = 0x3f000000,
|
|
||||||
XFERTYP_CMDTYP = 0x00c00000,
|
|
||||||
XFERTYP_DPSEL = 0x00200000,
|
|
||||||
XFERTYP_CICEN = 0x00100000,
|
|
||||||
XFERTYP_CCCEN = 0x00080000,
|
|
||||||
XFERTYP_RSPTYP = 0x00030000,
|
|
||||||
XFERTYP_MSBSEL = 0x00000020,
|
|
||||||
XFERTYP_DTDSEL = 0x00000010,
|
|
||||||
XFERTYP_AC12EN = 0x00000004,
|
|
||||||
XFERTYP_BCEN = 0x00000002,
|
|
||||||
XFERTYP_DMAEN = 0x00000001
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CMDINX_SHIFT (24)
|
|
||||||
|
|
||||||
enum xfertyp_cmdtyp {
|
|
||||||
CMDTYP_NORMAL = 0x00000000,
|
|
||||||
CMDYTP_SUSPEND = 0x00400000,
|
|
||||||
CMDTYP_RESUME = 0x00800000,
|
|
||||||
CMDTYP_ABORT = 0x00c00000
|
|
||||||
};
|
|
||||||
|
|
||||||
enum xfertyp_rsptyp {
|
|
||||||
RSPTYP_NONE = 0x00000000,
|
|
||||||
RSPTYP_136 = 0x00010000,
|
|
||||||
RSPTYP_48 = 0x00020000,
|
|
||||||
RSPTYP_48_BUSY = 0x00030000
|
|
||||||
};
|
|
||||||
|
|
||||||
enum blkattr_bits {
|
|
||||||
BLKATTR_BLKSZE = 0x00001fff,
|
|
||||||
BLKATTR_BLKCNT = 0xffff0000
|
|
||||||
};
|
|
||||||
#define BLKATTR_BLOCK_COUNT(x) (x << 16)
|
|
||||||
|
|
||||||
enum wml_bits {
|
|
||||||
WR_WML = 0x00ff0000,
|
|
||||||
RD_WML = 0x000000ff,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum sdhc_bit_mask {
|
|
||||||
MASK_CLOCK_CONTROL = 0x0000ffff,
|
|
||||||
MASK_IRQ_ALL = IRQ_DMAE | IRQ_AC12E | IRQ_DEBE | IRQ_DCE |
|
|
||||||
IRQ_DTOE | IRQ_CIE | IRQ_CEBE | IRQ_CCE |
|
|
||||||
IRQ_CTOE | IRQ_CINT | IRQ_CRM | IRQ_CINS |
|
|
||||||
IRQ_BRR | IRQ_BWR | IRQ_DINT | IRQ_BGE |
|
|
||||||
IRQ_TC | IRQ_CC,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum sdhc_line {
|
|
||||||
SDHC_DAT_LINE = 0x2,
|
|
||||||
SDHC_CMD_LINE = 0x1
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSL_SDHC_H_ */
|
|
@ -121,6 +121,9 @@ struct bio {
|
|||||||
void *_bio_caller2;
|
void *_bio_caller2;
|
||||||
uint8_t _bio_cflags;
|
uint8_t _bio_cflags;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
struct buf *bio_track_bp; /* Parent buf for tracking */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* XXX: these go away when bio chaining is introduced */
|
/* XXX: these go away when bio chaining is introduced */
|
||||||
daddr_t bio_pblkno; /* physical block number */
|
daddr_t bio_pblkno; /* physical block number */
|
||||||
@ -142,6 +145,23 @@ void biodone(struct bio *bp);
|
|||||||
void biofinish(struct bio *bp, struct devstat *stat, int error);
|
void biofinish(struct bio *bp, struct devstat *stat, int error);
|
||||||
int biowait(struct bio *bp, const char *wchan);
|
int biowait(struct bio *bp, const char *wchan);
|
||||||
|
|
||||||
|
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||||
|
void biotrack_buf(struct bio *bp, const char *location);
|
||||||
|
|
||||||
|
static __inline void
|
||||||
|
biotrack(struct bio *bp, const char *location)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (bp->bio_track_bp != NULL)
|
||||||
|
biotrack_buf(bp, location);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static __inline void
|
||||||
|
biotrack(struct bio *bp __unused, const char *location __unused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void bioq_disksort(struct bio_queue_head *ap, struct bio *bp);
|
void bioq_disksort(struct bio_queue_head *ap, struct bio *bp);
|
||||||
struct bio *bioq_first(struct bio_queue_head *head);
|
struct bio *bioq_first(struct bio_queue_head *head);
|
||||||
struct bio *bioq_takefirst(struct bio_queue_head *head);
|
struct bio *bioq_takefirst(struct bio_queue_head *head);
|
||||||
|
@ -140,6 +140,15 @@ struct buf {
|
|||||||
void *b_fsprivate1;
|
void *b_fsprivate1;
|
||||||
void *b_fsprivate2;
|
void *b_fsprivate2;
|
||||||
void *b_fsprivate3;
|
void *b_fsprivate3;
|
||||||
|
|
||||||
|
#if defined(FULL_BUF_TRACKING)
|
||||||
|
#define BUF_TRACKING_SIZE 32
|
||||||
|
#define BUF_TRACKING_ENTRY(x) ((x) & (BUF_TRACKING_SIZE - 1))
|
||||||
|
const char *b_io_tracking[BUF_TRACKING_SIZE];
|
||||||
|
uint32_t b_io_tcnt;
|
||||||
|
#elif defined(BUF_TRACKING)
|
||||||
|
const char *b_io_tracking;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define b_object b_bufobj->bo_object
|
#define b_object b_bufobj->bo_object
|
||||||
@ -429,6 +438,17 @@ buf_countdeps(struct buf *bp, int i)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __inline void
|
||||||
|
buf_track(struct buf *bp, const char *location)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(FULL_BUF_TRACKING)
|
||||||
|
bp->b_io_tracking[BUF_TRACKING_ENTRY(bp->b_io_tcnt++)] = location;
|
||||||
|
#elif defined(BUF_TRACKING)
|
||||||
|
bp->b_io_tracking = location;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -55,6 +55,9 @@ struct componentname {
|
|||||||
long cn_namelen; /* length of looked up component */
|
long cn_namelen; /* length of looked up component */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nameicap_tracker;
|
||||||
|
TAILQ_HEAD(nameicap_tracker_head, nameicap_tracker);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encapsulation of namei parameters.
|
* Encapsulation of namei parameters.
|
||||||
*/
|
*/
|
||||||
@ -72,7 +75,7 @@ struct nameidata {
|
|||||||
struct vnode *ni_rootdir; /* logical root directory */
|
struct vnode *ni_rootdir; /* logical root directory */
|
||||||
struct vnode *ni_topdir; /* logical top directory */
|
struct vnode *ni_topdir; /* logical top directory */
|
||||||
int ni_dirfd; /* starting directory for *at functions */
|
int ni_dirfd; /* starting directory for *at functions */
|
||||||
int ni_strictrelative; /* relative lookup only; no '..' */
|
int ni_lcf; /* local call flags */
|
||||||
/*
|
/*
|
||||||
* Results: returned from namei
|
* Results: returned from namei
|
||||||
*/
|
*/
|
||||||
@ -94,6 +97,7 @@ struct nameidata {
|
|||||||
* through the VOP interface.
|
* through the VOP interface.
|
||||||
*/
|
*/
|
||||||
struct componentname ni_cnd;
|
struct componentname ni_cnd;
|
||||||
|
struct nameicap_tracker_head ni_cap_tracker;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
@ -151,6 +155,12 @@ struct nameidata {
|
|||||||
#define NOCAPCHECK 0x20000000 /* do not perform capability checks */
|
#define NOCAPCHECK 0x20000000 /* do not perform capability checks */
|
||||||
#define PARAMASK 0x3ffffe00 /* mask of parameter descriptors */
|
#define PARAMASK 0x3ffffe00 /* mask of parameter descriptors */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags in ni_lcf, valid for the duration of the namei call.
|
||||||
|
*/
|
||||||
|
#define NI_LCF_STRICTRELATIVE 0x0001 /* relative lookup only */
|
||||||
|
#define NI_LCF_CAP_DOTDOT 0x0002 /* ".." in strictrelative case */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialization of a nameidata structure.
|
* Initialization of a nameidata structure.
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 4. Neither the name of the University nor the names of its contributors
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
@ -61,11 +61,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
* remaining space in the directory.
|
* remaining space in the directory.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ffs_blkatoff(vp, offset, res, bpp)
|
ffs_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp)
|
||||||
struct vnode *vp;
|
|
||||||
off_t offset;
|
|
||||||
char **res;
|
|
||||||
struct buf **bpp;
|
|
||||||
{
|
{
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
struct fs *fs;
|
struct fs *fs;
|
||||||
@ -95,11 +91,7 @@ ffs_blkatoff(vp, offset, res, bpp)
|
|||||||
* to the incore copy.
|
* to the incore copy.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ffs_load_inode(bp, ip, fs, ino)
|
ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino)
|
||||||
struct buf *bp;
|
|
||||||
struct inode *ip;
|
|
||||||
struct fs *fs;
|
|
||||||
ino_t ino;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
if (I_IS_UFS1(ip)) {
|
if (I_IS_UFS1(ip)) {
|
||||||
@ -131,11 +123,7 @@ ffs_load_inode(bp, ip, fs, ino)
|
|||||||
* of some frags.
|
* of some frags.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ffs_fragacct(fs, fragmap, fraglist, cnt)
|
ffs_fragacct(struct fs *fs, int fragmap, int32_t fraglist[], int cnt)
|
||||||
struct fs *fs;
|
|
||||||
int fragmap;
|
|
||||||
int32_t fraglist[];
|
|
||||||
int cnt;
|
|
||||||
{
|
{
|
||||||
int inblk;
|
int inblk;
|
||||||
int field, subfield;
|
int field, subfield;
|
||||||
@ -167,10 +155,7 @@ ffs_fragacct(fs, fragmap, fraglist, cnt)
|
|||||||
* check if a block is available
|
* check if a block is available
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ffs_isblock(fs, cp, h)
|
ffs_isblock(struct fs *fs, unsigned char *cp, ufs1_daddr_t h)
|
||||||
struct fs *fs;
|
|
||||||
unsigned char *cp;
|
|
||||||
ufs1_daddr_t h;
|
|
||||||
{
|
{
|
||||||
unsigned char mask;
|
unsigned char mask;
|
||||||
|
|
||||||
@ -199,10 +184,7 @@ ffs_isblock(fs, cp, h)
|
|||||||
* check if a block is free
|
* check if a block is free
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ffs_isfreeblock(fs, cp, h)
|
ffs_isfreeblock(struct fs *fs, u_char *cp, ufs1_daddr_t h)
|
||||||
struct fs *fs;
|
|
||||||
u_char *cp;
|
|
||||||
ufs1_daddr_t h;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
switch ((int)fs->fs_frag) {
|
switch ((int)fs->fs_frag) {
|
||||||
@ -227,10 +209,7 @@ ffs_isfreeblock(fs, cp, h)
|
|||||||
* take a block out of the map
|
* take a block out of the map
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ffs_clrblock(fs, cp, h)
|
ffs_clrblock(struct fs *fs, u_char *cp, ufs1_daddr_t h)
|
||||||
struct fs *fs;
|
|
||||||
u_char *cp;
|
|
||||||
ufs1_daddr_t h;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
switch ((int)fs->fs_frag) {
|
switch ((int)fs->fs_frag) {
|
||||||
@ -258,10 +237,7 @@ ffs_clrblock(fs, cp, h)
|
|||||||
* put a block into the map
|
* put a block into the map
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ffs_setblock(fs, cp, h)
|
ffs_setblock(struct fs *fs, unsigned char *cp, ufs1_daddr_t h)
|
||||||
struct fs *fs;
|
|
||||||
unsigned char *cp;
|
|
||||||
ufs1_daddr_t h;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
switch ((int)fs->fs_frag) {
|
switch ((int)fs->fs_frag) {
|
||||||
@ -292,11 +268,7 @@ ffs_setblock(fs, cp, h)
|
|||||||
* Cnt == 1 means free; cnt == -1 means allocating.
|
* Cnt == 1 means free; cnt == -1 means allocating.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ffs_clusteracct(fs, cgp, blkno, cnt)
|
ffs_clusteracct(struct fs *fs, struct cg *cgp, ufs1_daddr_t blkno, int cnt)
|
||||||
struct fs *fs;
|
|
||||||
struct cg *cgp;
|
|
||||||
ufs1_daddr_t blkno;
|
|
||||||
int cnt;
|
|
||||||
{
|
{
|
||||||
int32_t *sump;
|
int32_t *sump;
|
||||||
int32_t *lp;
|
int32_t *lp;
|
||||||
|
@ -420,8 +420,7 @@ RetryFault:;
|
|||||||
* they will stay around as well.
|
* they will stay around as well.
|
||||||
*
|
*
|
||||||
* Bump the paging-in-progress count to prevent size changes (e.g.
|
* Bump the paging-in-progress count to prevent size changes (e.g.
|
||||||
* truncation operations) during I/O. This must be done after
|
* truncation operations) during I/O.
|
||||||
* obtaining the vnode lock in order to avoid possible deadlocks.
|
|
||||||
*/
|
*/
|
||||||
vm_object_reference_locked(fs.first_object);
|
vm_object_reference_locked(fs.first_object);
|
||||||
vm_object_pip_add(fs.first_object, 1);
|
vm_object_pip_add(fs.first_object, 1);
|
||||||
@ -647,7 +646,13 @@ RetryFault:;
|
|||||||
|
|
||||||
if (locked != LK_EXCLUSIVE)
|
if (locked != LK_EXCLUSIVE)
|
||||||
locked = LK_SHARED;
|
locked = LK_SHARED;
|
||||||
/* Do not sleep for vnode lock while fs.m is busy */
|
|
||||||
|
/*
|
||||||
|
* We must not sleep acquiring the vnode lock
|
||||||
|
* while we have the page exclusive busied or
|
||||||
|
* the object's paging-in-progress count
|
||||||
|
* incremented. Otherwise, we could deadlock.
|
||||||
|
*/
|
||||||
error = vget(vp, locked | LK_CANRECURSE |
|
error = vget(vp, locked | LK_CANRECURSE |
|
||||||
LK_NOWAIT, curthread);
|
LK_NOWAIT, curthread);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
|
@ -376,6 +376,7 @@ initpbuf(struct buf *bp)
|
|||||||
bp->b_iodone = NULL;
|
bp->b_iodone = NULL;
|
||||||
bp->b_error = 0;
|
bp->b_error = 0;
|
||||||
BUF_LOCK(bp, LK_EXCLUSIVE, NULL);
|
BUF_LOCK(bp, LK_EXCLUSIVE, NULL);
|
||||||
|
buf_track(bp, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -473,6 +474,7 @@ relpbuf(struct buf *bp, int *pfreecnt)
|
|||||||
KASSERT(bp->b_vp == NULL, ("relpbuf with vp"));
|
KASSERT(bp->b_vp == NULL, ("relpbuf with vp"));
|
||||||
KASSERT(bp->b_bufobj == NULL, ("relpbuf with bufobj"));
|
KASSERT(bp->b_bufobj == NULL, ("relpbuf with bufobj"));
|
||||||
|
|
||||||
|
buf_track(bp, __func__);
|
||||||
BUF_UNLOCK(bp);
|
BUF_UNLOCK(bp);
|
||||||
|
|
||||||
mtx_lock(&pbuf_mtx);
|
mtx_lock(&pbuf_mtx);
|
||||||
|
@ -14,6 +14,11 @@ ATF_TESTS_C+= unix_passfd_test
|
|||||||
TEST_METADATA.unix_seqpacket_test+= timeout="15"
|
TEST_METADATA.unix_seqpacket_test+= timeout="15"
|
||||||
ATF_TESTS_C+= waitpid_nohang
|
ATF_TESTS_C+= waitpid_nohang
|
||||||
|
|
||||||
|
ATF_TESTS_SH+= coredump_phnum_test
|
||||||
|
|
||||||
|
BINDIR= ${TESTSDIR}
|
||||||
|
PROGS+= coredump_phnum_helper
|
||||||
|
|
||||||
LIBADD.ptrace_test+= pthread
|
LIBADD.ptrace_test+= pthread
|
||||||
LIBADD.unix_seqpacket_test+= pthread
|
LIBADD.unix_seqpacket_test+= pthread
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user