Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151058622
D5759.id15332.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D5759.id15332.diff
View Options
Index: head/sys/dev/bhnd/bhnd.h
===================================================================
--- head/sys/dev/bhnd/bhnd.h
+++ head/sys/dev/bhnd/bhnd.h
@@ -167,72 +167,104 @@
/**
* Wildcard hardware revision match descriptor.
*/
-#define BHND_HWREV_MATCH_ANY { BHND_HWREV_INVALID, BHND_HWREV_INVALID }
-
-
-/** A core match descriptor. */
-struct bhnd_core_match {
- uint16_t vendor; /**< required JEP106 device vendor or BHND_MFGID_INVALID. */
- uint16_t device; /**< required core ID or BHND_COREID_INVALID */
- struct bhnd_hwrev_match hwrev; /**< matching revisions. */
- bhnd_devclass_t class; /**< required class or BHND_DEVCLASS_INVALID */
- int unit; /**< required core unit, or -1 */
-};
-
+#define BHND_HWREV_ANY { BHND_HWREV_INVALID, BHND_HWREV_INVALID }
+#define BHND_HWREV_IS_ANY(_m) \
+ ((_m)->start == BHND_HWREV_INVALID && (_m)->end == BHND_HWREV_INVALID)
/**
- * Revision-specific hardware quirk descriptor.
- *
- * Defines a set of quirk flags applicable to a range of hardware
- * revisions.
- */
-struct bhnd_device_quirk {
- struct bhnd_hwrev_match hwrev; /**< applicable hardware revisions */
- uint32_t quirks; /**< applicable quirk flags */
-};
-
-/**
- * Define a bhnd_device_quirk over a range of hardware revisions.
+ * Hardware revision match descriptor for an inclusive range.
*
* @param _start The first applicable hardware revision.
* @param _end The last applicable hardware revision, or BHND_HWREV_INVALID
* to match on any revision.
- * @param _quirks Quirk flags applicable to this revision range.
*/
-#define BHND_QUIRK_HWREV_RANGE(_start, _end, _quirks) \
- { .hwrev = { _start, _end }, .quirks = _quirks }
+#define BHND_HWREV_RANGE(_start, _end) { _start, _end }
/**
- * Define a bhnd_device_quirk for a specific hardware revision.
+ * Hardware revision match descriptor for a single revision.
*
* @param _hwrev The hardware revision to match on.
- * @param _quirks Quirk flags applicable to this revision.
*/
-#define BHND_QUIRK_HWREV_EQ(_hwrev, _quirks) \
- BHND_QUIRK_HWREV_RANGE(_hwrev, _hwrev, _quirks)
+#define BHND_HWREV_EQ(_hwrev) BHND_HWREV_RANGE(_hwrev, _hwrev)
/**
- * Define a bhnd_device_quirk for any hardware revision equal or greater
+ * Hardware revision match descriptor for any revision equal to or greater
* than @p _start.
*
* @param _start The first hardware revision to match on.
- * @param _quirks Quirk flags applicable to this revision.
*/
-#define BHND_QUIRK_HWREV_GTE(_start, _quirks) \
- BHND_QUIRK_HWREV_RANGE(_start, BHND_HWREV_INVALID, _quirks)
+#define BHND_HWREV_GTE(_start) BHND_HWREV_RANGE(_start, BHND_HWREV_INVALID)
/**
- * Define a bhnd_device_quirk for any hardware revision equal or less
+ * Hardware revision match descriptor for any revision equal to or less
* than @p _end.
*
* @param _end The last hardware revision to match on.
- * @param _quirks Quirk flags applicable to this revision.
*/
-#define BHND_QUIRK_HWREV_LTE(_end, _quirks) \
- BHND_QUIRK_HWREV_RANGE(0, _end, _quirks)
+#define BHND_HWREV_LTE(_end) BHND_HWREV_RANGE(0, _end)
+
+
+/** A core match descriptor. */
+struct bhnd_core_match {
+ uint16_t vendor; /**< required JEP106 device vendor or BHND_MFGID_INVALID. */
+ uint16_t device; /**< required core ID or BHND_COREID_INVALID */
+ struct bhnd_hwrev_match hwrev; /**< matching revisions. */
+ bhnd_devclass_t class; /**< required class or BHND_DEVCLASS_INVALID */
+ int unit; /**< required core unit, or -1 */
+};
+
+/**
+ * Core match descriptor matching against the given @p _vendor, @p _device,
+ * and @p _hwrev match descriptors.
+ */
+#define BHND_CORE_MATCH(_vendor, _device, _hwrev) \
+ { _vendor, _device, _hwrev, BHND_DEVCLASS_INVALID, -1 }
-/** Mark the end of a bhnd_device_quirk table. */
-#define BHND_QUIRK_HWREV_END { BHND_HWREV_MATCH_ANY, 0 }
+/**
+ * Wildcard core match descriptor.
+ */
+#define BHND_CORE_MATCH_ANY \
+ { \
+ .vendor = BHND_MFGID_INVALID, \
+ .device = BHND_COREID_INVALID, \
+ .hwrev = BHND_HWREV_ANY, \
+ .class = BHND_DEVCLASS_INVALID, \
+ .unit = -1 \
+ }
+
+/**
+ * Device quirk table descriptor.
+ */
+struct bhnd_device_quirk {
+ struct bhnd_hwrev_match hwrev; /**< applicable hardware revisions */
+ uint32_t quirks; /**< quirk flags */
+};
+#define BHND_DEVICE_QUIRK_END { BHND_HWREV_ANY, 0 }
+#define BHND_DEVICE_QUIRK_IS_END(_q) \
+ (BHND_HWREV_IS_ANY(&(_q)->hwrev) && (_q)->quirks == 0)
+
+enum {
+ BHND_DF_ANY = 0,
+ BHND_DF_HOSTB = (1<<0) /**< core is serving as the bus'
+ * host bridge */
+};
+
+/** Device probe table descriptor */
+struct bhnd_device {
+ const struct bhnd_core_match core; /**< core match descriptor */
+ const char *desc; /**< device description, or NULL. */
+ const struct bhnd_device_quirk *quirks_table; /**< quirks table for this device, or NULL */
+ uint32_t device_flags; /**< required BHND_DF_* flags */
+};
+
+#define _BHND_DEVICE(_device, _desc, _quirks, _flags, ...) \
+ { BHND_CORE_MATCH(BHND_MFGID_BCM, BHND_COREID_ ## _device, \
+ BHND_HWREV_ANY), _desc, _quirks, _flags }
+
+#define BHND_DEVICE(_device, _desc, _quirks, ...) \
+ _BHND_DEVICE(_device, _desc, _quirks, ## __VA_ARGS__, 0)
+
+#define BHND_DEVICE_END { BHND_CORE_MATCH_ANY, NULL, NULL, 0 }
const char *bhnd_vendor_name(uint16_t vendor);
const char *bhnd_port_type_name(bhnd_port_type port_type);
@@ -271,6 +303,14 @@
bool bhnd_device_matches(device_t dev,
const struct bhnd_core_match *desc);
+const struct bhnd_device *bhnd_device_lookup(device_t dev,
+ const struct bhnd_device *table,
+ size_t entry_size);
+
+uint32_t bhnd_device_quirks(device_t dev,
+ const struct bhnd_device *table,
+ size_t entry_size);
+
struct bhnd_core_info bhnd_get_core_info(device_t dev);
@@ -290,9 +330,9 @@
bus_size_t chipc_offset,
struct bhnd_chipid *result);
-void bhnd_set_generic_core_desc(device_t dev);
-
-
+void bhnd_set_custom_core_desc(device_t dev,
+ const char *name);
+void bhnd_set_default_core_desc(device_t dev);
bool bhnd_bus_generic_is_hostb_device(device_t dev,
Index: head/sys/dev/bhnd/bhnd_subr.c
===================================================================
--- head/sys/dev/bhnd/bhnd_subr.c
+++ head/sys/dev/bhnd/bhnd_subr.c
@@ -470,6 +470,85 @@
}
/**
+ * Search @p table for an entry matching @p dev.
+ *
+ * @param dev A bhnd device to match against @p table.
+ * @param table The device table to search.
+ * @param entry_size The @p table entry size, in bytes.
+ *
+ * @retval bhnd_device the first matching device, if any.
+ * @retval NULL if no matching device is found in @p table.
+ */
+const struct bhnd_device *
+bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
+ size_t entry_size)
+{
+ const struct bhnd_device *entry;
+
+ for (entry = table; entry->desc != NULL; entry =
+ (const struct bhnd_device *) ((const char *) entry + entry_size))
+ {
+ /* match core info */
+ if (!bhnd_device_matches(dev, &entry->core))
+ continue;
+
+ /* match device flags */
+ if (entry->device_flags & BHND_DF_HOSTB) {
+ if (!bhnd_is_hostb_device(dev))
+ continue;
+ }
+
+ /* device found */
+ return (entry);
+ }
+
+ /* not found */
+ return (NULL);
+}
+
+/**
+ * Scan @p table for all quirk flags applicable to @p dev.
+ *
+ * @param dev A bhnd device to match against @p table.
+ * @param table The device table to search.
+ * @param entry_size The @p table entry size, in bytes.
+ *
+ * @return returns all matching quirk flags.
+ */
+uint32_t
+bhnd_device_quirks(device_t dev, const struct bhnd_device *table,
+ size_t entry_size)
+{
+ const struct bhnd_device *dent;
+ const struct bhnd_device_quirk *qtable, *qent;
+ uint32_t quirks;
+ uint16_t hwrev;
+
+ hwrev = bhnd_get_hwrev(dev);
+ quirks = 0;
+
+ /* Find the quirk table */
+ if ((dent = bhnd_device_lookup(dev, table, entry_size)) == NULL) {
+ /* This is almost certainly a (caller) implementation bug */
+ device_printf(dev, "quirk lookup did not match any device\n");
+ return (0);
+ }
+
+ /* Quirks aren't a mandatory field */
+ if ((qtable = dent->quirks_table) == NULL)
+ return (0);
+
+ /* Collect matching quirk entries */
+ for (qent = qtable; !BHND_DEVICE_QUIRK_IS_END(qent); qent++) {
+ if (bhnd_hwrev_matches(hwrev, &qent->hwrev))
+ quirks |= qent->quirks;
+ }
+
+ return (quirks);
+}
+
+
+/**
* Allocate bhnd(4) resources defined in @p rs from a parent bus.
*
* @param dev The device requesting ownership of the resources.
@@ -619,25 +698,21 @@
}
/**
- * Using the bhnd(4) bus-level core information, populate @p dev's device
- * description.
+ * Using the bhnd(4) bus-level core information and a custom core name,
+ * populate @p dev's device description.
*
* @param dev A bhnd-bus attached device.
+ * @param dev_name The core's name (e.g. "SDIO Device Core")
*/
void
-bhnd_set_generic_core_desc(device_t dev)
+bhnd_set_custom_core_desc(device_t dev, const char *dev_name)
{
- const char *dev_name;
const char *vendor_name;
char *desc;
vendor_name = bhnd_get_vendor_name(dev);
- dev_name = bhnd_get_device_name(dev);
-
- asprintf(&desc, M_BHND, "%s %s, rev %hhu",
- bhnd_get_vendor_name(dev),
- bhnd_get_device_name(dev),
- bhnd_get_hwrev(dev));
+ asprintf(&desc, M_BHND, "%s %s, rev %hhu", vendor_name, dev_name,
+ bhnd_get_hwrev(dev));
if (desc != NULL) {
device_set_desc_copy(dev, desc);
@@ -648,6 +723,18 @@
}
/**
+ * Using the bhnd(4) bus-level core information, populate @p dev's device
+ * description.
+ *
+ * @param dev A bhnd-bus attached device.
+ */
+void
+bhnd_set_default_core_desc(device_t dev)
+{
+ bhnd_set_custom_core_desc(dev, bhnd_get_device_name(dev));
+}
+
+/**
* Helper function for implementing BHND_BUS_IS_HOSTB_DEVICE().
*
* If a parent device is available, this implementation delegates the
Index: head/sys/dev/bhnd/bhndb/bhndb_pci.c
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pci.c
+++ head/sys/dev/bhnd/bhndb/bhndb_pci.c
@@ -111,56 +111,60 @@
*/
static const struct bhndb_pci_id bhndb_pci_ids[] = {
/* PCI */
- BHNDB_PCI_ID(PCI,
- BHND_QUIRK_HWREV_GTE (0,
- BHNDB_PCI_QUIRK_EXT_CLOCK_GATING |
- BHNDB_PCI_QUIRK_SBTOPCI2_PREF_BURST),
-
- BHND_QUIRK_HWREV_RANGE (0, 5,
- BHNDB_PCI_QUIRK_SBINTVEC),
-
- BHND_QUIRK_HWREV_GTE (11,
- BHNDB_PCI_QUIRK_SBTOPCI2_READMULTI |
- BHNDB_PCI_QUIRK_CLKRUN_DSBL),
+ { BHND_COREID_PCI, BHND_PCI_REGFMT_PCI,
+ (struct bhnd_device_quirk[]) {
+ { BHND_HWREV_GTE (0),
+ BHNDB_PCI_QUIRK_EXT_CLOCK_GATING |
+ BHNDB_PCI_QUIRK_SBTOPCI2_PREF_BURST },
+
+ { BHND_HWREV_RANGE (0, 5),
+ BHNDB_PCI_QUIRK_SBINTVEC },
+
+ { BHND_HWREV_GTE (11),
+ BHNDB_PCI_QUIRK_SBTOPCI2_READMULTI |
+ BHNDB_PCI_QUIRK_CLKRUN_DSBL },
- BHND_QUIRK_HWREV_END
- ),
+ BHND_DEVICE_QUIRK_END
+ }
+ },
/* PCI Gen 1 */
- BHNDB_PCI_ID(PCIE,
- BHND_QUIRK_HWREV_EQ (0,
- BHNDB_PCIE_QUIRK_SDR9_L0s_HANG),
+ { BHND_COREID_PCIE, BHND_PCI_REGFMT_PCIE,
+ (struct bhnd_device_quirk[]) {
+ { BHND_HWREV_EQ (0),
+ BHNDB_PCIE_QUIRK_SDR9_L0s_HANG },
- BHND_QUIRK_HWREV_RANGE (0, 1,
- BHNDB_PCIE_QUIRK_UR_STATUS_FIX),
+ { BHND_HWREV_RANGE (0, 1),
+ BHNDB_PCIE_QUIRK_UR_STATUS_FIX },
- BHND_QUIRK_HWREV_EQ (1,
- BHNDB_PCIE_QUIRK_PCIPM_REQEN),
+ { BHND_HWREV_EQ (1),
+ BHNDB_PCIE_QUIRK_PCIPM_REQEN },
- BHND_QUIRK_HWREV_RANGE (3, 5,
- BHNDB_PCIE_QUIRK_ASPM_OVR |
- BHNDB_PCIE_QUIRK_SDR9_POLARITY |
- BHNDB_PCIE_QUIRK_SDR9_NO_FREQRETRY),
+ { BHND_HWREV_RANGE (3, 5),
+ BHNDB_PCIE_QUIRK_ASPM_OVR |
+ BHNDB_PCIE_QUIRK_SDR9_POLARITY |
+ BHNDB_PCIE_QUIRK_SDR9_NO_FREQRETRY },
- BHND_QUIRK_HWREV_LTE (6,
- BHNDB_PCIE_QUIRK_L1_IDLE_THRESH),
+ { BHND_HWREV_LTE (6),
+ BHNDB_PCIE_QUIRK_L1_IDLE_THRESH },
- BHND_QUIRK_HWREV_GTE (6,
- BHNDB_PCIE_QUIRK_SPROM_L23_PCI_RESET),
+ { BHND_HWREV_GTE (6),
+ BHNDB_PCIE_QUIRK_SPROM_L23_PCI_RESET },
- BHND_QUIRK_HWREV_EQ (7,
- BHNDB_PCIE_QUIRK_SERDES_NOPLLDOWN),
+ { BHND_HWREV_EQ (7),
+ BHNDB_PCIE_QUIRK_SERDES_NOPLLDOWN },
- BHND_QUIRK_HWREV_GTE (8,
- BHNDB_PCIE_QUIRK_L1_TIMER_PERF),
+ { BHND_HWREV_GTE (8),
+ BHNDB_PCIE_QUIRK_L1_TIMER_PERF },
- BHND_QUIRK_HWREV_GTE (10,
- BHNDB_PCIE_QUIRK_SD_C22_EXTADDR),
+ { BHND_HWREV_GTE (10),
+ BHNDB_PCIE_QUIRK_SD_C22_EXTADDR },
- BHND_QUIRK_HWREV_END
- ),
+ BHND_DEVICE_QUIRK_END
+ }
+ },
- { BHND_COREID_INVALID, BHND_PCI_REGFMT_PCI, NULL }
+ { BHND_COREID_INVALID, BHND_PCI_REGFMT_PCI }
};
Index: head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
+++ head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
@@ -97,15 +97,6 @@
} sdr9_quirk_polarity;
};
-/* Declare a bhndb_pci_id entry */
-#define BHNDB_PCI_ID(_device, _desc, ...) { \
- BHND_COREID_ ## _device, \
- BHND_PCI_REGFMT_ ## _device, \
- (struct bhnd_device_quirk[]) { \
- __VA_ARGS__ \
- } \
-}
-
/*
* PCI/PCIe-Gen1 endpoint-mode device quirks
*/
Index: head/sys/dev/bhnd/cores/chipc/chipc.c
===================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c
+++ head/sys/dev/bhnd/cores/chipc/chipc.c
@@ -62,21 +62,22 @@
{ -1, -1, 0 }
};
+static struct bhnd_device_quirk chipc_quirks[];
+
/* Supported device identifiers */
-static const struct chipc_device {
- uint16_t device;
-} chipc_devices[] = {
- { BHND_COREID_CC },
- { BHND_COREID_INVALID }
+static const struct bhnd_device chipc_devices[] = {
+ BHND_DEVICE(CC, "", chipc_quirks),
+ BHND_DEVICE_END
};
+
/* Device quirks table */
static struct bhnd_device_quirk chipc_quirks[] = {
- BHND_QUIRK_HWREV_RANGE (0, 21, CHIPC_QUIRK_ALWAYS_HAS_SPROM),
- BHND_QUIRK_HWREV_EQ (22, CHIPC_QUIRK_SPROM_CHECK_CST_R22),
- BHND_QUIRK_HWREV_RANGE (23, 31, CHIPC_QUIRK_SPROM_CHECK_CST_R23),
- BHND_QUIRK_HWREV_GTE (35, CHIPC_QUIRK_SUPPORTS_NFLASH),
- BHND_QUIRK_HWREV_END
+ { BHND_HWREV_RANGE (0, 21), CHIPC_QUIRK_ALWAYS_HAS_SPROM },
+ { BHND_HWREV_EQ (22), CHIPC_QUIRK_SPROM_CHECK_CST_R22 },
+ { BHND_HWREV_RANGE (23, 31), CHIPC_QUIRK_SPROM_CHECK_CST_R23 },
+ { BHND_HWREV_GTE (35), CHIPC_QUIRK_SUPPORTS_NFLASH },
+ BHND_DEVICE_QUIRK_END
};
/* quirk and capability flag convenience macros */
@@ -95,25 +96,19 @@
static int
chipc_probe(device_t dev)
{
- const struct chipc_device *id;
+ const struct bhnd_device *id;
- for (id = chipc_devices; id->device != BHND_COREID_INVALID; id++)
- {
- if (bhnd_get_vendor(dev) == BHND_MFGID_BCM &&
- bhnd_get_device(dev) == id->device)
- {
- bhnd_set_generic_core_desc(dev);
- return (BUS_PROBE_DEFAULT);
- }
- }
+ id = bhnd_device_lookup(dev, chipc_devices, sizeof(chipc_devices[0]));
+ if (id == NULL)
+ return (ENXIO);
- return (ENXIO);
+ bhnd_set_default_core_desc(dev);
+ return (BUS_PROBE_DEFAULT);
}
static int
chipc_attach(device_t dev)
{
- struct bhnd_device_quirk *dq;
struct chipc_softc *sc;
bhnd_addr_t enum_addr;
uint32_t ccid_reg;
@@ -122,6 +117,8 @@
sc = device_get_softc(dev);
sc->dev = dev;
+ sc->quirks = bhnd_device_quirks(dev, chipc_devices,
+ sizeof(chipc_devices[0]));
/* Allocate bus resources */
memcpy(sc->rspec, chipc_rspec, sizeof(sc->rspec));
@@ -155,13 +152,6 @@
sc->caps = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES);
sc->cst = bhnd_bus_read_4(sc->core, CHIPC_CHIPST);
- /* Populate the set of applicable quirk flags */
- sc->quirks = 0;
- for (dq = chipc_quirks; dq->quirks != 0; dq++) {
- if (bhnd_hwrev_matches(bhnd_get_hwrev(dev), &dq->hwrev))
- sc->quirks |= dq->quirks;
- }
-
// TODO
switch (bhnd_chipc_nvram_src(dev)) {
case BHND_NVRAM_SRC_CIS:
Index: head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c
===================================================================
--- head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c
+++ head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c
@@ -68,7 +68,7 @@
if (!bhnd_is_hostb_device(dev))
return (ENXIO);
- bhnd_set_generic_core_desc(dev);
+ bhnd_set_default_core_desc(dev);
return (BUS_PROBE_DEFAULT);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 5:13 PM (8 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30987633
Default Alt Text
D5759.id15332.diff (15 KB)
Attached To
Mode
D5759: Standardize bhnd device tables and quirk matching.
Attached
Detach File
Event Timeline
Log In to Comment