summaryrefslogtreecommitdiff
path: root/drivers/memstick
diff options
context:
space:
mode:
authorUlf Hansson <ulfh@kernel.org>2026-09-30 18:01:51 +0200
committerUlf Hansson <ulfh@kernel.org>2026-09-30 18:01:51 +0200
commitb151b1e4bd6a32fdcd5bfd130af50a2efd3aaf7d (patch)
treef76becd5715b57520607deab147da05ddb4d59cf /drivers/memstick
parentc2063613bceaaffe864ff781082845d322ffb2e1 (diff)
parentc96ca94425b076dc398d929366e378d1e22ec794 (diff)
mmc: Merge branch fixes into next
Merge the mmc fixes for v7.3-rc[n] into the next branch, to allow them to get tested together with the mmc changes that are targeted for the next release. Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Diffstat (limited to 'drivers/memstick')
-rw-r--r--drivers/memstick/host/rtsx_usb_ms.c31
1 files changed, 11 insertions, 20 deletions
diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c
index beadc389f15f..d5b3a96fc609 100644
--- a/drivers/memstick/host/rtsx_usb_ms.c
+++ b/drivers/memstick/host/rtsx_usb_ms.c
@@ -27,7 +27,6 @@ struct rtsx_usb_ms {
struct memstick_host *msh;
struct memstick_request *req;
- struct mutex host_mutex;
struct work_struct handle_req;
struct delayed_work poll_card;
@@ -514,6 +513,13 @@ static void rtsx_usb_ms_handle_req(struct work_struct *work)
struct memstick_host *msh = host->msh;
int rc;
+ /* Fail requests after eject so their waiters are released. */
+ if (host->eject) {
+ while (!memstick_next_req(msh, &host->req))
+ host->req->error = -ENOMEDIUM;
+ return;
+ }
+
if (!host->req) {
pm_runtime_get_sync(ms_dev(host));
do {
@@ -547,8 +553,7 @@ static void rtsx_usb_ms_request(struct memstick_host *msh)
dev_dbg(ms_dev(host), "--> %s\n", __func__);
- if (!host->eject)
- schedule_work(&host->handle_req);
+ schedule_work(&host->handle_req);
}
static int rtsx_usb_ms_set_param(struct memstick_host *msh,
@@ -781,7 +786,6 @@ static int rtsx_usb_ms_drv_probe(struct platform_device *pdev)
host->power_mode = MEMSTICK_POWER_OFF;
platform_set_drvdata(pdev, host);
- mutex_init(&host->host_mutex);
INIT_WORK(&host->handle_req, rtsx_usb_ms_handle_req);
INIT_DELAYED_WORK(&host->poll_card, rtsx_usb_ms_poll_card);
@@ -812,27 +816,12 @@ static void rtsx_usb_ms_drv_remove(struct platform_device *pdev)
{
struct rtsx_usb_ms *host = platform_get_drvdata(pdev);
struct memstick_host *msh = host->msh;
- int err;
host->eject = true;
msh->removing = true;
- cancel_work_sync(&host->handle_req);
+ flush_work(&host->handle_req);
cancel_delayed_work_sync(&host->poll_card);
- mutex_lock(&host->host_mutex);
- if (host->req) {
- dev_dbg(ms_dev(host),
- "%s: Controller removed during transfer\n",
- dev_name(&msh->dev));
- host->req->error = -ENOMEDIUM;
- do {
- err = memstick_next_req(msh, &host->req);
- if (!err)
- host->req->error = -ENOMEDIUM;
- } while (!err);
- }
- mutex_unlock(&host->host_mutex);
-
/* Balance possible unbalanced usage count
* e.g. unconditional module removal
*/
@@ -841,6 +830,8 @@ static void rtsx_usb_ms_drv_remove(struct platform_device *pdev)
pm_runtime_disable(ms_dev(host));
memstick_remove_host(msh);
+ /* No card, no new requests; wait for the last failed one to finish. */
+ cancel_work_sync(&host->handle_req);
dev_dbg(ms_dev(host),
": Realtek USB Memstick controller has been removed\n");
memstick_free_host(msh);