mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
rtsx: Call taskqueue sooner, adjust DELAY(9) calls, add an inversion heuristic
- Some configurations, e.g. HP EliteBook 840 G3, come with a dummy card
in the card slot which is detected as a valid SD card. This added long
timeout at boot time. To alleviate the problem, the default timeout is
reduced to one second during the setup phase. [1]
- Some configurations crash at boot if rtsx(4) is defined in the kernel
config. At boot time, without a card inserted, the driver found that
a card is present and just after that a "spontaneous" interrupt is
generated showing that no card is present. To solve this problem,
DELAY(9) is set to one quarter of a second before checking card presence
during driver attach.
- As advised by adrian, taskqueue and DMA are set up sooner during
the driver attach. A heuristic to try to detect configuration needing
inversion was added.
PR: 255130 [1]
Differential Revision: https://reviews.freebsd.org/D30499
(cherry picked from commit 9d3bc16382)
This commit is contained in:
parent
adfb7f807c
commit
277a326b1e
2 changed files with 99 additions and 46 deletions
|
|
@ -24,7 +24,7 @@
|
|||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 24, 2020
|
||||
.Dd April 25, 2021
|
||||
.Dt RTSX 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -108,12 +108,19 @@ with modifications found in Linux and
|
|||
.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
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
|
|||
#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 rtsx_softc {
|
|||
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_timeout_cmd; /* interrupt timeout for setup commands */
|
||||
int rtsx_timeout_io; /* 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 @@ struct rtsx_softc {
|
|||
#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 @@ rtsx_handle_card_present(struct rtsx_softc *sc)
|
|||
|
||||
#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 @@ rtsx_card_task(void *arg, int pending __unused)
|
|||
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_card_task(void *arg, int pending __unused)
|
|||
}
|
||||
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 @@ rtsx_card_task(void *arg, int pending __unused)
|
|||
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_card_task(void *arg, int pending __unused)
|
|||
}
|
||||
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_init(struct rtsx_softc *sc)
|
|||
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_bus_power_on(struct rtsx_softc *sc)
|
|||
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_bus_power_on(struct rtsx_softc *sc)
|
|||
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 @@ rtsx_sd_tuning_rx_cmd_wait(struct rtsx_softc *sc, struct mmc_command *cmd)
|
|||
|
||||
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_timeout_cmd) == EWOULDBLOCK) {
|
||||
cmd->error = MMC_ERR_TIMEOUT;
|
||||
return (MMC_ERR_TIMEOUT);
|
||||
}
|
||||
|
|
@ -2254,7 +2267,7 @@ rtsx_req_done(struct rtsx_softc *sc)
|
|||
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 */
|
||||
}
|
||||
|
|
@ -2899,6 +2912,7 @@ rtsx_cam_action(struct cam_sim *sim, union ccb *ccb)
|
|||
cpi->ccb_h.status = CAM_REQ_CMP;
|
||||
break;
|
||||
}
|
||||
case XPT_MMC_GET_TRAN_SETTINGS:
|
||||
case XPT_GET_TRAN_SETTINGS:
|
||||
{
|
||||
struct ccb_trans_settings *cts = &ccb->cts;
|
||||
|
|
@ -2923,6 +2937,7 @@ rtsx_cam_action(struct cam_sim *sim, union ccb *ccb)
|
|||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
break;
|
||||
}
|
||||
case XPT_MMC_SET_TRAN_SETTINGS:
|
||||
case XPT_SET_TRAN_SETTINGS:
|
||||
if (bootverbose || sc->rtsx_debug)
|
||||
device_printf(sc->rtsx_dev, "rtsx_cam_action() - got XPT_SET_TRAN_SETTINGS\n");
|
||||
|
|
@ -3022,7 +3037,7 @@ rtsx_cam_set_tran_settings(struct rtsx_softc *sc, union ccb *ccb)
|
|||
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 +3441,7 @@ rtsx_mmcbr_request(device_t bus, device_t child __unused, struct mmc_request *re
|
|||
{
|
||||
struct rtsx_softc *sc;
|
||||
struct mmc_command *cmd;
|
||||
int timeout;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(bus);
|
||||
|
|
@ -3473,15 +3489,18 @@ rtsx_mmcbr_request(device_t bus, device_t child __unused, struct mmc_request *re
|
|||
|
||||
if (cmd->data == NULL) {
|
||||
DELAY(200);
|
||||
timeout = sc->rtsx_timeout_cmd;
|
||||
error = rtsx_send_req(sc, cmd);
|
||||
} else if (cmd->data->len <= 512) {
|
||||
timeout = sc->rtsx_timeout_io;
|
||||
error = rtsx_xfer_short(sc, cmd);
|
||||
} else {
|
||||
timeout = sc->rtsx_timeout_io;
|
||||
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 +3606,10 @@ rtsx_attach(device_t dev)
|
|||
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 +3617,53 @@ rtsx_attach(device_t dev)
|
|||
|
||||
sc->rtsx_dev = dev;
|
||||
sc->rtsx_req = NULL;
|
||||
sc->rtsx_timeout = 10;
|
||||
sc->rtsx_timeout_cmd = 1;
|
||||
sc->rtsx_timeout_io = 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, "timeout_io", CTLFLAG_RW,
|
||||
&sc->rtsx_timeout_io, 0, "Request timeout for I/O commands in seconds");
|
||||
SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "timeout_cmd", CTLFLAG_RW,
|
||||
&sc->rtsx_timeout_cmd, 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 +3696,15 @@ rtsx_attach(device_t dev)
|
|||
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 +3720,6 @@ rtsx_attach(device_t dev)
|
|||
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 +3755,16 @@ rtsx_attach(device_t dev)
|
|||
|
||||
/*
|
||||
* 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 +3777,7 @@ rtsx_attach(device_t dev)
|
|||
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 +3879,7 @@ rtsx_suspend(device_t dev)
|
|||
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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue