summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-09 13:04:41 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:37 +0200
commite4a8065910cd6b2e7e0448cc6431ca2906322389 (patch)
tree73492991cfa40f994c20d761d476e6bc16304536 /freebsd/sys/dev
parentUpdate to FreeBSD head 2017-08-01 (diff)
downloadrtems-libbsd-e4a8065910cd6b2e7e0448cc6431ca2906322389.tar.bz2
Update to FreeBSD head 2017-10-01
Git mirror commit b2f0376b45428f13151d229c5ae9d4d8f74acbd1. Update #3472.
Diffstat (limited to 'freebsd/sys/dev')
-rw-r--r--freebsd/sys/dev/e1000/if_em.c84
-rw-r--r--freebsd/sys/dev/e1000/if_em.h30
-rw-r--r--freebsd/sys/dev/fdt/fdt_common.c3
-rw-r--r--freebsd/sys/dev/mmc/bridge.h12
-rw-r--r--freebsd/sys/dev/mmc/mmc.c44
-rw-r--r--freebsd/sys/dev/mmc/mmc_subr.c42
-rw-r--r--freebsd/sys/dev/mmc/mmc_subr.h12
-rw-r--r--freebsd/sys/dev/mmc/mmcreg.h46
-rw-r--r--freebsd/sys/dev/mmc/mmcsd.c248
-rw-r--r--freebsd/sys/dev/mmc/mmcvar.h4
-rw-r--r--freebsd/sys/dev/nvme/nvme.h134
-rw-r--r--freebsd/sys/dev/ofw/ofw_bus_subr.c12
-rw-r--r--freebsd/sys/dev/ofw/ofw_fdt.c17
-rw-r--r--freebsd/sys/dev/pci/pci.c10
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn_ridx.h6
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn_rx.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e.h2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c6
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c.h4
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c46
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_priv.h2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c6
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c4
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_var.h2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192e/r92e_chan.c71
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c38
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c6
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c4
-rw-r--r--freebsd/sys/dev/sdhci/sdhci.c4
-rw-r--r--freebsd/sys/dev/sdhci/sdhci.h5
-rw-r--r--freebsd/sys/dev/smc/if_smc.c5
-rw-r--r--freebsd/sys/dev/usb/net/if_ure.c1
-rw-r--r--freebsd/sys/dev/usb/quirk/usb_quirk.c5
-rw-r--r--freebsd/sys/dev/usb/quirk/usb_quirk.h1
-rw-r--r--freebsd/sys/dev/usb/usb_hid.c74
-rw-r--r--freebsd/sys/dev/usb/usb_hub.c4
-rw-r--r--freebsd/sys/dev/usb/usbhid.h23
-rw-r--r--freebsd/sys/dev/usb/wlan/if_uath.c122
39 files changed, 760 insertions, 383 deletions
diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c
index f5a0b94e..dba6ef0a 100644
--- a/freebsd/sys/dev/e1000/if_em.c
+++ b/freebsd/sys/dev/e1000/if_em.c
@@ -341,6 +341,8 @@ MODULE_DEPEND(em, pci, 1, 1, 1);
MODULE_DEPEND(em, ether, 1, 1, 1);
MODULE_DEPEND(em, iflib, 1, 1, 1);
+IFLIB_PNP_INFO(pci, em, em_vendor_info_array);
+
static driver_t igb_driver = {
"igb", igb_methods, sizeof(struct adapter),
};
@@ -352,6 +354,7 @@ MODULE_DEPEND(igb, pci, 1, 1, 1);
MODULE_DEPEND(igb, ether, 1, 1, 1);
MODULE_DEPEND(igb, iflib, 1, 1, 1);
+IFLIB_PNP_INFO(pci, igb, igb_vendor_info_array);
static device_method_t em_if_methods[] = {
DEVMETHOD(ifdi_attach_pre, em_if_attach_pre),
@@ -485,7 +488,7 @@ static struct if_shared_ctx em_sctx_init = {
.isc_vendor_info = em_vendor_info_array,
.isc_driver_version = em_driver_version,
.isc_driver = &em_if_driver,
- .isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP,
+ .isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP | IFLIB_NEED_ZERO_CSUM,
.isc_nrxd_min = {EM_MIN_RXD},
.isc_ntxd_min = {EM_MIN_TXD},
@@ -513,12 +516,12 @@ static struct if_shared_ctx igb_sctx_init = {
.isc_vendor_info = igb_vendor_info_array,
.isc_driver_version = em_driver_version,
.isc_driver = &em_if_driver,
- .isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP,
+ .isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP | IFLIB_NEED_ZERO_CSUM,
.isc_nrxd_min = {EM_MIN_RXD},
.isc_ntxd_min = {EM_MIN_TXD},
- .isc_nrxd_max = {EM_MAX_RXD},
- .isc_ntxd_max = {EM_MAX_TXD},
+ .isc_nrxd_max = {IGB_MAX_RXD},
+ .isc_ntxd_max = {IGB_MAX_TXD},
.isc_nrxd_default = {EM_DEFAULT_RXD},
.isc_ntxd_default = {EM_DEFAULT_TXD},
};
@@ -536,22 +539,26 @@ static int em_get_regs(SYSCTL_HANDLER_ARGS)
{
struct adapter *adapter = (struct adapter *)arg1;
struct e1000_hw *hw = &adapter->hw;
-
struct sbuf *sb;
- u32 *regs_buff = (u32 *)malloc(sizeof(u32) * IGB_REGS_LEN, M_DEVBUF, M_NOWAIT);
+ u32 *regs_buff;
int rc;
+ regs_buff = malloc(sizeof(u32) * IGB_REGS_LEN, M_DEVBUF, M_WAITOK);
memset(regs_buff, 0, IGB_REGS_LEN * sizeof(u32));
rc = sysctl_wire_old_buffer(req, 0);
MPASS(rc == 0);
- if (rc != 0)
+ if (rc != 0) {
+ free(regs_buff, M_DEVBUF);
return (rc);
+ }
sb = sbuf_new_for_sysctl(NULL, NULL, 32*400, req);
MPASS(sb != NULL);
- if (sb == NULL)
+ if (sb == NULL) {
+ free(regs_buff, M_DEVBUF);
return (ENOMEM);
+ }
/* General Registers */
regs_buff[0] = E1000_READ_REG(hw, E1000_CTRL);
@@ -607,6 +614,8 @@ static int em_get_regs(SYSCTL_HANDLER_ARGS)
sbuf_printf(sb, "\tTDFHS\t %08x\n", regs_buff[20]);
sbuf_printf(sb, "\tTDFPC\t %08x\n\n", regs_buff[21]);
+ free(regs_buff, M_DEVBUF);
+
#ifdef DUMP_DESCS
{
if_softc_ctx_t scctx = adapter->shared;
@@ -3641,34 +3650,13 @@ em_enable_wakeup(if_ctx_t ctx)
struct adapter *adapter = iflib_get_softc(ctx);
device_t dev = iflib_get_dev(ctx);
if_t ifp = iflib_get_ifp(ctx);
- u32 pmc, ctrl, ctrl_ext, rctl, wuc;
+ int error = 0;
+ u32 pmc, ctrl, ctrl_ext, rctl;
u16 status;
- if ((pci_find_cap(dev, PCIY_PMG, &pmc) != 0))
+ if (pci_find_cap(dev, PCIY_PMG, &pmc) != 0)
return;
- /* Advertise the wakeup capability */
- ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
- ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
- E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
- wuc = E1000_READ_REG(&adapter->hw, E1000_WUC);
- wuc |= (E1000_WUC_PME_EN | E1000_WUC_APME);
- E1000_WRITE_REG(&adapter->hw, E1000_WUC, wuc);
-
- if ((adapter->hw.mac.type == e1000_ich8lan) ||
- (adapter->hw.mac.type == e1000_pchlan) ||
- (adapter->hw.mac.type == e1000_ich9lan) ||
- (adapter->hw.mac.type == e1000_ich10lan))
- e1000_suspend_workarounds_ich8lan(&adapter->hw);
-
- /* Keep the laser running on Fiber adapters */
- if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
- adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
- ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
- E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext);
- }
-
/*
* Determine type of Wakeup: note that wol
* is set with all bits on by default.
@@ -3687,10 +3675,34 @@ em_enable_wakeup(if_ctx_t ctx)
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
}
+ if (!(adapter->wol & (E1000_WUFC_EX | E1000_WUFC_MAG | E1000_WUFC_MC)))
+ goto pme;
+
+ /* Advertise the wakeup capability */
+ ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
+ ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
+
+ /* Keep the laser running on Fiber adapters */
+ if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
+ adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
+ ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
+ ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext);
+ }
+
+ if ((adapter->hw.mac.type == e1000_ich8lan) ||
+ (adapter->hw.mac.type == e1000_pchlan) ||
+ (adapter->hw.mac.type == e1000_ich9lan) ||
+ (adapter->hw.mac.type == e1000_ich10lan))
+ e1000_suspend_workarounds_ich8lan(&adapter->hw);
+
if ( adapter->hw.mac.type >= e1000_pchlan) {
- if (em_enable_phy_wakeup(adapter))
- return;
+ error = em_enable_phy_wakeup(adapter);
+ if (error)
+ goto pme;
} else {
+ /* Enable wakeup by the MAC */
E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol);
}
@@ -3698,10 +3710,10 @@ em_enable_wakeup(if_ctx_t ctx)
if (adapter->hw.phy.type == e1000_phy_igp_3)
e1000_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
- /* Request PME */
+pme:
status = pci_read_config(dev, pmc + PCIR_POWER_STATUS, 2);
status &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
- if (if_getcapenable(ifp) & IFCAP_WOL)
+ if (!error && (if_getcapenable(ifp) & IFCAP_WOL))
status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
pci_write_config(dev, pmc + PCIR_POWER_STATUS, status, 2);
diff --git a/freebsd/sys/dev/e1000/if_em.h b/freebsd/sys/dev/e1000/if_em.h
index 67d97e17..b7599291 100644
--- a/freebsd/sys/dev/e1000/if_em.h
+++ b/freebsd/sys/dev/e1000/if_em.h
@@ -96,10 +96,10 @@
/* Tunables */
/*
- * EM_TXD: Maximum number of Transmit Descriptors
+ * EM_MAX_TXD: Maximum number of Transmit Descriptors
* Valid Range: 80-256 for 82542 and 82543-based adapters
* 80-4096 for others
- * Default Value: 256
+ * Default Value: 1024
* This value is the number of transmit descriptors allocated by the driver.
* Increasing this value allows the driver to queue more transmits. Each
* descriptor is 16 bytes.
@@ -111,12 +111,13 @@
#define EM_MAX_TXD 4096
#define EM_DEFAULT_TXD 1024
#define EM_DEFAULT_MULTI_TXD 4096
+#define IGB_MAX_TXD 4096
/*
- * EM_RXD - Maximum number of receive Descriptors
+ * EM_MAX_RXD - Maximum number of receive Descriptors
* Valid Range: 80-256 for 82542 and 82543-based adapters
* 80-4096 for others
- * Default Value: 256
+ * Default Value: 1024
* This value is the number of receive descriptors allocated by the driver.
* Increasing this value allows the driver to buffer more incoming packets.
* Each descriptor is 16 bytes. A receive buffer is also allocated for each
@@ -129,6 +130,7 @@
#define EM_MAX_RXD 4096
#define EM_DEFAULT_RXD 1024
#define EM_DEFAULT_MULTI_RXD 4096
+#define IGB_MAX_RXD 4096
/*
* EM_TIDV - Transmit Interrupt Delay Value
@@ -555,26 +557,6 @@ typedef struct _em_vendor_info_t {
void em_dump_rs(struct adapter *);
-#define EM_CORE_LOCK_INIT(_sc, _name) \
- mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF)
-#define EM_TX_LOCK_INIT(_sc, _name) \
- mtx_init(&(_sc)->tx_mtx, _name, "EM TX Lock", MTX_DEF)
-#define EM_RX_LOCK_INIT(_sc, _name) \
- mtx_init(&(_sc)->rx_mtx, _name, "EM RX Lock", MTX_DEF)
-#define EM_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx)
-#define EM_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx)
-#define EM_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx)
-#define EM_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx)
-#define EM_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx)
-#define EM_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx)
-#define EM_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx)
-#define EM_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx)
-#define EM_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx)
-#define EM_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx)
-#define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED)
-#define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
-#define EM_RX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rx_mtx, MA_OWNED)
-
#define EM_RSSRK_SIZE 4
#define EM_RSSRK_VAL(key, i) (key[(i) * EM_RSSRK_SIZE] | \
key[(i) * EM_RSSRK_SIZE + 1] << 8 | \
diff --git a/freebsd/sys/dev/fdt/fdt_common.c b/freebsd/sys/dev/fdt/fdt_common.c
index b149695c..c8c777f1 100644
--- a/freebsd/sys/dev/fdt/fdt_common.c
+++ b/freebsd/sys/dev/fdt/fdt_common.c
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#define FDT_TYPE_LEN 64
#define FDT_REG_CELLS 4
+#define FDT_RANGES_SIZE 48
SYSCTL_NODE(_hw, OID_AUTO, fdt, CTLFLAG_RD, 0, "Flattened Device Tree");
@@ -151,7 +152,7 @@ fdt_get_range_by_busaddr(phandle_t node, u_long addr, u_long *base,
int
fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size)
{
- pcell_t ranges[6], *rangesptr;
+ pcell_t ranges[FDT_RANGES_SIZE], *rangesptr;
pcell_t addr_cells, size_cells, par_addr_cells;
u_long par_bus_addr, pbase, psize;
int err, len, tuple_size, tuples;
diff --git a/freebsd/sys/dev/mmc/bridge.h b/freebsd/sys/dev/mmc/bridge.h
index 53e61b48..b7d95ffc 100644
--- a/freebsd/sys/dev/mmc/bridge.h
+++ b/freebsd/sys/dev/mmc/bridge.h
@@ -65,12 +65,10 @@
* linux/mmc/host.h file.
*
* A mmc bridge is a chipset that can have one or more mmc and/or sd
- * cards attached to it. mmc cards are attached on a bus topology,
- * while sd and sdio cards are attached using a star topology (meaning
- * in practice each sd card has its own, independent slot). Each
- * mmcbr is assumed to be derived from the mmcbr. This is done to
- * allow for easier addition of bridges (as each bridge does not need
- * to be added to the mmcbus file).
+ * cards attached to it. mmc devices are attached on a bus topology,
+ * while sd and sdio cards usually are attached using a star topology
+ * (meaning in practice each sd card has its own, independent slot).
+ * Since SDHCI v3.00, buses for esd and esdio are possible, though.
*
* Attached to the mmc bridge is an mmcbus. The mmcbus is described
* in dev/mmc/mmcbus_if.m.
@@ -182,7 +180,7 @@ struct mmc_host {
extern driver_t mmc_driver;
extern devclass_t mmc_devclass;
-#define MMC_VERSION 4
+#define MMC_VERSION 5
#define MMC_DECLARE_BRIDGE(name) \
DRIVER_MODULE(mmc, name, mmc_driver, mmc_devclass, NULL, NULL); \
diff --git a/freebsd/sys/dev/mmc/mmc.c b/freebsd/sys/dev/mmc/mmc.c
index 74e26332..77934e86 100644
--- a/freebsd/sys/dev/mmc/mmc.c
+++ b/freebsd/sys/dev/mmc/mmc.c
@@ -106,12 +106,34 @@ struct mmc_ivars {
uint32_t hs_tran_speed; /* Max speed in high speed mode */
uint32_t erase_sector; /* Card native erase sector size */
uint32_t cmd6_time; /* Generic switch timeout [us] */
+ uint32_t quirks; /* Quirks as per mmc_quirk->quirks */
char card_id_string[64];/* Formatted CID info (serial, MFG, etc) */
char card_sn_string[16];/* Formatted serial # for disk->d_ident */
};
#define CMD_RETRIES 3
+static const struct mmc_quirk mmc_quirks[] = {
+ /*
+ * For some SanDisk iNAND devices, the CMD38 argument needs to be
+ * provided in EXT_CSD[113].
+ */
+ { 0x2, 0x100, "SEM02G", MMC_QUIRK_INAND_CMD38 },
+ { 0x2, 0x100, "SEM04G", MMC_QUIRK_INAND_CMD38 },
+ { 0x2, 0x100, "SEM08G", MMC_QUIRK_INAND_CMD38 },
+ { 0x2, 0x100, "SEM16G", MMC_QUIRK_INAND_CMD38 },
+ { 0x2, 0x100, "SEM32G", MMC_QUIRK_INAND_CMD38 },
+
+ /*
+ * Disable TRIM for Kingston eMMCs where a firmware bug can lead to
+ * unrecoverable data corruption.
+ */
+ { 0x70, MMC_QUIRK_OID_ANY, "V10008", MMC_QUIRK_BROKEN_TRIM },
+ { 0x70, MMC_QUIRK_OID_ANY, "V10016", MMC_QUIRK_BROKEN_TRIM },
+
+ { 0x0, 0x0, NULL, 0x0 }
+};
+
static SYSCTL_NODE(_hw, OID_AUTO, mmc, CTLFLAG_RD, NULL, "mmc driver");
static int mmc_debug;
@@ -1123,7 +1145,7 @@ mmc_format_card_id_string(struct mmc_ivars *ivar)
/*
* Format a card ID string for use by the mmcsd driver, it's what
* appears between the <> in the following:
- * mmcsd0: 968MB <SD SD01G 8.0 SN 2686905 Mfg 08/2008 by 3 TN> at mmc0
+ * mmcsd0: 968MB <SD SD01G 8.0 SN 2686905 MFG 08/2008 by 3 TN> at mmc0
* 22.5MHz/4bit/128-block
*
* Also format just the card serial number, which the mmcsd driver will
@@ -1561,6 +1583,7 @@ mmc_log_card(device_t dev, struct mmc_ivars *ivar, int newcard)
break;
}
}
+ device_printf(dev, " quirks: %b\n", ivar->quirks, MMC_QUIRKS_FMT);
device_printf(dev, " bus: %ubit, %uMHz (%s timing)\n",
(ivar->bus_width == bus_width_1 ? 1 :
(ivar->bus_width == bus_width_4 ? 4 : 8)),
@@ -1577,6 +1600,7 @@ mmc_discover_cards(struct mmc_softc *sc)
u_char switch_res[64];
uint32_t raw_cid[4];
struct mmc_ivars *ivar = NULL;
+ const struct mmc_quirk *quirk;
device_t child;
int err, host_caps, i, newcard;
uint32_t resp, sec_count, status;
@@ -1884,6 +1908,18 @@ mmc_discover_cards(struct mmc_softc *sc)
ivar->raw_ext_csd[EXT_CSD_REV] >= 5);
child_common:
+ for (quirk = &mmc_quirks[0]; quirk->mid != 0x0; quirk++) {
+ if ((quirk->mid == MMC_QUIRK_MID_ANY ||
+ quirk->mid == ivar->cid.mid) &&
+ (quirk->oid == MMC_QUIRK_OID_ANY ||
+ quirk->oid == ivar->cid.oid) &&
+ strncmp(quirk->pnm, ivar->cid.pnm,
+ sizeof(ivar->cid.pnm)) == 0) {
+ ivar->quirks = quirk->quirks;
+ break;
+ }
+ }
+
/*
* Some cards that report maximum I/O block sizes greater
* than 512 require the block length to be set to 512, even
@@ -2485,6 +2521,12 @@ mmc_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
case MMC_IVAR_MAX_DATA:
*result = mmcbr_get_max_data(bus);
break;
+ case MMC_IVAR_CMD6_TIMEOUT:
+ *result = ivar->cmd6_time;
+ break;
+ case MMC_IVAR_QUIRKS:
+ *result = ivar->quirks;
+ break;
case MMC_IVAR_CARD_ID_STRING:
*(char **)result = ivar->card_id_string;
break;
diff --git a/freebsd/sys/dev/mmc/mmc_subr.c b/freebsd/sys/dev/mmc/mmc_subr.c
index 006354ba..76a14028 100644
--- a/freebsd/sys/dev/mmc/mmc_subr.c
+++ b/freebsd/sys/dev/mmc/mmc_subr.c
@@ -74,7 +74,7 @@ __FBSDID("$FreeBSD$");
#define LOG_PPS 5 /* Log no more than 5 errors per second. */
int
-mmc_wait_for_cmd(device_t brdev, device_t reqdev, struct mmc_command *cmd,
+mmc_wait_for_cmd(device_t busdev, device_t dev, struct mmc_command *cmd,
int retries)
{
struct mmc_request mreq;
@@ -89,14 +89,14 @@ mmc_wait_for_cmd(device_t brdev, device_t reqdev, struct mmc_command *cmd,
if (cmd->data != NULL)
cmd->data->mrq = &mreq;
mreq.cmd = cmd;
- if (MMCBUS_WAIT_FOR_REQUEST(brdev, reqdev, &mreq) != 0)
+ if (MMCBUS_WAIT_FOR_REQUEST(busdev, dev, &mreq) != 0)
err = MMC_ERR_FAILED;
else
err = cmd->error;
} while (err != MMC_ERR_NONE && retries-- > 0);
- if (err != MMC_ERR_NONE && brdev == reqdev) {
- sc = device_get_softc(brdev);
+ if (err != MMC_ERR_NONE && busdev == dev) {
+ sc = device_get_softc(busdev);
if (sc->squelched == 0 && ppsratecheck(&sc->log_time,
&sc->log_count, LOG_PPS)) {
device_printf(sc->dev, "CMD%d failed, RESULT: %d\n",
@@ -108,14 +108,14 @@ mmc_wait_for_cmd(device_t brdev, device_t reqdev, struct mmc_command *cmd,
}
int
-mmc_wait_for_app_cmd(device_t brdev, device_t reqdev, uint16_t rca,
+mmc_wait_for_app_cmd(device_t busdev, device_t dev, uint16_t rca,
struct mmc_command *cmd, int retries)
{
struct mmc_command appcmd;
struct mmc_softc *sc;
int err;
- sc = device_get_softc(brdev);
+ sc = device_get_softc(busdev);
/* Squelch error reporting at lower levels, we report below. */
sc->squelched++;
@@ -124,14 +124,14 @@ mmc_wait_for_app_cmd(device_t brdev, device_t reqdev, uint16_t rca,
appcmd.opcode = MMC_APP_CMD;
appcmd.arg = (uint32_t)rca << 16;
appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
- if (mmc_wait_for_cmd(brdev, reqdev, &appcmd, 0) != 0)
+ if (mmc_wait_for_cmd(busdev, dev, &appcmd, 0) != 0)
err = MMC_ERR_FAILED;
else
err = appcmd.error;
if (err == MMC_ERR_NONE) {
if (!(appcmd.resp[0] & R1_APP_CMD))
err = MMC_ERR_FAILED;
- else if (mmc_wait_for_cmd(brdev, reqdev, cmd, 0) != 0)
+ else if (mmc_wait_for_cmd(busdev, dev, cmd, 0) != 0)
err = MMC_ERR_FAILED;
else
err = cmd->error;
@@ -139,7 +139,7 @@ mmc_wait_for_app_cmd(device_t brdev, device_t reqdev, uint16_t rca,
} while (err != MMC_ERR_NONE && retries-- > 0);
sc->squelched--;
- if (err != MMC_ERR_NONE && brdev == reqdev) {
+ if (err != MMC_ERR_NONE && busdev == dev) {
if (sc->squelched == 0 && ppsratecheck(&sc->log_time,
&sc->log_count, LOG_PPS)) {
device_printf(sc->dev, "ACMD%d failed, RESULT: %d\n",
@@ -151,7 +151,7 @@ mmc_wait_for_app_cmd(device_t brdev, device_t reqdev, uint16_t rca,
}
int
-mmc_switch(device_t brdev, device_t reqdev, uint16_t rca, uint8_t set,
+mmc_switch(device_t busdev, device_t dev, uint16_t rca, uint8_t set,
uint8_t index, uint8_t value, u_int timeout, bool status)
{
struct mmc_command cmd;
@@ -160,7 +160,7 @@ mmc_switch(device_t brdev, device_t reqdev, uint16_t rca, uint8_t set,
KASSERT(timeout != 0, ("%s: no timeout", __func__));
- sc = device_get_softc(brdev);
+ sc = device_get_softc(busdev);
memset(&cmd, 0, sizeof(cmd));
cmd.opcode = MMC_SWITCH_FUNC;
@@ -171,8 +171,8 @@ mmc_switch(device_t brdev, device_t reqdev, uint16_t rca, uint8_t set,
* exceeds the maximum host timeout, use a R1 instead of a R1B
* response in order to keep the hardware from timing out.
*/
- if (mmcbr_get_caps(brdev) & MMC_CAP_WAIT_WHILE_BUSY &&
- timeout > mmcbr_get_max_busy_timeout(brdev))
+ if (mmcbr_get_caps(busdev) & MMC_CAP_WAIT_WHILE_BUSY &&
+ timeout > mmcbr_get_max_busy_timeout(busdev))
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
else
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
@@ -182,17 +182,17 @@ mmc_switch(device_t brdev, device_t reqdev, uint16_t rca, uint8_t set,
* than to a tuning command that may have snuck in between.
*/
sc->retune_paused++;
- err = mmc_wait_for_cmd(brdev, reqdev, &cmd, CMD_RETRIES);
+ err = mmc_wait_for_cmd(busdev, dev, &cmd, CMD_RETRIES);
if (err != MMC_ERR_NONE || status == false)
goto out;
- err = mmc_switch_status(brdev, reqdev, rca, timeout);
+ err = mmc_switch_status(busdev, dev, rca, timeout);
out:
sc->retune_paused--;
return (err);
}
int
-mmc_switch_status(device_t brdev, device_t reqdev, uint16_t rca, u_int timeout)
+mmc_switch_status(device_t busdev, device_t dev, uint16_t rca, u_int timeout)
{
struct timeval cur, end;
int err;
@@ -207,7 +207,7 @@ mmc_switch_status(device_t brdev, device_t reqdev, uint16_t rca, u_int timeout)
*/
end.tv_sec = end.tv_usec = 0;
for (;;) {
- err = mmc_send_status(brdev, reqdev, rca, &status);
+ err = mmc_send_status(busdev, dev, rca, &status);
if (err != MMC_ERR_NONE)
break;
if (R1_CURRENT_STATE(status) == R1_STATE_TRAN)
@@ -228,7 +228,7 @@ mmc_switch_status(device_t brdev, device_t reqdev, uint16_t rca, u_int timeout)
}
int
-mmc_send_ext_csd(device_t brdev, device_t reqdev, uint8_t *rawextcsd)
+mmc_send_ext_csd(device_t busdev, device_t dev, uint8_t *rawextcsd)
{
struct mmc_command cmd;
struct mmc_data data;
@@ -246,12 +246,12 @@ mmc_send_ext_csd(device_t brdev, device_t reqdev, uint8_t *rawextcsd)
data.len = MMC_EXTCSD_SIZE;
data.flags = MMC_DATA_READ;
- err = mmc_wait_for_cmd(brdev, reqdev, &cmd, CMD_RETRIES);
+ err = mmc_wait_for_cmd(busdev, dev, &cmd, CMD_RETRIES);
return (err);
}
int
-mmc_send_status(device_t brdev, device_t reqdev, uint16_t rca, uint32_t *status)
+mmc_send_status(device_t busdev, device_t dev, uint16_t rca, uint32_t *status)
{
struct mmc_command cmd;
int err;
@@ -260,7 +260,7 @@ mmc_send_status(device_t brdev, device_t reqdev, uint16_t rca, uint32_t *status)
cmd.opcode = MMC_SEND_STATUS;
cmd.arg = (uint32_t)rca << 16;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
- err = mmc_wait_for_cmd(brdev, reqdev, &cmd, CMD_RETRIES);
+ err = mmc_wait_for_cmd(busdev, dev, &cmd, CMD_RETRIES);
*status = cmd.resp[0];
return (err);
}
diff --git a/freebsd/sys/dev/mmc/mmc_subr.h b/freebsd/sys/dev/mmc/mmc_subr.h
index 6e300d2f..33ea6760 100644
--- a/freebsd/sys/dev/mmc/mmc_subr.h
+++ b/freebsd/sys/dev/mmc/mmc_subr.h
@@ -57,16 +57,16 @@
struct mmc_command;
-int mmc_send_ext_csd(device_t brdev, device_t reqdev, uint8_t *rawextcsd);
-int mmc_send_status(device_t brdev, device_t reqdev, uint16_t rca,
+int mmc_send_ext_csd(device_t busdev, device_t dev, uint8_t *rawextcsd);
+int mmc_send_status(device_t busdev, device_t dev, uint16_t rca,
uint32_t *status);
-int mmc_switch(device_t brdev, device_t reqdev, uint16_t rca, uint8_t set,
+int mmc_switch(device_t busdev, device_t dev, uint16_t rca, uint8_t set,
uint8_t index, uint8_t value, u_int timeout, bool send_status);
-int mmc_switch_status(device_t brdev, device_t reqdev, uint16_t rca,
+int mmc_switch_status(device_t busdev, device_t dev, uint16_t rca,
u_int timeout);
-int mmc_wait_for_app_cmd(device_t brdev, device_t reqdev, uint16_t rca,
+int mmc_wait_for_app_cmd(device_t busdev, device_t dev, uint16_t rca,
struct mmc_command *cmd, int retries);
-int mmc_wait_for_cmd(device_t brdev, device_t reqdev, struct mmc_command *cmd,
+int mmc_wait_for_cmd(device_t busdev, device_t dev, struct mmc_command *cmd,
int retries);
#endif /* DEV_MMC_SUBR_H */
diff --git a/freebsd/sys/dev/mmc/mmcreg.h b/freebsd/sys/dev/mmc/mmcreg.h
index 80f433c1..8120b69f 100644
--- a/freebsd/sys/dev/mmc/mmcreg.h
+++ b/freebsd/sys/dev/mmc/mmcreg.h
@@ -276,6 +276,13 @@ struct mmc_request {
#define MMC_ERASE_GROUP_END 36
/* 37 -- reserved old command */
#define MMC_ERASE 38
+#define MMC_ERASE_ERASE 0x00000000
+#define MMC_ERASE_TRIM 0x00000001
+#define MMC_ERASE_FULE 0x00000002
+#define MMC_ERASE_DISCARD 0x00000003
+#define MMC_ERASE_SECURE_ERASE 0x80000000
+#define MMC_ERASE_SECURE_TRIM1 0x80000001
+#define MMC_ERASE_SECURE_TRIM2 0x80008000
/* Class 9: I/O mode commands */
#define MMC_FAST_IO 39
@@ -383,6 +390,7 @@ struct mmc_request {
#define EXT_CSD_ERASE_TO_MULT 223 /* RO */
#define EXT_CSD_ERASE_GRP_SIZE 224 /* RO */
#define EXT_CSD_BOOT_SIZE_MULT 226 /* RO */
+#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
#define EXT_CSD_PWR_CL_52_195_DDR 238 /* RO */
@@ -467,6 +475,22 @@ struct mmc_request {
#define EXT_CSD_STROBE_SUPPORT_EN 0x01
+#define EXT_CSD_SEC_FEATURE_SUPPORT_ER_EN 0x01
+#define EXT_CSD_SEC_FEATURE_SUPPORT_BD_BLK_EN 0x04
+#define EXT_CSD_SEC_FEATURE_SUPPORT_GB_CL_EN 0x10
+#define EXT_CSD_SEC_FEATURE_SUPPORT_SANITIZE 0x40
+
+/*
+ * Vendor specific EXT_CSD fields
+ */
+/* SanDisk iNAND */
+#define EXT_CSD_INAND_CMD38 113
+#define EXT_CSD_INAND_CMD38_ERASE 0x00
+#define EXT_CSD_INAND_CMD38_TRIM 0x01
+#define EXT_CSD_INAND_CMD38_SECURE_ERASE 0x80
+#define EXT_CSD_INAND_CMD38_SECURE_TRIM1 0x81
+#define EXT_CSD_INAND_CMD38_SECURE_TRIM2 0x82
+
#define MMC_TYPE_HS_26_MAX 26000000
#define MMC_TYPE_HS_52_MAX 52000000
#define MMC_TYPE_DDR52_MAX 52000000
@@ -608,8 +632,7 @@ struct mmc_cid {
uint8_t fwrev;
};
-struct mmc_csd
-{
+struct mmc_csd {
uint8_t csd_structure;
uint8_t spec_vers;
uint16_t ccc;
@@ -635,16 +658,14 @@ struct mmc_csd
wp_grp_enable:1;
};
-struct mmc_scr
-{
+struct mmc_scr {
unsigned char sda_vsn;
unsigned char bus_widths;
#define SD_SCR_BUS_WIDTH_1 (1 << 0)
#define SD_SCR_BUS_WIDTH_4 (1 << 2)
};
-struct mmc_sd_status
-{
+struct mmc_sd_status {
uint8_t bus_width;
uint8_t secured_mode;
uint16_t card_type;
@@ -657,6 +678,19 @@ struct mmc_sd_status
uint8_t erase_offset;
};
+struct mmc_quirk {
+ uint32_t mid;
+#define MMC_QUIRK_MID_ANY ((uint32_t)-1)
+ uint16_t oid;
+#define MMC_QUIRK_OID_ANY ((uint16_t)-1)
+ const char *pnm;
+ uint32_t quirks;
+#define MMC_QUIRK_INAND_CMD38 0x0001
+#define MMC_QUIRK_BROKEN_TRIM 0x0002
+};
+
+#define MMC_QUIRKS_FMT "\020" "\001INAND_CMD38" "\002BROKEN_TRIM"
+
/*
* Various MMC/SD constants
*/
diff --git a/freebsd/sys/dev/mmc/mmcsd.c b/freebsd/sys/dev/mmc/mmcsd.c
index 195feae2..45bd9c50 100644
--- a/freebsd/sys/dev/mmc/mmcsd.c
+++ b/freebsd/sys/dev/mmc/mmcsd.c
@@ -128,7 +128,7 @@ struct mmcsd_part {
struct mmcsd_softc {
device_t dev;
- device_t mmcbr;
+ device_t mmcbus;
struct mmcsd_part *part[MMC_PART_MAX];
enum mmc_card_mode mode;
u_int max_data; /* Maximum data size [blocks] */
@@ -137,6 +137,10 @@ struct mmcsd_softc {
uint8_t part_curr; /* Partition currently switched to */
uint8_t ext_csd[MMC_EXTCSD_SIZE];
uint16_t rca;
+ uint32_t flags;
+#define MMCSD_INAND_CMD38 0x0001
+#define MMCSD_USE_TRIM 0x0002
+ uint32_t cmd6_time; /* Generic switch timeout [us] */
uint32_t part_time; /* Partition switch timeout [us] */
off_t enh_base; /* Enhanced user data area slice base ... */
off_t enh_size; /* ... and size [bytes] */
@@ -147,6 +151,9 @@ struct mmcsd_softc {
#ifndef __rtems__
static const char *errmsg[] =
+#else /* __rtems__ */
+static const char * const errmsg[] =
+#endif /* __rtems__ */
{
"None",
"Timeout",
@@ -156,7 +163,6 @@ static const char *errmsg[] =
"Invalid",
"NO MEMORY"
};
-#endif /* __rtems__ */
#define LOG_PPS 5 /* Log no more than 5 errors per second. */
@@ -183,11 +189,12 @@ static int mmcsd_ioctl_rpmb(struct cdev *dev, u_long cmd, caddr_t data,
int fflag, struct thread *td);
static void mmcsd_add_part(struct mmcsd_softc *sc, u_int type,
- const char *name, u_int cnt, off_t media_size, off_t erase_size, bool ro);
+ const char *name, u_int cnt, off_t media_size, bool ro);
static int mmcsd_bus_bit_width(device_t dev);
#ifndef __rtems__
static daddr_t mmcsd_delete(struct mmcsd_part *part, struct bio *bp);
#endif /* __rtems__ */
+static const char *mmcsd_errmsg(int e);
static int mmcsd_ioctl(struct mmcsd_part *part, u_long cmd, void *data,
int fflag);
static int mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic,
@@ -440,20 +447,21 @@ error:
static int
mmcsd_attach(device_t dev)
{
- device_t mmcbr;
+ device_t mmcbus;
struct mmcsd_softc *sc;
const uint8_t *ext_csd;
off_t erase_size, sector_size, size, wp_size;
uintmax_t bytes;
int err, i;
+ uint32_t quirks;
uint8_t rev;
bool comp, ro;
char unit[2];
sc = device_get_softc(dev);
sc->dev = dev;
- sc->mmcbr = mmcbr = device_get_parent(dev);
- sc->mode = mmcbr_get_mode(mmcbr);
+ sc->mmcbus = mmcbus = device_get_parent(dev);
+ sc->mode = mmcbr_get_mode(mmcbus);
/*
* Note that in principle with an SDHCI-like re-tuning implementation,
* the maximum data size can change at runtime due to a device removal/
@@ -464,20 +472,47 @@ mmcsd_attach(device_t dev)
* place either.
*/
sc->max_data = mmc_get_max_data(dev);
- sc->erase_sector = mmc_get_erase_sector(dev);
sc->high_cap = mmc_get_high_cap(dev);
sc->rca = mmc_get_rca(dev);
+ sc->cmd6_time = mmc_get_cmd6_timeout(dev);
+ quirks = mmc_get_quirks(dev);
/* Only MMC >= 4.x devices support EXT_CSD. */
if (mmc_get_spec_vers(dev) >= 4) {
- MMCBUS_ACQUIRE_BUS(mmcbr, dev);
- err = mmc_send_ext_csd(mmcbr, dev, sc->ext_csd);
- MMCBUS_RELEASE_BUS(mmcbr, dev);
- if (err != MMC_ERR_NONE)
- bzero(sc->ext_csd, sizeof(sc->ext_csd));
+ MMCBUS_ACQUIRE_BUS(mmcbus, dev);
+ err = mmc_send_ext_csd(mmcbus, dev, sc->ext_csd);
+ MMCBUS_RELEASE_BUS(mmcbus, dev);
+ if (err != MMC_ERR_NONE) {
+ device_printf(dev, "Error reading EXT_CSD %s\n",
+ mmcsd_errmsg(err));
+ return (ENXIO);
+ }
}
ext_csd = sc->ext_csd;
+ if ((quirks & MMC_QUIRK_INAND_CMD38) != 0) {
+ if (mmc_get_spec_vers(dev) < 4) {
+ device_printf(dev,
+ "MMC_QUIRK_INAND_CMD38 set but no EXT_CSD\n");
+ return (EINVAL);
+ }
+ sc->flags |= MMCSD_INAND_CMD38;
+ }
+
+ /*
+ * EXT_CSD_SEC_FEATURE_SUPPORT_GB_CL_EN denotes support for both
+ * insecure and secure TRIM.
+ */
+ if ((ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] &
+ EXT_CSD_SEC_FEATURE_SUPPORT_GB_CL_EN) != 0 &&
+ (quirks & MMC_QUIRK_BROKEN_TRIM) == 0) {
+ if (bootverbose)
+ device_printf(dev, "taking advantage of TRIM\n");
+ sc->flags |= MMCSD_USE_TRIM;
+ sc->erase_sector = 1;
+ } else
+ sc->erase_sector = mmc_get_erase_sector(dev);
+
/*
* Enhanced user data area and general purpose partitions are only
* supported in revision 1.4 (EXT_CSD_REV == 4) and later, the RPMB
@@ -531,8 +566,7 @@ mmcsd_attach(device_t dev)
*/
ro = mmc_get_read_only(dev);
mmcsd_add_part(sc, EXT_CSD_PART_CONFIG_ACC_DEFAULT, "mmcsd",
- device_get_unit(dev), mmc_get_media_size(dev) * sector_size,
- sc->erase_sector * sector_size, ro);
+ device_get_unit(dev), mmc_get_media_size(dev) * sector_size, ro);
if (mmc_get_spec_vers(dev) < 3)
return (0);
@@ -555,13 +589,13 @@ mmcsd_attach(device_t dev)
/* Add boot partitions, which are of a fixed multiple of 128 KB. */
size = ext_csd[EXT_CSD_BOOT_SIZE_MULT] * MMC_BOOT_RPMB_BLOCK_SIZE;
- if (size > 0 && (mmcbr_get_caps(mmcbr) & MMC_CAP_BOOT_NOACC) == 0) {
+ if (size > 0 && (mmcbr_get_caps(mmcbus) & MMC_CAP_BOOT_NOACC) == 0) {
mmcsd_add_part(sc, EXT_CSD_PART_CONFIG_ACC_BOOT0,
- MMCSD_FMT_BOOT, 0, size, MMC_BOOT_RPMB_BLOCK_SIZE,
+ MMCSD_FMT_BOOT, 0, size,
ro | ((ext_csd[EXT_CSD_BOOT_WP_STATUS] &
EXT_CSD_BOOT_WP_STATUS_BOOT0_MASK) != 0));
mmcsd_add_part(sc, EXT_CSD_PART_CONFIG_ACC_BOOT1,
- MMCSD_FMT_BOOT, 1, size, MMC_BOOT_RPMB_BLOCK_SIZE,
+ MMCSD_FMT_BOOT, 1, size,
ro | ((ext_csd[EXT_CSD_BOOT_WP_STATUS] &
EXT_CSD_BOOT_WP_STATUS_BOOT1_MASK) != 0));
}
@@ -570,7 +604,7 @@ mmcsd_attach(device_t dev)
size = ext_csd[EXT_CSD_RPMB_MULT] * MMC_BOOT_RPMB_BLOCK_SIZE;
if (rev >= 5 && size > 0)
mmcsd_add_part(sc, EXT_CSD_PART_CONFIG_ACC_RPMB,
- MMCSD_FMT_RPMB, 0, size, MMC_BOOT_RPMB_BLOCK_SIZE, ro);
+ MMCSD_FMT_RPMB, 0, size, ro);
if (rev <= 3 || comp == FALSE)
return (0);
@@ -590,8 +624,7 @@ mmcsd_attach(device_t dev)
if (size == 0)
continue;
mmcsd_add_part(sc, EXT_CSD_PART_CONFIG_ACC_GP0 + i,
- MMCSD_FMT_GP, i, size * erase_size * wp_size,
- erase_size, ro);
+ MMCSD_FMT_GP, i, size * erase_size * wp_size, ro);
}
}
return (0);
@@ -644,10 +677,10 @@ static struct cdevsw mmcsd_rpmb_cdevsw = {
static void
mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt,
- off_t media_size, off_t erase_size, bool ro)
+ off_t media_size, bool ro)
{
struct make_dev_args args;
- device_t dev, mmcbr;
+ device_t dev, mmcbus;
const char *ext;
const uint8_t *ext_csd;
struct mmcsd_part *part;
@@ -662,7 +695,7 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt,
char unit[2];
dev = sc->dev;
- mmcbr = sc->mmcbr;
+ mmcbus = sc->mmcbus;
part = sc->part[type] = malloc(sizeof(*part), M_DEVBUF,
M_WAITOK | M_ZERO);
part->sc = sc;
@@ -710,10 +743,10 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt,
d->d_sectorsize = mmc_get_sector_size(dev);
d->d_maxsize = sc->max_data * d->d_sectorsize;
d->d_mediasize = media_size;
- d->d_stripesize = erase_size;
+ d->d_stripesize = sc->erase_sector * d->d_sectorsize;
d->d_unit = cnt;
d->d_flags = DISKFLAG_CANDELETE;
- d->d_delmaxsize = erase_size;
+ d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize;
strlcpy(d->d_ident, mmc_get_card_sn_string(dev),
sizeof(d->d_ident));
strlcpy(d->d_descr, mmc_get_card_id_string(dev),
@@ -735,10 +768,10 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt,
bytes = mmcsd_pretty_size(media_size, unit);
if (type == EXT_CSD_PART_CONFIG_ACC_DEFAULT) {
- speed = mmcbr_get_clock(mmcbr);
+ speed = mmcbr_get_clock(mmcbus);
printf("%s%d: %ju%sB <%s>%s at %s %d.%01dMHz/%dbit/%d-block\n",
part->name, cnt, bytes, unit, mmc_get_card_id_string(dev),
- ro ? " (read-only)" : "", device_get_nameunit(mmcbr),
+ ro ? " (read-only)" : "", device_get_nameunit(mmcbus),
speed / 1000000, (speed / 100000) % 10,
mmcsd_bus_bit_width(dev), sc->max_data);
} else if (type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
@@ -1053,7 +1086,7 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag)
struct mmc_command cmd;
struct mmc_data data;
struct mmcsd_softc *sc;
- device_t dev, mmcbr;
+ device_t dev, mmcbus;
void *dp;
u_long len;
int err, retries;
@@ -1136,9 +1169,9 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag)
}
}
dev = sc->dev;
- mmcbr = sc->mmcbr;
- MMCBUS_ACQUIRE_BUS(mmcbr, dev);
- err = mmcsd_switch_part(mmcbr, dev, rca, part->type);
+ mmcbus = sc->mmcbus;
+ MMCBUS_ACQUIRE_BUS(mmcbus, dev);
+ err = mmcsd_switch_part(mmcbus, dev, rca, part->type);
if (err != MMC_ERR_NONE)
goto release;
if (part->type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
@@ -1148,9 +1181,9 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag)
goto switch_back;
}
if (mic->is_acmd != 0)
- (void)mmc_wait_for_app_cmd(mmcbr, dev, rca, &cmd, 0);
+ (void)mmc_wait_for_app_cmd(mmcbus, dev, rca, &cmd, 0);
else
- (void)mmc_wait_for_cmd(mmcbr, dev, &cmd, 0);
+ (void)mmc_wait_for_cmd(mmcbus, dev, &cmd, 0);
if (part->type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
/*
* If the request went to the RPMB partition, try to ensure
@@ -1158,7 +1191,7 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag)
*/
retries = MMCSD_CMD_RETRIES;
do {
- err = mmc_send_status(mmcbr, dev, rca, &status);
+ err = mmc_send_status(mmcbus, dev, rca, &status);
if (err != MMC_ERR_NONE)
break;
if (R1_STATUS(status) == 0 &&
@@ -1169,7 +1202,7 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag)
switch_back:
/* ... and always switch back to the default partition. */
- err = mmcsd_switch_part(mmcbr, dev, rca,
+ err = mmcsd_switch_part(mmcbus, dev, rca,
EXT_CSD_PART_CONFIG_ACC_DEFAULT);
if (err != MMC_ERR_NONE)
goto release;
@@ -1180,11 +1213,11 @@ switch_back:
* so retrieve EXT_CSD again.
*/
if (cmd.opcode == MMC_SWITCH_FUNC) {
- err = mmc_send_ext_csd(mmcbr, dev, sc->ext_csd);
+ err = mmc_send_ext_csd(mmcbus, dev, sc->ext_csd);
if (err != MMC_ERR_NONE)
goto release;
}
- MMCBUS_RELEASE_BUS(mmcbr, dev);
+ MMCBUS_RELEASE_BUS(mmcbus, dev);
if (cmd.error != MMC_ERR_NONE) {
switch (cmd.error) {
case MMC_ERR_TIMEOUT:
@@ -1214,7 +1247,7 @@ switch_back:
goto out;
release:
- MMCBUS_RELEASE_BUS(mmcbr, dev);
+ MMCBUS_RELEASE_BUS(mmcbus, dev);
err = EIO;
out:
@@ -1262,7 +1295,7 @@ mmcsd_set_blockcount(struct mmcsd_softc *sc, u_int count, bool reliable)
if (reliable)
cmd.arg |= 1 << 31;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
- MMCBUS_WAIT_FOR_REQUEST(sc->mmcbr, sc->dev, &req);
+ MMCBUS_WAIT_FOR_REQUEST(sc->mmcbus, sc->dev, &req);
return (cmd.error);
}
@@ -1289,7 +1322,7 @@ mmcsd_switch_part(device_t bus, device_t dev, uint16_t rca, u_int part)
* anew.
*/
if (part == EXT_CSD_PART_CONFIG_ACC_RPMB)
- MMCBUS_RETUNE_PAUSE(sc->mmcbr, sc->dev, true);
+ MMCBUS_RETUNE_PAUSE(sc->mmcbus, sc->dev, true);
if (sc->part_curr == part)
return (MMC_ERR_NONE);
@@ -1301,18 +1334,17 @@ mmcsd_switch_part(device_t bus, device_t dev, uint16_t rca, u_int part)
EXT_CSD_PART_CONFIG, value, sc->part_time, true);
if (err != MMC_ERR_NONE) {
if (part == EXT_CSD_PART_CONFIG_ACC_RPMB)
- MMCBUS_RETUNE_UNPAUSE(sc->mmcbr, sc->dev);
+ MMCBUS_RETUNE_UNPAUSE(sc->mmcbus, sc->dev);
return (err);
}
sc->ext_csd[EXT_CSD_PART_CONFIG] = value;
if (sc->part_curr == EXT_CSD_PART_CONFIG_ACC_RPMB)
- MMCBUS_RETUNE_UNPAUSE(sc->mmcbr, sc->dev);
+ MMCBUS_RETUNE_UNPAUSE(sc->mmcbus, sc->dev);
sc->part_curr = part;
return (MMC_ERR_NONE);
}
-#ifndef __rtems__
static const char *
mmcsd_errmsg(int e)
{
@@ -1322,6 +1354,7 @@ mmcsd_errmsg(int e)
return (errmsg[e]);
}
+#ifndef __rtems__
static daddr_t
mmcsd_rw(struct mmcsd_part *part, struct bio *bp)
{
@@ -1331,13 +1364,13 @@ mmcsd_rw(struct mmcsd_part *part, struct bio *bp)
struct mmc_request req;
struct mmc_data data;
struct mmcsd_softc *sc;
- device_t dev, mmcbr;
+ device_t dev, mmcbus;
u_int numblocks, sz;
char *vaddr;
sc = part->sc;
dev = sc->dev;
- mmcbr = sc->mmcbr;
+ mmcbus = sc->mmcbus;
block = bp->bio_pblkno;
sz = part->disk->d_sectorsize;
@@ -1382,7 +1415,7 @@ mmcsd_rw(struct mmcsd_part *part, struct bio *bp)
stop.mrq = &req;
req.stop = &stop;
}
- MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req);
+ MMCBUS_WAIT_FOR_REQUEST(mmcbus, dev, &req);
if (req.cmd->error != MMC_ERR_NONE) {
if (ppsratecheck(&sc->log_time, &sc->log_count,
LOG_PPS))
@@ -1403,32 +1436,56 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp)
struct mmc_command cmd;
struct mmc_request req;
struct mmcsd_softc *sc;
- device_t dev, mmcbr;
+ device_t dev, mmcbus;
u_int erase_sector, sz;
+ int err;
+ bool use_trim;
sc = part->sc;
dev = sc->dev;
- mmcbr = sc->mmcbr;
+ mmcbus = sc->mmcbus;
block = bp->bio_pblkno;
sz = part->disk->d_sectorsize;
end = bp->bio_pblkno + (bp->bio_bcount / sz);
- /* Coalesce with part remaining from previous request. */
- if (block > part->eblock && block <= part->eend)
- block = part->eblock;
- if (end >= part->eblock && end < part->eend)
- end = part->eend;
- /* Safe round to the erase sector boundaries. */
- erase_sector = sc->erase_sector;
- start = block + erase_sector - 1; /* Round up. */
- start -= start % erase_sector;
- stop = end; /* Round down. */
- stop -= end % erase_sector;
- /* We can't erase an area smaller than a sector, store it for later. */
- if (start >= stop) {
- part->eblock = block;
- part->eend = end;
- return (end);
+ use_trim = sc->flags & MMCSD_USE_TRIM;
+ if (use_trim == true) {
+ start = block;
+ stop = end;
+ } else {
+ /* Coalesce with the remainder of the previous request. */
+ if (block > part->eblock && block <= part->eend)
+ block = part->eblock;
+ if (end >= part->eblock && end < part->eend)
+ end = part->eend;
+ /* Safely round to the erase sector boundaries. */
+ erase_sector = sc->erase_sector;
+ start = block + erase_sector - 1; /* Round up. */
+ start -= start % erase_sector;
+ stop = end; /* Round down. */
+ stop -= end % erase_sector;
+ /*
+ * We can't erase an area smaller than an erase sector, so
+ * store it for later.
+ */
+ if (start >= stop) {
+ part->eblock = block;
+ part->eend = end;
+ return (end);
+ }
+ }
+
+ if ((sc->flags & MMCSD_INAND_CMD38) != 0) {
+ err = mmc_switch(mmcbus, dev, sc->rca, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_INAND_CMD38, use_trim == true ?
+ EXT_CSD_INAND_CMD38_TRIM : EXT_CSD_INAND_CMD38_ERASE,
+ sc->cmd6_time, true);
+ if (err != MMC_ERR_NONE) {
+ device_printf(dev,
+ "Setting iNAND erase command failed %s\n",
+ mmcsd_errmsg(err));
+ return (block);
+ }
}
/*
@@ -1436,7 +1493,7 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp)
* commands. Note that these latter don't use the data lines, so
* re-tuning shouldn't actually become necessary during erase.
*/
- MMCBUS_RETUNE_PAUSE(mmcbr, dev, false);
+ MMCBUS_RETUNE_PAUSE(mmcbus, dev, false);
/* Set erase start position. */
memset(&req, 0, sizeof(req));
memset(&cmd, 0, sizeof(cmd));
@@ -1450,10 +1507,10 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp)
if (sc->high_cap == 0)
cmd.arg <<= 9;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
- MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req);
+ MMCBUS_WAIT_FOR_REQUEST(mmcbus, dev, &req);
if (req.cmd->error != MMC_ERR_NONE) {
- device_printf(dev, "Setting erase start position failed %d\n",
- req.cmd->error);
+ device_printf(dev, "Setting erase start position failed %s\n",
+ mmcsd_errmsg(req.cmd->error));
block = bp->bio_pblkno;
goto unpause;
}
@@ -1470,10 +1527,10 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp)
cmd.arg <<= 9;
cmd.arg--;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
- MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req);
+ MMCBUS_WAIT_FOR_REQUEST(mmcbus, dev, &req);
if (req.cmd->error != MMC_ERR_NONE) {
- device_printf(dev, "Setting erase stop position failed %d\n",
- req.cmd->error);
+ device_printf(dev, "Setting erase stop position failed %s\n",
+ mmcsd_errmsg(req.cmd->error));
block = bp->bio_pblkno;
goto unpause;
}
@@ -1482,27 +1539,28 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp)
memset(&cmd, 0, sizeof(cmd));
req.cmd = &cmd;
cmd.opcode = MMC_ERASE;
- cmd.arg = 0;
+ cmd.arg = use_trim == true ? MMC_ERASE_TRIM : MMC_ERASE_ERASE;
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
- MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req);
+ MMCBUS_WAIT_FOR_REQUEST(mmcbus, dev, &req);
if (req.cmd->error != MMC_ERR_NONE) {
- device_printf(dev, "erase err3: %d\n", req.cmd->error);
- device_printf(dev, "Issuing erase command failed %d\n",
- req.cmd->error);
+ device_printf(dev, "Issuing erase command failed %s\n",
+ mmcsd_errmsg(req.cmd->error));
block = bp->bio_pblkno;
goto unpause;
}
- /* Store one of remaining parts for the next call. */
- if (bp->bio_pblkno >= part->eblock || block == start) {
- part->eblock = stop; /* Predict next forward. */
- part->eend = end;
- } else {
- part->eblock = block; /* Predict next backward. */
- part->eend = start;
+ if (use_trim == false) {
+ /* Store one of the remaining parts for the next call. */
+ if (bp->bio_pblkno >= part->eblock || block == start) {
+ part->eblock = stop; /* Predict next forward. */
+ part->eend = end;
+ } else {
+ part->eblock = block; /* Predict next backward. */
+ part->eend = start;
+ }
}
block = end;
unpause:
- MMCBUS_RETUNE_UNPAUSE(mmcbr, dev);
+ MMCBUS_RETUNE_UNPAUSE(mmcbus, dev);
return (block);
}
@@ -1515,7 +1573,7 @@ mmcsd_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset,
struct disk *disk;
struct mmcsd_softc *sc;
struct mmcsd_part *part;
- device_t dev, mmcbr;
+ device_t dev, mmcbus;
int err;
/* length zero is special and really means flush buffers to media */
@@ -1526,7 +1584,7 @@ mmcsd_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset,
part = disk->d_drv1;
sc = part->sc;
dev = sc->dev;
- mmcbr = sc->mmcbr;
+ mmcbus = sc->mmcbus;
g_reset_bio(&bp);
bp.bio_disk = disk;
@@ -1535,16 +1593,16 @@ mmcsd_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset,
bp.bio_data = virtual;
bp.bio_cmd = BIO_WRITE;
end = bp.bio_pblkno + bp.bio_bcount / disk->d_sectorsize;
- MMCBUS_ACQUIRE_BUS(mmcbr, dev);
- err = mmcsd_switch_part(mmcbr, dev, sc->rca, part->type);
+ MMCBUS_ACQUIRE_BUS(mmcbus, dev);
+ err = mmcsd_switch_part(mmcbus, dev, sc->rca, part->type);
if (err != MMC_ERR_NONE) {
if (ppsratecheck(&sc->log_time, &sc->log_count, LOG_PPS))
device_printf(dev, "Partition switch error\n");
- MMCBUS_RELEASE_BUS(mmcbr, dev);
+ MMCBUS_RELEASE_BUS(mmcbus, dev);
return (EIO);
}
block = mmcsd_rw(part, &bp);
- MMCBUS_RELEASE_BUS(mmcbr, dev);
+ MMCBUS_RELEASE_BUS(mmcbus, dev);
return ((end < block) ? EIO : 0);
}
@@ -1555,13 +1613,13 @@ mmcsd_task(void *arg)
struct mmcsd_part *part;
struct mmcsd_softc *sc;
struct bio *bp;
- device_t dev, mmcbr;
+ device_t dev, mmcbus;
int err, sz;
part = arg;
sc = part->sc;
dev = sc->dev;
- mmcbr = sc->mmcbr;
+ mmcbus = sc->mmcbus;
while (1) {
MMCSD_DISK_LOCK(part);
@@ -1581,11 +1639,11 @@ mmcsd_task(void *arg)
biodone(bp);
continue;
}
- MMCBUS_ACQUIRE_BUS(mmcbr, dev);
+ MMCBUS_ACQUIRE_BUS(mmcbus, dev);
sz = part->disk->d_sectorsize;
block = bp->bio_pblkno;
end = bp->bio_pblkno + (bp->bio_bcount / sz);
- err = mmcsd_switch_part(mmcbr, dev, sc->rca, part->type);
+ err = mmcsd_switch_part(mmcbus, dev, sc->rca, part->type);
if (err != MMC_ERR_NONE) {
if (ppsratecheck(&sc->log_time, &sc->log_count,
LOG_PPS))
@@ -1601,7 +1659,7 @@ mmcsd_task(void *arg)
block = mmcsd_delete(part, bp);
}
release:
- MMCBUS_RELEASE_BUS(mmcbr, dev);
+ MMCBUS_RELEASE_BUS(mmcbus, dev);
if (block < end) {
bp->bio_error = EIO;
bp->bio_resid = (end - block) * sz;
diff --git a/freebsd/sys/dev/mmc/mmcvar.h b/freebsd/sys/dev/mmc/mmcvar.h
index 9f62b112..d0f4e330 100644
--- a/freebsd/sys/dev/mmc/mmcvar.h
+++ b/freebsd/sys/dev/mmc/mmcvar.h
@@ -68,6 +68,8 @@ enum mmc_device_ivars {
MMC_IVAR_BUS_WIDTH,
MMC_IVAR_ERASE_SECTOR,
MMC_IVAR_MAX_DATA,
+ MMC_IVAR_CMD6_TIMEOUT,
+ MMC_IVAR_QUIRKS,
MMC_IVAR_CARD_ID_STRING,
MMC_IVAR_CARD_SN_STRING,
};
@@ -90,6 +92,8 @@ MMC_ACCESSOR(card_type, CARD_TYPE, int)
MMC_ACCESSOR(bus_width, BUS_WIDTH, int)
MMC_ACCESSOR(erase_sector, ERASE_SECTOR, int)
MMC_ACCESSOR(max_data, MAX_DATA, int)
+MMC_ACCESSOR(cmd6_timeout, CMD6_TIMEOUT, u_int)
+MMC_ACCESSOR(quirks, QUIRKS, u_int)
MMC_ACCESSOR(card_id_string, CARD_ID_STRING, const char *)
MMC_ACCESSOR(card_sn_string, CARD_SN_STRING, const char *)
diff --git a/freebsd/sys/dev/nvme/nvme.h b/freebsd/sys/dev/nvme/nvme.h
index aa640b37..d4fc131e 100644
--- a/freebsd/sys/dev/nvme/nvme.h
+++ b/freebsd/sys/dev/nvme/nvme.h
@@ -69,6 +69,8 @@ union cap_lo_register {
} bits __packed;
} __packed;
+_Static_assert(sizeof(union cap_lo_register) == 4, "bad size for cap_lo_register");
+
union cap_hi_register {
uint32_t raw;
struct {
@@ -93,6 +95,8 @@ union cap_hi_register {
} bits __packed;
} __packed;
+_Static_assert(sizeof(union cap_hi_register) == 4, "bad size of cap_hi_register");
+
union cc_register {
uint32_t raw;
struct {
@@ -123,6 +127,8 @@ union cc_register {
} bits __packed;
} __packed;
+_Static_assert(sizeof(union cc_register) == 4, "bad size for cc_register");
+
enum shn_value {
NVME_SHN_NORMAL = 0x1,
NVME_SHN_ABRUPT = 0x2,
@@ -144,6 +150,8 @@ union csts_register {
} bits __packed;
} __packed;
+_Static_assert(sizeof(union csts_register) == 4, "bad size for csts_register");
+
enum shst_value {
NVME_SHST_NORMAL = 0x0,
NVME_SHST_OCCURRING = 0x1,
@@ -165,6 +173,8 @@ union aqa_register {
} bits __packed;
} __packed;
+_Static_assert(sizeof(union aqa_register) == 4, "bad size for aqa_resgister");
+
struct nvme_registers
{
/** controller capabilities */
@@ -198,6 +208,8 @@ struct nvme_registers
} doorbell[1] __packed;
} __packed;
+_Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_registers");
+
struct nvme_command
{
/* dword 0 */
@@ -231,6 +243,8 @@ struct nvme_command
uint32_t cdw15; /* command-specific */
} __packed;
+_Static_assert(sizeof(struct nvme_command) == 16 * 4, "bad size for nvme_command");
+
struct nvme_status {
uint16_t p : 1; /* phase tag */
@@ -241,6 +255,8 @@ struct nvme_status {
uint16_t dnr : 1; /* do not retry */
} __packed;
+_Static_assert(sizeof(struct nvme_status) == 2, "bad size for nvme_status");
+
struct nvme_completion {
/* dword 0 */
@@ -258,6 +274,8 @@ struct nvme_completion {
struct nvme_status status;
} __packed;
+_Static_assert(sizeof(struct nvme_completion) == 4 * 4, "bad size for nvme_completion");
+
struct nvme_dsm_range {
uint32_t attributes;
@@ -265,6 +283,8 @@ struct nvme_dsm_range {
uint64_t starting_lba;
} __packed;
+_Static_assert(sizeof(struct nvme_dsm_range) == 16, "bad size for nvme_dsm_ranage");
+
/* status code types */
enum nvme_status_code_type {
NVME_SCT_GENERIC = 0x0,
@@ -377,7 +397,14 @@ enum nvme_feature {
NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
NVME_FEAT_WRITE_ATOMICITY = 0x0A,
NVME_FEAT_ASYNC_EVENT_CONFIGURATION = 0x0B,
- /* 0x0C-0x7F - reserved */
+ NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C,
+ NVME_FEAT_HOST_MEMORY_BUFFER = 0x0D,
+ NVME_FEAT_TIMESTAMP = 0x0E,
+ NVME_FEAT_KEEP_ALIVE_TIMER = 0x0F,
+ NVME_FEAT_HOST_CONTROLLED_THERMAL_MGMT = 0x10,
+ NVME_FEAT_NON_OP_POWER_STATE_CONFIG = 0x11,
+ /* 0x12-0x77 - reserved */
+ /* 0x78-0x7f - NVMe Management Interface */
NVME_FEAT_SOFTWARE_PROGRESS_MARKER = 0x80,
/* 0x81-0xBF - command set specific (reserved) */
/* 0xC0-0xFF - vendor specific */
@@ -423,6 +450,8 @@ struct nvme_power_state {
uint8_t ps_rsvd10[9];
} __packed;
+_Static_assert(sizeof(struct nvme_power_state) == 32, "bad size for nvme_power_state");
+
#define NVME_SERIAL_NUMBER_LENGTH 20
#define NVME_MODEL_NUMBER_LENGTH 40
#define NVME_FIRMWARE_REVISION_LENGTH 8
@@ -461,7 +490,27 @@ struct nvme_controller_data {
/** Controller ID */
uint16_t ctrlr_id;
- uint8_t reserved1[176];
+ /** Version */
+ uint32_t ver;
+
+ /** RTD3 Resume Latency */
+ uint32_t rtd3r;
+
+ /** RTD3 Enter Latency */
+ uint32_t rtd3e;
+
+ /** Optional Asynchronous Events Supported */
+ uint32_t oaes; /* bitfield really */
+
+ /** Controller Attributes */
+ uint32_t ctratt; /* bitfield really */
+
+ uint8_t reserved1[12];
+
+ /** FRU Globally Unique Identifier */
+ uint8_t fguid[16];
+
+ uint8_t reserved2[128];
/* bytes 256-511: admin command set attributes */
@@ -521,7 +570,28 @@ struct nvme_controller_data {
uint8_t avscc_rsvd : 7;
} __packed avscc;
- uint8_t reserved2[15];
+ /** Autonomous Power State Transition Attributes */
+ struct {
+ /* Autonmous Power State Transitions supported */
+ uint8_t apst_supp : 1;
+
+ uint8_t apsta_rsvd : 7;
+ } __packed apsta;
+
+ /** Warning Composite Temperature Threshold */
+ uint16_t wctemp;
+
+ /** Critical Composite Temperature Threshold */
+ uint16_t cctemp;
+
+ /** Maximum Time for Firmware Activation */
+ uint16_t mtfa;
+
+ /** Host Memory Buffer Preferred Size */
+ uint32_t hmpre;
+
+ /** Host Memory Buffer Minimum Size */
+ uint32_t hmmin;
/** Name space capabilities */
struct {
@@ -530,7 +600,34 @@ struct nvme_controller_data {
uint8_t unvmcap[16];
} __packed untncap;
- uint8_t reserved3[200];
+ /** Replay Protected Memory Block Support */
+ uint32_t rpmbs; /* Really a bitfield */
+
+ /** Extended Device Self-test Time */
+ uint16_t edstt;
+
+ /** Device Self-test Options */
+ uint8_t dsto; /* Really a bitfield */
+
+ /** Firmware Update Granularity */
+ uint8_t fwug;
+
+ /** Keep Alive Support */
+ uint16_t kas;
+
+ /** Host Controlled Thermal Management Attributes */
+ uint16_t hctma; /* Really a bitfield */
+
+ /** Minimum Thermal Management Temperature */
+ uint16_t mntmt;
+
+ /** Maximum Thermal Management Temperature */
+ uint16_t mxtmt;
+
+ /** Sanitize Capabilities */
+ uint32_t sanicap; /* Really a bitfield */
+
+ uint8_t reserved3[180];
/* bytes 512-703: nvm command set attributes */
/** submission queue entry size */
@@ -545,7 +642,8 @@ struct nvme_controller_data {
uint8_t max : 4;
} __packed cqes;
- uint8_t reserved4[2];
+ /** Maximum Outstanding Commands */
+ uint16_t maxcmd;
/** number of namespaces */
uint32_t nn;
@@ -583,6 +681,8 @@ struct nvme_controller_data {
uint8_t vs[1024];
} __packed __aligned(4);
+_Static_assert(sizeof(struct nvme_controller_data) == 4096, "bad size for nvme_controller_data");
+
struct nvme_namespace_data {
/** namespace size */
@@ -673,6 +773,8 @@ struct nvme_namespace_data {
uint8_t vendor_specific[3712];
} __packed __aligned(4);
+_Static_assert(sizeof(struct nvme_namespace_data) == 4096, "bad size for nvme_namepsace_data");
+
enum nvme_log_page {
/* 0x00 - reserved */
@@ -715,6 +817,8 @@ struct nvme_error_information_entry {
uint8_t reserved[35];
} __packed __aligned(4);
+_Static_assert(sizeof(struct nvme_error_information_entry) == 64, "bad size for nvme_error_information_entry");
+
union nvme_critical_warning_state {
uint8_t raw;
@@ -729,6 +833,8 @@ union nvme_critical_warning_state {
} __packed bits;
} __packed;
+_Static_assert(sizeof(union nvme_critical_warning_state) == 1, "bad size for nvme_critical_warning_state");
+
struct nvme_health_information_page {
union nvme_critical_warning_state critical_warning;
@@ -765,6 +871,8 @@ struct nvme_health_information_page {
uint8_t reserved2[296];
} __packed __aligned(4);
+_Static_assert(sizeof(struct nvme_health_information_page) == 512, "bad size for nvme_health_information_page");
+
struct nvme_firmware_page {
struct {
@@ -777,6 +885,8 @@ struct nvme_firmware_page {
uint8_t reserved2[448];
} __packed __aligned(4);
+_Static_assert(sizeof(struct nvme_firmware_page) == 512, "bad size for nvme_firmware_page");
+
struct intel_log_temp_stats
{
uint64_t current;
@@ -790,6 +900,8 @@ struct intel_log_temp_stats
uint64_t est_offset;
} __packed __aligned(4);
+_Static_assert(sizeof(struct intel_log_temp_stats) == 13 * 8, "bad size for intel_log_temp_stats");
+
#define NVME_TEST_MAX_THREADS 128
struct nvme_io_test {
@@ -958,7 +1070,7 @@ int nvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp,
/* Command building helper functions -- shared with CAM */
static inline
-void nvme_ns_flush_cmd(struct nvme_command *cmd, uint16_t nsid)
+void nvme_ns_flush_cmd(struct nvme_command *cmd, uint32_t nsid)
{
cmd->opc = NVME_OPC_FLUSH;
@@ -966,7 +1078,7 @@ void nvme_ns_flush_cmd(struct nvme_command *cmd, uint16_t nsid)
}
static inline
-void nvme_ns_rw_cmd(struct nvme_command *cmd, uint32_t rwcmd, uint16_t nsid,
+void nvme_ns_rw_cmd(struct nvme_command *cmd, uint32_t rwcmd, uint32_t nsid,
uint64_t lba, uint32_t count)
{
cmd->opc = rwcmd;
@@ -980,21 +1092,21 @@ void nvme_ns_rw_cmd(struct nvme_command *cmd, uint32_t rwcmd, uint16_t nsid,
}
static inline
-void nvme_ns_write_cmd(struct nvme_command *cmd, uint16_t nsid,
+void nvme_ns_write_cmd(struct nvme_command *cmd, uint32_t nsid,
uint64_t lba, uint32_t count)
{
nvme_ns_rw_cmd(cmd, NVME_OPC_WRITE, nsid, lba, count);
}
static inline
-void nvme_ns_read_cmd(struct nvme_command *cmd, uint16_t nsid,
+void nvme_ns_read_cmd(struct nvme_command *cmd, uint32_t nsid,
uint64_t lba, uint32_t count)
{
nvme_ns_rw_cmd(cmd, NVME_OPC_READ, nsid, lba, count);
}
static inline
-void nvme_ns_trim_cmd(struct nvme_command *cmd, uint16_t nsid,
+void nvme_ns_trim_cmd(struct nvme_command *cmd, uint32_t nsid,
uint32_t num_ranges)
{
cmd->opc = NVME_OPC_DATASET_MANAGEMENT;
@@ -1003,6 +1115,8 @@ void nvme_ns_trim_cmd(struct nvme_command *cmd, uint16_t nsid,
cmd->cdw11 = NVME_DSM_ATTR_DEALLOCATE;
}
+extern int nvme_use_nvd;
+
#endif /* _KERNEL */
#endif /* __NVME_H__ */
diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.c b/freebsd/sys/dev/ofw/ofw_bus_subr.c
index cc30578d..418304a0 100644
--- a/freebsd/sys/dev/ofw/ofw_bus_subr.c
+++ b/freebsd/sys/dev/ofw/ofw_bus_subr.c
@@ -722,22 +722,14 @@ phandle_t
ofw_bus_find_compatible(phandle_t node, const char *onecompat)
{
phandle_t child, ret;
- void *compat;
- int len;
/*
* Traverse all children of 'start' node, and find first with
* matching 'compatible' property.
*/
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
- len = OF_getprop_alloc(child, "compatible", 1, &compat);
- if (len >= 0) {
- ret = ofw_bus_node_is_compatible_int(compat, len,
- onecompat);
- free(compat, M_OFWPROP);
- if (ret != 0)
- return (child);
- }
+ if (ofw_bus_node_is_compatible(child, onecompat) != 0)
+ return (child);
ret = ofw_bus_find_compatible(child, onecompat);
if (ret != 0)
diff --git a/freebsd/sys/dev/ofw/ofw_fdt.c b/freebsd/sys/dev/ofw/ofw_fdt.c
index 766be90f..282c3667 100644
--- a/freebsd/sys/dev/ofw/ofw_fdt.c
+++ b/freebsd/sys/dev/ofw/ofw_fdt.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofwvar.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus_subr.h>
#include <rtems/bsd/local/ofw_if.h>
@@ -388,7 +389,11 @@ ofw_fdt_setprop(ofw_t ofw, phandle_t package, const char *propname,
if (offset < 0)
return (-1);
- return (fdt_setprop_inplace(fdtp, offset, propname, buf, len));
+ if (fdt_setprop_inplace(fdtp, offset, propname, buf, len) != 0)
+ /* Try to add property, when setting value inplace failed */
+ return (fdt_setprop(fdtp, offset, propname, buf, len));
+
+ return (0);
}
/* Convert a device specifier to a fully qualified pathname. */
@@ -459,7 +464,15 @@ ofw_fdt_fixup(ofw_t ofw)
for (i = 0; fdt_fixup_table[i].model != NULL; i++) {
if (strncmp(model, fdt_fixup_table[i].model,
FDT_MODEL_LEN) != 0)
- continue;
+ /*
+ * Sometimes it's convenient to provide one
+ * fixup entry that refers to many boards.
+ * To handle this case, simply check if model
+ * is compatible parameter
+ */
+ if(!ofw_bus_node_is_compatible(root,
+ fdt_fixup_table[i].model))
+ continue;
if (fdt_fixup_table[i].handler != NULL)
(*fdt_fixup_table[i].handler)(root);
diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c
index be4c626f..69497d2c 100644
--- a/freebsd/sys/dev/pci/pci.c
+++ b/freebsd/sys/dev/pci/pci.c
@@ -2906,13 +2906,21 @@ pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp,
* Determine the BAR's length by writing all 1's. The bottom
* log_2(size) bits of the BAR will stick as 0 when we read
* the value back.
+ *
+ * NB: according to the PCI Local Bus Specification, rev. 3.0:
+ * "Software writes 0FFFFFFFFh to both registers, reads them back,
+ * and combines the result into a 64-bit value." (section 6.2.5.1)
+ *
+ * Writes to both registers must be performed before attempting to
+ * read back the size value.
*/
+ testval = 0;
pci_write_config(dev, reg, 0xffffffff, 4);
- testval = pci_read_config(dev, reg, 4);
if (ln2range == 64) {
pci_write_config(dev, reg + 4, 0xffffffff, 4);
testval |= (pci_addr_t)pci_read_config(dev, reg + 4, 4) << 32;
}
+ testval |= pci_read_config(dev, reg, 4);
/*
* Restore the original value of the BAR. We may have reprogrammed
diff --git a/freebsd/sys/dev/rtwn/if_rtwn_ridx.h b/freebsd/sys/dev/rtwn/if_rtwn_ridx.h
index eef43898..76f87aab 100644
--- a/freebsd/sys/dev/rtwn/if_rtwn_ridx.h
+++ b/freebsd/sys/dev/rtwn/if_rtwn_ridx.h
@@ -36,7 +36,7 @@
#define RTWN_RIDX_OFDM36 9
#define RTWN_RIDX_OFDM48 10
#define RTWN_RIDX_OFDM54 11
-#define RTWN_RIDX_MCS(i) (12 + (i))
+#define RTWN_RIDX_HT_MCS(i) (12 + (i))
#define RTWN_RIDX_COUNT 28
#define RTWN_RIDX_UNKNOWN (uint8_t)-1
@@ -82,10 +82,10 @@ rtwn_ctl_mcsrate(const struct ieee80211_rate_table *rt, uint8_t ridx)
uint8_t cix, rate;
/* Check if we are using MCS rate. */
- KASSERT(ridx >= RTWN_RIDX_MCS(0) && ridx != RTWN_RIDX_UNKNOWN,
+ KASSERT(ridx >= RTWN_RIDX_HT_MCS(0) && ridx != RTWN_RIDX_UNKNOWN,
("bad mcs rate index %d", ridx));
- rate = (ridx - RTWN_RIDX_MCS(0)) | IEEE80211_RATE_MCS;
+ rate = (ridx - RTWN_RIDX_HT_MCS(0)) | IEEE80211_RATE_MCS;
cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex;
KASSERT(cix != (uint8_t)-1, ("rate %d (%d) has no info", rate, ridx));
return rt->info[cix].dot11Rate;
diff --git a/freebsd/sys/dev/rtwn/if_rtwn_rx.c b/freebsd/sys/dev/rtwn/if_rtwn_rx.c
index 7b3f1c2e..fb260596 100644
--- a/freebsd/sys/dev/rtwn/if_rtwn_rx.c
+++ b/freebsd/sys/dev/rtwn/if_rtwn_rx.c
@@ -90,7 +90,7 @@ rtwn_get_rates(struct rtwn_softc *sc, const struct ieee80211_rateset *rs,
if ((rs_ht->rs_rates[i] & 0x7f) > 0xf)
continue;
/* 11n rates start at index 12 */
- ridx = RTWN_RIDX_MCS((rs_ht->rs_rates[i]) & 0xf);
+ ridx = RTWN_RIDX_HT_MCS((rs_ht->rs_rates[i]) & 0xf);
rates |= (1 << ridx);
/* Guard against the rate table being oddly ordered */
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e.h b/freebsd/sys/dev/rtwn/rtl8188e/r88e.h
index 1c03ddd3..3a3c0865 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/r88e.h
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e.h
@@ -49,7 +49,7 @@ uint8_t r88e_temp_read(struct rtwn_softc *);
/* r88e_chan.c */
void r88e_get_txpower(struct rtwn_softc *, int,
- struct ieee80211_channel *, uint16_t[]);
+ struct ieee80211_channel *, uint8_t[]);
void r88e_set_bw20(struct rtwn_softc *, uint8_t);
void r88e_set_gain(struct rtwn_softc *, uint8_t);
diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c
index 903398a4..530df320 100644
--- a/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c
+++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c
@@ -87,7 +87,7 @@ r88e_get_power_group(struct rtwn_softc *sc, struct ieee80211_channel *c)
void
r88e_get_txpower(struct rtwn_softc *sc, int chain,
- struct ieee80211_channel *c, uint16_t power[RTWN_RIDX_COUNT])
+ struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
{
struct r92c_softc *rs = sc->sc_priv;
const struct rtwn_r88e_txpwr *rt = rs->rs_txpwr;
@@ -103,7 +103,7 @@ r88e_get_txpower(struct rtwn_softc *sc, int chain,
/* XXX net80211 regulatory */
- max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
+ max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1);
KASSERT(max_mcs <= RTWN_RIDX_COUNT, ("increase ridx limit\n"));
memset(power, 0, max_mcs * sizeof(power[0]));
@@ -123,7 +123,7 @@ r88e_get_txpower(struct rtwn_softc *sc, int chain,
power[ridx] = ofdmpow;
bw20pow = htpow + rt->bw20_tx_pwr_diff;
- for (ridx = RTWN_RIDX_MCS(0); ridx <= max_mcs; ridx++)
+ for (ridx = RTWN_RIDX_HT_MCS(0); ridx <= max_mcs; ridx++)
power[ridx] = bw20pow;
/* Apply max limit. */
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c.h
index 5ac666d0..d8f7afc8 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c.h
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c.h
@@ -55,7 +55,9 @@ uint8_t r92c_temp_read(struct rtwn_softc *);
/* r92c_chan.c */
void r92c_get_txpower(struct rtwn_softc *, int,
- struct ieee80211_channel *, uint16_t[]);
+ struct ieee80211_channel *, uint8_t[]);
+void r92c_write_txpower(struct rtwn_softc *, int,
+ uint8_t power[]);
void r92c_set_bw20(struct rtwn_softc *, uint8_t);
void r92c_set_chan(struct rtwn_softc *, struct ieee80211_channel *);
void r92c_set_gain(struct rtwn_softc *, uint8_t);
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c
index c5d72f87..2e50daf1 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c
@@ -84,7 +84,7 @@ r92c_get_power_group(struct rtwn_softc *sc, struct ieee80211_channel *c)
/* XXX recheck */
void
r92c_get_txpower(struct rtwn_softc *sc, int chain,
- struct ieee80211_channel *c, uint16_t power[RTWN_RIDX_COUNT])
+ struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
{
struct r92c_softc *rs = sc->sc_priv;
struct rtwn_r92c_txpwr *rt = rs->rs_txpwr;
@@ -101,7 +101,7 @@ r92c_get_txpower(struct rtwn_softc *sc, int chain,
/* XXX net80211 regulatory */
- max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
+ max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1);
KASSERT(max_mcs <= RTWN_RIDX_COUNT, ("increase ridx limit\n"));
memset(power, 0, max_mcs * sizeof(power[0]));
@@ -148,7 +148,7 @@ r92c_get_txpower(struct rtwn_softc *sc, int chain,
diff = rt->ht20_tx_pwr_diff[chain][group];
htpow += diff; /* HT40->HT20 correction. */
}
- for (ridx = RTWN_RIDX_MCS(0); ridx <= max_mcs; ridx++)
+ for (ridx = RTWN_RIDX_HT_MCS(0); ridx <= max_mcs; ridx++)
power[ridx] += htpow;
/* Apply max limit. */
@@ -158,9 +158,9 @@ r92c_get_txpower(struct rtwn_softc *sc, int chain,
}
}
-static void
+void
r92c_write_txpower(struct rtwn_softc *sc, int chain,
- uint16_t power[RTWN_RIDX_COUNT])
+ uint8_t power[RTWN_RIDX_COUNT])
{
uint32_t reg;
@@ -197,33 +197,33 @@ r92c_write_txpower(struct rtwn_softc *sc, int chain,
SM(R92C_TXAGC_RATE54, power[RTWN_RIDX_OFDM54]));
/* Write per-MCS Tx power. */
rtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain),
- SM(R92C_TXAGC_MCS00, power[RTWN_RIDX_MCS(0)]) |
- SM(R92C_TXAGC_MCS01, power[RTWN_RIDX_MCS(1)]) |
- SM(R92C_TXAGC_MCS02, power[RTWN_RIDX_MCS(2)]) |
- SM(R92C_TXAGC_MCS03, power[RTWN_RIDX_MCS(3)]));
+ SM(R92C_TXAGC_MCS00, power[RTWN_RIDX_HT_MCS(0)]) |
+ SM(R92C_TXAGC_MCS01, power[RTWN_RIDX_HT_MCS(1)]) |
+ SM(R92C_TXAGC_MCS02, power[RTWN_RIDX_HT_MCS(2)]) |
+ SM(R92C_TXAGC_MCS03, power[RTWN_RIDX_HT_MCS(3)]));
rtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain),
- SM(R92C_TXAGC_MCS04, power[RTWN_RIDX_MCS(4)]) |
- SM(R92C_TXAGC_MCS05, power[RTWN_RIDX_MCS(5)]) |
- SM(R92C_TXAGC_MCS06, power[RTWN_RIDX_MCS(6)]) |
- SM(R92C_TXAGC_MCS07, power[RTWN_RIDX_MCS(7)]));
+ SM(R92C_TXAGC_MCS04, power[RTWN_RIDX_HT_MCS(4)]) |
+ SM(R92C_TXAGC_MCS05, power[RTWN_RIDX_HT_MCS(5)]) |
+ SM(R92C_TXAGC_MCS06, power[RTWN_RIDX_HT_MCS(6)]) |
+ SM(R92C_TXAGC_MCS07, power[RTWN_RIDX_HT_MCS(7)]));
if (sc->ntxchains >= 2) {
rtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain),
- SM(R92C_TXAGC_MCS08, power[RTWN_RIDX_MCS(8)]) |
- SM(R92C_TXAGC_MCS09, power[RTWN_RIDX_MCS(9)]) |
- SM(R92C_TXAGC_MCS10, power[RTWN_RIDX_MCS(10)]) |
- SM(R92C_TXAGC_MCS11, power[RTWN_RIDX_MCS(11)]));
+ SM(R92C_TXAGC_MCS08, power[RTWN_RIDX_HT_MCS(8)]) |
+ SM(R92C_TXAGC_MCS09, power[RTWN_RIDX_HT_MCS(9)]) |
+ SM(R92C_TXAGC_MCS10, power[RTWN_RIDX_HT_MCS(10)]) |
+ SM(R92C_TXAGC_MCS11, power[RTWN_RIDX_HT_MCS(11)]));
rtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain),
- SM(R92C_TXAGC_MCS12, power[RTWN_RIDX_MCS(12)]) |
- SM(R92C_TXAGC_MCS13, power[RTWN_RIDX_MCS(13)]) |
- SM(R92C_TXAGC_MCS14, power[RTWN_RIDX_MCS(14)]) |
- SM(R92C_TXAGC_MCS15, power[RTWN_RIDX_MCS(15)]));
+ SM(R92C_TXAGC_MCS12, power[RTWN_RIDX_HT_MCS(12)]) |
+ SM(R92C_TXAGC_MCS13, power[RTWN_RIDX_HT_MCS(13)]) |
+ SM(R92C_TXAGC_MCS14, power[RTWN_RIDX_HT_MCS(14)]) |
+ SM(R92C_TXAGC_MCS15, power[RTWN_RIDX_HT_MCS(15)]));
}
}
static void
r92c_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
- uint16_t power[RTWN_RIDX_COUNT];
+ uint8_t power[RTWN_RIDX_COUNT];
int i;
for (i = 0; i < sc->ntxchains; i++) {
@@ -233,7 +233,7 @@ r92c_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c)
if (sc->sc_debug & RTWN_DEBUG_TXPWR) {
int max_mcs, ridx;
- max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
+ max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1);
/* Dump per-rate Tx power values. */
printf("Tx power for chain %d:\n", i);
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c
index ab8b4989..e6c09eb2 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_fw.c
@@ -200,7 +200,7 @@ r92c_send_ra_cmd(struct rtwn_softc *sc, int macid, uint32_t rates,
#endif
/* Set rates mask for unicast frames. */
- if (maxrate >= RTWN_RIDX_MCS(0))
+ if (maxrate >= RTWN_RIDX_HT_MCS(0))
mode = R92C_RAID_11GN;
else if (maxrate >= RTWN_RIDX_OFDM6)
mode = R92C_RAID_11BG;
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_priv.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_priv.h
index 13c38fb2..80f05828 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_priv.h
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_priv.h
@@ -333,7 +333,7 @@ static const struct rtwn_rf_prog rtl8192c_rf[] = {
struct rtwn_r92c_txagc {
- uint8_t pwr[R92C_GROUP_2G][28]; /* RTWN_RIDX_MCS(15) + 1 */
+ uint8_t pwr[R92C_GROUP_2G][28]; /* RTWN_RIDX_HT_MCS(15) + 1 */
};
/*
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c
index b877fb88..80d2859c 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_rx.c
@@ -119,7 +119,7 @@ r92c_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
rxs->c_pktflags |= IEEE80211_RX_F_AMPDU;
else if (rxdw1 & R92C_RXDW1_AMPDU_MORE)
rxs->c_pktflags |= IEEE80211_RX_F_AMPDU_MORE;
- if ((rxdw3 & R92C_RXDW3_SPLCP) && rate >= RTWN_RIDX_MCS(0))
+ if ((rxdw3 & R92C_RXDW3_SPLCP) && rate >= RTWN_RIDX_HT_MCS(0))
rxs->c_pktflags |= IEEE80211_RX_F_SHORTGI;
if (rxdw3 & R92C_RXDW3_HT40)
@@ -129,13 +129,13 @@ r92c_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
if (RTWN_RATE_IS_CCK(rate))
rxs->c_phytype = IEEE80211_RX_FP_11B;
- else if (rate < RTWN_RIDX_MCS(0))
+ else if (rate < RTWN_RIDX_HT_MCS(0))
rxs->c_phytype = IEEE80211_RX_FP_11G;
else
rxs->c_phytype = IEEE80211_RX_FP_11NG;
/* Map HW rate index to 802.11 rate. */
- if (rate < RTWN_RIDX_MCS(0)) {
+ if (rate < RTWN_RIDX_HT_MCS(0)) {
rxs->c_rate = ridx2rate[rate];
if (RTWN_RATE_IS_CCK(rate))
rxs->c_pktflags |= IEEE80211_RX_F_CCK;
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
index c2a6eab0..5c80af90 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
@@ -101,7 +101,7 @@ r92c_tx_protection(struct rtwn_softc *sc, struct r92c_tx_desc *txd,
if (mode == IEEE80211_PROT_CTSONLY ||
mode == IEEE80211_PROT_RTSCTS) {
- if (ridx >= RTWN_RIDX_MCS(0))
+ if (ridx >= RTWN_RIDX_HT_MCS(0))
rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx);
else
rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]);
@@ -287,7 +287,7 @@ r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
txd->txdw4 |= htole32(R92C_TXDW4_DATA_SHPRE);
prot = IEEE80211_PROT_NONE;
- if (ridx >= RTWN_RIDX_MCS(0)) {
+ if (ridx >= RTWN_RIDX_HT_MCS(0)) {
r92c_tx_set_ht40(sc, txd, ni);
r92c_tx_set_sgi(sc, txd, ni);
prot = ic->ic_htprotmode;
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_var.h b/freebsd/sys/dev/rtwn/rtl8192c/r92c_var.h
index c48318d9..79592449 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_var.h
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_var.h
@@ -53,7 +53,7 @@ struct r92c_softc {
void (*rs_set_bw20)(struct rtwn_softc *, uint8_t);
void (*rs_get_txpower)(struct rtwn_softc *, int,
- struct ieee80211_channel *, uint16_t[]);
+ struct ieee80211_channel *, uint8_t[]);
void (*rs_set_gain)(struct rtwn_softc *, uint8_t);
void (*rs_tx_enable_ampdu)(void *, int);
void (*rs_tx_setup_hwseq)(void *);
diff --git a/freebsd/sys/dev/rtwn/rtl8192e/r92e_chan.c b/freebsd/sys/dev/rtwn/rtl8192e/r92e_chan.c
index 130ac5ca..0046b9f0 100644
--- a/freebsd/sys/dev/rtwn/rtl8192e/r92e_chan.c
+++ b/freebsd/sys/dev/rtwn/rtl8192e/r92e_chan.c
@@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$");
#include <dev/rtwn/if_rtwn_ridx.h>
#include <dev/rtwn/if_rtwn_rx.h>
+#include <dev/rtwn/rtl8192c/r92c.h>
+
#include <dev/rtwn/rtl8192e/r92e.h>
#include <dev/rtwn/rtl8192e/r92e_reg.h>
#include <dev/rtwn/rtl8192e/r92e_var.h>
@@ -102,7 +104,7 @@ r92e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c,
return;
}
- max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
+ max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1);
/* XXX regulatory */
/* XXX net80211 regulatory */
@@ -124,7 +126,7 @@ r92e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c,
else
pwr_diff = rs->bw20_tx_pwr_diff_2g[chain][i];
- min_mcs = RTWN_RIDX_MCS(i * 8);
+ min_mcs = RTWN_RIDX_HT_MCS(i * 8);
for (ridx = min_mcs; ridx <= max_mcs; ridx++)
power[ridx] += pwr_diff;
@@ -146,69 +148,6 @@ r92e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c,
#endif
}
-
-static void
-r92e_write_txpower(struct rtwn_softc *sc, int chain,
- uint8_t power[RTWN_RIDX_COUNT])
-{
- uint32_t reg;
-
- /* Write per-CCK rate Tx power. */
- if (chain == 0) {
- reg = rtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32);
- reg = RW(reg, R92C_TXAGC_A_CCK1, power[RTWN_RIDX_CCK1]);
- rtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg);
- reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
- reg = RW(reg, R92C_TXAGC_A_CCK2, power[RTWN_RIDX_CCK2]);
- reg = RW(reg, R92C_TXAGC_A_CCK55, power[RTWN_RIDX_CCK55]);
- reg = RW(reg, R92C_TXAGC_A_CCK11, power[RTWN_RIDX_CCK11]);
- rtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
- } else {
- reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32);
- reg = RW(reg, R92C_TXAGC_B_CCK1, power[RTWN_RIDX_CCK1]);
- reg = RW(reg, R92C_TXAGC_B_CCK2, power[RTWN_RIDX_CCK2]);
- reg = RW(reg, R92C_TXAGC_B_CCK55, power[RTWN_RIDX_CCK55]);
- rtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg);
- reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
- reg = RW(reg, R92C_TXAGC_B_CCK11, power[RTWN_RIDX_CCK11]);
- rtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
- }
- /* Write per-OFDM rate Tx power. */
- rtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain),
- SM(R92C_TXAGC_RATE06, power[RTWN_RIDX_OFDM6]) |
- SM(R92C_TXAGC_RATE09, power[RTWN_RIDX_OFDM9]) |
- SM(R92C_TXAGC_RATE12, power[RTWN_RIDX_OFDM12]) |
- SM(R92C_TXAGC_RATE18, power[RTWN_RIDX_OFDM18]));
- rtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain),
- SM(R92C_TXAGC_RATE24, power[RTWN_RIDX_OFDM24]) |
- SM(R92C_TXAGC_RATE36, power[RTWN_RIDX_OFDM36]) |
- SM(R92C_TXAGC_RATE48, power[RTWN_RIDX_OFDM48]) |
- SM(R92C_TXAGC_RATE54, power[RTWN_RIDX_OFDM54]));
- /* Write per-MCS Tx power. */
- rtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain),
- SM(R92C_TXAGC_MCS00, power[RTWN_RIDX_MCS(0)]) |
- SM(R92C_TXAGC_MCS01, power[RTWN_RIDX_MCS(1)]) |
- SM(R92C_TXAGC_MCS02, power[RTWN_RIDX_MCS(2)]) |
- SM(R92C_TXAGC_MCS03, power[RTWN_RIDX_MCS(3)]));
- rtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain),
- SM(R92C_TXAGC_MCS04, power[RTWN_RIDX_MCS(4)]) |
- SM(R92C_TXAGC_MCS05, power[RTWN_RIDX_MCS(5)]) |
- SM(R92C_TXAGC_MCS06, power[RTWN_RIDX_MCS(6)]) |
- SM(R92C_TXAGC_MCS07, power[RTWN_RIDX_MCS(7)]));
- if (sc->ntxchains >= 2) {
- rtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain),
- SM(R92C_TXAGC_MCS08, power[RTWN_RIDX_MCS(8)]) |
- SM(R92C_TXAGC_MCS09, power[RTWN_RIDX_MCS(9)]) |
- SM(R92C_TXAGC_MCS10, power[RTWN_RIDX_MCS(10)]) |
- SM(R92C_TXAGC_MCS11, power[RTWN_RIDX_MCS(11)]));
- rtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain),
- SM(R92C_TXAGC_MCS12, power[RTWN_RIDX_MCS(12)]) |
- SM(R92C_TXAGC_MCS13, power[RTWN_RIDX_MCS(13)]) |
- SM(R92C_TXAGC_MCS14, power[RTWN_RIDX_MCS(14)]) |
- SM(R92C_TXAGC_MCS15, power[RTWN_RIDX_MCS(15)]));
- }
-}
-
static void
r92e_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
@@ -220,7 +159,7 @@ r92e_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c)
/* Compute per-rate Tx power values. */
r92e_get_txpower(sc, i, c, power);
/* Write per-rate Tx power values to hardware. */
- r92e_write_txpower(sc, i, power);
+ r92c_write_txpower(sc, i, power);
}
}
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c
index 27a71bd9..1f18bf56 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c
@@ -91,26 +91,26 @@ r12a_write_txpower(struct rtwn_softc *sc, int chain,
SM(R12A_TXAGC_OFDM54, power[RTWN_RIDX_OFDM54]));
/* Write per-MCS Tx power. */
rtwn_bb_write(sc, R12A_TXAGC_MCS3_0(chain),
- SM(R12A_TXAGC_MCS0, power[RTWN_RIDX_MCS(0)]) |
- SM(R12A_TXAGC_MCS1, power[RTWN_RIDX_MCS(1)]) |
- SM(R12A_TXAGC_MCS2, power[RTWN_RIDX_MCS(2)]) |
- SM(R12A_TXAGC_MCS3, power[RTWN_RIDX_MCS(3)]));
+ SM(R12A_TXAGC_MCS0, power[RTWN_RIDX_HT_MCS(0)]) |
+ SM(R12A_TXAGC_MCS1, power[RTWN_RIDX_HT_MCS(1)]) |
+ SM(R12A_TXAGC_MCS2, power[RTWN_RIDX_HT_MCS(2)]) |
+ SM(R12A_TXAGC_MCS3, power[RTWN_RIDX_HT_MCS(3)]));
rtwn_bb_write(sc, R12A_TXAGC_MCS7_4(chain),
- SM(R12A_TXAGC_MCS4, power[RTWN_RIDX_MCS(4)]) |
- SM(R12A_TXAGC_MCS5, power[RTWN_RIDX_MCS(5)]) |
- SM(R12A_TXAGC_MCS6, power[RTWN_RIDX_MCS(6)]) |
- SM(R12A_TXAGC_MCS7, power[RTWN_RIDX_MCS(7)]));
+ SM(R12A_TXAGC_MCS4, power[RTWN_RIDX_HT_MCS(4)]) |
+ SM(R12A_TXAGC_MCS5, power[RTWN_RIDX_HT_MCS(5)]) |
+ SM(R12A_TXAGC_MCS6, power[RTWN_RIDX_HT_MCS(6)]) |
+ SM(R12A_TXAGC_MCS7, power[RTWN_RIDX_HT_MCS(7)]));
if (sc->ntxchains >= 2) {
rtwn_bb_write(sc, R12A_TXAGC_MCS11_8(chain),
- SM(R12A_TXAGC_MCS8, power[RTWN_RIDX_MCS(8)]) |
- SM(R12A_TXAGC_MCS9, power[RTWN_RIDX_MCS(9)]) |
- SM(R12A_TXAGC_MCS10, power[RTWN_RIDX_MCS(10)]) |
- SM(R12A_TXAGC_MCS11, power[RTWN_RIDX_MCS(11)]));
+ SM(R12A_TXAGC_MCS8, power[RTWN_RIDX_HT_MCS(8)]) |
+ SM(R12A_TXAGC_MCS9, power[RTWN_RIDX_HT_MCS(9)]) |
+ SM(R12A_TXAGC_MCS10, power[RTWN_RIDX_HT_MCS(10)]) |
+ SM(R12A_TXAGC_MCS11, power[RTWN_RIDX_HT_MCS(11)]));
rtwn_bb_write(sc, R12A_TXAGC_MCS15_12(chain),
- SM(R12A_TXAGC_MCS12, power[RTWN_RIDX_MCS(12)]) |
- SM(R12A_TXAGC_MCS13, power[RTWN_RIDX_MCS(13)]) |
- SM(R12A_TXAGC_MCS14, power[RTWN_RIDX_MCS(14)]) |
- SM(R12A_TXAGC_MCS15, power[RTWN_RIDX_MCS(15)]));
+ SM(R12A_TXAGC_MCS12, power[RTWN_RIDX_HT_MCS(12)]) |
+ SM(R12A_TXAGC_MCS13, power[RTWN_RIDX_HT_MCS(13)]) |
+ SM(R12A_TXAGC_MCS14, power[RTWN_RIDX_HT_MCS(14)]) |
+ SM(R12A_TXAGC_MCS15, power[RTWN_RIDX_HT_MCS(15)]));
}
/* TODO: VHT rates */
@@ -178,7 +178,7 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
}
/* TODO: VHT rates. */
- max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
+ max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1);
/* XXX regulatory */
/* XXX net80211 regulatory */
@@ -207,7 +207,7 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
else
pwr_diff = rs->bw20_tx_pwr_diff_2g[chain][i];
- min_mcs = RTWN_RIDX_MCS(i * 8);
+ min_mcs = RTWN_RIDX_HT_MCS(i * 8);
for (ridx = min_mcs; ridx <= max_mcs; ridx++)
power[ridx] += pwr_diff;
}
@@ -233,7 +233,7 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
else
pwr_diff = rs->bw20_tx_pwr_diff_5g[chain][i];
- min_mcs = RTWN_RIDX_MCS(i * 8);
+ min_mcs = RTWN_RIDX_HT_MCS(i * 8);
for (ridx = min_mcs; ridx <= max_mcs; ridx++)
power[ridx] += pwr_diff;
}
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c
index dd90d7e9..c2dc4c3a 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_rx.c
@@ -264,7 +264,7 @@ r12a_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
rxs->c_pktflags |= IEEE80211_RX_F_AMPDU_MORE;
}
- if ((rxdw4 & R12A_RXDW4_SPLCP) && rate >= RTWN_RIDX_MCS(0))
+ if ((rxdw4 & R12A_RXDW4_SPLCP) && rate >= RTWN_RIDX_HT_MCS(0))
rxs->c_pktflags |= IEEE80211_RX_F_SHORTGI;
switch (MS(rxdw4, R12A_RXDW4_BW)) {
@@ -290,7 +290,7 @@ r12a_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
/* XXX check with RTL8812AU */
is5ghz = (physt->cfosho[2] != 0x01);
- if (rate < RTWN_RIDX_MCS(0)) {
+ if (rate < RTWN_RIDX_HT_MCS(0)) {
if (is5ghz)
rxs->c_phytype = IEEE80211_RX_FP_11A;
else
@@ -304,7 +304,7 @@ r12a_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
}
/* Map HW rate index to 802.11 rate. */
- if (rate < RTWN_RIDX_MCS(0)) {
+ if (rate < RTWN_RIDX_HT_MCS(0)) {
rxs->c_rate = ridx2rate[rate];
if (RTWN_RATE_IS_CCK(rate))
rxs->c_pktflags |= IEEE80211_RX_F_CCK;
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
index 895f71e4..77e9e423 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
@@ -109,7 +109,7 @@ r12a_tx_protection(struct rtwn_softc *sc, struct r12a_tx_desc *txd,
if (mode == IEEE80211_PROT_CTSONLY ||
mode == IEEE80211_PROT_RTSCTS) {
- if (ridx >= RTWN_RIDX_MCS(0))
+ if (ridx >= RTWN_RIDX_HT_MCS(0))
rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx);
else
rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]);
@@ -294,7 +294,7 @@ r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
txd->txdw5 |= htole32(R12A_TXDW5_DATA_SHORT);
prot = IEEE80211_PROT_NONE;
- if (ridx >= RTWN_RIDX_MCS(0)) {
+ if (ridx >= RTWN_RIDX_HT_MCS(0)) {
r12a_tx_set_ht40(sc, txd, ni);
r12a_tx_set_sgi(sc, txd, ni);
r12a_tx_set_ldpc(sc, txd, ni);
diff --git a/freebsd/sys/dev/sdhci/sdhci.c b/freebsd/sys/dev/sdhci/sdhci.c
index f1616a6e..8d1fed8f 100644
--- a/freebsd/sys/dev/sdhci/sdhci.c
+++ b/freebsd/sys/dev/sdhci/sdhci.c
@@ -1053,12 +1053,14 @@ no_tuning:
return (0);
}
+#ifndef MMCCAM
void
sdhci_start_slot(struct sdhci_slot *slot)
{
sdhci_card_task(slot, 0);
}
+#endif
int
sdhci_cleanup_slot(struct sdhci_slot *slot)
@@ -2398,7 +2400,7 @@ sdhci_generic_write_ivar(device_t bus, device_t child, int which,
#ifdef MMCCAM
void
-sdhci_cam_start_slot(struct sdhci_slot *slot)
+sdhci_start_slot(struct sdhci_slot *slot)
{
if ((slot->devq = cam_simq_alloc(1)) == NULL) {
goto fail;
diff --git a/freebsd/sys/dev/sdhci/sdhci.h b/freebsd/sys/dev/sdhci/sdhci.h
index 73aa84b6..ba66415f 100644
--- a/freebsd/sys/dev/sdhci/sdhci.h
+++ b/freebsd/sys/dev/sdhci/sdhci.h
@@ -430,9 +430,4 @@ bool sdhci_generic_get_card_present(device_t brdev, struct sdhci_slot *slot);
void sdhci_generic_set_uhs_timing(device_t brdev, struct sdhci_slot *slot);
void sdhci_handle_card_present(struct sdhci_slot *slot, bool is_present);
-#ifdef MMCCAM
-/* CAM-related */
-void sdhci_cam_start_slot(struct sdhci_slot *slot);
-#endif
-
#endif /* __SDHCI_H__ */
diff --git a/freebsd/sys/dev/smc/if_smc.c b/freebsd/sys/dev/smc/if_smc.c
index a018e09e..fd1a0960 100644
--- a/freebsd/sys/dev/smc/if_smc.c
+++ b/freebsd/sys/dev/smc/if_smc.c
@@ -784,7 +784,7 @@ smc_task_rx(void *context, int pending)
}
#ifdef DEVICE_POLLING
-static void
+static int
smc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
{
struct smc_softc *sc;
@@ -794,12 +794,13 @@ smc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
SMC_LOCK(sc);
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
SMC_UNLOCK(sc);
- return;
+ return (0);
}
SMC_UNLOCK(sc);
if (cmd == POLL_AND_CHECK_STATUS)
taskqueue_enqueue(sc->smc_tq, &sc->smc_intr);
+ return (0);
}
#endif
diff --git a/freebsd/sys/dev/usb/net/if_ure.c b/freebsd/sys/dev/usb/net/if_ure.c
index 27e3ecca..89ce723b 100644
--- a/freebsd/sys/dev/usb/net/if_ure.c
+++ b/freebsd/sys/dev/usb/net/if_ure.c
@@ -69,6 +69,7 @@ SYSCTL_INT(_hw_usb_ure, OID_AUTO, debug, CTLFLAG_RWTUN, &ure_debug, 0,
*/
static const STRUCT_USB_HOST_ID ure_devs[] = {
#define URE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+ URE_DEV(LENOVO, RTL8153, 0),
URE_DEV(REALTEK, RTL8152, URE_FLAG_8152),
URE_DEV(REALTEK, RTL8153, 0),
#undef URE_DEV
diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.c b/freebsd/sys/dev/usb/quirk/usb_quirk.c
index a5fac1b3..3ea3f3c6 100644
--- a/freebsd/sys/dev/usb/quirk/usb_quirk.c
+++ b/freebsd/sys/dev/usb/quirk/usb_quirk.c
@@ -236,6 +236,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
UQ_MSC_FORCE_PROTO_RBC),
USB_QUIRK(INSYSTEM, STORAGE_V2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
UQ_MSC_FORCE_PROTO_RBC),
+ USB_QUIRK(INTENSO, MEMORY_BOX, 0x0000, 0xffff, UQ_MSC_NO_INQUIRY),
USB_QUIRK(IODATA, IU_CD2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI),
USB_QUIRK(IODATA, DVR_UEH8, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
@@ -335,7 +336,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE,
UQ_MSC_NO_START_STOP),
USB_QUIRK(PROLIFIC, PL2506, 0x0000, 0xffff,
- UQ_MSC_NO_SYNC_CACHE),
+ UQ_MSC_NO_SYNC_CACHE, UQ_MSC_NO_PREVENT_ALLOW),
USB_QUIRK_VP(USB_VENDOR_SAMSUNG_TECHWIN,
USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
@@ -509,6 +510,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
USB_QUIRK(ROLAND, SD20, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
USB_QUIRK(ROLAND, SD80, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
USB_QUIRK(ROLAND, UA700, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
+ USB_QUIRK(ROLAND, PCR300, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
USB_QUIRK(EGO, M4U, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI),
USB_QUIRK(LOGILINK, U2M, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI),
USB_QUIRK(MEDELI, DD305, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI, UQ_MATCH_VENDOR_ONLY),
@@ -608,6 +610,7 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = {
[UQ_SINGLE_CMD_MIDI] = "UQ_SINGLE_CMD_MIDI",
[UQ_MSC_DYMO_EJECT] = "UQ_MSC_DYMO_EJECT",
[UQ_AU_SET_SPDIF_CM6206] = "UQ_AU_SET_SPDIF_CM6206",
+ [UQ_WMT_IGNORE] = "UQ_WMT_IGNORE",
};
/*------------------------------------------------------------------------*
diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.h b/freebsd/sys/dev/usb/quirk/usb_quirk.h
index f7e490ce..bb9fe190 100644
--- a/freebsd/sys/dev/usb/quirk/usb_quirk.h
+++ b/freebsd/sys/dev/usb/quirk/usb_quirk.h
@@ -110,6 +110,7 @@ enum {
UQ_SINGLE_CMD_MIDI, /* at most one command per USB packet */
UQ_MSC_DYMO_EJECT, /* ejects Dymo MSC device */
UQ_AU_SET_SPDIF_CM6206, /* enable S/PDIF audio output */
+ UQ_WMT_IGNORE, /* device should be ignored by wmt driver */
USB_QUIRK_MAX
};
diff --git a/freebsd/sys/dev/usb/usb_hid.c b/freebsd/sys/dev/usb/usb_hid.c
index 56e31a6e..5019aa1a 100644
--- a/freebsd/sys/dev/usb/usb_hid.c
+++ b/freebsd/sys/dev/usb/usb_hid.c
@@ -851,6 +851,80 @@ usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx,
}
/*------------------------------------------------------------------------*
+ * calculate HID item resolution. unit/mm for distances, unit/rad for angles
+ *------------------------------------------------------------------------*/
+int32_t
+hid_item_resolution(struct hid_item *hi)
+{
+ /*
+ * hid unit scaling table according to HID Usage Table Review
+ * Request 39 Tbl 17 http://www.usb.org/developers/hidpage/HUTRR39b.pdf
+ */
+ static const int64_t scale[0x10][2] = {
+ [0x00] = { 1, 1 },
+ [0x01] = { 1, 10 },
+ [0x02] = { 1, 100 },
+ [0x03] = { 1, 1000 },
+ [0x04] = { 1, 10000 },
+ [0x05] = { 1, 100000 },
+ [0x06] = { 1, 1000000 },
+ [0x07] = { 1, 10000000 },
+ [0x08] = { 100000000, 1 },
+ [0x09] = { 10000000, 1 },
+ [0x0A] = { 1000000, 1 },
+ [0x0B] = { 100000, 1 },
+ [0x0C] = { 10000, 1 },
+ [0x0D] = { 1000, 1 },
+ [0x0E] = { 100, 1 },
+ [0x0F] = { 10, 1 },
+ };
+ int64_t logical_size;
+ int64_t physical_size;
+ int64_t multiplier;
+ int64_t divisor;
+ int64_t resolution;
+
+ switch (hi->unit) {
+ case HUM_CENTIMETER:
+ multiplier = 1;
+ divisor = 10;
+ break;
+ case HUM_INCH:
+ multiplier = 10;
+ divisor = 254;
+ break;
+ case HUM_RADIAN:
+ multiplier = 1;
+ divisor = 1;
+ break;
+ case HUM_DEGREE:
+ multiplier = 573;
+ divisor = 10;
+ break;
+ default:
+ return (0);
+ }
+
+ if ((hi->logical_maximum <= hi->logical_minimum) ||
+ (hi->physical_maximum <= hi->physical_minimum) ||
+ (hi->unit_exponent < 0) || (hi->unit_exponent >= nitems(scale)))
+ return (0);
+
+ logical_size = (int64_t)hi->logical_maximum -
+ (int64_t)hi->logical_minimum;
+ physical_size = (int64_t)hi->physical_maximum -
+ (int64_t)hi->physical_minimum;
+ /* Round to ceiling */
+ resolution = logical_size * multiplier * scale[hi->unit_exponent][0] /
+ (physical_size * divisor * scale[hi->unit_exponent][1]);
+
+ if (resolution > INT32_MAX)
+ return (0);
+
+ return (resolution);
+}
+
+/*------------------------------------------------------------------------*
* hid_is_mouse
*
* This function will decide if a USB descriptor belongs to a USB mouse.
diff --git a/freebsd/sys/dev/usb/usb_hub.c b/freebsd/sys/dev/usb/usb_hub.c
index e70be43b..0eaeeb60 100644
--- a/freebsd/sys/dev/usb/usb_hub.c
+++ b/freebsd/sys/dev/usb/usb_hub.c
@@ -102,7 +102,9 @@ SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RWTUN,
#if USB_HAVE_DISABLE_ENUM
static int usb_disable_enumeration = 0;
SYSCTL_INT(_hw_usb, OID_AUTO, disable_enumeration, CTLFLAG_RWTUN,
- &usb_disable_enumeration, 0, "Set to disable all USB device enumeration.");
+ &usb_disable_enumeration, 0, "Set to disable all USB device enumeration. "
+ "This can secure against USB devices turning evil, "
+ "for example a USB memory stick becoming a USB keyboard.");
static int usb_disable_port_power = 0;
SYSCTL_INT(_hw_usb, OID_AUTO, disable_port_power, CTLFLAG_RWTUN,
diff --git a/freebsd/sys/dev/usb/usbhid.h b/freebsd/sys/dev/usb/usbhid.h
index 28dfede2..31aa7ea4 100644
--- a/freebsd/sys/dev/usb/usbhid.h
+++ b/freebsd/sys/dev/usb/usbhid.h
@@ -134,6 +134,12 @@ struct usb_hid_descriptor {
/* Usages Digitizers */
#define HUD_UNDEFINED 0x0000
+#define HUD_DIGITIZER 0x0001
+#define HUD_PEN 0x0002
+#define HUD_TOUCHSCREEN 0x0004
+#define HUD_TOUCHPAD 0x0005
+#define HUD_CONFIG 0x000e
+#define HUD_FINGER 0x0022
#define HUD_TIP_PRESSURE 0x0030
#define HUD_BARREL_PRESSURE 0x0031
#define HUD_IN_RANGE 0x0032
@@ -157,6 +163,16 @@ struct usb_hid_descriptor {
#define HUD_BARREL_SWITCH 0x0044
#define HUD_ERASER 0x0045
#define HUD_TABLET_PICK 0x0046
+#define HUD_CONFIDENCE 0x0047
+#define HUD_WIDTH 0x0048
+#define HUD_HEIGHT 0x0049
+#define HUD_CONTACTID 0x0051
+#define HUD_INPUT_MODE 0x0052
+#define HUD_DEVICE_INDEX 0x0053
+#define HUD_CONTACTCOUNT 0x0054
+#define HUD_CONTACT_MAX 0x0055
+#define HUD_SCAN_TIME 0x0056
+#define HUD_BUTTON_TYPE 0x0059
/* Usages, Consumer */
#define HUC_AC_PAN 0x0238
@@ -178,6 +194,12 @@ struct usb_hid_descriptor {
#define HIO_VOLATILE 0x080
#define HIO_BUFBYTES 0x100
+/* Units of Measure */
+#define HUM_CENTIMETER 0x11
+#define HUM_RADIAN 0x12
+#define HUM_INCH 0x13
+#define HUM_DEGREE 0x14
+
#ifdef _KERNEL
struct usb_config_descriptor;
@@ -244,6 +266,7 @@ struct usb_hid_descriptor *hid_get_descriptor_from_usb(
usb_error_t usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx,
void **descp, uint16_t *sizep, struct malloc_type *mem,
uint8_t iface_index);
+int32_t hid_item_resolution(struct hid_item *hi);
int hid_is_mouse(const void *d_ptr, uint16_t d_len);
int hid_is_keyboard(const void *d_ptr, uint16_t d_len);
#endif /* _KERNEL */
diff --git a/freebsd/sys/dev/usb/wlan/if_uath.c b/freebsd/sys/dev/usb/wlan/if_uath.c
index c3435d57..c4ebe5ed 100644
--- a/freebsd/sys/dev/usb/wlan/if_uath.c
+++ b/freebsd/sys/dev/usb/wlan/if_uath.c
@@ -2203,17 +2203,19 @@ uath_sysctl_node(struct uath_softc *sc)
#undef UATH_SYSCTL_STAT_ADD32
+CTASSERT(sizeof(u_int) >= sizeof(uint32_t));
+
static void
uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
{
struct uath_cmd_hdr *hdr;
- int dlen;
+ uint32_t dlen;
hdr = (struct uath_cmd_hdr *)cmd->buf;
/* NB: msgid is passed thru w/o byte swapping */
#ifdef UATH_DEBUG
if (sc->sc_debug & UATH_DEBUG_CMDS) {
- int len = be32toh(hdr->len);
+ uint32_t len = be32toh(hdr->len);
printf("%s: %s [ix %u] len %u status %u\n",
__func__, uath_codename(be32toh(hdr->code)),
hdr->msgid, len, be32toh(hdr->magic));
@@ -2229,15 +2231,9 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
switch (hdr->code & 0xff) {
/* reply to a read command */
default:
- dlen = hdr->len - sizeof(*hdr);
- if (dlen < 0) {
- device_printf(sc->sc_dev,
- "Invalid header length %d\n", dlen);
- return;
- }
DPRINTF(sc, UATH_DEBUG_RX_PROC | UATH_DEBUG_RECV_ALL,
- "%s: code %d data len %u\n",
- __func__, hdr->code & 0xff, dlen);
+ "%s: code %d hdr len %u\n",
+ __func__, hdr->code & 0xff, hdr->len);
/*
* The first response from the target after the
* HOST_AVAILABLE has an invalid msgid so we must
@@ -2247,8 +2243,8 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
uint32_t *rp = (uint32_t *)(hdr+1);
u_int olen;
- if (!(sizeof(*hdr) <= hdr->len &&
- hdr->len < UATH_MAX_CMDSZ)) {
+ if (sizeof(*hdr) > hdr->len ||
+ hdr->len >= UATH_MAX_CMDSZ) {
device_printf(sc->sc_dev,
"%s: invalid WDC msg length %u; "
"msg ignored\n", __func__, hdr->len);
@@ -2260,7 +2256,8 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
* number of bytes--unless it's 0 in which
* case a single 32-bit word should be present.
*/
- if (dlen >= (int)sizeof(uint32_t)) {
+ dlen = hdr->len - sizeof(*hdr);
+ if (dlen >= sizeof(uint32_t)) {
olen = be32toh(rp[0]);
dlen -= sizeof(uint32_t);
if (olen == 0) {
@@ -2280,7 +2277,7 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
cmd->olen);
olen = cmd->olen;
}
- if (olen > (u_int)dlen) {
+ if (olen > dlen) {
/* XXX complain, shouldn't happen */
device_printf(sc->sc_dev,
"%s: cmd 0x%x olen %u dlen %u\n",
@@ -2302,8 +2299,10 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
return;
}
dlen = hdr->len - sizeof(*hdr);
- if (dlen != (int)sizeof(uint32_t)) {
- /* XXX something wrong */
+ if (dlen != sizeof(uint32_t)) {
+ device_printf(sc->sc_dev,
+ "%s: dlen (%u) != %zu!\n",
+ __func__, dlen, sizeof(uint32_t));
return;
}
/* XXX have submitter do this */
@@ -2332,6 +2331,7 @@ uath_intr_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct uath_softc *sc = usbd_xfer_softc(xfer);
struct uath_cmd *cmd;
+ struct uath_cmd_hdr *hdr;
struct usb_page_cache *pc;
int actlen;
@@ -2349,10 +2349,25 @@ uath_intr_rx_callback(struct usb_xfer *xfer, usb_error_t error)
STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next);
UATH_STAT_INC(sc, st_cmd_inactive);
- KASSERT(actlen >= (int)sizeof(struct uath_cmd_hdr),
- ("short xfer error"));
+ if (actlen < sizeof(struct uath_cmd_hdr)) {
+ device_printf(sc->sc_dev,
+ "%s: short xfer error (actlen %d)\n",
+ __func__, actlen);
+ goto setup;
+ }
+
pc = usbd_xfer_get_frame(xfer, 0);
usbd_copy_out(pc, 0, cmd->buf, actlen);
+
+ hdr = (struct uath_cmd_hdr *)cmd->buf;
+ hdr->len = be32toh(hdr->len);
+ if (hdr->len > (uint32_t)actlen) {
+ device_printf(sc->sc_dev,
+ "%s: truncated xfer (len %u, actlen %d)\n",
+ __func__, hdr->len, actlen);
+ goto setup;
+ }
+
uath_cmdeof(sc, cmd);
case USB_ST_SETUP:
setup:
@@ -2453,6 +2468,8 @@ uath_update_rxstat(struct uath_softc *sc, uint32_t status)
}
}
+CTASSERT(UATH_MIN_RXBUFSZ >= sizeof(struct uath_chunk));
+
static struct mbuf *
uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
struct uath_rx_desc **pdesc)
@@ -2475,13 +2492,24 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
}
chunk = (struct uath_chunk *)data->buf;
- if (chunk->seqnum == 0 && chunk->flags == 0 && chunk->length == 0) {
+ chunklen = be16toh(chunk->length);
+ if (chunk->seqnum == 0 && chunk->flags == 0 && chunklen == 0) {
device_printf(sc->sc_dev, "%s: strange response\n", __func__);
counter_u64_add(ic->ic_ierrors, 1);
UATH_RESET_INTRX(sc);
return (NULL);
}
+ if (chunklen > actlen) {
+ device_printf(sc->sc_dev,
+ "%s: invalid chunk length (len %u > actlen %d)\n",
+ __func__, chunklen, actlen);
+ counter_u64_add(ic->ic_ierrors, 1);
+ /* XXX cleanup? */
+ UATH_RESET_INTRX(sc);
+ return (NULL);
+ }
+
if (chunk->seqnum != sc->sc_intrx_nextnum) {
DPRINTF(sc, UATH_DEBUG_XMIT, "invalid seqnum %d, expected %d\n",
chunk->seqnum, sc->sc_intrx_nextnum);
@@ -2498,9 +2526,19 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
chunk->flags & UATH_CFLAGS_RXMSG)
UATH_STAT_INC(sc, st_multichunk);
- chunklen = be16toh(chunk->length);
- if (chunk->flags & UATH_CFLAGS_FINAL)
+ if (chunk->flags & UATH_CFLAGS_FINAL) {
+ if (chunklen < sizeof(struct uath_rx_desc)) {
+ device_printf(sc->sc_dev,
+ "%s: invalid chunk length %d\n",
+ __func__, chunklen);
+ counter_u64_add(ic->ic_ierrors, 1);
+ if (sc->sc_intrx_head != NULL)
+ m_freem(sc->sc_intrx_head);
+ UATH_RESET_INTRX(sc);
+ return (NULL);
+ }
chunklen -= sizeof(struct uath_rx_desc);
+ }
if (chunklen > 0 &&
(!(chunk->flags & UATH_CFLAGS_FINAL) || !(chunk->seqnum == 0))) {
@@ -2561,6 +2599,19 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
(struct uath_rx_desc *)(((uint8_t *)chunk) +
sizeof(struct uath_chunk) + be16toh(chunk->length) -
sizeof(struct uath_rx_desc));
+ if ((uint8_t *)chunk + actlen - sizeof(struct uath_rx_desc) <
+ (uint8_t *)desc) {
+ device_printf(sc->sc_dev,
+ "%s: wrong Rx descriptor pointer "
+ "(desc %p chunk %p actlen %d)\n",
+ __func__, desc, chunk, actlen);
+ counter_u64_add(ic->ic_ierrors, 1);
+ if (sc->sc_intrx_head != NULL)
+ m_freem(sc->sc_intrx_head);
+ UATH_RESET_INTRX(sc);
+ return (NULL);
+ }
+
*pdesc = desc;
DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
@@ -2588,8 +2639,33 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
/* finalize mbuf */
if (sc->sc_intrx_head == NULL) {
- m->m_pkthdr.len = m->m_len =
- be32toh(desc->framelen) - UATH_RX_DUMMYSIZE;
+ uint32_t framelen;
+
+ if (be32toh(desc->framelen) < UATH_RX_DUMMYSIZE) {
+ device_printf(sc->sc_dev,
+ "%s: framelen too small (%u)\n",
+ __func__, be32toh(desc->framelen));
+ counter_u64_add(ic->ic_ierrors, 1);
+ if (sc->sc_intrx_head != NULL)
+ m_freem(sc->sc_intrx_head);
+ UATH_RESET_INTRX(sc);
+ return (NULL);
+ }
+
+ framelen = be32toh(desc->framelen) - UATH_RX_DUMMYSIZE;
+ if (framelen > actlen - sizeof(struct uath_chunk) ||
+ framelen < sizeof(struct ieee80211_frame_ack)) {
+ device_printf(sc->sc_dev,
+ "%s: wrong frame length (%u, actlen %d)!\n",
+ __func__, framelen, actlen);
+ counter_u64_add(ic->ic_ierrors, 1);
+ if (sc->sc_intrx_head != NULL)
+ m_freem(sc->sc_intrx_head);
+ UATH_RESET_INTRX(sc);
+ return (NULL);
+ }
+
+ m->m_pkthdr.len = m->m_len = framelen;
m->m_data += sizeof(struct uath_chunk);
} else {
mp = sc->sc_intrx_head;