Changeset View
Standalone View
sys/dev/rtsx/rtsx.c
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#include <sys/systm.h> /* For FreeBSD 11 */ | #include <sys/systm.h> /* For FreeBSD 11 */ | ||||
#include <sys/types.h> /* For FreeBSD 11 */ | #include <sys/types.h> /* For FreeBSD 11 */ | ||||
#include <sys/errno.h> | #include <sys/errno.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/endian.h> | #include <sys/endian.h> | ||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/malloc.h> | |||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/taskqueue.h> | #include <sys/taskqueue.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <dev/pci/pcivar.h> | #include <dev/pci/pcivar.h> | ||||
#include <dev/pci/pcireg.h> | #include <dev/pci/pcireg.h> | ||||
#include <dev/mmc/bridge.h> | #include <dev/mmc/bridge.h> | ||||
#include <dev/mmc/mmcreg.h> | #include <dev/mmc/mmcreg.h> | ||||
Show All 20 Lines | struct rtsx_softc { | ||||
uint16_t rtsx_device_id; /* device ID */ | uint16_t rtsx_device_id; /* device ID */ | ||||
device_t rtsx_mmc_dev; /* device of mmc bus */ | device_t rtsx_mmc_dev; /* device of mmc bus */ | ||||
uint32_t rtsx_intr_enabled; /* enabled interrupts */ | uint32_t rtsx_intr_enabled; /* enabled interrupts */ | ||||
uint32_t rtsx_intr_status; /* soft interrupt status */ | uint32_t rtsx_intr_status; /* soft interrupt status */ | ||||
int rtsx_irq_res_id; /* bus IRQ resource id */ | int rtsx_irq_res_id; /* bus IRQ resource id */ | ||||
struct resource *rtsx_irq_res; /* bus IRQ resource */ | struct resource *rtsx_irq_res; /* bus IRQ resource */ | ||||
void *rtsx_irq_cookie; /* bus IRQ resource cookie */ | void *rtsx_irq_cookie; /* bus IRQ resource cookie */ | ||||
struct callout rtsx_timeout_callout; /* callout for timeout */ | 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); | void (*rtsx_intr_trans_ok)(struct rtsx_softc *sc); | ||||
/* function to call if transfer succeed */ | /* function to call if transfer succeed */ | ||||
void (*rtsx_intr_trans_ko)(struct rtsx_softc *sc); | void (*rtsx_intr_trans_ko)(struct rtsx_softc *sc); | ||||
/* function to call if transfer fail */ | /* function to call if transfer fail */ | ||||
struct timeout_task | struct timeout_task | ||||
rtsx_card_insert_task; /* card insert delayed task */ | rtsx_card_insert_task; /* card insert delayed task */ | ||||
struct task rtsx_card_remove_task; /* card remove task */ | struct task rtsx_card_remove_task; /* card remove task */ | ||||
int rtsx_res_id; /* bus memory resource id */ | int rtsx_res_id; /* bus memory resource id */ | ||||
struct resource *rtsx_res; /* bus memory resource */ | struct resource *rtsx_res; /* bus memory resource */ | ||||
int rtsx_res_type; /* bus memory resource type */ | int rtsx_res_type; /* bus memory resource type */ | ||||
bus_space_tag_t rtsx_btag; /* host register set tag */ | bus_space_tag_t rtsx_btag; /* host register set tag */ | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
#define RTSX_RTS5229 0x5229 | #define RTSX_RTS5229 0x5229 | ||||
#define RTSX_RTS522A 0x522a | #define RTSX_RTS522A 0x522a | ||||
#define RTSX_RTS525A 0x525a | #define RTSX_RTS525A 0x525a | ||||
#define RTSX_RTS5249 0x5249 | #define RTSX_RTS5249 0x5249 | ||||
#define RTSX_RTL8402 0x5286 | #define RTSX_RTL8402 0x5286 | ||||
#define RTSX_RTL8411 0x5289 | #define RTSX_RTL8411 0x5289 | ||||
#define RTSX_RTL8411B 0x5287 | #define RTSX_RTL8411B 0x5287 | ||||
#define RTSX_VERSION "2.0c" | #define RTSX_VERSION "2.0i" | ||||
static const struct rtsx_device { | static const struct rtsx_device { | ||||
uint16_t vendor_id; | uint16_t vendor_id; | ||||
uint16_t device_id; | uint16_t device_id; | ||||
const char *desc; | const char *desc; | ||||
} rtsx_devices[] = { | } rtsx_devices[] = { | ||||
{ RTSX_REALTEK, RTSX_RTS5209, RTSX_VERSION " Realtek RTS5209 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 PCI 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 PCI 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 PCI 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 PCI 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 PCI 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 PCI 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 PCI 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 PCI MMC/SD Card Reader"}, | { RTSX_REALTEK, RTSX_RTL8411B, RTSX_VERSION " Realtek RTL8411B PCIe MMC/SD Card Reader"}, | ||||
{ 0, 0, NULL} | { 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 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_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error); | ||||
static void rtsx_dma_free(struct rtsx_softc *sc); | static void rtsx_dma_free(struct rtsx_softc *sc); | ||||
static void rtsx_intr(void *arg); | static void rtsx_intr(void *arg); | ||||
static void rtsx_handle_card_present(struct rtsx_softc *sc); | static void rtsx_handle_card_present(struct rtsx_softc *sc); | ||||
static void rtsx_card_task(void *arg, int pending __unused); | static void rtsx_card_task(void *arg, int pending __unused); | ||||
static bool rtsx_is_card_present(struct rtsx_softc *sc); | static bool rtsx_is_card_present(struct rtsx_softc *sc); | ||||
static int rtsx_init(struct rtsx_softc *sc); | static int rtsx_init(struct rtsx_softc *sc); | ||||
▲ Show 20 Lines • Show All 400 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
rtsx_handle_card_present(struct rtsx_softc *sc) | rtsx_handle_card_present(struct rtsx_softc *sc) | ||||
{ | { | ||||
bool was_present; | bool was_present; | ||||
bool is_present; | bool is_present; | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
was_present = sc->rtsx_cam_status; | was_present = sc->rtsx_cam_status; | ||||
#else | #else /* !MMCCAM */ | ||||
was_present = sc->rtsx_mmc_dev != NULL; | was_present = sc->rtsx_mmc_dev != NULL; | ||||
#endif /* MMCCAM */ | #endif /* MMCCAM */ | ||||
is_present = rtsx_is_card_present(sc); | is_present = rtsx_is_card_present(sc); | ||||
if (is_present) | if (is_present) | ||||
device_printf(sc->rtsx_dev, "Card present\n"); | device_printf(sc->rtsx_dev, "Card present\n"); | ||||
else | else | ||||
device_printf(sc->rtsx_dev, "Card absent\n"); | device_printf(sc->rtsx_dev, "Card absent\n"); | ||||
Show All 22 Lines | rtsx_card_task(void *arg, int pending __unused) | ||||
if (rtsx_is_card_present(sc)) { | if (rtsx_is_card_present(sc)) { | ||||
sc->rtsx_flags |= RTSX_F_CARD_PRESENT; | sc->rtsx_flags |= RTSX_F_CARD_PRESENT; | ||||
/* Card is present, attach if necessary. */ | /* Card is present, attach if necessary. */ | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
if (sc->rtsx_cam_status == 0) { | if (sc->rtsx_cam_status == 0) { | ||||
union ccb *ccb; | union ccb *ccb; | ||||
uint32_t pathid; | uint32_t pathid; | ||||
#else | #else /* !MMCCAM */ | ||||
if (sc->rtsx_mmc_dev == NULL) { | if (sc->rtsx_mmc_dev == NULL) { | ||||
#endif /* MMCCAM */ | #endif /* MMCCAM */ | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(sc->rtsx_dev, "Card inserted\n"); | device_printf(sc->rtsx_dev, "Card inserted\n"); | ||||
sc->rtsx_read_count = sc->rtsx_write_count = 0; | sc->rtsx_read_count = sc->rtsx_write_count = 0; | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
sc->rtsx_cam_status = 1; | sc->rtsx_cam_status = 1; | ||||
Show All 12 Lines | #ifdef MMCCAM | ||||
/* target */ 0, /* lun */ 0) != CAM_REQ_CMP) { | /* target */ 0, /* lun */ 0) != CAM_REQ_CMP) { | ||||
device_printf(sc->rtsx_dev, "Unable to create path for rescan\n"); | device_printf(sc->rtsx_dev, "Unable to create path for rescan\n"); | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
xpt_free_ccb(ccb); | xpt_free_ccb(ccb); | ||||
return; | return; | ||||
} | } | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
xpt_rescan(ccb); | xpt_rescan(ccb); | ||||
#else | #else /* !MMCCAM */ | ||||
sc->rtsx_mmc_dev = device_add_child(sc->rtsx_dev, "mmc", -1); | sc->rtsx_mmc_dev = device_add_child(sc->rtsx_dev, "mmc", -1); | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
if (sc->rtsx_mmc_dev == NULL) { | if (sc->rtsx_mmc_dev == NULL) { | ||||
device_printf(sc->rtsx_dev, "Adding MMC bus failed\n"); | device_printf(sc->rtsx_dev, "Adding MMC bus failed\n"); | ||||
} else { | } else { | ||||
device_set_ivars(sc->rtsx_mmc_dev, sc); | device_set_ivars(sc->rtsx_mmc_dev, sc); | ||||
device_probe_and_attach(sc->rtsx_mmc_dev); | device_probe_and_attach(sc->rtsx_mmc_dev); | ||||
} | } | ||||
#endif /* MMCCAM */ | #endif /* MMCCAM */ | ||||
} else | } else | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
} else { | } else { | ||||
sc->rtsx_flags &= ~RTSX_F_CARD_PRESENT; | sc->rtsx_flags &= ~RTSX_F_CARD_PRESENT; | ||||
/* Card isn't present, detach if necessary. */ | /* Card isn't present, detach if necessary. */ | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
if (sc->rtsx_cam_status != 0) { | if (sc->rtsx_cam_status != 0) { | ||||
union ccb *ccb; | union ccb *ccb; | ||||
uint32_t pathid; | uint32_t pathid; | ||||
#else | #else /* !MMCCAM */ | ||||
if (sc->rtsx_mmc_dev != NULL) { | if (sc->rtsx_mmc_dev != NULL) { | ||||
#endif /* MMCCAM */ | #endif /* MMCCAM */ | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(sc->rtsx_dev, "Card removed\n"); | device_printf(sc->rtsx_dev, "Card removed\n"); | ||||
if (sc->rtsx_debug) | if (sc->rtsx_debug) | ||||
device_printf(sc->rtsx_dev, "Read count: %" PRIu64 ", write count: %" PRIu64 "\n", | device_printf(sc->rtsx_dev, "Read count: %" PRIu64 ", write count: %" PRIu64 "\n", | ||||
sc->rtsx_read_count, sc->rtsx_write_count); | sc->rtsx_read_count, sc->rtsx_write_count); | ||||
Show All 14 Lines | #ifdef MMCCAM | ||||
/* target */ 0, /* lun */ 0) != CAM_REQ_CMP) { | /* target */ 0, /* lun */ 0) != CAM_REQ_CMP) { | ||||
device_printf(sc->rtsx_dev, "Unable to create path for rescan\n"); | device_printf(sc->rtsx_dev, "Unable to create path for rescan\n"); | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
xpt_free_ccb(ccb); | xpt_free_ccb(ccb); | ||||
return; | return; | ||||
} | } | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
xpt_rescan(ccb); | xpt_rescan(ccb); | ||||
#else | #else /* !MMCCAM */ | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
if (device_delete_child(sc->rtsx_dev, sc->rtsx_mmc_dev)) | if (device_delete_child(sc->rtsx_dev, sc->rtsx_mmc_dev)) | ||||
device_printf(sc->rtsx_dev, "Detaching MMC bus failed\n"); | device_printf(sc->rtsx_dev, "Detaching MMC bus failed\n"); | ||||
sc->rtsx_mmc_dev = NULL; | sc->rtsx_mmc_dev = NULL; | ||||
#endif /* MMCCAM */ | #endif /* MMCCAM */ | ||||
} else | } else | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 248 Lines • ▼ Show 20 Lines | case RTSX_RTS5249: | ||||
RTSX_CLR(sc, RTSX_PM_CTRL3, RTSX_D3_DELINK_MODE_EN); | RTSX_CLR(sc, RTSX_PM_CTRL3, RTSX_D3_DELINK_MODE_EN); | ||||
if ((error = rtsx_write_phy(sc, RTSX_PHY_REV, | if ((error = rtsx_write_phy(sc, RTSX_PHY_REV, | ||||
RTSX_PHY_REV_RESV | RTSX_PHY_REV_RXIDLE_LATCHED | | RTSX_PHY_REV_RESV | RTSX_PHY_REV_RXIDLE_LATCHED | | ||||
RTSX_PHY_REV_P1_EN | RTSX_PHY_REV_RXIDLE_EN | | RTSX_PHY_REV_P1_EN | RTSX_PHY_REV_RXIDLE_EN | | ||||
RTSX_PHY_REV_CLKREQ_TX_EN | RTSX_PHY_REV_RX_PWST | | RTSX_PHY_REV_CLKREQ_TX_EN | RTSX_PHY_REV_RX_PWST | | ||||
RTSX_PHY_REV_CLKREQ_DT_1_0 | RTSX_PHY_REV_STOP_CLKRD | | RTSX_PHY_REV_CLKREQ_DT_1_0 | RTSX_PHY_REV_STOP_CLKRD | | ||||
RTSX_PHY_REV_STOP_CLKWR))) | RTSX_PHY_REV_STOP_CLKWR))) | ||||
return (error); | return (error); | ||||
DELAY(10); | DELAY(1000); | ||||
if ((error = rtsx_write_phy(sc, RTSX_PHY_BPCR, | if ((error = rtsx_write_phy(sc, RTSX_PHY_BPCR, | ||||
RTSX_PHY_BPCR_IBRXSEL | RTSX_PHY_BPCR_IBTXSEL | | RTSX_PHY_BPCR_IBRXSEL | RTSX_PHY_BPCR_IBTXSEL | | ||||
RTSX_PHY_BPCR_IB_FILTER | RTSX_PHY_BPCR_CMIRROR_EN))) | RTSX_PHY_BPCR_IB_FILTER | RTSX_PHY_BPCR_CMIRROR_EN))) | ||||
return (error); | return (error); | ||||
if ((error = rtsx_write_phy(sc, RTSX_PHY_PCR, | if ((error = rtsx_write_phy(sc, RTSX_PHY_PCR, | ||||
RTSX_PHY_PCR_FORCE_CODE | RTSX_PHY_PCR_OOBS_CALI_50 | | RTSX_PHY_PCR_FORCE_CODE | RTSX_PHY_PCR_OOBS_CALI_50 | | ||||
RTSX_PHY_PCR_OOBS_VCM_08 | RTSX_PHY_PCR_OOBS_SEN_90 | | RTSX_PHY_PCR_OOBS_VCM_08 | RTSX_PHY_PCR_OOBS_SEN_90 | | ||||
RTSX_PHY_PCR_RSSI_EN | RTSX_PHY_PCR_RX10K))) | RTSX_PHY_PCR_RSSI_EN | RTSX_PHY_PCR_RX10K))) | ||||
▲ Show 20 Lines • Show All 603 Lines • ▼ Show 20 Lines | case RTSX_RTS5209: | ||||
RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, RTSX_LDO3318_ON); | RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, RTSX_LDO3318_ON); | ||||
break; | break; | ||||
case RTSX_RTS5227: | case RTSX_RTS5227: | ||||
case RTSX_RTS522A: | case RTSX_RTS522A: | ||||
/* Partial power. */ | /* Partial power. */ | ||||
RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PARTIAL_PWR_ON); | 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); | RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, RTSX_LDO3318_VCC1); | ||||
DELAY(200); | DELAY(20000); | ||||
/* Full power. */ | /* Full power. */ | ||||
RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PWR_ON); | RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PWR_ON); | ||||
RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, | RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, | ||||
RTSX_LDO3318_VCC1 | RTSX_LDO3318_VCC2); | RTSX_LDO3318_VCC1 | RTSX_LDO3318_VCC2); | ||||
RTSX_BITOP(sc, RTSX_CARD_OE, RTSX_SD_OUTPUT_EN, RTSX_SD_OUTPUT_EN); | RTSX_BITOP(sc, RTSX_CARD_OE, RTSX_SD_OUTPUT_EN, RTSX_SD_OUTPUT_EN); | ||||
RTSX_BITOP(sc, RTSX_CARD_OE, RTSX_MS_OUTPUT_EN, RTSX_MS_OUTPUT_EN); | RTSX_BITOP(sc, RTSX_CARD_OE, RTSX_MS_OUTPUT_EN, RTSX_MS_OUTPUT_EN); | ||||
break; | break; | ||||
Show All 11 Lines | case RTSX_RTS5229: | ||||
break; | break; | ||||
case RTSX_RTS525A: | case RTSX_RTS525A: | ||||
RTSX_BITOP(sc, RTSX_LDO_VCC_CFG1, RTSX_LDO_VCC_TUNE_MASK, RTSX_LDO_VCC_3V3); | RTSX_BITOP(sc, RTSX_LDO_VCC_CFG1, RTSX_LDO_VCC_TUNE_MASK, RTSX_LDO_VCC_3V3); | ||||
case RTSX_RTS5249: | case RTSX_RTS5249: | ||||
/* Partial power. */ | /* Partial power. */ | ||||
RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PARTIAL_PWR_ON); | 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); | RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, RTSX_LDO3318_VCC1); | ||||
DELAY(200); | DELAY(5000); | ||||
/* Full power. */ | /* Full power. */ | ||||
RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PWR_ON); | RTSX_BITOP(sc, RTSX_CARD_PWR_CTL, RTSX_SD_PWR_MASK, RTSX_SD_PWR_ON); | ||||
RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, | RTSX_BITOP(sc, RTSX_PWR_GATE_CTRL, RTSX_LDO3318_PWR_MASK, | ||||
RTSX_LDO3318_VCC1 | RTSX_LDO3318_VCC2); | RTSX_LDO3318_VCC1 | RTSX_LDO3318_VCC2); | ||||
break; | break; | ||||
case RTSX_RTL8402: | case RTSX_RTL8402: | ||||
case RTSX_RTL8411: | case RTSX_RTL8411: | ||||
▲ Show 20 Lines • Show All 334 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
rtsx_sd_tuning_rx_cmd_wait(struct rtsx_softc *sc, struct mmc_command *cmd) | rtsx_sd_tuning_rx_cmd_wait(struct rtsx_softc *sc, struct mmc_command *cmd) | ||||
{ | { | ||||
int status; | int status; | ||||
int mask = RTSX_TRANS_OK_INT | RTSX_TRANS_FAIL_INT; | int mask = RTSX_TRANS_OK_INT | RTSX_TRANS_FAIL_INT; | ||||
status = sc->rtsx_intr_status & mask; | status = sc->rtsx_intr_status & mask; | ||||
while (status == 0) { | 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; | cmd->error = MMC_ERR_TIMEOUT; | ||||
return (MMC_ERR_TIMEOUT); | return (MMC_ERR_TIMEOUT); | ||||
} | } | ||||
status = sc->rtsx_intr_status & mask; | status = sc->rtsx_intr_status & mask; | ||||
} | } | ||||
return (cmd->error); | return (cmd->error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | #endif /* MMCCAM */ | ||||
} | } | ||||
callout_stop(&sc->rtsx_timeout_callout); | callout_stop(&sc->rtsx_timeout_callout); | ||||
sc->rtsx_req = NULL; | sc->rtsx_req = NULL; | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
ccb = sc->rtsx_ccb; | ccb = sc->rtsx_ccb; | ||||
sc->rtsx_ccb = NULL; | sc->rtsx_ccb = NULL; | ||||
ccb->ccb_h.status = (req->cmd->error == 0 ? CAM_REQ_CMP : CAM_REQ_CMP_ERR); | ccb->ccb_h.status = (req->cmd->error == 0 ? CAM_REQ_CMP : CAM_REQ_CMP_ERR); | ||||
xpt_done(ccb); | xpt_done(ccb); | ||||
#else | #else /* !MMCCAM */ | ||||
req->done(req); | req->done(req); | ||||
#endif /* MMCCAM */ | #endif /* MMCCAM */ | ||||
} | } | ||||
/* | /* | ||||
* Send request. | * Send request. | ||||
*/ | */ | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 751 Lines • ▼ Show 20 Lines | rtsx_cam_set_tran_settings(struct rtsx_softc *sc, union ccb *ccb) | ||||
} | } | ||||
#if __FreeBSD__ > 12 | #if __FreeBSD__ > 12 | ||||
if (cts->ios_valid & MMC_VCCQ) { | if (cts->ios_valid & MMC_VCCQ) { | ||||
ios->vccq = new_ios->vccq; | ios->vccq = new_ios->vccq; | ||||
sc->rtsx_ios_vccq = -1; /* To be updated by rtsx_mmcbr_update_ios(). */ | sc->rtsx_ios_vccq = -1; /* To be updated by rtsx_mmcbr_update_ios(). */ | ||||
if (bootverbose || sc->rtsx_debug) | if (bootverbose || sc->rtsx_debug) | ||||
device_printf(sc->rtsx_dev, "rtsx_cam_set_tran_settings() - vccq: %d\n", ios->vccq); | 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) | if (rtsx_mmcbr_update_ios(sc->rtsx_dev, NULL) == 0) | ||||
ccb->ccb_h.status = CAM_REQ_CMP; | ccb->ccb_h.status = CAM_REQ_CMP; | ||||
else | else | ||||
ccb->ccb_h.status = CAM_REQ_CMP_ERR; | ccb->ccb_h.status = CAM_REQ_CMP_ERR; | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 387 Lines • ▼ Show 20 Lines | rtsx_mmcbr_retune(device_t bus, device_t child __unused, bool reset __unused) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
rtsx_mmcbr_request(device_t bus, device_t child __unused, struct mmc_request *req) | rtsx_mmcbr_request(device_t bus, device_t child __unused, struct mmc_request *req) | ||||
{ | { | ||||
struct rtsx_softc *sc; | struct rtsx_softc *sc; | ||||
struct mmc_command *cmd; | struct mmc_command *cmd; | ||||
int timeout; | |||||
int error; | int error; | ||||
sc = device_get_softc(bus); | sc = device_get_softc(bus); | ||||
RTSX_LOCK(sc); | RTSX_LOCK(sc); | ||||
if (sc->rtsx_req != NULL) { | if (sc->rtsx_req != NULL) { | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
return (EBUSY); | return (EBUSY); | ||||
Show All 31 Lines | rtsx_mmcbr_request(device_t bus, device_t child __unused, struct mmc_request *req) | ||||
} | } | ||||
/* Select SD card. */ | /* Select SD card. */ | ||||
RTSX_BITOP(sc, RTSX_CARD_SELECT, 0x07, RTSX_SD_MOD_SEL); | RTSX_BITOP(sc, RTSX_CARD_SELECT, 0x07, RTSX_SD_MOD_SEL); | ||||
RTSX_BITOP(sc, RTSX_CARD_SHARE_MODE, RTSX_CARD_SHARE_MASK, RTSX_CARD_SHARE_48_SD); | RTSX_BITOP(sc, RTSX_CARD_SHARE_MODE, RTSX_CARD_SHARE_MASK, RTSX_CARD_SHARE_48_SD); | ||||
if (cmd->data == NULL) { | if (cmd->data == NULL) { | ||||
DELAY(200); | DELAY(200); | ||||
timeout = sc->rtsx_timeout1; | |||||
error = rtsx_send_req(sc, cmd); | error = rtsx_send_req(sc, cmd); | ||||
} else if (cmd->data->len <= 512) { | } else if (cmd->data->len <= 512) { | ||||
timeout = sc->rtsx_timeout2; | |||||
error = rtsx_xfer_short(sc, cmd); | error = rtsx_xfer_short(sc, cmd); | ||||
} else { | } else { | ||||
timeout = sc->rtsx_timeout2; | |||||
error = rtsx_xfer(sc, cmd); | error = rtsx_xfer(sc, cmd); | ||||
} | } | ||||
end: | end: | ||||
if (error == MMC_ERR_NONE) { | 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 { | } else { | ||||
rtsx_req_done(sc); | rtsx_req_done(sc); | ||||
} | } | ||||
RTSX_UNLOCK(sc); | RTSX_UNLOCK(sc); | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | |||||
rtsx_attach(device_t dev) | rtsx_attach(device_t dev) | ||||
{ | { | ||||
struct rtsx_softc *sc = device_get_softc(dev); | struct rtsx_softc *sc = device_get_softc(dev); | ||||
struct sysctl_ctx_list *ctx; | struct sysctl_ctx_list *ctx; | ||||
struct sysctl_oid_list *tree; | struct sysctl_oid_list *tree; | ||||
int msi_count = 1; | int msi_count = 1; | ||||
uint32_t sdio_cfg; | uint32_t sdio_cfg; | ||||
int error; | int error; | ||||
char *maker; | |||||
char *family; | |||||
char *product; | |||||
int i; | |||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(dev, "Attach - Vendor ID: 0x%x - Device ID: 0x%x\n", | device_printf(dev, "Attach - Vendor ID: 0x%x - Device ID: 0x%x\n", | ||||
pci_get_vendor(dev), pci_get_device(dev)); | pci_get_vendor(dev), pci_get_device(dev)); | ||||
sc->rtsx_dev = dev; | sc->rtsx_dev = dev; | ||||
sc->rtsx_req = NULL; | sc->rtsx_req = NULL; | ||||
sc->rtsx_timeout = 10; | sc->rtsx_timeout1 = 1; | ||||
sc->rtsx_timeout2 = 10; | |||||
sc->rtsx_read_only = 0; | sc->rtsx_read_only = 0; | ||||
sc->rtsx_inversion = 0; | |||||
sc->rtsx_force_timing = 0; | sc->rtsx_force_timing = 0; | ||||
sc->rtsx_debug = 0; | sc->rtsx_debug = 0; | ||||
sc->rtsx_read_count = 0; | sc->rtsx_read_count = 0; | ||||
sc->rtsx_write_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); | RTSX_LOCK_INIT(sc); | ||||
ctx = device_get_sysctl_ctx(dev); | ctx = device_get_sysctl_ctx(dev); | ||||
tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); | tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); | ||||
SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout", CTLFLAG_RW, | SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout2", CTLFLAG_RW, | ||||
&sc->rtsx_timeout, 0, "Request timeout in seconds"); | &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"); | |||||
jkim: Can you please swap the order of timeout1 and timeout2? | |||||
hlh_restart.beAuthorUnsubmitted Done Inline ActionsI use this order to have timeout1 before timeout2 in If this seems not appropriate I will switch them. hlh_restart.be: I use this order to have timeout1 before timeout2 in
sysctl dev.rtsx wich can be seen by the… | |||||
jkimUnsubmitted Not Done Inline ActionsSo, you did it to make it easier to read from user point of view? If so, please rename them to something more descriptive, e.g., timeout_io, timeout_cmd. jkim: So, you did it to make it easier to read from user point of view? If so, please rename them to… | |||||
SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "read_only", CTLFLAG_RD, | SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "read_only", CTLFLAG_RD, | ||||
&sc->rtsx_read_only, 0, "Card is write protected"); | &sc->rtsx_read_only, 0, "Card is write protected"); | ||||
SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "inversion", CTLFLAG_RWTUN, | SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "inversion", CTLFLAG_RWTUN, | ||||
&sc->rtsx_inversion, 0, "Inversion of card detection and read only status"); | &sc->rtsx_inversion, 0, "Inversion of card detection and read only status"); | ||||
SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "force_timing", CTLFLAG_RW, | SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "force_timing", CTLFLAG_RW, | ||||
&sc->rtsx_force_timing, 0, "Force bus_timing_uhs_sdr50"); | &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_RW, | ||||
&sc->rtsx_debug, 0, "Debugging flag"); | &sc->rtsx_debug, 0, "Debugging flag"); | ||||
SYSCTL_ADD_U64(ctx, tree, OID_AUTO, "read_count", CTLFLAG_RD, | SYSCTL_ADD_U64(ctx, tree, OID_AUTO, "read_count", CTLFLAG_RD, | ||||
&sc->rtsx_read_count, 0, "Count of read operations"); | &sc->rtsx_read_count, 0, "Count of read operations"); | ||||
SYSCTL_ADD_U64(ctx, tree, OID_AUTO, "write_count", CTLFLAG_RD, | SYSCTL_ADD_U64(ctx, tree, OID_AUTO, "write_count", CTLFLAG_RD, | ||||
&sc->rtsx_write_count, 0, "Count of write operations"); | &sc->rtsx_write_count, 0, "Count of write operations"); | ||||
device_printf(dev, "We are running with inversion: %d\n", sc->rtsx_inversion); | |||||
jkimUnsubmitted Done Inline ActionsMaybe you should hide it under bootverbose or rtsx_debug? jkim: Maybe you should hide it under bootverbose or rtsx_debug? | |||||
/* Allocate IRQ. */ | /* Allocate IRQ. */ | ||||
sc->rtsx_irq_res_id = 0; | sc->rtsx_irq_res_id = 0; | ||||
if (pci_alloc_msi(dev, &msi_count) == 0) | if (pci_alloc_msi(dev, &msi_count) == 0) | ||||
sc->rtsx_irq_res_id = 1; | sc->rtsx_irq_res_id = 1; | ||||
sc->rtsx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->rtsx_irq_res_id, | sc->rtsx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->rtsx_irq_res_id, | ||||
RF_ACTIVE | (sc->rtsx_irq_res_id != 0 ? 0 : RF_SHAREABLE)); | RF_ACTIVE | (sc->rtsx_irq_res_id != 0 ? 0 : RF_SHAREABLE)); | ||||
if (sc->rtsx_irq_res == NULL) { | if (sc->rtsx_irq_res == NULL) { | ||||
device_printf(dev, "Can't allocate IRQ resources for %d\n", sc->rtsx_irq_res_id); | device_printf(dev, "Can't allocate IRQ resources for %d\n", sc->rtsx_irq_res_id); | ||||
Show All 16 Lines | rtsx_attach(device_t dev) | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(dev, "rtsx_irq_res_id: %d, rtsx_res_id: %d\n", | device_printf(dev, "rtsx_irq_res_id: %d, rtsx_res_id: %d\n", | ||||
sc->rtsx_irq_res_id, sc->rtsx_res_id); | sc->rtsx_irq_res_id, sc->rtsx_res_id); | ||||
sc->rtsx_btag = rman_get_bustag(sc->rtsx_res); | sc->rtsx_btag = rman_get_bustag(sc->rtsx_res); | ||||
sc->rtsx_bhandle = rman_get_bushandle(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; | |||||
} | |||||
jkimUnsubmitted Done Inline ActionsThe braces look too excessive for the simple goto statement, i.e., if (error) goto destroy_rtsx_irq_res; jkim: The braces look too excessive for the simple goto statement, i.e.,
```
if (error)… | |||||
/* Activate the interrupt. */ | /* Activate the interrupt. */ | ||||
error = bus_setup_intr(dev, sc->rtsx_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, | error = bus_setup_intr(dev, sc->rtsx_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, | ||||
NULL, rtsx_intr, sc, &sc->rtsx_irq_cookie); | NULL, rtsx_intr, sc, &sc->rtsx_irq_cookie); | ||||
if (error) { | if (error) { | ||||
device_printf(dev, "Can't set up irq [0x%x]!\n", error); | device_printf(dev, "Can't set up irq [0x%x]!\n", error); | ||||
goto destroy_rtsx_res; | goto destroy_rtsx_res; | ||||
} | } | ||||
pci_enable_busmaster(dev); | pci_enable_busmaster(dev); | ||||
if (rtsx_read_cfg(sc, 0, RTSX_SDIOCFG_REG, &sdio_cfg) == 0) { | if (rtsx_read_cfg(sc, 0, RTSX_SDIOCFG_REG, &sdio_cfg) == 0) { | ||||
if ((sdio_cfg & RTSX_SDIOCFG_SDIO_ONLY) || | if ((sdio_cfg & RTSX_SDIOCFG_SDIO_ONLY) || | ||||
(sdio_cfg & RTSX_SDIOCFG_HAVE_SDIO)) | (sdio_cfg & RTSX_SDIOCFG_HAVE_SDIO)) | ||||
sc->rtsx_flags |= RTSX_F_SDIO_SUPPORT; | 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 | #ifdef MMCCAM | ||||
sc->rtsx_ccb = NULL; | sc->rtsx_ccb = NULL; | ||||
sc->rtsx_cam_status = 0; | sc->rtsx_cam_status = 0; | ||||
SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "cam_status", CTLFLAG_RD, | SYSCTL_ADD_U8(ctx, tree, OID_AUTO, "cam_status", CTLFLAG_RD, | ||||
&sc->rtsx_cam_status, 0, "driver cam card present"); | &sc->rtsx_cam_status, 0, "driver cam card present"); | ||||
if ((sc->rtsx_devq = cam_simq_alloc(1)) == NULL) { | if ((sc->rtsx_devq = cam_simq_alloc(1)) == NULL) { | ||||
device_printf(dev, "Error during CAM queue allocation\n"); | device_printf(dev, "Error during CAM queue allocation\n"); | ||||
Show All 19 Lines | #endif /* MMCCAM */ | ||||
/* Initialize device. */ | /* Initialize device. */ | ||||
if (rtsx_init(sc)) { | if (rtsx_init(sc)) { | ||||
device_printf(dev, "Error during rtsx_init()\n"); | device_printf(dev, "Error during rtsx_init()\n"); | ||||
goto destroy_rtsx_irq; | goto destroy_rtsx_irq; | ||||
} | } | ||||
/* | /* | ||||
* Schedule a card detection as we won't get an interrupt | * 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); | ||||
Not Done Inline ActionsThis panic is fixed by commit d5341d72a11be200e536ac7d8967449a3f521792, I believe. The delay should not be necessary anymore. markj: This panic is fixed by commit d5341d72a11be200e536ac7d8967449a3f521792, I believe. The delay… | |||||
Not Done Inline Actions
@hlh_restart.be, please confirm. I'll revert this one when you do. jkim: > This panic is fixed by commit d5341d72a11be200e536ac7d8967449a3f521792, I believe. The delay… | |||||
Done Inline ActionsI never encounter this panic on my development/test configuration (acer with RTL8411B) so I can't test if everything is OK with delay(500). This delay is only during attach so I think it make no harm to keep it like this. hlh_restart.be: I never encounter this panic on my development/test configuration (acer with RTL8411B) so I… | |||||
if (rtsx_is_card_present(sc)) | 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 | else | ||||
device_printf(sc->rtsx_dev, "Card absent\n"); | device_printf(sc->rtsx_dev, "No card is detected\n"); | ||||
rtsx_card_task(sc, 0); | rtsx_card_task(sc, 0); | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(dev, "Device attached\n"); | device_printf(dev, "Device attached\n"); | ||||
return (0); | return (0); | ||||
destroy_rtsx_irq: | destroy_rtsx_irq: | ||||
bus_teardown_intr(dev, sc->rtsx_irq_res, sc->rtsx_irq_cookie); | bus_teardown_intr(dev, sc->rtsx_irq_res, sc->rtsx_irq_cookie); | ||||
destroy_rtsx_res: | destroy_rtsx_res: | ||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->rtsx_res_id, | bus_release_resource(dev, SYS_RES_MEMORY, sc->rtsx_res_id, | ||||
sc->rtsx_res); | sc->rtsx_res); | ||||
rtsx_dma_free(sc); | |||||
destroy_rtsx_irq_res: | destroy_rtsx_irq_res: | ||||
callout_drain(&sc->rtsx_timeout_callout); | callout_drain(&sc->rtsx_timeout_callout); | ||||
bus_release_resource(dev, SYS_RES_IRQ, sc->rtsx_irq_res_id, | bus_release_resource(dev, SYS_RES_IRQ, sc->rtsx_irq_res_id, | ||||
sc->rtsx_irq_res); | sc->rtsx_irq_res); | ||||
pci_release_msi(dev); | pci_release_msi(dev); | ||||
RTSX_LOCK_DESTROY(sc); | RTSX_LOCK_DESTROY(sc); | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
if (sc->rtsx_sim != NULL) { | if (sc->rtsx_sim != NULL) { | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | rtsx_suspend(device_t dev) | ||||
device_printf(dev, "Suspend\n"); | device_printf(dev, "Suspend\n"); | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
if (sc->rtsx_ccb != NULL) { | if (sc->rtsx_ccb != NULL) { | ||||
device_printf(dev, "Request in progress: CMD%u, rtsr_intr_status: 0x%08x\n", | device_printf(dev, "Request in progress: CMD%u, rtsr_intr_status: 0x%08x\n", | ||||
sc->rtsx_ccb->mmcio.cmd.opcode, sc->rtsx_intr_status); | sc->rtsx_ccb->mmcio.cmd.opcode, sc->rtsx_intr_status); | ||||
} | } | ||||
#else | #else /* !MMCCAM */ | ||||
if (sc->rtsx_req != NULL) { | if (sc->rtsx_req != NULL) { | ||||
device_printf(dev, "Request in progress: CMD%u, rtsr_intr_status: 0x%08x\n", | device_printf(dev, "Request in progress: CMD%u, rtsr_intr_status: 0x%08x\n", | ||||
sc->rtsx_req->cmd->opcode, sc->rtsx_intr_status); | sc->rtsx_req->cmd->opcode, sc->rtsx_intr_status); | ||||
} | } | ||||
#endif /* MMCCAM */ | #endif /* MMCCAM */ | ||||
bus_generic_suspend(dev); | bus_generic_suspend(dev); | ||||
▲ Show 20 Lines • Show All 49 Lines • Show Last 20 Lines |
Can you please swap the order of timeout1 and timeout2?