summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/mv/mpic.c12
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c36
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c12
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c233
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h16
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c68
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil_freebsd.c16
-rw-r--r--sys/dev/acpica/acpi.c7
-rw-r--r--sys/dev/usb/controller/uhci_pci.c7
-rw-r--r--sys/dev/usb/controller/xhci_pci.c18
-rw-r--r--sys/dev/usb/quirk/usb_quirk.c140
-rw-r--r--sys/dev/usb/serial/u3g.c1
-rw-r--r--sys/dev/usb/usbdevs2
-rw-r--r--sys/kern/kern_shutdown.c4
-rw-r--r--sys/net/if_gre.c2
-rw-r--r--sys/net/if_var.h11
-rw-r--r--sys/netinet/tcp_output.c12
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/queue.h87
-rw-r--r--sys/sys/systm.h1
-rw-r--r--sys/sys/types.h7
24 files changed, 460 insertions, 243 deletions
diff --git a/sys/arm/mv/mpic.c b/sys/arm/mv/mpic.c
index 813caf4..0682e14 100644
--- a/sys/arm/mv/mpic.c
+++ b/sys/arm/mv/mpic.c
@@ -378,10 +378,14 @@ int
pic_ipi_get(int i __unused)
{
uint32_t val;
+ int ipi;
val = MPIC_CPU_READ(mv_mpic_sc, MPIC_IN_DRBL);
- if (val)
- return (ffs(val) - 1);
+ if (val) {
+ ipi = ffs(val) - 1;
+ MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DRBL, ~(1 << ipi));
+ return (ipi);
+ }
return (0x3ff);
}
@@ -389,10 +393,6 @@ pic_ipi_get(int i __unused)
void
pic_ipi_clear(int ipi)
{
- uint32_t val;
-
- val = ~(1 << ipi);
- MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DRBL, val);
}
#endif
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
index 9ad18f0..f84ff37 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
@@ -680,40 +680,8 @@ dmu_objset_evict(objset_t *os)
for (int t = 0; t < TXG_SIZE; t++)
ASSERT(!dmu_objset_is_dirty(os, t));
- if (ds) {
- if (!ds->ds_is_snapshot) {
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_CHECKSUM),
- checksum_changed_cb, os));
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_COMPRESSION),
- compression_changed_cb, os));
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_COPIES),
- copies_changed_cb, os));
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_DEDUP),
- dedup_changed_cb, os));
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_LOGBIAS),
- logbias_changed_cb, os));
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_SYNC),
- sync_changed_cb, os));
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_REDUNDANT_METADATA),
- redundant_metadata_changed_cb, os));
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_RECORDSIZE),
- recordsize_changed_cb, os));
- }
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_PRIMARYCACHE),
- primary_cache_changed_cb, os));
- VERIFY0(dsl_prop_unregister(ds,
- zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE),
- secondary_cache_changed_cb, os));
- }
+ if (ds)
+ dsl_prop_unregister_all(ds, os);
if (os->os_sa)
sa_tear_down(os);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
index f4fdaf9..4fbbe7c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
@@ -288,6 +288,7 @@ dsl_dataset_evict(void *dbu)
ASSERT(!list_link_active(&ds->ds_synced_link));
+ list_destroy(&ds->ds_prop_cbs);
if (mutex_owned(&ds->ds_lock))
mutex_exit(&ds->ds_lock);
mutex_destroy(&ds->ds_lock);
@@ -434,6 +435,9 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
list_create(&ds->ds_sendstreams, sizeof (dmu_sendarg_t),
offsetof(dmu_sendarg_t, dsa_link));
+ list_create(&ds->ds_prop_cbs, sizeof (dsl_prop_cb_record_t),
+ offsetof(dsl_prop_cb_record_t, cbr_ds_node));
+
if (doi.doi_type == DMU_OTN_ZAP_METADATA) {
for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
if (!(spa_feature_table[f].fi_flags &
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
index 4b268da..00341ad 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
@@ -152,11 +152,7 @@ dsl_dir_evict(void *dbu)
spa_async_close(dd->dd_pool->dp_spa, dd);
- /*
- * The props callback list should have been cleaned up by
- * objset_evict().
- */
- list_destroy(&dd->dd_prop_cbs);
+ dsl_prop_fini(dd);
mutex_destroy(&dd->dd_lock);
kmem_free(dd, sizeof (dsl_dir_t));
}
@@ -191,9 +187,7 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
dd->dd_dbuf = dbuf;
dd->dd_pool = dp;
mutex_init(&dd->dd_lock, NULL, MUTEX_DEFAULT, NULL);
-
- list_create(&dd->dd_prop_cbs, sizeof (dsl_prop_cb_record_t),
- offsetof(dsl_prop_cb_record_t, cbr_node));
+ dsl_prop_init(dd);
dsl_dir_snap_cmtime_update(dd);
@@ -251,6 +245,7 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
if (winner != NULL) {
if (dd->dd_parent)
dsl_dir_rele(dd->dd_parent, dd);
+ dsl_prop_fini(dd);
mutex_destroy(&dd->dd_lock);
kmem_free(dd, sizeof (dsl_dir_t));
dd = winner;
@@ -278,6 +273,7 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
errout:
if (dd->dd_parent)
dsl_dir_rele(dd->dd_parent, dd);
+ dsl_prop_fini(dd);
mutex_destroy(&dd->dd_lock);
kmem_free(dd, sizeof (dsl_dir_t));
dmu_buf_rele(dbuf, tag);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c
index 094b07d..12e2771 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c
@@ -215,6 +215,58 @@ dsl_prop_get_ds(dsl_dataset_t *ds, const char *propname,
intsz, numints, buf, setpoint, ds->ds_is_snapshot));
}
+static dsl_prop_record_t *
+dsl_prop_record_find(dsl_dir_t *dd, const char *propname)
+{
+ dsl_prop_record_t *pr = NULL;
+
+ ASSERT(MUTEX_HELD(&dd->dd_lock));
+
+ for (pr = list_head(&dd->dd_props);
+ pr != NULL; pr = list_next(&dd->dd_props, pr)) {
+ if (strcmp(pr->pr_propname, propname) == 0)
+ break;
+ }
+
+ return (pr);
+}
+
+static dsl_prop_record_t *
+dsl_prop_record_create(dsl_dir_t *dd, const char *propname)
+{
+ dsl_prop_record_t *pr;
+
+ ASSERT(MUTEX_HELD(&dd->dd_lock));
+
+ pr = kmem_alloc(sizeof (dsl_prop_record_t), KM_SLEEP);
+ pr->pr_propname = spa_strdup(propname);
+ list_create(&pr->pr_cbs, sizeof (dsl_prop_cb_record_t),
+ offsetof(dsl_prop_cb_record_t, cbr_pr_node));
+ list_insert_head(&dd->dd_props, pr);
+
+ return (pr);
+}
+
+void
+dsl_prop_init(dsl_dir_t *dd)
+{
+ list_create(&dd->dd_props, sizeof (dsl_prop_record_t),
+ offsetof(dsl_prop_record_t, pr_node));
+}
+
+void
+dsl_prop_fini(dsl_dir_t *dd)
+{
+ dsl_prop_record_t *pr;
+
+ while ((pr = list_remove_head(&dd->dd_props)) != NULL) {
+ list_destroy(&pr->pr_cbs);
+ strfree((char *)pr->pr_propname);
+ kmem_free(pr, sizeof (dsl_prop_record_t));
+ }
+ list_destroy(&dd->dd_props);
+}
+
/*
* Register interest in the named property. We'll call the callback
* once to notify it of the current property value, and again each time
@@ -229,6 +281,7 @@ dsl_prop_register(dsl_dataset_t *ds, const char *propname,
dsl_dir_t *dd = ds->ds_dir;
dsl_pool_t *dp = dd->dd_pool;
uint64_t value;
+ dsl_prop_record_t *pr;
dsl_prop_cb_record_t *cbr;
int err;
@@ -240,12 +293,16 @@ dsl_prop_register(dsl_dataset_t *ds, const char *propname,
cbr = kmem_alloc(sizeof (dsl_prop_cb_record_t), KM_SLEEP);
cbr->cbr_ds = ds;
- cbr->cbr_propname = kmem_alloc(strlen(propname)+1, KM_SLEEP);
- (void) strcpy((char *)cbr->cbr_propname, propname);
cbr->cbr_func = callback;
cbr->cbr_arg = cbarg;
+
mutex_enter(&dd->dd_lock);
- list_insert_head(&dd->dd_prop_cbs, cbr);
+ pr = dsl_prop_record_find(dd, propname);
+ if (pr == NULL)
+ pr = dsl_prop_record_create(dd, propname);
+ cbr->cbr_pr = pr;
+ list_insert_head(&pr->pr_cbs, cbr);
+ list_insert_head(&ds->ds_prop_cbs, cbr);
mutex_exit(&dd->dd_lock);
cbr->cbr_func(cbr->cbr_arg, value);
@@ -376,56 +433,34 @@ dsl_prop_predict(dsl_dir_t *dd, const char *propname,
}
/*
- * Unregister this callback. Return 0 on success, ENOENT if ddname is
- * invalid, or ENOMSG if no matching callback registered.
+ * Unregister all callbacks that are registered with the
+ * given callback argument.
*/
-int
-dsl_prop_unregister(dsl_dataset_t *ds, const char *propname,
- dsl_prop_changed_cb_t *callback, void *cbarg)
+void
+dsl_prop_unregister_all(dsl_dataset_t *ds, void *cbarg)
{
+ dsl_prop_cb_record_t *cbr, *next_cbr;
+
dsl_dir_t *dd = ds->ds_dir;
- dsl_prop_cb_record_t *cbr;
mutex_enter(&dd->dd_lock);
- for (cbr = list_head(&dd->dd_prop_cbs);
- cbr; cbr = list_next(&dd->dd_prop_cbs, cbr)) {
- if (cbr->cbr_ds == ds &&
- cbr->cbr_func == callback &&
- cbr->cbr_arg == cbarg &&
- strcmp(cbr->cbr_propname, propname) == 0)
- break;
- }
-
- if (cbr == NULL) {
- mutex_exit(&dd->dd_lock);
- return (SET_ERROR(ENOMSG));
+ next_cbr = list_head(&ds->ds_prop_cbs);
+ while (next_cbr != NULL) {
+ cbr = next_cbr;
+ next_cbr = list_next(&ds->ds_prop_cbs, cbr);
+ if (cbr->cbr_arg == cbarg) {
+ list_remove(&ds->ds_prop_cbs, cbr);
+ list_remove(&cbr->cbr_pr->pr_cbs, cbr);
+ kmem_free(cbr, sizeof (dsl_prop_cb_record_t));
+ }
}
-
- list_remove(&dd->dd_prop_cbs, cbr);
mutex_exit(&dd->dd_lock);
- kmem_free((void*)cbr->cbr_propname, strlen(cbr->cbr_propname)+1);
- kmem_free(cbr, sizeof (dsl_prop_cb_record_t));
-
- return (0);
}
boolean_t
dsl_prop_hascb(dsl_dataset_t *ds)
{
- dsl_dir_t *dd = ds->ds_dir;
- boolean_t rv = B_FALSE;
- dsl_prop_cb_record_t *cbr;
-
- mutex_enter(&dd->dd_lock);
- for (cbr = list_head(&dd->dd_prop_cbs); cbr;
- cbr = list_next(&dd->dd_prop_cbs, cbr)) {
- if (cbr->cbr_ds == ds) {
- rv = B_TRUE;
- break;
- }
- }
- mutex_exit(&dd->dd_lock);
- return (rv);
+ return (!list_is_empty(&ds->ds_prop_cbs));
}
/* ARGSUSED */
@@ -433,38 +468,50 @@ static int
dsl_prop_notify_all_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
{
dsl_dir_t *dd = ds->ds_dir;
+ dsl_prop_record_t *pr;
dsl_prop_cb_record_t *cbr;
mutex_enter(&dd->dd_lock);
- for (cbr = list_head(&dd->dd_prop_cbs); cbr;
- cbr = list_next(&dd->dd_prop_cbs, cbr)) {
- uint64_t value;
+ for (pr = list_head(&dd->dd_props);
+ pr; pr = list_next(&dd->dd_props, pr)) {
+ for (cbr = list_head(&pr->pr_cbs); cbr;
+ cbr = list_next(&pr->pr_cbs, cbr)) {
+ uint64_t value;
- /*
- * Callback entries do not have holds on their datasets
- * so that datasets with registered callbacks are still
- * eligible for eviction. Unlike operations on callbacks
- * for a single dataset, we are performing a recursive
- * descent of related datasets and the calling context
- * for this iteration only has a dataset hold on the root.
- * Without a hold, the callback's pointer to the dataset
- * could be invalidated by eviction at any time.
- *
- * Use dsl_dataset_try_add_ref() to verify that the
- * dataset has not begun eviction processing and to
- * prevent eviction from occurring for the duration
- * of the callback. If the hold attempt fails, this
- * object is already being evicted and the callback can
- * be safely ignored.
- */
- if (!dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
- continue;
+ /*
+ * Callback entries do not have holds on their
+ * datasets so that datasets with registered
+ * callbacks are still eligible for eviction.
+ * Unlike operations to update properties on a
+ * single dataset, we are performing a recursive
+ * descent of related head datasets. The caller
+ * of this function only has a dataset hold on
+ * the passed in head dataset, not the snapshots
+ * associated with this dataset. Without a hold,
+ * the dataset pointer within callback records
+ * for snapshots can be invalidated by eviction
+ * at any time.
+ *
+ * Use dsl_dataset_try_add_ref() to verify
+ * that the dataset for a snapshot has not
+ * begun eviction processing and to prevent
+ * eviction from occurring for the duration of
+ * the callback. If the hold attempt fails,
+ * this object is already being evicted and the
+ * callback can be safely ignored.
+ */
+ if (ds != cbr->cbr_ds &&
+ !dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
+ continue;
- if (dsl_prop_get_ds(cbr->cbr_ds, cbr->cbr_propname,
- sizeof (value), 1, &value, NULL) == 0)
- cbr->cbr_func(cbr->cbr_arg, value);
+ if (dsl_prop_get_ds(cbr->cbr_ds,
+ cbr->cbr_pr->pr_propname, sizeof (value), 1,
+ &value, NULL) == 0)
+ cbr->cbr_func(cbr->cbr_arg, value);
- dsl_dataset_rele(cbr->cbr_ds, FTAG);
+ if (ds != cbr->cbr_ds)
+ dsl_dataset_rele(cbr->cbr_ds, FTAG);
+ }
}
mutex_exit(&dd->dd_lock);
@@ -489,6 +536,7 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj,
const char *propname, uint64_t value, int first)
{
dsl_dir_t *dd;
+ dsl_prop_record_t *pr;
dsl_prop_cb_record_t *cbr;
objset_t *mos = dp->dp_meta_objset;
zap_cursor_t zc;
@@ -515,30 +563,33 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj,
}
mutex_enter(&dd->dd_lock);
- for (cbr = list_head(&dd->dd_prop_cbs); cbr;
- cbr = list_next(&dd->dd_prop_cbs, cbr)) {
- uint64_t propobj;
+ pr = dsl_prop_record_find(dd, propname);
+ if (pr != NULL) {
+ for (cbr = list_head(&pr->pr_cbs); cbr;
+ cbr = list_next(&pr->pr_cbs, cbr)) {
+ uint64_t propobj;
- /*
- * cbr->cbf_ds may be invalidated due to eviction,
- * requiring the use of dsl_dataset_try_add_ref().
- * See comment block in dsl_prop_notify_all_cb()
- * for details.
- */
- if (strcmp(cbr->cbr_propname, propname) != 0 ||
- !dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
- continue;
+ /*
+ * cbr->cbr_ds may be invalidated due to eviction,
+ * requiring the use of dsl_dataset_try_add_ref().
+ * See comment block in dsl_prop_notify_all_cb()
+ * for details.
+ */
+ if (!dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
+ continue;
- propobj = dsl_dataset_phys(cbr->cbr_ds)->ds_props_obj;
+ propobj = dsl_dataset_phys(cbr->cbr_ds)->ds_props_obj;
- /*
- * If the property is not set on this ds, then it is
- * inherited here; call the callback.
- */
- if (propobj == 0 || zap_contains(mos, propobj, propname) != 0)
- cbr->cbr_func(cbr->cbr_arg, value);
+ /*
+ * If the property is not set on this ds, then it is
+ * inherited here; call the callback.
+ */
+ if (propobj == 0 ||
+ zap_contains(mos, propobj, propname) != 0)
+ cbr->cbr_func(cbr->cbr_arg, value);
- dsl_dataset_rele(cbr->cbr_ds, FTAG);
+ dsl_dataset_rele(cbr->cbr_ds, FTAG);
+ }
}
mutex_exit(&dd->dd_lock);
@@ -678,10 +729,10 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
* ds here.
*/
mutex_enter(&ds->ds_dir->dd_lock);
- for (cbr = list_head(&ds->ds_dir->dd_prop_cbs); cbr;
- cbr = list_next(&ds->ds_dir->dd_prop_cbs, cbr)) {
- if (cbr->cbr_ds == ds &&
- strcmp(cbr->cbr_propname, propname) == 0)
+ for (cbr = list_head(&ds->ds_prop_cbs); cbr;
+ cbr = list_next(&ds->ds_prop_cbs, cbr)) {
+ if (strcmp(cbr->cbr_pr->pr_propname,
+ propname) == 0)
cbr->cbr_func(cbr->cbr_arg, intval);
}
mutex_exit(&ds->ds_dir->dd_lock);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
index 001bff5..c9cd589 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
@@ -184,6 +184,9 @@ typedef struct dsl_dataset {
kmutex_t ds_sendstream_lock;
list_t ds_sendstreams;
+ /* Protected by our dsl_dir's dd_lock */
+ list_t ds_prop_cbs;
+
/*
* For ZFEATURE_FLAG_PER_DATASET features, set if this dataset
* uses this feature.
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
index f50014d..93fb73f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
@@ -102,7 +102,7 @@ struct dsl_dir {
/* Protected by dd_lock */
kmutex_t dd_lock;
- list_t dd_prop_cbs; /* list of dsl_prop_cb_record_t's */
+ list_t dd_props; /* list of dsl_prop_record_t's */
timestruc_t dd_snap_cmtime; /* last time snapshot namespace changed */
uint64_t dd_origin_txg;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h
index 5fe18d6..21e6f46 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h
@@ -41,10 +41,17 @@ struct dsl_dir;
/* The callback func may not call into the DMU or DSL! */
typedef void (dsl_prop_changed_cb_t)(void *arg, uint64_t newval);
+typedef struct dsl_prop_record {
+ list_node_t pr_node; /* link on dd_props */
+ const char *pr_propname;
+ list_t pr_cbs;
+} dsl_prop_record_t;
+
typedef struct dsl_prop_cb_record {
- list_node_t cbr_node; /* link on dd_prop_cbs */
+ list_node_t cbr_pr_node; /* link on pr_cbs */
+ list_node_t cbr_ds_node; /* link on ds_prop_cbs */
+ dsl_prop_record_t *cbr_pr;
struct dsl_dataset *cbr_ds;
- const char *cbr_propname;
dsl_prop_changed_cb_t *cbr_func;
void *cbr_arg;
} dsl_prop_cb_record_t;
@@ -54,10 +61,11 @@ typedef struct dsl_props_arg {
zprop_source_t pa_source;
} dsl_props_arg_t;
+void dsl_prop_init(dsl_dir_t *dd);
+void dsl_prop_fini(dsl_dir_t *dd);
int dsl_prop_register(struct dsl_dataset *ds, const char *propname,
dsl_prop_changed_cb_t *callback, void *cbarg);
-int dsl_prop_unregister(struct dsl_dataset *ds, const char *propname,
- dsl_prop_changed_cb_t *callback, void *cbarg);
+void dsl_prop_unregister_all(struct dsl_dataset *ds, void *cbarg);
void dsl_prop_notify_all(struct dsl_dir *dd);
boolean_t dsl_prop_hascb(struct dsl_dataset *ds);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 201627a..8e66044 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -549,35 +549,7 @@ zfs_register_callbacks(vfs_t *vfsp)
return (0);
unregister:
- /*
- * We may attempt to unregister some callbacks that are not
- * registered, but this is OK; it will simply return ENOMSG,
- * which we will ignore.
- */
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_ATIME),
- atime_changed_cb, zfsvfs);
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_XATTR),
- xattr_changed_cb, zfsvfs);
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_RECORDSIZE),
- blksz_changed_cb, zfsvfs);
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_READONLY),
- readonly_changed_cb, zfsvfs);
-#ifdef illumos
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_DEVICES),
- devices_changed_cb, zfsvfs);
-#endif
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_SETUID),
- setuid_changed_cb, zfsvfs);
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_EXEC),
- exec_changed_cb, zfsvfs);
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_SNAPDIR),
- snapdir_changed_cb, zfsvfs);
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_ACLMODE),
- acl_mode_changed_cb, zfsvfs);
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_ACLINHERIT),
- acl_inherit_changed_cb, zfsvfs);
- (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_VSCAN),
- vscan_changed_cb, zfsvfs);
+ dsl_prop_unregister_all(ds, zfsvfs);
return (error);
}
@@ -1246,43 +1218,9 @@ void
zfs_unregister_callbacks(zfsvfs_t *zfsvfs)
{
objset_t *os = zfsvfs->z_os;
- struct dsl_dataset *ds;
-
- /*
- * Unregister properties.
- */
- if (!dmu_objset_is_snapshot(os)) {
- ds = dmu_objset_ds(os);
- VERIFY(dsl_prop_unregister(ds, "atime", atime_changed_cb,
- zfsvfs) == 0);
-
- VERIFY(dsl_prop_unregister(ds, "xattr", xattr_changed_cb,
- zfsvfs) == 0);
- VERIFY(dsl_prop_unregister(ds, "recordsize", blksz_changed_cb,
- zfsvfs) == 0);
-
- VERIFY(dsl_prop_unregister(ds, "readonly", readonly_changed_cb,
- zfsvfs) == 0);
-
- VERIFY(dsl_prop_unregister(ds, "setuid", setuid_changed_cb,
- zfsvfs) == 0);
-
- VERIFY(dsl_prop_unregister(ds, "exec", exec_changed_cb,
- zfsvfs) == 0);
-
- VERIFY(dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb,
- zfsvfs) == 0);
-
- VERIFY(dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb,
- zfsvfs) == 0);
-
- VERIFY(dsl_prop_unregister(ds, "aclinherit",
- acl_inherit_changed_cb, zfsvfs) == 0);
-
- VERIFY(dsl_prop_unregister(ds, "vscan",
- vscan_changed_cb, zfsvfs) == 0);
- }
+ if (!dmu_objset_is_snapshot(os))
+ dsl_prop_unregister_all(dmu_objset_ds(os), zfsvfs);
}
#ifdef SECLABEL
diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
index 325ddce..f10699d 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
@@ -1134,6 +1134,22 @@ ipf_checkv4sum(fin)
return -1;
}
if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
+ /* Depending on the driver, UDP may have zero checksum */
+ if (fin->fin_p == IPPROTO_UDP && (fin->fin_flx &
+ (FI_FRAG|FI_SHORT|FI_BAD)) == 0) {
+ udphdr_t *udp = fin->fin_dp;
+ if (udp->uh_sum == 0) {
+ /*
+ * we're good no matter what the hardware
+ * checksum flags and csum_data say (handling
+ * of csum_data for zero UDP checksum is not
+ * consistent across all drivers)
+ */
+ fin->fin_cksum = 1;
+ return 0;
+ }
+ }
+
if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
sum = m->m_pkthdr.csum_data;
else
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 107f12d..55b0dd2 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -2546,8 +2546,11 @@ acpi_ReqSleepState(struct acpi_softc *sc, int state)
if (!acpi_sleep_states[state])
return (EOPNOTSUPP);
- /* If a suspend request is already in progress, just return. */
- if (sc->acpi_next_sstate != 0) {
+ /*
+ * If a reboot/shutdown/suspend request is already in progress or
+ * suspend is blocked due to an upcoming shutdown, just return.
+ */
+ if (rebooting || sc->acpi_next_sstate != 0 || suspend_blocked) {
return (0);
}
diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c
index 4ac0d54..a7db9a9 100644
--- a/sys/dev/usb/controller/uhci_pci.c
+++ b/sys/dev/usb/controller/uhci_pci.c
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include "usb_if.h"
#define PCI_UHCI_VENDORID_INTEL 0x8086
+#define PCI_UHCI_VENDORID_HP 0x103c
#define PCI_UHCI_VENDORID_VIA 0x1106
/* PIIX4E has no separate stepping */
@@ -222,6 +223,9 @@ uhci_pci_match(device_t self)
case 0x76028086:
return ("Intel 82372FB/82468GX USB controller");
+ case 0x3300103c:
+ return ("HP iLO Standard Virtual USB controller");
+
case 0x30381106:
return ("VIA 83C572 USB controller");
@@ -309,6 +313,9 @@ uhci_pci_attach(device_t self)
case PCI_UHCI_VENDORID_INTEL:
sprintf(sc->sc_vendor, "Intel");
break;
+ case PCI_UHCI_VENDORID_HP:
+ sprintf(sc->sc_vendor, "HP");
+ break;
case PCI_UHCI_VENDORID_VIA:
sprintf(sc->sc_vendor, "VIA");
break;
diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c
index c2367f4..c4295aa 100644
--- a/sys/dev/usb/controller/xhci_pci.c
+++ b/sys/dev/usb/controller/xhci_pci.c
@@ -99,11 +99,14 @@ xhci_pci_match(device_t self)
case 0x01941033:
return ("NEC uPD720200 USB 3.0 controller");
+ case 0x10001b73:
+ return ("Fresco Logic FL1000G USB 3.0 controller");
+
case 0x10421b21:
return ("ASMedia ASM1042 USB 3.0 controller");
case 0x0f358086:
- return ("Intel Intel BayTrail USB 3.0 controller");
+ return ("Intel BayTrail USB 3.0 controller");
case 0x9c318086:
case 0x1e318086:
return ("Intel Panther Point USB 3.0 controller");
@@ -112,6 +115,9 @@ xhci_pci_match(device_t self)
case 0x8cb18086:
return ("Intel Wildcat Point USB 3.0 controller");
+ case 0xa01b177d:
+ return ("Cavium ThunderX USB 3.0 controller");
+
default:
break;
}
@@ -180,7 +186,8 @@ xhci_pci_attach(device_t self)
{
struct xhci_softc *sc = device_get_softc(self);
int count, err, rid;
- uint8_t usedma32;
+ uint8_t usemsi = 1;
+ uint8_t usedma32 = 0;
rid = PCI_XHCI_CBMEM;
sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
@@ -198,8 +205,9 @@ xhci_pci_attach(device_t self)
case 0x01941033: /* NEC uPD720200 USB 3.0 controller */
usedma32 = 1;
break;
- default:
- usedma32 = 0;
+ case 0x10001b73: /* FL1000G */
+ /* Fresco Logic host doesn't support MSI. */
+ usemsi = 0;
break;
}
@@ -215,7 +223,7 @@ xhci_pci_attach(device_t self)
usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0);
rid = 0;
- if (xhci_use_msi) {
+ if (xhci_use_msi && usemsi) {
count = 1;
if (pci_alloc_msi(self, &count) == 0) {
if (bootverbose)
diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index c756b24..a4f4b42 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -61,6 +61,7 @@ MODULE_VERSION(usb_quirk, 1);
#define USB_DEV_QUIRKS_MAX 384
#define USB_SUB_QUIRKS_MAX 8
+#define USB_QUIRK_ENVROOT "hw.usb.quirk."
struct usb_quirk_entry {
uint16_t vid;
@@ -97,6 +98,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
USB_QUIRK(REALTEK, RTL8153, 0x0000, 0xffff, UQ_CFG_INDEX_1),
USB_QUIRK(ELSA, MODEM1, 0x0000, 0xffff, UQ_CFG_INDEX_1),
USB_QUIRK(PLANEX2, MZKUE150N, 0x0000, 0xffff, UQ_CFG_INDEX_1),
+ USB_QUIRK(CISCOLINKSYS, USB3GIGV1, 0x0000, 0xffff, UQ_CFG_INDEX_1),
/* Quirks for printer devices */
USB_QUIRK(HP, 895C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
USB_QUIRK(HP, 880C, 0x0000, 0xffff, UQ_BROKEN_BIDIR),
@@ -607,8 +609,32 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
static const char *
usb_quirkstr(uint16_t quirk)
{
- return ((quirk < USB_QUIRK_MAX) ?
- usb_quirk_str[quirk] : "USB_QUIRK_UNKNOWN");
+ return ((quirk < USB_QUIRK_MAX && usb_quirk_str[quirk] != NULL) ?
+ usb_quirk_str[quirk] : "UQ_UNKNOWN");
+}
+
+/*------------------------------------------------------------------------*
+ * usb_strquirk
+ *
+ * This function converts a string into a USB quirk code.
+ *
+ * Returns:
+ * Less than USB_QUIRK_MAX: Quirk code
+ * Else: Quirk code not found
+ *------------------------------------------------------------------------*/
+static uint16_t
+usb_strquirk(const char *str, size_t len)
+{
+ const char *quirk;
+ uint16_t x;
+
+ for (x = 0; x != USB_QUIRK_MAX; x++) {
+ quirk = usb_quirkstr(x);
+ if (strncmp(str, quirk, len) == 0 &&
+ quirk[len] == 0)
+ break;
+ }
+ return (x);
}
/*------------------------------------------------------------------------*
@@ -853,12 +879,122 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
return (ENOIOCTL);
}
+/*------------------------------------------------------------------------*
+ * usb_quirk_strtou16
+ *
+ * Helper function to scan a 16-bit integer.
+ *------------------------------------------------------------------------*/
+static uint16_t
+usb_quirk_strtou16(const char **pptr, const char *name, const char *what)
+{
+ unsigned long value;
+ char *end;
+
+ value = strtoul(*pptr, &end, 0);
+ if (value > 65535 || *pptr == end || (*end != ' ' && *end != '\t')) {
+ printf("%s: %s 16-bit %s value set to zero\n",
+ name, what, *end == 0 ? "incomplete" : "invalid");
+ return (0);
+ }
+ *pptr = end + 1;
+ return ((uint16_t)value);
+}
+
+/*------------------------------------------------------------------------*
+ * usb_quirk_add_entry_from_str
+ *
+ * Add a USB quirk entry from string.
+ * "VENDOR PRODUCT LO_REV HI_REV QUIRK[,QUIRK[,...]]"
+ *------------------------------------------------------------------------*/
+static void
+usb_quirk_add_entry_from_str(const char *name, const char *env)
+{
+ struct usb_quirk_entry entry = { };
+ struct usb_quirk_entry *new;
+ uint16_t quirk_idx;
+ uint16_t quirk;
+ const char *end;
+
+ /* check for invalid environment variable */
+ if (name == NULL || env == NULL)
+ return;
+
+ if (bootverbose)
+ printf("Adding USB QUIRK '%s' = '%s'\n", name, env);
+
+ /* parse device information */
+ entry.vid = usb_quirk_strtou16(&env, name, "Vendor ID");
+ entry.pid = usb_quirk_strtou16(&env, name, "Product ID");
+ entry.lo_rev = usb_quirk_strtou16(&env, name, "Low revision");
+ entry.hi_rev = usb_quirk_strtou16(&env, name, "High revision");
+
+ /* parse quirk information */
+ quirk_idx = 0;
+ while (*env != 0 && quirk_idx != USB_SUB_QUIRKS_MAX) {
+ /* skip whitespace before quirks */
+ while (*env == ' ' || *env == '\t')
+ env++;
+
+ /* look for quirk separation character */
+ end = strchr(env, ',');
+ if (end == NULL)
+ end = env + strlen(env);
+
+ /* lookup quirk in string table */
+ quirk = usb_strquirk(env, end - env);
+ if (quirk < USB_QUIRK_MAX) {
+ entry.quirks[quirk_idx++] = quirk;
+ } else {
+ printf("%s: unknown USB quirk '%.*s' (skipped)\n",
+ name, (int)(end - env), env);
+ }
+ env = end;
+
+ /* skip quirk delimiter, if any */
+ if (*env != 0)
+ env++;
+ }
+
+ /* register quirk */
+ if (quirk_idx != 0) {
+ if (*env != 0) {
+ printf("%s: Too many USB quirks, only %d allowed!\n",
+ name, USB_SUB_QUIRKS_MAX);
+ }
+ mtx_lock(&usb_quirk_mtx);
+ new = usb_quirk_get_entry(entry.vid, entry.pid,
+ entry.lo_rev, entry.hi_rev, 1);
+ if (new == NULL)
+ printf("%s: USB quirks table is full!\n", name);
+ else
+ memcpy(new->quirks, entry.quirks, sizeof(entry.quirks));
+ mtx_unlock(&usb_quirk_mtx);
+ } else {
+ printf("%s: No USB quirks found!\n", name);
+ }
+}
+
static void
usb_quirk_init(void *arg)
{
+ char envkey[sizeof(USB_QUIRK_ENVROOT) + 2]; /* 2 digits max, 0 to 99 */
+ int i;
+
/* initialize mutex */
mtx_init(&usb_quirk_mtx, "USB quirk", NULL, MTX_DEF);
+ /* look for quirks defined by the environment variable */
+ for (i = 0; i != 100; i++) {
+ snprintf(envkey, sizeof(envkey), USB_QUIRK_ENVROOT "%d", i);
+
+ /* Stop at first undefined var */
+ if (!testenv(envkey))
+ break;
+
+ /* parse environment variable */
+ usb_quirk_add_entry_from_str(envkey, getenv(envkey));
+ }
+
/* register our function */
usb_test_quirk_p = &usb_test_quirk_by_info;
usb_quirk_ioctl_p = &usb_quirk_ioctl;
diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index 1fe9b21..9e55cb1 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -316,6 +316,7 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = {
U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E392, U3GINIT_HUAWEISCSI),
+ U3G_DEV(HUAWEI, ME909U, U3GINIT_HUAWEISCSI2),
U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E1752, U3GINIT_HUAWEISCSI),
U3G_DEV(HUAWEI, E1820, U3GINIT_HUAWEISCSI),
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index d649402..99b7655 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1407,6 +1407,7 @@ product CISCOLINKSYS WUSB54GC 0x0020 WUSB54GC
product CISCOLINKSYS WUSB54GR 0x0023 WUSB54GR
product CISCOLINKSYS WUSBF54G 0x0024 WUSBF54G
product CISCOLINKSYS AE1000 0x002f AE1000
+product CISCOLINKSYS USB3GIGV1 0x0041 USB3GIGV1 USB Ethernet Adapter
product CISCOLINKSYS2 RT3070 0x4001 RT3070
product CISCOLINKSYS3 RT3070 0x0101 RT3070
@@ -2364,6 +2365,7 @@ product HUAWEI K3765_INIT 0x1520 K3765 Initial
product HUAWEI K4505_INIT 0x1521 K4505 Initial
product HUAWEI K3772_INIT 0x1526 K3772 Initial
product HUAWEI E3272_INIT 0x155b LTE modem initial
+product HUAWEI ME909U 0x1573 LTE modem
product HUAWEI R215_INIT 0x1582 LTE modem initial
product HUAWEI R215 0x1588 LTE modem
product HUAWEI ETS2055 0x1803 CDMA modem
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index f3b3c30..55fee01 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -139,6 +139,10 @@ static int show_busybufs = 1;
SYSCTL_INT(_kern_shutdown, OID_AUTO, show_busybufs, CTLFLAG_RW,
&show_busybufs, 0, "");
+int suspend_blocked = 0;
+SYSCTL_INT(_kern, OID_AUTO, suspend_blocked, CTLFLAG_RW,
+ &suspend_blocked, 0, "Block suspend due to a pending shutdown");
+
/*
* Variable panicstr contains argument to first call to panic; used as flag
* to indicate that the kernel has already called panic.
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index 3b22f43..3e2d826 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -624,7 +624,7 @@ gre_set_tunnel(struct ifnet *ifp, struct sockaddr *src,
default:
return (EAFNOSUPPORT);
}
- if (sc->gre_family != src->sa_family)
+ if (sc->gre_family != 0)
gre_detach(sc);
GRE_WLOCK(sc);
if (sc->gre_family != 0)
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 58391a1..1ff7a4b 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -236,11 +236,12 @@ struct ifnet {
* count limit does not apply. If all three fields are zero,
* there is no TSO limit.
*
- * NOTE: The TSO limits only apply to the data payload part of
- * a TCP/IP packet. That means there is no need to subtract
- * space for ethernet-, vlan-, IP- or TCP- headers from the
- * TSO limits unless the hardware driver in question requires
- * so.
+ * NOTE: The TSO limits should reflect the values used in the
+ * BUSDMA tag a network adapter is using to load a mbuf chain
+ * for transmission. The TCP/IP network stack will subtract
+ * space for all linklevel and protocol level headers and
+ * ensure that the full mbuf chain passed to the network
+ * adapter fits within the given limits.
*/
u_int if_hw_tsomax;
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index ba0ec40..f1196e1 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -807,7 +807,8 @@ send:
*/
if (if_hw_tsomax != 0) {
/* compute maximum TSO length */
- max_len = (if_hw_tsomax - hdrlen);
+ max_len = (if_hw_tsomax - hdrlen -
+ max_linkhdr);
if (max_len <= 0) {
len = 0;
} else if (len > max_len) {
@@ -822,6 +823,15 @@ send:
*/
if (if_hw_tsomaxsegcount != 0 &&
if_hw_tsomaxsegsize != 0) {
+ /*
+ * Subtract one segment for the LINK
+ * and TCP/IP headers mbuf that will
+ * be prepended to this mbuf chain
+ * after the code in this section
+ * limits the number of mbufs in the
+ * chain to if_hw_tsomaxsegcount.
+ */
+ if_hw_tsomaxsegcount -= 1;
max_len = 0;
mb = sbsndmbuf(&so->so_snd, off, &moff);
diff --git a/sys/sys/param.h b/sys/sys/param.h
index a25939d..5c938ec 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1002500 /* Master, propagated to newvers */
+#define __FreeBSD_version 1002501 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index a490543..1be9e9c 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -79,8 +79,10 @@
*
* SLIST LIST STAILQ TAILQ
* _HEAD + + + +
+ * _CLASS_HEAD + + + +
* _HEAD_INITIALIZER + + + +
* _ENTRY + + + +
+ * _CLASS_ENTRY + + + +
* _INIT + + + +
* _EMPTY + + + +
* _FIRST + + + +
@@ -143,6 +145,15 @@ struct qm_trace {
#define TRASHIT(x)
#endif /* QUEUE_MACRO_DEBUG */
+#ifdef __cplusplus
+/*
+ * In C++ there can be structure lists and class lists:
+ */
+#define QUEUE_TYPEOF(type) type
+#else
+#define QUEUE_TYPEOF(type) struct type
+#endif
+
/*
* Singly-linked List declarations.
*/
@@ -151,6 +162,11 @@ struct name { \
struct type *slh_first; /* first element */ \
}
+#define SLIST_CLASS_HEAD(name, type) \
+struct name { \
+ class type *slh_first; /* first element */ \
+}
+
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
@@ -159,6 +175,11 @@ struct { \
struct type *sle_next; /* next element */ \
}
+#define SLIST_CLASS_ENTRY(type) \
+struct { \
+ class type *sle_next; /* next element */ \
+}
+
/*
* Singly-linked List functions.
*/
@@ -213,7 +234,7 @@ struct { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
- struct type *curelm = SLIST_FIRST((head)); \
+ QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \
while (SLIST_NEXT(curelm, field) != (elm)) \
curelm = SLIST_NEXT(curelm, field); \
SLIST_REMOVE_AFTER(curelm, field); \
@@ -231,7 +252,7 @@ struct { \
} while (0)
#define SLIST_SWAP(head1, head2, type) do { \
- struct type *swap_first = SLIST_FIRST(head1); \
+ QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
SLIST_FIRST(head1) = SLIST_FIRST(head2); \
SLIST_FIRST(head2) = swap_first; \
} while (0)
@@ -245,6 +266,12 @@ struct name { \
struct type **stqh_last;/* addr of last next element */ \
}
+#define STAILQ_CLASS_HEAD(name, type) \
+struct name { \
+ class type *stqh_first; /* first element */ \
+ class type **stqh_last; /* addr of last next element */ \
+}
+
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
@@ -253,6 +280,11 @@ struct { \
struct type *stqe_next; /* next element */ \
}
+#define STAILQ_CLASS_ENTRY(type) \
+struct { \
+ class type *stqe_next; /* next element */ \
+}
+
/*
* Singly-linked Tail queue functions.
*/
@@ -311,9 +343,10 @@ struct { \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
-#define STAILQ_LAST(head, type, field) \
- (STAILQ_EMPTY((head)) ? NULL : \
- __containerof((head)->stqh_last, struct type, field.stqe_next))
+#define STAILQ_LAST(head, type, field) \
+ (STAILQ_EMPTY((head)) ? NULL : \
+ __containerof((head)->stqh_last, \
+ QUEUE_TYPEOF(type), field.stqe_next))
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
@@ -323,7 +356,7 @@ struct { \
STAILQ_REMOVE_HEAD((head), field); \
} \
else { \
- struct type *curelm = STAILQ_FIRST((head)); \
+ QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \
while (STAILQ_NEXT(curelm, field) != (elm)) \
curelm = STAILQ_NEXT(curelm, field); \
STAILQ_REMOVE_AFTER(head, curelm, field); \
@@ -344,8 +377,8 @@ struct { \
} while (0)
#define STAILQ_SWAP(head1, head2, type) do { \
- struct type *swap_first = STAILQ_FIRST(head1); \
- struct type **swap_last = (head1)->stqh_last; \
+ QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \
+ QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \
STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
(head1)->stqh_last = (head2)->stqh_last; \
STAILQ_FIRST(head2) = swap_first; \
@@ -365,6 +398,11 @@ struct name { \
struct type *lh_first; /* first element */ \
}
+#define LIST_CLASS_HEAD(name, type) \
+struct name { \
+ class type *lh_first; /* first element */ \
+}
+
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
@@ -374,6 +412,12 @@ struct { \
struct type **le_prev; /* address of previous next element */ \
}
+#define LIST_CLASS_ENTRY(type) \
+struct { \
+ class type *le_next; /* next element */ \
+ class type **le_prev; /* address of previous next element */ \
+}
+
/*
* List functions.
*/
@@ -458,9 +502,10 @@ struct { \
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-#define LIST_PREV(elm, head, type, field) \
- ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
- __containerof((elm)->field.le_prev, struct type, field.le_next))
+#define LIST_PREV(elm, head, type, field) \
+ ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
+ __containerof((elm)->field.le_prev, \
+ QUEUE_TYPEOF(type), field.le_next))
#define LIST_REMOVE(elm, field) do { \
QMD_SAVELINK(oldnext, (elm)->field.le_next); \
@@ -476,7 +521,7 @@ struct { \
} while (0)
#define LIST_SWAP(head1, head2, type, field) do { \
- struct type *swap_tmp = LIST_FIRST((head1)); \
+ QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
LIST_FIRST((head1)) = LIST_FIRST((head2)); \
LIST_FIRST((head2)) = swap_tmp; \
if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
@@ -495,6 +540,13 @@ struct name { \
TRACEBUF \
}
+#define TAILQ_CLASS_HEAD(name, type) \
+struct name { \
+ class type *tqh_first; /* first element */ \
+ class type **tqh_last; /* addr of last next element */ \
+ TRACEBUF \
+}
+
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
@@ -505,6 +557,13 @@ struct { \
TRACEBUF \
}
+#define TAILQ_CLASS_ENTRY(type) \
+struct { \
+ class type *tqe_next; /* next element */ \
+ class type **tqe_prev; /* address of previous next element */ \
+ TRACEBUF \
+}
+
/*
* Tail queue functions.
*/
@@ -675,8 +734,8 @@ struct { \
} while (0)
#define TAILQ_SWAP(head1, head2, type, field) do { \
- struct type *swap_first = (head1)->tqh_first; \
- struct type **swap_last = (head1)->tqh_last; \
+ QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
+ QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
(head1)->tqh_first = (head2)->tqh_first; \
(head1)->tqh_last = (head2)->tqh_last; \
(head2)->tqh_first = swap_first; \
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 9bf3ffa..cb83ba4 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -46,6 +46,7 @@
#include <sys/stdint.h> /* for people using printf mainly */
extern int cold; /* nonzero if we are doing a cold boot */
+extern int suspend_blocked; /* block suspend due to pending shutdown */
extern int rebooting; /* kern_reboot() has been called. */
extern const char *panicstr; /* panic message */
extern char version[]; /* system version */
diff --git a/sys/sys/types.h b/sys/sys/types.h
index b6c4c89..24ba55e 100644
--- a/sys/sys/types.h
+++ b/sys/sys/types.h
@@ -285,9 +285,6 @@ typedef _Bool bool;
* The following are all things that really shouldn't exist in this header,
* since its purpose is to provide typedefs, not miscellaneous doodads.
*/
-#if __BSD_VISIBLE
-
-#include <sys/select.h>
#ifdef __POPCNT__
#define __bitcount64(x) __builtin_popcountll((__uint64_t)(x))
@@ -351,6 +348,10 @@ __bitcount64(__uint64_t _x)
#define __bitcount(x) __bitcount32((unsigned int)(x))
#endif
+#if __BSD_VISIBLE
+
+#include <sys/select.h>
+
/*
* minor() gives a cookie instead of an index since we don't want to
* change the meanings of bits 0-15 or waste time and space shifting
OpenPOWER on IntegriCloud