Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143171505
D30499.id90044.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D30499.id90044.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D30499: Call taskqueue sooner, adjust some DELAY(), add inversion heuristic
Attached
Detach File
Event Timeline
Log In to Comment