Page MenuHomeFreeBSD

D30499.id90044.diff
No OneTemporary

D30499.id90044.diff

Index: share/man/man4/rtsx.4
===================================================================
--- share/man/man4/rtsx.4
+++ share/man/man4/rtsx.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 24, 2020
+.Dd April 25, 2021
.Dt RTSX 4
.Os
.Sh NAME
@@ -108,12 +108,19 @@
.It
The timeouts experienced during card insert and during I/O are solved in version 1.0g.
.It
-RTS522A on Lenovo P50s and Lenovo T470p, card detection and read-only switch are reversed.
-This is sovled by adding in
+RTS522A on Lenovo T470p, card detection and read-only switch are reversed.
+This is solved by adding in
.Em loader.conf(5) :
.Bd -ragged
.Cd dev.rtsx.0.inversion=1
.Ed
+.Pp
+The driver tries to automate those exceptions.
+If this automation is wrong, it can be avoided by adding in
+.Em loader.conf(5) :
+.Bd -ragged
+.Cd dev.rtsx.0.inversion=0
+.Ed
.It
Mounting a filesystem with write access on a card write protected may involve a kernel crash.
.It
Index: sys/dev/rtsx/rtsx.c
===================================================================
--- sys/dev/rtsx/rtsx.c
+++ sys/dev/rtsx/rtsx.c
@@ -47,6 +47,7 @@
#include <sys/endian.h>
#include <machine/bus.h>
#include <sys/mutex.h>
+#include <sys/malloc.h>
#include <sys/rman.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
@@ -83,11 +84,13 @@
struct resource *rtsx_irq_res; /* bus IRQ resource */
void *rtsx_irq_cookie; /* bus IRQ resource cookie */
struct callout rtsx_timeout_callout; /* callout for timeout */
- int rtsx_timeout; /* interrupt timeout value */
+ int rtsx_timeout1; /* interrupt timeout for setup commands */
+ int rtsx_timeout2; /* interrupt timeout for I/O commands */
void (*rtsx_intr_trans_ok)(struct rtsx_softc *sc);
/* function to call if transfer succeed */
void (*rtsx_intr_trans_ko)(struct rtsx_softc *sc);
/* function to call if transfer fail */
+
struct timeout_task
rtsx_card_insert_task; /* card insert delayed task */
struct task rtsx_card_remove_task; /* card remove task */
@@ -166,25 +169,35 @@
#define RTSX_RTL8411 0x5289
#define RTSX_RTL8411B 0x5287
-#define RTSX_VERSION "2.0c"
+#define RTSX_VERSION "2.0i"
static const struct rtsx_device {
uint16_t vendor_id;
uint16_t device_id;
const char *desc;
} rtsx_devices[] = {
- { RTSX_REALTEK, RTSX_RTS5209, RTSX_VERSION " Realtek RTS5209 PCI MMC/SD Card Reader"},
- { RTSX_REALTEK, RTSX_RTS5227, RTSX_VERSION " Realtek RTS5227 PCI MMC/SD Card Reader"},
- { RTSX_REALTEK, RTSX_RTS5229, RTSX_VERSION " Realtek RTS5229 PCI MMC/SD Card Reader"},
- { RTSX_REALTEK, RTSX_RTS522A, RTSX_VERSION " Realtek RTS522A PCI MMC/SD Card Reader"},
- { RTSX_REALTEK, RTSX_RTS525A, RTSX_VERSION " Realtek RTS525A PCI MMC/SD Card Reader"},
- { RTSX_REALTEK, RTSX_RTS5249, RTSX_VERSION " Realtek RTS5249 PCI MMC/SD Card Reader"},
- { RTSX_REALTEK, RTSX_RTL8402, RTSX_VERSION " Realtek RTL8402 PCI MMC/SD Card Reader"},
- { RTSX_REALTEK, RTSX_RTL8411, RTSX_VERSION " Realtek RTL8411 PCI MMC/SD Card Reader"},
- { RTSX_REALTEK, RTSX_RTL8411B, RTSX_VERSION " Realtek RTL8411B PCI MMC/SD Card Reader"},
+ { RTSX_REALTEK, RTSX_RTS5209, RTSX_VERSION " Realtek RTS5209 PCIe MMC/SD Card Reader"},
+ { RTSX_REALTEK, RTSX_RTS5227, RTSX_VERSION " Realtek RTS5227 PCIe MMC/SD Card Reader"},
+ { RTSX_REALTEK, RTSX_RTS5229, RTSX_VERSION " Realtek RTS5229 PCIe MMC/SD Card Reader"},
+ { RTSX_REALTEK, RTSX_RTS522A, RTSX_VERSION " Realtek RTS522A PCIe MMC/SD Card Reader"},
+ { RTSX_REALTEK, RTSX_RTS525A, RTSX_VERSION " Realtek RTS525A PCIe MMC/SD Card Reader"},
+ { RTSX_REALTEK, RTSX_RTS5249, RTSX_VERSION " Realtek RTS5249 PCIe MMC/SD Card Reader"},
+ { RTSX_REALTEK, RTSX_RTL8402, RTSX_VERSION " Realtek RTL8402 PCIe MMC/SD Card Reader"},
+ { RTSX_REALTEK, RTSX_RTL8411, RTSX_VERSION " Realtek RTL8411 PCIe MMC/SD Card Reader"},
+ { RTSX_REALTEK, RTSX_RTL8411B, RTSX_VERSION " Realtek RTL8411B PCIe MMC/SD Card Reader"},
{ 0, 0, NULL}
};
+/* See `kenv | grep smbios.system` */
+static const struct rtsx_inversion_model {
+ char *maker;
+ char *family;
+ char *product;
+} rtsx_inversion_models[] = {
+ { "LENOVO", "ThinkPad T470p", "20J7S0PM00"},
+ { NULL, NULL, NULL}
+};
+
static int rtsx_dma_alloc(struct rtsx_softc *sc);
static void rtsx_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error);
static void rtsx_dma_free(struct rtsx_softc *sc);
@@ -601,7 +614,7 @@
#ifdef MMCCAM
was_present = sc->rtsx_cam_status;
-#else
+#else /* !MMCCAM */
was_present = sc->rtsx_mmc_dev != NULL;
#endif /* MMCCAM */
is_present = rtsx_is_card_present(sc);
@@ -640,7 +653,7 @@
if (sc->rtsx_cam_status == 0) {
union ccb *ccb;
uint32_t pathid;
-#else
+#else /* !MMCCAM */
if (sc->rtsx_mmc_dev == NULL) {
#endif /* MMCCAM */
if (bootverbose)
@@ -669,7 +682,7 @@
}
RTSX_UNLOCK(sc);
xpt_rescan(ccb);
-#else
+#else /* !MMCCAM */
sc->rtsx_mmc_dev = device_add_child(sc->rtsx_dev, "mmc", -1);
RTSX_UNLOCK(sc);
if (sc->rtsx_mmc_dev == NULL) {
@@ -688,7 +701,7 @@
if (sc->rtsx_cam_status != 0) {
union ccb *ccb;
uint32_t pathid;
-#else
+#else /* !MMCCAM */
if (sc->rtsx_mmc_dev != NULL) {
#endif /* MMCCAM */
if (bootverbose)
@@ -719,7 +732,7 @@
}
RTSX_UNLOCK(sc);
xpt_rescan(ccb);
-#else
+#else /* !MMCCAM */
RTSX_UNLOCK(sc);
if (device_delete_child(sc->rtsx_dev, sc->rtsx_mmc_dev))
device_printf(sc->rtsx_dev, "Detaching MMC bus failed\n");
@@ -984,7 +997,7 @@
RTSX_PHY_REV_CLKREQ_DT_1_0 | RTSX_PHY_REV_STOP_CLKRD |
RTSX_PHY_REV_STOP_CLKWR)))
return (error);
- DELAY(10);
+ DELAY(1000);
if ((error = rtsx_write_phy(sc, RTSX_PHY_BPCR,
RTSX_PHY_BPCR_IBRXSEL | RTSX_PHY_BPCR_IBTXSEL |
RTSX_PHY_BPCR_IB_FILTER | RTSX_PHY_BPCR_CMIRROR_EN)))
@@ -1604,7 +1617,7 @@
RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PARTIAL_PWR_ON);
RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, RTSX_LDO3318_VCC1);
- DELAY(200);
+ DELAY(20000);
/* Full power. */
RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PWR_ON);
@@ -1632,7 +1645,7 @@
RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PARTIAL_PWR_ON);
RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, RTSX_LDO3318_VCC1);
- DELAY(200);
+ DELAY(5000);
/* Full power. */
RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PWR_ON);
@@ -1983,7 +1996,7 @@
status = sc->rtsx_intr_status & mask;
while (status == 0) {
- if (msleep(&sc->rtsx_intr_status, &sc->rtsx_mtx, 0, "rtsxintr", sc->rtsx_timeout) == EWOULDBLOCK) {
+ if (msleep(&sc->rtsx_intr_status, &sc->rtsx_mtx, 0, "rtsxintr", sc->rtsx_timeout1) == EWOULDBLOCK) {
cmd->error = MMC_ERR_TIMEOUT;
return (MMC_ERR_TIMEOUT);
}
@@ -2254,7 +2267,7 @@
sc->rtsx_ccb = NULL;
ccb->ccb_h.status = (req->cmd->error == 0 ? CAM_REQ_CMP : CAM_REQ_CMP_ERR);
xpt_done(ccb);
-#else
+#else /* !MMCCAM */
req->done(req);
#endif /* MMCCAM */
}
@@ -3022,7 +3035,7 @@
if (bootverbose || sc->rtsx_debug)
device_printf(sc->rtsx_dev, "rtsx_cam_set_tran_settings() - vccq: %d\n", ios->vccq);
}
-#endif
+#endif /* __FreeBSD__ > 12 */
if (rtsx_mmcbr_update_ios(sc->rtsx_dev, NULL) == 0)
ccb->ccb_h.status = CAM_REQ_CMP;
else
@@ -3426,6 +3439,7 @@
{
struct rtsx_softc *sc;
struct mmc_command *cmd;
+ int timeout;
int error;
sc = device_get_softc(bus);
@@ -3473,15 +3487,18 @@
if (cmd->data == NULL) {
DELAY(200);
+ timeout = sc->rtsx_timeout1;
error = rtsx_send_req(sc, cmd);
} else if (cmd->data->len <= 512) {
+ timeout = sc->rtsx_timeout2;
error = rtsx_xfer_short(sc, cmd);
} else {
+ timeout = sc->rtsx_timeout2;
error = rtsx_xfer(sc, cmd);
}
end:
if (error == MMC_ERR_NONE) {
- callout_reset(&sc->rtsx_timeout_callout, sc->rtsx_timeout * hz, rtsx_timeout, sc);
+ callout_reset(&sc->rtsx_timeout_callout, timeout * hz, rtsx_timeout, sc);
} else {
rtsx_req_done(sc);
}
@@ -3587,6 +3604,10 @@
int msi_count = 1;
uint32_t sdio_cfg;
int error;
+ char *maker;
+ char *family;
+ char *product;
+ int i;
if (bootverbose)
device_printf(dev, "Attach - Vendor ID: 0x%x - Device ID: 0x%x\n",
@@ -3594,32 +3615,53 @@
sc->rtsx_dev = dev;
sc->rtsx_req = NULL;
- sc->rtsx_timeout = 10;
+ sc->rtsx_timeout1 = 1;
+ sc->rtsx_timeout2 = 10;
sc->rtsx_read_only = 0;
+ sc->rtsx_inversion = 0;
sc->rtsx_force_timing = 0;
sc->rtsx_debug = 0;
sc->rtsx_read_count = 0;
sc->rtsx_write_count = 0;
+ maker = kern_getenv("smbios.system.maker");
+ family = kern_getenv("smbios.system.family");
+ product = kern_getenv("smbios.system.product");
+ for (i = 0; rtsx_inversion_models[i].maker != NULL; i++) {
+ if (strcmp(rtsx_inversion_models[i].maker, maker) == 0 &&
+ strcmp(rtsx_inversion_models[i].family, family) == 0 &&
+ strcmp(rtsx_inversion_models[i].product, product) == 0) {
+ device_printf(dev, "Inversion activated for %s/%s/%s, see BUG in rtsx(4)\n", maker, family, product);
+ device_printf(dev, "If a card is detected without an SD card present,"
+ " add dev.rtsx.0.inversion=0 in loader.conf(5)\n");
+ sc->rtsx_inversion = 1;
+ }
+ }
+
RTSX_LOCK_INIT(sc);
ctx = device_get_sysctl_ctx(dev);
tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
- SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout", CTLFLAG_RW,
- &sc->rtsx_timeout, 0, "Request timeout in seconds");
+ SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout2", CTLFLAG_RW,
+ &sc->rtsx_timeout2, 0, "Request timeout for I/O commands in seconds");
+ SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout1", CTLFLAG_RW,
+ &sc->rtsx_timeout1, 0, "Request timeout for setup commands in seconds");
SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "read_only", CTLFLAG_RD,
&sc->rtsx_read_only, 0, "Card is write protected");
SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "inversion", CTLFLAG_RWTUN,
&sc->rtsx_inversion, 0, "Inversion of card detection and read only status");
SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "force_timing", CTLFLAG_RW,
&sc->rtsx_force_timing, 0, "Force bus_timing_uhs_sdr50");
- SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "debug", CTLFLAG_RW,
+ SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "debug", CTLFLAG_RWTUN,
&sc->rtsx_debug, 0, "Debugging flag");
SYSCTL_ADD_U64(ctx, tree, OID_AUTO, "read_count", CTLFLAG_RD,
&sc->rtsx_read_count, 0, "Count of read operations");
SYSCTL_ADD_U64(ctx, tree, OID_AUTO, "write_count", CTLFLAG_RD,
&sc->rtsx_write_count, 0, "Count of write operations");
+ if (bootverbose || sc->rtsx_debug)
+ device_printf(dev, "We are running with inversion: %d\n", sc->rtsx_inversion);
+
/* Allocate IRQ. */
sc->rtsx_irq_res_id = 0;
if (pci_alloc_msi(dev, &msi_count) == 0)
@@ -3652,6 +3694,15 @@
sc->rtsx_btag = rman_get_bustag(sc->rtsx_res);
sc->rtsx_bhandle = rman_get_bushandle(sc->rtsx_res);
+ TIMEOUT_TASK_INIT(taskqueue_swi_giant, &sc->rtsx_card_insert_task, 0,
+ rtsx_card_task, sc);
+ TASK_INIT(&sc->rtsx_card_remove_task, 0, rtsx_card_task, sc);
+
+ /* Allocate two DMA buffers: a command buffer and a data buffer. */
+ error = rtsx_dma_alloc(sc);
+ if (error)
+ goto destroy_rtsx_irq_res;
+
/* Activate the interrupt. */
error = bus_setup_intr(dev, sc->rtsx_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
NULL, rtsx_intr, sc, &sc->rtsx_irq_cookie);
@@ -3667,17 +3718,6 @@
sc->rtsx_flags |= RTSX_F_SDIO_SUPPORT;
}
- /* Allocate two DMA buffers: a command buffer and a data buffer. */
- error = rtsx_dma_alloc(sc);
- if (error) {
- goto destroy_rtsx_irq;
- }
-
- /* From dwmmc.c. */
- TIMEOUT_TASK_INIT(taskqueue_swi_giant, &sc->rtsx_card_insert_task, 0,
- rtsx_card_task, sc);
- TASK_INIT(&sc->rtsx_card_remove_task, 0, rtsx_card_task, sc);
-
#ifdef MMCCAM
sc->rtsx_ccb = NULL;
sc->rtsx_cam_status = 0;
@@ -3713,13 +3753,16 @@
/*
* Schedule a card detection as we won't get an interrupt
- * if the card is inserted when we attach
+ * if the card is inserted when we attach. We wait a quarter
+ * of a second to allow for a "spontaneous" interrupt which may
+ * change the card presence state. This delay avoid a panic
+ * on some configuration (e.g. Lenovo T540p).
*/
- DELAY(500);
+ DELAY(250000);
if (rtsx_is_card_present(sc))
- device_printf(sc->rtsx_dev, "Card present\n");
+ device_printf(sc->rtsx_dev, "A card is detected\n");
else
- device_printf(sc->rtsx_dev, "Card absent\n");
+ device_printf(sc->rtsx_dev, "No card is detected\n");
rtsx_card_task(sc, 0);
if (bootverbose)
@@ -3732,6 +3775,7 @@
destroy_rtsx_res:
bus_release_resource(dev, SYS_RES_MEMORY, sc->rtsx_res_id,
sc->rtsx_res);
+ rtsx_dma_free(sc);
destroy_rtsx_irq_res:
callout_drain(&sc->rtsx_timeout_callout);
bus_release_resource(dev, SYS_RES_IRQ, sc->rtsx_irq_res_id,
@@ -3833,7 +3877,7 @@
device_printf(dev, "Request in progress: CMD%u, rtsr_intr_status: 0x%08x\n",
sc->rtsx_ccb->mmcio.cmd.opcode, sc->rtsx_intr_status);
}
-#else
+#else /* !MMCCAM */
if (sc->rtsx_req != NULL) {
device_printf(dev, "Request in progress: CMD%u, rtsr_intr_status: 0x%08x\n",
sc->rtsx_req->cmd->opcode, sc->rtsx_intr_status);

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 27, 10:12 PM (1 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28060673
Default Alt Text
D30499.id90044.diff (12 KB)

Event Timeline